Skip to content
Open
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
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"require-dev": {
"phpunit/phpunit": "^8.0 || ^9.0",
"php-coveralls/php-coveralls": "^2.0",
"vimeo/psalm": "6.12.0"
"vimeo/psalm": "6.13.1"
},
"autoload": {
"psr-4": {
Expand Down
184 changes: 134 additions & 50 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="6.12.0@cf420941d061a57050b6c468ef2c778faf40aee2">
<files psalm-version="6.13.1@1e3b7f0a8ab32b23197b91107adc0a7ed8a05b51">
<file src="src/DOMBuilder.php">
<MixedReturnStatement>
<code><![CDATA[HTMLDocument::createFromFile($file, LIBXML_NOERROR | HTML_NO_DEFAULT_NS)]]></code>
<code><![CDATA[HTMLDocument::createFromString($html, LIBXML_NOERROR | HTML_NO_DEFAULT_NS)]]></code>
</MixedReturnStatement>
</file>
<file src="src/Reader/JsonLdReader.php">
<ArgumentTypeCoercion>
<code><![CDATA[$data]]></code>
<code><![CDATA[$item]]></code>
<code><![CDATA[$value]]></code>
</ArgumentTypeCoercion>
<DocblockTypeContradiction>
<code><![CDATA[is_string($type)]]></code>
</DocblockTypeContradiction>
<MissingClosureParamType>
<code><![CDATA[$a]]></code>
</MissingClosureParamType>
<MixedArgument>
<code><![CDATA[$name]]></code>
<code><![CDATA[$node->textContent]]></code>
<code><![CDATA[$nodes]]></code>
</MixedArgument>
<MixedArrayAccess>
<code><![CDATA[$name[0]]]></code>
</MixedArrayAccess>
<MixedMethodCall>
<code><![CDATA[$nodes]]></code>
</MixedMethodCall>
<PossiblyInvalidArgument>
<code><![CDATA[fn (DOMNode $node) => $this->readJson($node->textContent, $url)]]></code>
<code><![CDATA[fn (DOMNode|Node $node) => $this->readJson($node->textContent, $url)]]></code>
</PossiblyInvalidArgument>
<RawObjectIteration>
<code><![CDATA[$item]]></code>
</RawObjectIteration>
<RedundantConditionGivenDocblockType>
<code><![CDATA[null]]></code>
</RedundantConditionGivenDocblockType>
</file>
<file src="src/Reader/MicrodataReader.php">
<InvalidArgument>
<code><![CDATA[function (DOMNode $itemprop) use ($node, $xpath) {
<code><![CDATA[function (DOMNode|Node $itemprop) use ($node) {
for (; ;) {
$itemprop = $itemprop->parentNode;

Expand All @@ -44,9 +38,57 @@
}
}]]></code>
</InvalidArgument>
<MixedArgument>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$itemid->textContent]]></code>
<code><![CDATA[$itemprops]]></code>
<code><![CDATA[$itemtype->textContent]]></code>
<code><![CDATA[$names]]></code>
<code><![CDATA[$node->textContent]]></code>
<code><![CDATA[$nodes]]></code>
</MixedArgument>
<MixedMethodCall>
<code><![CDATA[$itemprops]]></code>
<code><![CDATA[$nodes]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[isSameNode]]></code>
</MixedMethodCall>
<MixedPropertyFetch>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$itemid->textContent]]></code>
<code><![CDATA[$itemprop->attributes]]></code>
<code><![CDATA[$itemprop->attributes->getNamedItem('itemprop')->textContent]]></code>
<code><![CDATA[$itemprop->parentNode]]></code>
<code><![CDATA[$itemtype->textContent]]></code>
</MixedPropertyFetch>
<MixedReturnStatement>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
</MixedReturnStatement>
<PossiblyInvalidArgument>
<code><![CDATA[fn (DOMNode $node) => $this->nodeToItem($node, $xpath, $url)]]></code>
<code><![CDATA[function (DOMNode $itemprop) use ($node, $xpath) {
<code><![CDATA[$node]]></code>
<code><![CDATA[$node]]></code>
<code><![CDATA[$node]]></code>
<code><![CDATA[fn (DOMNode|Node $node) => $this->nodeToItem($node, $xpath, $url)]]></code>
<code><![CDATA[function (DOMNode|Node $itemprop) use ($node) {
for (; ;) {
$itemprop = $itemprop->parentNode;

Expand All @@ -59,25 +101,29 @@
}
}
}]]></code>
</PossiblyInvalidArgument>
<PossiblyNullArgument>
<code><![CDATA[$names]]></code>
<code><![CDATA[preg_replace('/\s+/', ' ', $node->textContent)]]></code>
</PossiblyNullArgument>
</PossiblyInvalidArgument>
<PossiblyNullPropertyFetch>
<code><![CDATA[$itemprop->attributes->getNamedItem('itemprop')->textContent]]></code>
<code><![CDATA[$itemprop->attributes]]></code>
<code><![CDATA[$itemprop->parentNode]]></code>
</PossiblyNullPropertyFetch>
<PossiblyNullReference>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[isSameNode]]></code>
</PossiblyNullReference>
<RiskyTruthyFalsyComparison>
<code><![CDATA[$itemprop->attributes->getNamedItem('itemscope')]]></code>
<code><![CDATA[$itemprop->isSameNode($node)]]></code>
</RiskyTruthyFalsyComparison>
<UndefinedPropertyFetch>
<code><![CDATA[$itemprop->attributes]]></code>
<code><![CDATA[$node->attributes]]></code>
<code><![CDATA[$node->attributes]]></code>
</UndefinedPropertyFetch>
</file>
<file src="src/Reader/RdfaLiteReader.php">
<InvalidArgument>
<code><![CDATA[function (DOMNode $itemprop) use ($node, $xpath) {
<code><![CDATA[function (DOMNode|Node $itemprop) use ($node) {
for (; ;) {
$itemprop = $itemprop->parentNode;

Expand All @@ -89,14 +135,53 @@
return false;
}
}

// Unreachable, but makes static analysis happy
return false;
}]]></code>
</InvalidArgument>
<MixedArgument>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$names]]></code>
<code><![CDATA[$node->textContent]]></code>
<code><![CDATA[$nodes]]></code>
<code><![CDATA[$properties]]></code>
<code><![CDATA[$resource->textContent]]></code>
<code><![CDATA[$typeof->textContent]]></code>
<code><![CDATA[$vocab->textContent]]></code>
</MixedArgument>
<MixedMethodCall>
<code><![CDATA[$nodes]]></code>
<code><![CDATA[$properties]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[isSameNode]]></code>
</MixedMethodCall>
<MixedPropertyFetch>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$attr->textContent]]></code>
<code><![CDATA[$itemprop->attributes]]></code>
<code><![CDATA[$itemprop->parentNode]]></code>
<code><![CDATA[$property->attributes->getNamedItem('property')->textContent]]></code>
<code><![CDATA[$resource->textContent]]></code>
<code><![CDATA[$typeof->textContent]]></code>
<code><![CDATA[$vocab->textContent]]></code>
</MixedPropertyFetch>
<MixedReturnStatement>
<code><![CDATA[$attr->textContent]]></code>
</MixedReturnStatement>
<PossiblyInvalidArgument>
<code><![CDATA[fn (DOMNode $node) => $this->nodeToItem($node, $xpath, $url, self::PREDEFINED_PREFIXES, null)]]></code>
<code><![CDATA[function (DOMNode $itemprop) use ($node, $xpath) {
<code><![CDATA[$node]]></code>
<code><![CDATA[$node]]></code>
<code><![CDATA[$node]]></code>
<code><![CDATA[fn (DOMNode|Node $node) => $this->nodeToItem($node, $xpath, $url, self::PREDEFINED_PREFIXES, null)]]></code>
<code><![CDATA[function (DOMNode|Node $itemprop) use ($node) {
for (; ;) {
$itemprop = $itemprop->parentNode;

Expand All @@ -108,27 +193,26 @@
return false;
}
}

// Unreachable, but makes static analysis happy
return false;
}]]></code>
</PossiblyInvalidArgument>
<PossiblyNullArgument>
<code><![CDATA[$names]]></code>
<code><![CDATA[$typeof->textContent]]></code>
<code><![CDATA[preg_replace('/\s+/', ' ', $node->textContent)]]></code>
</PossiblyNullArgument>
</PossiblyInvalidArgument>
<PossiblyNullPropertyFetch>
<code><![CDATA[$property->attributes->getNamedItem('property')->textContent]]></code>
<code><![CDATA[$typeof->textContent]]></code>
<code><![CDATA[$itemprop->attributes]]></code>
<code><![CDATA[$itemprop->parentNode]]></code>
</PossiblyNullPropertyFetch>
<PossiblyNullReference>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[getNamedItem]]></code>
<code><![CDATA[isSameNode]]></code>
</PossiblyNullReference>
<RiskyTruthyFalsyComparison>
<code><![CDATA[$itemprop->attributes->getNamedItem('typeof')]]></code>
<code><![CDATA[$itemprop->isSameNode($node)]]></code>
</RiskyTruthyFalsyComparison>
<UndefinedPropertyFetch>
<code><![CDATA[$node->attributes]]></code>
<code><![CDATA[$node->attributes]]></code>
<code><![CDATA[$node->attributes]]></code>
<code><![CDATA[$property->attributes]]></code>
</UndefinedPropertyFetch>
</file>
</files>
21 changes: 17 additions & 4 deletions src/DOMBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,42 @@

namespace Brick\StructuredData;

use Dom\Document;
use Dom\HTMLDocument;
use DOMDocument;

use function class_exists;

use const Dom\HTML_NO_DEFAULT_NS;
use const LIBXML_NOERROR;
use const LIBXML_NOWARNING;

final class DOMBuilder
{
/**
* Builds a DOMDocument from an HTML string.
* Builds a (DOM)Document from an HTML string.
*/
public static function fromHTML(string $html): DOMDocument
public static function fromHTML(string $html): Document|DOMDocument
{
if (class_exists(HTMLDocument::class)) {
return HTMLDocument::createFromString($html, LIBXML_NOERROR | HTML_NO_DEFAULT_NS);
}

$document = new DOMDocument();
$document->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);

return $document;
}

/**
* Builds a DOMDocument from an HTML file.
* Builds a (DOM)Document from an HTML file.
*/
public static function fromHTMLFile(string $file): DOMDocument
public static function fromHTMLFile(string $file): Document|DOMDocument
{
if (class_exists(HTMLDocument::class)) {
return HTMLDocument::createFromFile($file, LIBXML_NOERROR | HTML_NO_DEFAULT_NS);
}

$document = new DOMDocument();
$document->loadHTMLFile($file, LIBXML_NOWARNING | LIBXML_NOERROR);

Expand Down
9 changes: 5 additions & 4 deletions src/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Brick\StructuredData;

use Dom\Document;
use DOMDocument;

/**
Expand All @@ -14,11 +15,11 @@ interface Reader
/**
* Reads the items contained in the given document.
*
* @param DOMDocument $document The DOM document to read.
* @param string $url The URL the document was retrieved from. This will be used only to resolve relative
* URLs in property values. The implementation must not attempt to connect to this URL.
* @param Document|DOMDocument $document The (DOM)Document to read.
* @param string $url The URL the document was retrieved from. This will be used only to resolve relative
* URLs in property values. The implementation must not attempt to connect to this URL.
*
* @return Item[] The top-level items.
*/
public function read(DOMDocument $document, string $url): array;
public function read(Document|DOMDocument $document, string $url): array;
}
Loading