|
|
@ -11,7 +11,8 @@ use JKingWeb\Arsse\User\Exception as UserException; |
|
|
|
|
|
|
|
class OPML { |
|
|
|
public function import(string $user, string $opml, bool $flat = false, bool $replace = false): bool { |
|
|
|
list($folders, $feeds) = $this->parse($opml, $flat); |
|
|
|
list($feeds, $folders) = $this->parse($opml, $flat); |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
@ -29,34 +30,47 @@ class OPML { |
|
|
|
$body = $body->item(0); |
|
|
|
$folders = []; |
|
|
|
$feeds = []; |
|
|
|
// add the root folder to a map from folder DOM nodes to folder ID numbers |
|
|
|
$folderMap = new \SplObjectStorage; |
|
|
|
$folderMap[$body] = sizeof($folderMap); |
|
|
|
// iterate through each node in the body |
|
|
|
$node = $body->firstChild; |
|
|
|
while ($node && $node != $body) { |
|
|
|
if ($node->nodeType == \XML_ELEMENT_NODE && $node->nodeName === "outline") { |
|
|
|
// process any nodes which are outlines |
|
|
|
if ($node->getAttribute("type") === "rss") { |
|
|
|
// feed nodes |
|
|
|
$url = $node->getAttribute("xmlUrl"); |
|
|
|
if (strlen($url)) { |
|
|
|
// only process the node if it has a URL |
|
|
|
$title = $node->getAttribute("text"); |
|
|
|
$folder = $folderMap[$node->parentNode] ?? 0; |
|
|
|
$categories = $node->getAttribute("category"); |
|
|
|
if (strlen($categories)) { |
|
|
|
// collapse and trim whitespace from category names, if any, splitting along commas |
|
|
|
$categories = array_map(function($v) { |
|
|
|
return trim(preg_replace("/\s+/g", " ", $v)); |
|
|
|
}, explode(",", $categories)); |
|
|
|
} else { |
|
|
|
$categories = []; |
|
|
|
} |
|
|
|
$feeds[] = ['url' => $url, 'title' => $title, 'folder' => $folder, 'categories' => $categories]; |
|
|
|
} |
|
|
|
// skip any child nodes of a feed outline-entry |
|
|
|
$node = $node->nextSibling ?: $node->parentNode; |
|
|
|
} else { |
|
|
|
// any outline entries which are not feeds are treated as folders |
|
|
|
if (!$flat) { |
|
|
|
// only process folders if we're not treating he file as flat |
|
|
|
$id = sizeof($folderMap); |
|
|
|
$folderMap[$node] = $id; |
|
|
|
$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); |
|
|
|
} |
|
|
|
} 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; |
|
|
|
} |
|
|
|
} |
|
|
|