Skip to content

Commit f30a684

Browse files
Merge pull request #231 from barnabywalters/main
Fixed issue parsing elements with mixed valid and invalid mf2 classnames
2 parents 2a2e140 + b404109 commit f30a684

File tree

2 files changed

+47
-10
lines changed

2 files changed

+47
-10
lines changed

Mf2/Parser.php

+16-10
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ function mfNamesFromClass($class, $prefix='h-') {
144144
return $matches;
145145
}
146146

147+
/**
148+
* Registered with the XPath object and used within XPaths for finding root elements.
149+
* @param string $class
150+
* @return bool
151+
*/
152+
function classHasMf2RootClassname($class) {
153+
return count(mfNamesFromClass($class, 'h-')) > 0;
154+
}
155+
147156
/**
148157
* Get Nested µf Property Name From Class
149158
*
@@ -371,7 +380,10 @@ public function __construct($input, $url = null, $jsonMode = false) {
371380
@$doc->loadHTML('');
372381
}
373382

383+
// Create an XPath object and allow some PHP functions to be used within XPath queries.
374384
$this->xpath = new DOMXPath($doc);
385+
$this->xpath->registerNamespace('php', 'http://php.net/xpath');
386+
$this->xpath->registerPhpFunctions('\\Mf2\\classHasMf2RootClassname');
375387

376388
$baseurl = $url;
377389
foreach ($this->xpath->query('//base[@href]') as $base) {
@@ -1164,7 +1176,7 @@ public function parseH(\DOMElement $e, $is_backcompat = false, $has_nested_mf =
11641176
'type' => $mfTypes,
11651177
'properties' => $return
11661178
);
1167-
1179+
11681180
if(trim($e->getAttribute('id')) !== '') {
11691181
$parsed['id'] = trim($e->getAttribute("id"));
11701182
}
@@ -1506,7 +1518,7 @@ public function parseFromId($id, $convertClassic=true) {
15061518
public function getRootMF(DOMElement $context = null) {
15071519
// start with mf2 root class name xpath
15081520
$xpaths = array(
1509-
'contains(concat(" ",normalize-space(@class)), " h-")'
1521+
'(php:function("\\Mf2\\classHasMf2RootClassname", normalize-space(@class)))'
15101522
);
15111523

15121524
// add mf1 root class names
@@ -1687,15 +1699,9 @@ public function addMfClasses(DOMElement $el, $classes) {
16871699
*/
16881700
public function hasRootMf2(\DOMElement $el) {
16891701
$class = str_replace(array("\t", "\n"), ' ', $el->getAttribute('class'));
1690-
$classes = array_filter(explode(' ', $class));
16911702

1692-
foreach ( $classes as $classname ) {
1693-
if ( strpos($classname, 'h-') === 0 ) {
1694-
return true;
1695-
}
1696-
}
1697-
1698-
return false;
1703+
// Check for valid mf2 root classnames, not just any classname with a h- prefix.
1704+
return count(mfNamesFromClass($class, 'h-')) > 0;
16991705
}
17001706

17011707
/**

tests/Mf2/ParserTest.php

+31
Original file line numberDiff line numberDiff line change
@@ -860,5 +860,36 @@ public function testInvalidOrdinalDate() {
860860
$this->assertEquals('2016-12-31', Mf2\normalizeOrdinalDate('2016-366'));
861861
$this->assertEquals('', Mf2\normalizeOrdinalDate('2016-367'));
862862
}
863+
864+
/**
865+
* @see https://github.com/microformats/php-mf2/issues/230
866+
*/
867+
public function testPropertyWithInvalidHPrefixedRootClassParsed() {
868+
$input = <<<EOF
869+
<div class="h-card">
870+
<img class="u-photo w-32 h-32" alt="Jon Doe" src="/image.jpg"/>
871+
</div>
872+
EOF;
873+
874+
$output = Mf2\parse($input);
875+
$this->assertEquals(array('value' => '/image.jpg', 'alt' => 'Jon Doe'), $output['items'][0]['properties']['photo'][0]);
876+
}
877+
878+
public function testGetRootMfOnlyFindsValidElements() {
879+
$input = <<<EOF
880+
<div class="h-entry>"> <a href="https://example.com" class="u-url">content</a></div>
881+
<div class="h-entry1>"> <a href="https://example.com" class="u-url">content</a></div>
882+
<div class="h-👍"> <a href="https://example.com" class="u-url">content</a></div>
883+
<div class="h-hentry_"> <a href="https://example.com" class="u-url">content</a></div>
884+
<div class="h-"> <a href="https://example.com" class="u-url">content</a></div>
885+
<div class="h-vendor123-name"><a href="https://example.com" class="u-url">content</a></div>
886+
EOF;
887+
888+
$p = new Mf2\Parser($input);
889+
$rootEls = $p->getRootMF();
890+
891+
$this->assertEquals(1, count($rootEls));
892+
$this->assertEquals('h-vendor123-name', $rootEls->item(0)->getAttribute('class'));
893+
}
863894
}
864895

0 commit comments

Comments
 (0)