xref: /plugin/combo/action/pageprotection.php (revision 977ce05d19d8dab0a70c9a27f8da0b7039299e82)
1<?php
2
3require_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
4
5use ComboStrap\DokuPath;
6use ComboStrap\Identity;
7use ComboStrap\LowQualityPage;
8use ComboStrap\Page;
9use ComboStrap\PageProtection;
10use ComboStrap\PagePublicationDate;
11
12
13
14/**
15 *
16 */
17class action_plugin_combo_pageprotection extends DokuWiki_Action_Plugin
18{
19
20
21    public function register(Doku_Event_Handler $controller)
22    {
23
24
25        /**
26         * https://www.dokuwiki.org/devel:event:pageutils_id_hidepage
27         */
28        $controller->register_hook('PAGEUTILS_ID_HIDEPAGE', 'BEFORE', $this, 'handleHiddenCheck', array());
29
30        /**
31         * https://www.dokuwiki.org/devel:event:auth_acl_check
32         */
33        $controller->register_hook('AUTH_ACL_CHECK', 'AFTER', $this, 'handleAclCheck', array());
34
35        /**
36         * https://www.dokuwiki.org/devel:event:sitemap_generate
37         */
38        $controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSiteMapGenerate', array());
39
40        /**
41         * https://www.dokuwiki.org/devel:event:search_query_pagelookup
42         */
43        $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'handleSearchPageLookup', array());
44
45        /**
46         * https://www.dokuwiki.org/devel:event:search_query_fullpage
47         */
48        $controller->register_hook('SEARCH_QUERY_FULLPAGE', 'AFTER', $this, 'handleSearchFullPage', array());
49
50        /**
51         * https://www.dokuwiki.org/devel:event:feed_data_process
52         */
53        $controller->register_hook('FEED_DATA_PROCESS', 'BEFORE', $this, 'handleRssFeed', array());
54
55
56        /**
57         * Robots meta
58         * https://www.dokuwiki.org/devel:event:tpl_metaheader_output
59         */
60        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleRobotsMeta', array());
61
62
63    }
64
65    /**
66     * Set page has hidden
67     * @param $event
68     * @param $param
69     */
70    function handleHiddenCheck(&$event, $param)
71    {
72
73        /**
74         * Only for public
75         */
76        if (Identity::isLoggedIn()) {
77            return;
78        }
79
80        $id = $event->data['id'];
81        if ($id == null) {
82            /**
83             * Happens in test when rendering
84             * with instructions only
85             */
86            return;
87        }
88        $page = Page::createPageFromId($id);
89
90        if ($page->isLowQualityPage()) {
91            if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) {
92                $event->data['hidden'] = true;
93                return;
94            }
95        }
96        if ($page->isLatePublication()) {
97            if (PagePublicationDate::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) {
98                $event->data['hidden'] = true;
99            }
100
101        }
102
103    }
104
105    /**
106     *
107     * https://www.dokuwiki.org/devel:event:auth_acl_check
108     * @param $event
109     * @param $param
110     */
111    function handleAclCheck(&$event, $param)
112    {
113        /**
114         * Only for public
115         *
116         * Note: user is also
117         * to be found at
118         * $user = $event->data['user'];
119         */
120        if (Identity::isLoggedIn()) {
121            return;
122        }
123
124        /**
125         * Are we on a page script
126         */
127        $imageScript = ["/lib/exe/mediamanager.php", "/lib/exe/detail.php"];
128        if (in_array($_SERVER['SCRIPT_NAME'], $imageScript)) {
129            // id may be null or end with a star
130            // this is not a image
131            return;
132        }
133
134        $id = $event->data['id'];
135
136        $dokuPath = DokuPath::createFromUnknownRoot($id);
137        if ($dokuPath->isPage()) {
138
139            /**
140             * It should be only a page
141             * https://www.dokuwiki.org/devel:event:auth_acl_check
142             */
143            $page = Page::createPageFromId($id);
144
145            if ($page->isLowQualityPage()) {
146                if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE, true)) {
147                    $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL);
148                    if ($securityConf == PageProtection::CONF_VALUE_ACL) {
149                        $event->result = AUTH_NONE;
150                        return;
151                    }
152                }
153            }
154            if ($page->isLatePublication()) {
155                if ($this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_ENABLE, true)) {
156                    $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL);
157                    if ($securityConf == PageProtection::CONF_VALUE_ACL) {
158                        $event->result = AUTH_NONE;
159                        return;
160                    }
161                }
162            }
163
164        }
165
166    }
167
168    function handleSiteMapGenerate(&$event, $param)
169    {
170        $pageItems = $event->data["items"];
171        foreach ($pageItems as $key => $pageItem) {
172            $url = $pageItem->url;
173            $dokuPath = DokuPath::createFromUrl($url);
174            $page = Page::createPageFromId($dokuPath->getDokuwikiId());
175            if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) {
176
177                unset($event->data["items"][$key]);
178                continue;
179
180            }
181            if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) {
182                unset($event->data["items"][$key]);
183            }
184        }
185
186    }
187
188    /**
189     * @param $event
190     * @param $param
191     * The autocomplete do a search on page name
192     */
193    function handleSearchPageLookup(&$event, $param)
194    {
195        $this->excludePageFromSearch($event);
196    }
197
198    /**
199     * @param $event
200     * @param $param
201     * The search page do a search on page name
202     */
203    function handleSearchFullPage(&$event, $param)
204    {
205
206        $this->excludePageFromSearch($event);
207    }
208
209    /**
210     *
211     * @param $event
212     * @param $param
213     * The Rss
214     * https://www.dokuwiki.org/syndication
215     * Example
216     * https://example.com/feed.php?type=rss2&num=5
217     */
218    function handleRssFeed(&$event, $param)
219    {
220        $isLowQualityProtectionEnabled = LowQualityPage::isProtectionEnabled();
221        $isLatePublicationProtectionEnabled = PagePublicationDate::isLatePublicationProtectionEnabled();
222        if (!$isLatePublicationProtectionEnabled && !$isLowQualityProtectionEnabled) {
223            return;
224        }
225
226        $pagesToBeAdded = &$event->data["data"];
227        foreach ($pagesToBeAdded as $key => $data) {
228
229            // To prevent an Illegal string offset 'id'
230            if(isset($data["id"])) {
231
232                $page = Page::createPageFromId($data["id"]);
233
234                if ($page->isLowQualityPage() && $isLowQualityProtectionEnabled) {
235                    $protectionMode = LowQualityPage::getLowQualityProtectionMode();
236                    if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) {
237                        unset($pagesToBeAdded[$key]);
238                    }
239                }
240
241                if ($page->isLatePublication() && $isLatePublicationProtectionEnabled) {
242                    $protectionMode = PagePublicationDate::getLatePublicationProtectionMode();
243                    if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) {
244                        unset($pagesToBeAdded[$key]);
245                    }
246                }
247
248            }
249        }
250
251    }
252
253    /**
254     * @param $event
255     * @param array $protectionModes
256     */
257    private
258    function excludePageFromSearch(&$event, $protectionModes = [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])
259    {
260
261        /**
262         * The value is always an array
263         * but as we got this error:
264         * ```
265         * array_keys() expects parameter 1 to be array
266         * ```
267         * The result is a list of page id
268         */
269        if (is_array($event->result)) {
270            foreach (array_keys($event->result) as $idx) {
271                $page = Page::createPageFromId($idx);
272                if ($page->isLowQualityPage()) {
273                    $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE);
274                    if (in_array($securityConf, $protectionModes)) {
275                        unset($event->result[$idx]);
276                        return;
277                    }
278                }
279                if ($page->isLatePublication()) {
280                    $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE);
281                    if (in_array($securityConf, [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])) {
282                        unset($event->result[$idx]);
283                        return;
284                    }
285                }
286            }
287        }
288
289    }
290
291
292    /**
293     * Handle the meta robots
294     * https://www.dokuwiki.org/devel:event:tpl_metaheader_output
295     * @param $event
296     * @param $param
297     */
298    function handleRobotsMeta(&$event, $param)
299    {
300
301        global $ID;
302        if (empty($ID)) {
303            // $_SERVER['SCRIPT_NAME']== "/lib/exe/mediamanager.php"
304            // $ID is null
305            return;
306        }
307
308        $page = Page::createPageFromId($ID);
309
310        /**
311         * No management for slot page
312         */
313        if ($page->isSecondarySlot()) {
314            return;
315        }
316
317        $protected = false;
318        $follow = "nofollow";
319        if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) {
320            $protected = true;
321            if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_ACL) {
322                $follow = "nofollow";
323            } else {
324                $follow = "follow";
325            }
326        }
327        if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) {
328            $protected = true;
329            if (PagePublicationDate::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_ACL) {
330                $follow = "nofollow";
331            } else {
332                $follow = "follow";
333            }
334        }
335        if ($protected) {
336            foreach ($event->data['meta'] as $key => $meta) {
337                if (array_key_exists("name", $meta)) {
338                    /**
339                     * We may have several properties
340                     */
341                    if ($meta["name"] == "robots") {
342                        $event->data['meta'][$key]["content"] = "noindex,$follow";
343                    }
344                }
345            }
346        }
347    }
348
349}
350