summaryrefslogtreecommitdiffstats
path: root/lib/Utility/OPMLImporter.php
blob: 0068f3e712e90bb2a0a87d950ab4b6d6254c0d4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
/**
 * Nextcloud - News
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 */

namespace OCA\News\Utility;

use \DOMDocument;
use \DOMElement;
use \DOMText;

/**
 * Imports the OPML
 */
class OPMLImporter
{

    /**
     * The user ID to import to.
     */
    private ?string $userId = null;

    /**
     * Intermediate data.
     */
    private array $feeds = [];
    private array $folders = [];

    /**
     * Imports the OPML
     *
     * @return null|array{0: list<array<string,mixed>>, 1: list<array<string,mixed>>} the items to import
     */
    public function import(string $userId, string $data): ?array
    {
        $this->feeds = [];
        $this->folders = [];
        $this->userId = $userId;

        $document = new DOMDocument('1.0', 'UTF-8');
        $loaded = $document->loadXML($data);
        if ($loaded === false) {
            return null;
        }

        $bodies = $document->getElementsByTagName('body');
        if ($bodies->count() < 1) {
            return null;
        }

        foreach ($bodies[0]->childNodes as $node) {
            if ($node instanceof DOMText) {
                continue;
            }

            $this->outlineToItem($node);
        }

        return [$this->folders, $this->feeds];
    }

    private function outlineToItem(DOMElement $outline, ?string $parent = null): void
    {
        if ($outline->getAttribute('type') === 'rss') {
            $feed = [
                'link' => $outline->getAttribute('htmlUrl'),
                'url' => $outline->getAttribute('xmlUrl'),
                'title' => $outline->getAttribute('title'),
                'folder' => $parent,
            ];

            $this->feeds[] = $feed;
            return;
        }

        $folder = ['name' => $outline->getAttribute('text'), 'parentName' => $parent];

        $this->folders[] = $folder;

        if ($outline->hasChildNodes() === false) {
            return;
        }

        foreach ($outline->childNodes as $child) {
            if ($child instanceof DOMText) {
                continue;
            }

            $this->outlineToItem($child, $folder['name']);
        }
    }
}