mirror of
https://github.com/j0k3r/php-readability.git
synced 2026-09-27 06:26:17 +00:00
Fix "Undefined array key 0" error
If a matching element isn't the first child (e.g. preceded by a whitespace text node), it may sit at a key other than 0 after some cleanup, leading to a "Undefined array key 0" error. This fix is now covered by 6 tests. Fixes #96 Signed-off-by: Kevin Decherf <kevin@kdecherf.com>
This commit is contained in:
+8
-1
@@ -1483,8 +1483,15 @@ class Readability implements LoggerAwareInterface
|
||||
$childNodes = iterator_to_array($node->childNodes);
|
||||
$children = array_filter($childNodes, static fn ($childNode) => $childNode instanceof \DOMElement);
|
||||
|
||||
// array_first() has been added in PHP 8.5, failing back for older versions
|
||||
if (!\function_exists('array_first')) {
|
||||
$firstChild = $children ? $children[array_key_first($children)] : null;
|
||||
} else {
|
||||
$firstChild = array_first($children);
|
||||
}
|
||||
|
||||
// There should be exactly 1 element child with given tag
|
||||
if (1 !== \count($children) || $children[0]->nodeName !== $tag) {
|
||||
if (1 !== \count($children) || $firstChild->nodeName !== $tag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -464,6 +464,49 @@ class ReadabilityTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertTrue($res);
|
||||
}
|
||||
|
||||
public function dataForHasSingleTagInsideElement(): array
|
||||
{
|
||||
return [
|
||||
'single matching tag, no other content' => [
|
||||
'<div><p>Some text</p></div>', 'p', true,
|
||||
],
|
||||
'single matching tag with comment' => [
|
||||
'<div><!-- comment --><p>Some text</p></div>', 'p', true,
|
||||
],
|
||||
'whitespace-only text around single matching tag' => [
|
||||
'<div> <p>Some text</p> </div>', 'p', true,
|
||||
],
|
||||
'two matching tags' => [
|
||||
'<div><p>One</p><p>Two</p></div>', 'p', false,
|
||||
],
|
||||
'non-whitespace text alongside the single tag' => [
|
||||
'<div>Some text<p>One</p></div>', 'p', false,
|
||||
],
|
||||
'single tag with a different name' => [
|
||||
'<div><span>One</span></div>', 'p', false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataForHasSingleTagInsideElement
|
||||
*/
|
||||
public function testHasSingleTagInsideElement(string $html, string $tag, bool $expected): void
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadHTML('<html><body>' . $html . '</body></html>');
|
||||
$node = $dom->getElementsByTagName('div')->item(0);
|
||||
|
||||
$readability = $this->getReadability('', '', 'libxml', false);
|
||||
|
||||
$method = new \ReflectionMethod($readability, 'hasSingleTagInsideElement');
|
||||
if (\PHP_VERSION_ID < 80100) {
|
||||
$method->setAccessible(true);
|
||||
}
|
||||
|
||||
$this->assertSame($expected, $method->invoke($readability, $node, $tag));
|
||||
}
|
||||
|
||||
public function testKeepFootnotes(): void
|
||||
{
|
||||
// from https://www.schreibdichte.de/blog/feed-aggregator-und-spaeter-lesen-dienst-im-team
|
||||
|
||||
Reference in New Issue
Block a user