Browse Source

More OPML tests and fixes

microsub
J. King 5 years ago
parent
commit
0f7d49c21e
  1. 5
      lib/CLI.php
  2. 23
      lib/ImportExport/OPML.php
  3. 33
      tests/cases/ImportExport/TestOPML.php
  4. 12
      tests/docroot/Import/OPML/FoldersOnly.opml

5
lib/CLI.php

@ -78,9 +78,8 @@ Commands:
user set-pass <username> [<password>]
Changes <username>'s password to <password>. If not password is
specified, a random password will be generated and printed to standard
output.
Changes <username>'s password to <password>. If no password is specified,
a random password will be generated and printed to standard output.
The --oldpass=<pass> option can be used to supply a user's exiting
password if this is required by the authentication driver to change a

23
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];

33
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,
],
]]],
];
}
}

12
tests/docroot/Import/OPML/FoldersOnly.opml

@ -0,0 +1,12 @@
<opml>
<body>
<outline text="Folder 1"/>
<outline text="Folder 2">
<outline type="atom" text="Also a folder"/>
<outline type=" rss " text="Still a folder">
<outline text="Folder 5"/>
</outline>
</outline>
<outline text="Folder 6"/>
</body>
</opml>
Loading…
Cancel
Save