Skip to content

Commit 3e4b182

Browse files
committed
Fix recursive parsing
1 parent bc9de8f commit 3e4b182

File tree

2 files changed

+40
-75
lines changed

2 files changed

+40
-75
lines changed

Mf2/Parser.php

Lines changed: 25 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,64 +1348,44 @@ public function parse($convertClassic = true, DOMElement $context = null) {
13481348
*/
13491349
public function parse_recursive(DOMElement $context = null, $depth = 0) {
13501350
$mfs = array();
1351-
$children = array();
1352-
$properties = array();
13531351
$mfElements = $this->getRootMF($context);
1354-
$result = array();
13551352

13561353
foreach ($mfElements as $node) {
1357-
$merge_properties = array();
1358-
$children = array();
1359-
13601354
$is_backcompat = !$this->hasRootMf2($node);
13611355

1362-
if ( $this->convertClassic && $is_backcompat ) {
1356+
if ($this->convertClassic && $is_backcompat) {
13631357
$this->backcompat($node);
13641358
}
13651359

1366-
$recurse = $this->parse_recursive($node, ++$depth);
1367-
1368-
// recursion returned parsed result
1369-
if ( !empty($recurse) ) {
1370-
1371-
// parsed result is an mf root
1372-
if ( is_numeric(key($recurse)) ) {
1373-
1374-
// nested mf
1375-
if ( $depth > 0 ) {
1376-
$children = $recurse;
1377-
// top-level mf
1378-
} else {
1379-
$mfs = array_merge_recursive($mfs, $recurse);
1380-
}
1381-
1382-
// parsed result is an mf property
1383-
} else {
1384-
$merge_properties = $recurse;
1385-
}
1386-
1387-
}
1360+
$recurse = $this->parse_recursive($node, $depth + 1);
13881361

13891362
// set bool flag for nested mf
1390-
$has_nested_mf = ($children || $merge_properties);
1363+
$has_nested_mf = ($recurse);
13911364

13921365
// parse for root mf
13931366
$result = $this->parseH($node, $is_backcompat, $has_nested_mf);
13941367

1395-
// merge nested mf properties
1396-
if ( $merge_properties && isset($result['properties']) ) {
1397-
$result['properties'] = array_merge($result['properties'], $merge_properties);
1398-
}
1368+
// TODO: Determine if clearing this is required?
1369+
$this->elementPrefixParsed($node, 'h');
1370+
$this->elementPrefixParsed($node, 'p');
1371+
$this->elementPrefixParsed($node, 'u');
1372+
$this->elementPrefixParsed($node, 'dt');
1373+
$this->elementPrefixParsed($node, 'e');
13991374

14001375
// parseH returned a parsed result
1401-
if ( $result ) {
1376+
if ($result) {
1377+
1378+
// merge recursive results into current results
1379+
if ($recurse) {
1380+
$result = array_merge_recursive($result, $recurse);
1381+
}
14021382

14031383
// currently a nested mf; check if node is an mf property of parent
1404-
if ( $depth > 0 ) {
1384+
if ($depth > 0) {
14051385
$temp_properties = nestedMfPropertyNamesFromElement($node);
14061386

1407-
// properties found; set up parsed result in $properties
1408-
if ( !empty($temp_properties) ) {
1387+
// properties found; set up parsed result in 'properties'
1388+
if (!empty($temp_properties)) {
14091389

14101390
foreach ($temp_properties as $property => $prefixes) {
14111391
// Note: handling microformat nesting under multiple conflicting prefixes is not currently specified by the mf2 parsing spec.
@@ -1420,39 +1400,20 @@ public function parse_recursive(DOMElement $context = null, $depth = 0) {
14201400
$prefixSpecificResult['value'] = (empty($result['properties']['url'])) ? $this->parseU($node) : reset($result['properties']['url']);
14211401
}
14221402

1423-
if ( $children ) {
1424-
$prefixSpecificResult['children'] = $children;
1425-
}
1426-
1427-
$properties[$property][] = $prefixSpecificResult;
1403+
$mfs['properties'][$property][] = $prefixSpecificResult;
14281404
}
14291405

1406+
// otherwise, set up in 'children'
1407+
} else {
1408+
$mfs['children'][] = $result;
14301409
}
1431-
1432-
// TODO: Determine if clearing this is required?
1433-
$this->elementPrefixParsed($node, 'h');
1434-
$this->elementPrefixParsed($node, 'p');
1435-
$this->elementPrefixParsed($node, 'u');
1436-
$this->elementPrefixParsed($node, 'dt');
1437-
$this->elementPrefixParsed($node, 'e');
1438-
}
1439-
1440-
// add children mf from recursion
1441-
if ( $children ) {
1442-
$result['children'] = $children;
1410+
// otherwise, top-level mf
1411+
} else {
1412+
$mfs[] = $result;
14431413
}
1444-
1445-
$mfs[] = $result;
14461414
}
1447-
14481415
}
14491416

1450-
// node is an mf property of parent, return $properties which has property name(s) as array indices
1451-
if ( $properties && ($depth > 1) ) {
1452-
return $properties;
1453-
}
1454-
1455-
// otherwise, return $mfs which has numeric array indices
14561417
return $mfs;
14571418
}
14581419

tests/Mf2/ParserTest.php

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -598,8 +598,11 @@ public function testNoImpliedNameWhenNestedMicroformat()
598598
$this->assertArrayNotHasKey('name', $output['items'][0]['properties']);
599599
}
600600

601-
public function testChildObjects() {
602-
$input = <<<END
601+
/**
602+
* @see https://github.com/indieweb/php-mf2/issues/143
603+
*/
604+
public function testChildObjects() {
605+
$input = <<<END
603606
<html>
604607
<head>
605608
<title>Test</title>
@@ -628,15 +631,16 @@ public function testChildObjects() {
628631
</body>
629632
</html>
630633
END;
631-
$output = Mf2\parse($input);
632-
633-
$this->assertEquals('Author Name', $output['items'][0]['properties']['author'][0]['properties']['name'][0]);
634-
$this->assertEquals(4, count($output['items'][0]['children']));
635-
$this->assertEquals('One', count($output['items'][0]['children'][0]['properties']['name'][0]));
636-
$this->assertEquals('Two', count($output['items'][0]['children'][1]['properties']['name'][0]));
637-
$this->assertEquals('Three', count($output['items'][0]['children'][2]['properties']['name'][0]));
638-
$this->assertEquals('Four', count($output['items'][0]['children'][3]['properties']['name'][0]));
639-
}
634+
$output = Mf2\parse($input);
635+
636+
$this->assertArrayHasKey('author', $output['items'][0]['properties']);
637+
$this->assertEquals('Author Name', $output['items'][0]['properties']['author'][0]['properties']['name'][0]);
638+
$this->assertCount(4, $output['items'][0]['children']);
639+
$this->assertEquals('One', $output['items'][0]['children'][0]['properties']['name'][0]);
640+
$this->assertEquals('Two', $output['items'][0]['children'][1]['properties']['name'][0]);
641+
$this->assertEquals('Three', $output['items'][0]['children'][2]['properties']['name'][0]);
642+
$this->assertEquals('Four', $output['items'][0]['children'][3]['properties']['name'][0]);
643+
}
640644

641645
}
642646

0 commit comments

Comments
 (0)