diff --git a/lib/CLI.php b/lib/CLI.php index 7f22f94..0b1f3b9 100644 --- a/lib/CLI.php +++ b/lib/CLI.php @@ -78,9 +78,8 @@ Commands: user set-pass [] - Changes 's password to . If not password is - specified, a random password will be generated and printed to standard - output. + Changes 's password to . If no password is specified, + a random password will be generated and printed to standard output. The --oldpass= option can be used to supply a user's exiting password if this is required by the authentication driver to change a diff --git a/lib/ImportExport/OPML.php b/lib/ImportExport/OPML.php index 7328413..a45d4e1 100644 --- a/lib/ImportExport/OPML.php +++ b/lib/ImportExport/OPML.php @@ -151,6 +151,23 @@ class OPML { throw new Exception("invalidSemantics", ['type' => "OPML"]); } $body = $body->item(0); + // function to find the next node in the tree + $next = function(\DOMNode $node, bool $visitChildren = true) use ($body) { + if ($visitChildren && $node->hasChildNodes()) { + return $node->firstChild; + } elseif ($node->nextSibling) { + return $node->nextSibling; + } else { + while (!$node->nextSibling && !$node->isSameNode($body)) { + $node = $node->parentNode; + } + if (!$node->isSameNode($body)) { + return $node->nextSibling; + } else { + return null; + } + } + }; $folders = []; $feeds = []; // add the root folder to a map from folder DOM nodes to folder ID numbers @@ -158,7 +175,7 @@ class OPML { $folderMap[$body] = sizeof($folderMap); // iterate through each node in the body $node = $body->firstChild; - while ($node && !$node->isSameNode($body)) { + while ($node) { if ($node->nodeType == \XML_ELEMENT_NODE && $node->nodeName === "outline") { // process any nodes which are outlines if ($node->getAttribute("type") === "rss") { @@ -187,11 +204,11 @@ class OPML { $folders[$id] = ['id' => $id, 'name' => $node->getAttribute("text"), 'parent' => $folderMap[$node->parentNode]]; } // proceed to child nodes, if any - $node = $node->hasChildNodes() ? $node->firstChild : ($node->nextSibling ?: $node->parentNode); + $node = $next($node); } } else { // skip any node which is not an outline element; if the node has descendents they are skipped as well - $node = $node->nextSibling ?: $node->parentNode; + $node = $next($node, false); } } return [$feeds, $folders]; diff --git a/tests/cases/ImportExport/TestOPML.php b/tests/cases/ImportExport/TestOPML.php index 94d1b05..59ea9c1 100644 --- a/tests/cases/ImportExport/TestOPML.php +++ b/tests/cases/ImportExport/TestOPML.php @@ -166,6 +166,39 @@ OPML_EXPORT_SERIALIZATION; 'tags' => ["whee", "whoo", ""], ], ], []]], + ["FoldersOnly.opml", true, [[], []]], + ["FoldersOnly.opml", false, [[], [1 => + [ + 'id' => 1, + 'name' => "Folder 1", + 'parent' => 0, + ], + [ + 'id' => 2, + 'name' => "Folder 2", + 'parent' => 0, + ], + [ + 'id' => 3, + 'name' => "Also a folder", + 'parent' => 2, + ], + [ + 'id' => 4, + 'name' => "Still a folder", + 'parent' => 2, + ], + [ + 'id' => 5, + 'name' => "Folder 5", + 'parent' => 4, + ], + [ + 'id' => 6, + 'name' => "Folder 6", + 'parent' => 0, + ], + ]]], ]; } } diff --git a/tests/docroot/Import/OPML/FoldersOnly.opml b/tests/docroot/Import/OPML/FoldersOnly.opml new file mode 100644 index 0000000..34b7a69 --- /dev/null +++ b/tests/docroot/Import/OPML/FoldersOnly.opml @@ -0,0 +1,12 @@ + + + + + + + + + + + +