xref: /dokuwiki/inc/Feed/FeedItemProcessor.php (revision fe9d054b302adfcd4618e9e33079c36cccb90d10)
1*fe9d054bSAndreas Gohr<?php
2*fe9d054bSAndreas Gohr
3*fe9d054bSAndreas Gohrnamespace dokuwiki\Feed;
4*fe9d054bSAndreas Gohr
5*fe9d054bSAndreas Gohruse dokuwiki\Extension\AuthPlugin;
6*fe9d054bSAndreas Gohruse RuntimeException;
7*fe9d054bSAndreas Gohr
8*fe9d054bSAndreas Gohr/**
9*fe9d054bSAndreas Gohr * Accept more or less arbitrary data to represent data to later construct a feed item from.
10*fe9d054bSAndreas Gohr * Provide lazy loading accessors to all the data we need for feed generation.
11*fe9d054bSAndreas Gohr */
12*fe9d054bSAndreas Gohrabstract class FeedItemProcessor
13*fe9d054bSAndreas Gohr{
14*fe9d054bSAndreas Gohr    /** @var string This page's ID */
15*fe9d054bSAndreas Gohr    protected $id;
16*fe9d054bSAndreas Gohr
17*fe9d054bSAndreas Gohr    /** @var array bag of holding */
18*fe9d054bSAndreas Gohr    protected $data;
19*fe9d054bSAndreas Gohr
20*fe9d054bSAndreas Gohr
21*fe9d054bSAndreas Gohr    /**
22*fe9d054bSAndreas Gohr     * Constructor
23*fe9d054bSAndreas Gohr     *
24*fe9d054bSAndreas Gohr     * @param array $data Needs to have at least an 'id' key
25*fe9d054bSAndreas Gohr     */
26*fe9d054bSAndreas Gohr    public function __construct($data)
27*fe9d054bSAndreas Gohr    {
28*fe9d054bSAndreas Gohr        if (!isset($data['id'])) throw new RuntimeException('Missing ID');
29*fe9d054bSAndreas Gohr        $this->id = cleanID($data['id']);
30*fe9d054bSAndreas Gohr        $this->data = $data;
31*fe9d054bSAndreas Gohr    }
32*fe9d054bSAndreas Gohr
33*fe9d054bSAndreas Gohr    /**
34*fe9d054bSAndreas Gohr     * Get the page ID
35*fe9d054bSAndreas Gohr     *
36*fe9d054bSAndreas Gohr     * @return string
37*fe9d054bSAndreas Gohr     */
38*fe9d054bSAndreas Gohr    public function getId()
39*fe9d054bSAndreas Gohr    {
40*fe9d054bSAndreas Gohr        return $this->id;
41*fe9d054bSAndreas Gohr    }
42*fe9d054bSAndreas Gohr
43*fe9d054bSAndreas Gohr    /**
44*fe9d054bSAndreas Gohr     * Get the revision timestamp of this page
45*fe9d054bSAndreas Gohr     *
46*fe9d054bSAndreas Gohr     * If the input gave us a revision, date or lastmodified already, we trust that it is correct.
47*fe9d054bSAndreas Gohr     *
48*fe9d054bSAndreas Gohr     * Note: we only handle most current revisions in feeds, so the revision is usually just the
49*fe9d054bSAndreas Gohr     * lastmodifed timestamp of the page file. However, if the item does not exist, we need to
50*fe9d054bSAndreas Gohr     * determine the revision from the changelog.
51*fe9d054bSAndreas Gohr     *
52*fe9d054bSAndreas Gohr     * @return int
53*fe9d054bSAndreas Gohr     */
54*fe9d054bSAndreas Gohr    public function getRev()
55*fe9d054bSAndreas Gohr    {
56*fe9d054bSAndreas Gohr        if ($this->data['rev'] ?? 0) return $this->data['rev'];
57*fe9d054bSAndreas Gohr
58*fe9d054bSAndreas Gohr        if (isset($this->data['date'])) {
59*fe9d054bSAndreas Gohr            $this->data['rev'] = (int)$this->data['date'];
60*fe9d054bSAndreas Gohr        }
61*fe9d054bSAndreas Gohr
62*fe9d054bSAndreas Gohr        if (isset($this->data['lastmodified'])) {
63*fe9d054bSAndreas Gohr            $this->data['rev'] = (int)$this->data['lastmodified'];
64*fe9d054bSAndreas Gohr        }
65*fe9d054bSAndreas Gohr
66*fe9d054bSAndreas Gohr        return $this->data['rev'] ?? 0;
67*fe9d054bSAndreas Gohr    }
68*fe9d054bSAndreas Gohr
69*fe9d054bSAndreas Gohr    /**
70*fe9d054bSAndreas Gohr     * Construct the URL for the feed item based on the link_to option
71*fe9d054bSAndreas Gohr     *
72*fe9d054bSAndreas Gohr     * @param string $linkto The link_to option
73*fe9d054bSAndreas Gohr     * @return string URL
74*fe9d054bSAndreas Gohr     */
75*fe9d054bSAndreas Gohr    abstract public function getURL($linkto);
76*fe9d054bSAndreas Gohr
77*fe9d054bSAndreas Gohr    /**
78*fe9d054bSAndreas Gohr     * @return string
79*fe9d054bSAndreas Gohr     */
80*fe9d054bSAndreas Gohr    public function getTitle()
81*fe9d054bSAndreas Gohr    {
82*fe9d054bSAndreas Gohr        return $this->data['title'] ?? noNS($this->getId());
83*fe9d054bSAndreas Gohr    }
84*fe9d054bSAndreas Gohr
85*fe9d054bSAndreas Gohr    /**
86*fe9d054bSAndreas Gohr     * Construct the body of the feed item based on the item_content option
87*fe9d054bSAndreas Gohr     *
88*fe9d054bSAndreas Gohr     * @param string $content The item_content option
89*fe9d054bSAndreas Gohr     * @return string
90*fe9d054bSAndreas Gohr     */
91*fe9d054bSAndreas Gohr    abstract public function getBody($content);
92*fe9d054bSAndreas Gohr
93*fe9d054bSAndreas Gohr    /**
94*fe9d054bSAndreas Gohr     * Get the change summary for this item if any
95*fe9d054bSAndreas Gohr     *
96*fe9d054bSAndreas Gohr     * @return string
97*fe9d054bSAndreas Gohr     */
98*fe9d054bSAndreas Gohr    public function getSummary()
99*fe9d054bSAndreas Gohr    {
100*fe9d054bSAndreas Gohr        return (string)($this->data['sum'] ?? '');
101*fe9d054bSAndreas Gohr    }
102*fe9d054bSAndreas Gohr
103*fe9d054bSAndreas Gohr    /**
104*fe9d054bSAndreas Gohr     * Get the author info for this item
105*fe9d054bSAndreas Gohr     *
106*fe9d054bSAndreas Gohr     * @return string[] [email, author]
107*fe9d054bSAndreas Gohr     */
108*fe9d054bSAndreas Gohr    public function getAuthor()
109*fe9d054bSAndreas Gohr    {
110*fe9d054bSAndreas Gohr        global $conf;
111*fe9d054bSAndreas Gohr        global $auth;
112*fe9d054bSAndreas Gohr
113*fe9d054bSAndreas Gohr        $user = $this->data['user'] ?? '';
114*fe9d054bSAndreas Gohr        $author = 'Anonymous';
115*fe9d054bSAndreas Gohr        $email = 'anonymous@undisclosed.example.com';
116*fe9d054bSAndreas Gohr
117*fe9d054bSAndreas Gohr        if (!$user) return [$email, $author];
118*fe9d054bSAndreas Gohr        $author = $user;
119*fe9d054bSAndreas Gohr        $email = $user . '@undisclosed.example.com';
120*fe9d054bSAndreas Gohr
121*fe9d054bSAndreas Gohr        if ($conf['useacl'] && $auth instanceof AuthPlugin) {
122*fe9d054bSAndreas Gohr            $userInfo = $auth->getUserData($user);
123*fe9d054bSAndreas Gohr            if ($userInfo) {
124*fe9d054bSAndreas Gohr                switch ($conf['showuseras']) {
125*fe9d054bSAndreas Gohr                    case 'username':
126*fe9d054bSAndreas Gohr                    case 'username_link':
127*fe9d054bSAndreas Gohr                        $author = $userInfo['name'];
128*fe9d054bSAndreas Gohr                        break;
129*fe9d054bSAndreas Gohr                }
130*fe9d054bSAndreas Gohr            }
131*fe9d054bSAndreas Gohr        }
132*fe9d054bSAndreas Gohr        return [$email, $author];
133*fe9d054bSAndreas Gohr    }
134*fe9d054bSAndreas Gohr
135*fe9d054bSAndreas Gohr    /**
136*fe9d054bSAndreas Gohr     * Get the categories for this item
137*fe9d054bSAndreas Gohr     *
138*fe9d054bSAndreas Gohr     * @return string[]
139*fe9d054bSAndreas Gohr     */
140*fe9d054bSAndreas Gohr    abstract public function getCategory();
141*fe9d054bSAndreas Gohr
142*fe9d054bSAndreas Gohr
143*fe9d054bSAndreas Gohr    /**
144*fe9d054bSAndreas Gohr     * Clean HTML for the use in feeds
145*fe9d054bSAndreas Gohr     *
146*fe9d054bSAndreas Gohr     * @param string $html
147*fe9d054bSAndreas Gohr     * @return string
148*fe9d054bSAndreas Gohr     */
149*fe9d054bSAndreas Gohr    protected function cleanHTML($html)
150*fe9d054bSAndreas Gohr    {
151*fe9d054bSAndreas Gohr        global $conf;
152*fe9d054bSAndreas Gohr
153*fe9d054bSAndreas Gohr        // no TOC in feeds
154*fe9d054bSAndreas Gohr        $html = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s', '', $html);
155*fe9d054bSAndreas Gohr
156*fe9d054bSAndreas Gohr        // add alignment for images
157*fe9d054bSAndreas Gohr        $html = preg_replace('/(<img .*?class="medialeft")/s', '\\1 align="left"', $html);
158*fe9d054bSAndreas Gohr        $html = preg_replace('/(<img .*?class="mediaright")/s', '\\1 align="right"', $html);
159*fe9d054bSAndreas Gohr
160*fe9d054bSAndreas Gohr        // make URLs work when canonical is not set, regexp instead of rerendering!
161*fe9d054bSAndreas Gohr        if (!$conf['canonical']) {
162*fe9d054bSAndreas Gohr            $base = preg_quote(DOKU_REL, '/');
163*fe9d054bSAndreas Gohr            $html = preg_replace(
164*fe9d054bSAndreas Gohr                '/(<a href|<img src)="(' . $base . ')/s',
165*fe9d054bSAndreas Gohr                '$1="' . DOKU_URL,
166*fe9d054bSAndreas Gohr                $html
167*fe9d054bSAndreas Gohr            );
168*fe9d054bSAndreas Gohr        }
169*fe9d054bSAndreas Gohr
170*fe9d054bSAndreas Gohr        return $html;
171*fe9d054bSAndreas Gohr    }
172*fe9d054bSAndreas Gohr}
173