mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
OPML parsing comments and minr fixes
This commit is contained in:
parent
825c286e5b
commit
ceecd58393
2 changed files with 16 additions and 2 deletions
|
@ -700,7 +700,7 @@ class Database {
|
||||||
* @param string $url The URL of the newsfeed or discovery source
|
* @param string $url The URL of the newsfeed or discovery source
|
||||||
* @param string $fetchUser The user name required to access the newsfeed, if applicable
|
* @param string $fetchUser The user name required to access the newsfeed, if applicable
|
||||||
* @param string $fetchPassword The password required to fetch the newsfeed, if applicable; this will be stored in cleartext
|
* @param string $fetchPassword The password required to fetch the newsfeed, if applicable; this will be stored in cleartext
|
||||||
* @param boolean $discovery Whether to perform newsfeed discovery if $url points to an HTML document
|
* @param boolean $discover Whether to perform newsfeed discovery if $url points to an HTML document
|
||||||
*/
|
*/
|
||||||
public function subscriptionAdd(string $user, string $url, string $fetchUser = "", string $fetchPassword = "", bool $discover = true): int {
|
public function subscriptionAdd(string $user, string $url, string $fetchUser = "", string $fetchPassword = "", bool $discover = true): int {
|
||||||
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
if (!Arsse::$user->authorize($user, __FUNCTION__)) {
|
||||||
|
|
|
@ -11,7 +11,8 @@ use JKingWeb\Arsse\User\Exception as UserException;
|
||||||
|
|
||||||
class OPML {
|
class OPML {
|
||||||
public function import(string $user, string $opml, bool $flat = false, bool $replace = false): bool {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,34 +30,47 @@ class OPML {
|
||||||
$body = $body->item(0);
|
$body = $body->item(0);
|
||||||
$folders = [];
|
$folders = [];
|
||||||
$feeds = [];
|
$feeds = [];
|
||||||
|
// add the root folder to a map from folder DOM nodes to folder ID numbers
|
||||||
$folderMap = new \SplObjectStorage;
|
$folderMap = new \SplObjectStorage;
|
||||||
$folderMap[$body] = sizeof($folderMap);
|
$folderMap[$body] = sizeof($folderMap);
|
||||||
|
// iterate through each node in the body
|
||||||
$node = $body->firstChild;
|
$node = $body->firstChild;
|
||||||
while ($node && $node != $body) {
|
while ($node && $node != $body) {
|
||||||
if ($node->nodeType == \XML_ELEMENT_NODE && $node->nodeName === "outline") {
|
if ($node->nodeType == \XML_ELEMENT_NODE && $node->nodeName === "outline") {
|
||||||
|
// process any nodes which are outlines
|
||||||
if ($node->getAttribute("type") === "rss") {
|
if ($node->getAttribute("type") === "rss") {
|
||||||
|
// feed nodes
|
||||||
$url = $node->getAttribute("xmlUrl");
|
$url = $node->getAttribute("xmlUrl");
|
||||||
if (strlen($url)) {
|
if (strlen($url)) {
|
||||||
|
// only process the node if it has a URL
|
||||||
$title = $node->getAttribute("text");
|
$title = $node->getAttribute("text");
|
||||||
$folder = $folderMap[$node->parentNode] ?? 0;
|
$folder = $folderMap[$node->parentNode] ?? 0;
|
||||||
$categories = $node->getAttribute("category");
|
$categories = $node->getAttribute("category");
|
||||||
if (strlen($categories)) {
|
if (strlen($categories)) {
|
||||||
|
// collapse and trim whitespace from category names, if any, splitting along commas
|
||||||
$categories = array_map(function($v) {
|
$categories = array_map(function($v) {
|
||||||
return trim(preg_replace("/\s+/g", " ", $v));
|
return trim(preg_replace("/\s+/g", " ", $v));
|
||||||
}, explode(",", $categories));
|
}, explode(",", $categories));
|
||||||
|
} else {
|
||||||
|
$categories = [];
|
||||||
}
|
}
|
||||||
$feeds[] = ['url' => $url, 'title' => $title, 'folder' => $folder, 'categories' => $categories];
|
$feeds[] = ['url' => $url, 'title' => $title, 'folder' => $folder, 'categories' => $categories];
|
||||||
}
|
}
|
||||||
|
// skip any child nodes of a feed outline-entry
|
||||||
$node = $node->nextSibling ?: $node->parentNode;
|
$node = $node->nextSibling ?: $node->parentNode;
|
||||||
} else {
|
} else {
|
||||||
|
// any outline entries which are not feeds are treated as folders
|
||||||
if (!$flat) {
|
if (!$flat) {
|
||||||
|
// only process folders if we're not treating he file as flat
|
||||||
$id = sizeof($folderMap);
|
$id = sizeof($folderMap);
|
||||||
$folderMap[$node] = $id;
|
$folderMap[$node] = $id;
|
||||||
$folders[$id] = ['id' => $id, 'name' => $node->getAttribute("text"), 'parent' => $folderMap[$node->parentNode]];
|
$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 = $node->hasChildNodes() ? $node->firstChild : ($node->nextSibling ?: $node->parentNode);
|
||||||
}
|
}
|
||||||
} else {
|
} 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 = $node->nextSibling ?: $node->parentNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue