Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP8.1 compatibility #2

Merged
merged 6 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ build
composer.lock
vendor
phpcs.xml
phpunit.xml
phpunit.xml
.idea
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
}
],
"require": {
"php" : "~7.0",
"ext-dom": "*"
"php" : "~8.1",
"ext-dom": "*",
"ext-libxml": "*"
},
"require-dev": {
"phpunit/phpunit" : ">=5.4.3",
Expand Down
16 changes: 9 additions & 7 deletions src/MicrodataDOMDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace YusufKandemir\MicrodataParser;

class MicrodataDOMDocument extends \DOMDocument
use DOMDocument;
use DOMXPath;

class MicrodataDOMDocument extends DOMDocument
{
/** @var \DOMXPath */
public $xpath;
public DOMXPath $xpath;

/**
* Get top-level items of the document
Expand All @@ -23,11 +25,11 @@ public function getItems() : \DOMNodeList
* {@inheritdoc}
* Also assigns $xpath with DOMXPath of freshly loaded DOMDocument
*/
public function loadHTML($source, $options = 0)
public function loadHTML($source, $options = 0): DOMDocument|bool
{
$return = parent::loadHTML($source, $options);

$this->xpath = new \DOMXPath($this);
$this->xpath = new DOMXPath($this);

return $return;
}
Expand All @@ -36,11 +38,11 @@ public function loadHTML($source, $options = 0)
* {@inheritdoc}
* Also assigns $xpath with DOMXPath of freshly loaded DOMDocument
*/
public function loadHTMLFile($filename, $options = 0)
public function loadHTMLFile($filename, $options = 0): DOMDocument|bool
{
$return = parent::loadHTMLFile($filename, $options);

$this->xpath = new \DOMXPath($this);
$this->xpath = new DOMXPath($this);

return $return;
}
Expand Down
31 changes: 17 additions & 14 deletions src/MicrodataDOMElement.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@

namespace YusufKandemir\MicrodataParser;

use function array_key_exists;
use function in_array;

class MicrodataDOMElement extends \DOMElement
{
/** @var array "tag name" to "attribute name" mapping */
private static $tagNameLookup = [
private static array $tagNameLookup = [
'audio' => 'src',
'embed' => 'src',
'iframe' => 'src',
Expand All @@ -23,7 +26,7 @@ class MicrodataDOMElement extends \DOMElement
];

/** @var array Attributes that have absolute values */
private static $absoluteAttributes = ['src', 'href', 'data',];
private static array $absoluteAttributes = ['src', 'href', 'data',];

/**
* @see https://www.w3.org/TR/2018/WD-microdata-20180426/#dfn-item-properties for details of algorithm
Expand Down Expand Up @@ -94,11 +97,11 @@ public function getPropertyNames() : array
/**
* @see https://www.w3.org/TR/2018/WD-microdata-20180426/#dfn-property-value for details of algorithm
*
* @param callable $absoluteUriHandler
* @param callable|null $absoluteUriHandler
*
* @return $this|string
*/
public function getPropertyValue(callable $absoluteUriHandler = null)
public function getPropertyValue(callable $absoluteUriHandler = null): string|static
{
if ($this->hasAttribute('itemscope')) {
return $this;
Expand All @@ -110,11 +113,11 @@ public function getPropertyValue(callable $absoluteUriHandler = null)

$value = '';

if (\array_key_exists($this->tagName, self::$tagNameLookup)) {
if (array_key_exists($this->tagName, self::$tagNameLookup)) {
$attribute = self::$tagNameLookup[$this->tagName];
$value = $this->getAttribute($attribute);

if (!empty($value) && \in_array($attribute, self::$absoluteAttributes) && !$this->isAbsoluteUri($value)) {
if (!empty($value) && in_array($attribute, self::$absoluteAttributes) && !$this->isAbsoluteUri($value)) {
$value = $absoluteUriHandler($value, $this->ownerDocument->documentURI);
}
}
Expand All @@ -132,7 +135,7 @@ public function getPropertyValue(callable $absoluteUriHandler = null)
*
* @return false|int
*/
protected function isAbsoluteUri(string $uri)
protected function isAbsoluteUri(string $uri): bool|int
{
return preg_match("/^\w+:/", trim($uri));
}
Expand All @@ -142,7 +145,7 @@ protected function isAbsoluteUri(string $uri)
*
* @return array Result array which contains child ElementNodes
*/
protected function getChildElementNodes()
protected function getChildElementNodes(): array
{
$childNodes = [];

Expand All @@ -160,9 +163,9 @@ protected function getChildElementNodes()
*
* @param string $attributeName Name of the attribute
*
* @return array|array[]|false|string[]
* @return array|false
*/
public function tokenizeAttribute(string $attributeName)
public function tokenizeAttribute(string $attributeName): array|bool
{
$attribute = [];

Expand All @@ -176,15 +179,15 @@ public function tokenizeAttribute(string $attributeName)
/**
* Splits given attribute value in space characters to array
*
* @param string $attribute
*
* @return array|false
* @see \preg_split() for possible return values and behaviour
*
* @see https://www.w3.org/TR/2018/WD-microdata-20180426/#dfn-split-a-string-on-spaces for definition of tokens
*
* @param string $attribute
*
* @return array[]|false|string[]
*/
protected function tokenize(string $attribute)
protected function tokenize(string $attribute): array|bool
{
return preg_split('/\s+/', trim($attribute));
}
Expand Down
32 changes: 17 additions & 15 deletions src/MicrodataParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace YusufKandemir\MicrodataParser;

use DOMElement;
use stdClass;

class MicrodataParser
{
/** @var MicrodataDOMDocument */
protected $dom;
protected MicrodataDOMDocument $dom;

/**
* Handler will be called with $value(non-absolute uri string) and $base(base uri) parameters
Expand All @@ -26,7 +28,7 @@ class MicrodataParser
*/
public function __construct(MicrodataDOMDocument $dom, callable $absoluteUriHandler = null)
{
$dom->registerNodeClass(\DOMElement::class, MicrodataDOMElement::class);
$dom->registerNodeClass(DOMElement::class, MicrodataDOMElement::class);

$this->dom = $dom;
$this->absoluteUriHandler = $absoluteUriHandler ?: function ($value, $base) {
Expand All @@ -48,34 +50,34 @@ public function toArray() : array
/**
* Extracts and converts microdata to object
*
* @return \stdClass
* @return stdClass
*/
public function toObject() : \stdClass
public function toObject() : stdClass
{
return $this->extractMicrodata();
}

/**
* Extracts and converts microdata to json using \json_encode()
*
* @see \json_encode() to description of parameters and return values
*
* @param int $options
* @param int $depth
*
* @return false|string
* @see \json_encode() to description of parameters and return values
*
*/
public function toJSON($options = 0, $depth = 512)
public function toJSON(int $options = 0, int $depth = 512): bool|string
{
return json_encode($this->extractMicrodata(), $options, $depth);
}

/**
* @return \stdClass
* @return stdClass
*/
protected function extractMicrodata() : \stdClass
protected function extractMicrodata() : stdClass
{
$result = new \stdClass;
$result = new stdClass;

$result->items = [];

Expand All @@ -92,11 +94,11 @@ protected function extractMicrodata() : \stdClass
* @param MicrodataDOMElement $item
* @param array $memory
*
* @return \stdClass
* @return stdClass
*/
protected function getObject(MicrodataDOMElement $item, $memory = []) : \stdClass
protected function getObject(MicrodataDOMElement $item, array $memory = []) : stdClass
{
$result = new \stdClass;
$result = new stdClass;

$memory[] = $item;

Expand All @@ -108,7 +110,7 @@ protected function getObject(MicrodataDOMElement $item, $memory = []) : \stdClas
}
// @todo Check if item ids are valid absolute urls or like isbn:xxx

$properties = new \stdClass;
$properties = new stdClass;

foreach ($item->getProperties() as $element) {
$value = $element->getPropertyValue($this->absoluteUriHandler);
Expand Down
28 changes: 21 additions & 7 deletions tests/MicrodataParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

namespace YusufKandemir\MicrodataParser\Tests;

use PHPUnit\Framework\TestCase;
use YusufKandemir\MicrodataParser\MicrodataDOMDocument;
use YusufKandemir\MicrodataParser\MicrodataParser;

class MicrodataParserTest extends \PHPUnit\Framework\TestCase
class MicrodataParserTest extends TestCase
{
protected function setUp()
protected function setUp() :void
{
libxml_use_internal_errors(true); // Ignore warnings of DOMDocument::loadHTML check
}

protected function getParser($data)
protected function getParser($data): MicrodataParser
{
$dom = new MicrodataDOMDocument;
$dom->loadHTML($data['source']);
Expand Down Expand Up @@ -66,7 +67,7 @@ public function testItUsesAbsoluteUriHandlerWhenHandlingAbsoluteUris()
$resultBefore = $parser->toObject();
$resultBeforeUri = $resultBefore->items[0]->properties->work[0];

$this->assertNotContains($baseUri, $resultBeforeUri);
$this->assertStringNotContainsString($baseUri, $resultBeforeUri);

$parser->setAbsoluteUriHandler(
function (string $value, string $base) use ($baseUri) : string {
Expand All @@ -77,13 +78,19 @@ function (string $value, string $base) use ($baseUri) : string {
$resultAfter = $parser->toObject();
$resultAfterUri = $resultAfter->items[0]->properties->work[0];

$this->assertContains($baseUri, $resultAfterUri);
$this->assertStringContainsString($baseUri, $resultAfterUri);
}

/**
* @todo Provide more test data
* @return array{
* 'W3C Example': array{uri: string, source: string, result: string}[],
* 'Itemref & src based tags': array{uri: string, source: string, result: string}[],
* 'Object & Data tags': array{uri: string, source: string, result: string}[],
* 'Itemid & Content attributes': array{uri: string, source: string, result: string}[]
* }
*/
public function data()
public function data(): array
{
return [
// https://www.w3.org/TR/microdata/#ex-jsonconv
Expand All @@ -102,13 +109,20 @@ public function data()
];
}

private function getTestData($folderName, $sourceName, $resultName)
/**
* @return array{uri: string, source: string, result: string}
*/
private function getTestData($folderName, $sourceName, $resultName): array
{
$folderPath = __DIR__.'/data/'.$folderName.'/';

$source = file_get_contents($folderPath . $sourceName);
$result = file_get_contents($folderPath . $resultName);

if ($source === false || $result === false) {
throw new \Exception('Could not load test data');
}

$uri = '';
// Set $uri if URI specified in test data
if (preg_match('/<!-- URI: (.*) -->/', $source, $matches)) {
Expand Down
5 changes: 3 additions & 2 deletions tests/MicrodataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

namespace YusufKandemir\MicrodataParser\Tests;

use DOMDocument;
use YusufKandemir\MicrodataParser\Microdata;
use YusufKandemir\MicrodataParser\MicrodataParser;

class MicrodataTest extends \PHPUnit\Framework\TestCase
{
protected $htmlFileName = __DIR__ . '/data/W3C/source.html';
protected string $htmlFileName = __DIR__ . '/data/W3C/source.html';

public function testItCreatesMicrodataParserFromHtml()
{
Expand All @@ -26,7 +27,7 @@ public function testItCreatesMicrodataParserFromHtmlFile()

public function testItCreatesMicrodataParserFromDomDocument()
{
$dom = new \DOMDocument;
$dom = new DOMDocument;
$dom->loadHTMLFile($this->htmlFileName);

$microdata = Microdata::fromDOMDocument($dom);
Expand Down