xref: /plugin/combo/action/pageprotection.php (revision c3437056399326d621a01da73b649707fbb0ae69)
15f891b7eSNickeau<?php
25f891b7eSNickeau
3*c3437056SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php');
45f891b7eSNickeau
521913ab3SNickeauuse ComboStrap\DokuPath;
6*c3437056SNickeauuse ComboStrap\Identity;
75f891b7eSNickeauuse ComboStrap\LowQualityPage;
85f891b7eSNickeauuse ComboStrap\Page;
95f891b7eSNickeauuse ComboStrap\PageProtection;
10*c3437056SNickeauuse ComboStrap\PagePublicationDate;
115f891b7eSNickeau
12*c3437056SNickeau
135f891b7eSNickeau
145f891b7eSNickeau/**
155f891b7eSNickeau *
165f891b7eSNickeau */
175f891b7eSNickeauclass action_plugin_combo_pageprotection extends DokuWiki_Action_Plugin
185f891b7eSNickeau{
195f891b7eSNickeau
205f891b7eSNickeau
215f891b7eSNickeau    public function register(Doku_Event_Handler $controller)
225f891b7eSNickeau    {
235f891b7eSNickeau
245f891b7eSNickeau
255f891b7eSNickeau        /**
265f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:pageutils_id_hidepage
275f891b7eSNickeau         */
285f891b7eSNickeau        $controller->register_hook('PAGEUTILS_ID_HIDEPAGE', 'BEFORE', $this, 'handleHiddenCheck', array());
2985e82846SNickeau
305f891b7eSNickeau        /**
315f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:auth_acl_check
325f891b7eSNickeau         */
335f891b7eSNickeau        $controller->register_hook('AUTH_ACL_CHECK', 'AFTER', $this, 'handleAclCheck', array());
3485e82846SNickeau
3585e82846SNickeau        /**
3685e82846SNickeau         * https://www.dokuwiki.org/devel:event:sitemap_generate
3785e82846SNickeau         */
3885e82846SNickeau        $controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSiteMapGenerate', array());
395f891b7eSNickeau
405f891b7eSNickeau        /**
415f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:search_query_pagelookup
425f891b7eSNickeau         */
435f891b7eSNickeau        $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'handleSearchPageLookup', array());
445f891b7eSNickeau
455f891b7eSNickeau        /**
465f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:search_query_fullpage
475f891b7eSNickeau         */
485f891b7eSNickeau        $controller->register_hook('SEARCH_QUERY_FULLPAGE', 'AFTER', $this, 'handleSearchFullPage', array());
4985e82846SNickeau
505f891b7eSNickeau        /**
515f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:feed_data_process
525f891b7eSNickeau         */
5385e82846SNickeau        $controller->register_hook('FEED_DATA_PROCESS', 'BEFORE', $this, 'handleRssFeed', array());
545f891b7eSNickeau
555f891b7eSNickeau
5685e82846SNickeau        /**
5785e82846SNickeau         * Robots meta
5885e82846SNickeau         * https://www.dokuwiki.org/devel:event:tpl_metaheader_output
5985e82846SNickeau         */
6085e82846SNickeau        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleRobotsMeta', array());
6185e82846SNickeau
625f891b7eSNickeau
635f891b7eSNickeau    }
645f891b7eSNickeau
655f891b7eSNickeau    /**
6685e82846SNickeau     * Set page has hidden
675f891b7eSNickeau     * @param $event
685f891b7eSNickeau     * @param $param
695f891b7eSNickeau     */
705f891b7eSNickeau    function handleHiddenCheck(&$event, $param)
715f891b7eSNickeau    {
725f891b7eSNickeau
7385e82846SNickeau        /**
7485e82846SNickeau         * Only for public
7585e82846SNickeau         */
7685e82846SNickeau        if (Identity::isLoggedIn()) {
7785e82846SNickeau            return;
7885e82846SNickeau        }
795f891b7eSNickeau
8085e82846SNickeau        $id = $event->data['id'];
8185e82846SNickeau        if ($id == null) {
8285e82846SNickeau            /**
8385e82846SNickeau             * Happens in test when rendering
8485e82846SNickeau             * with instructions only
8585e82846SNickeau             */
8685e82846SNickeau            return;
8785e82846SNickeau        }
8885e82846SNickeau        $page = Page::createPageFromId($id);
8985e82846SNickeau
9085e82846SNickeau        if ($page->isLowQualityPage()) {
9185e82846SNickeau            if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) {
9285e82846SNickeau                $event->data['hidden'] = true;
9385e82846SNickeau                return;
9485e82846SNickeau            }
9585e82846SNickeau        }
9685e82846SNickeau        if ($page->isLatePublication()) {
97*c3437056SNickeau            if (PagePublicationDate::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) {
985f891b7eSNickeau                $event->data['hidden'] = true;
995f891b7eSNickeau            }
1005f891b7eSNickeau
1015f891b7eSNickeau        }
1025f891b7eSNickeau
10385e82846SNickeau    }
10485e82846SNickeau
1055f891b7eSNickeau    /**
10685e82846SNickeau     *
10785e82846SNickeau     * https://www.dokuwiki.org/devel:event:auth_acl_check
1085f891b7eSNickeau     * @param $event
1095f891b7eSNickeau     * @param $param
1105f891b7eSNickeau     */
1115f891b7eSNickeau    function handleAclCheck(&$event, $param)
1125f891b7eSNickeau    {
11385e82846SNickeau        /**
11485e82846SNickeau         * Only for public
11585e82846SNickeau         *
11685e82846SNickeau         * Note: user is also
11785e82846SNickeau         * to be found at
11885e82846SNickeau         * $user = $event->data['user'];
11985e82846SNickeau         */
12085e82846SNickeau        if (Identity::isLoggedIn()) {
12185e82846SNickeau            return;
12285e82846SNickeau        }
1235f891b7eSNickeau
12432b85071SNickeau        /**
12521913ab3SNickeau         * Are we on a page script
12632b85071SNickeau         */
12721913ab3SNickeau        $imageScript = ["/lib/exe/mediamanager.php", "/lib/exe/detail.php"];
12821913ab3SNickeau        if (in_array($_SERVER['SCRIPT_NAME'], $imageScript)) {
12921913ab3SNickeau            // id may be null or end with a star
13021913ab3SNickeau            // this is not a image
1315f891b7eSNickeau            return;
13221913ab3SNickeau        }
13332b85071SNickeau
13421913ab3SNickeau        $id = $event->data['id'];
13532b85071SNickeau
136*c3437056SNickeau        $dokuPath = DokuPath::createUnknownFromIdOrPath($id);
13721913ab3SNickeau        if ($dokuPath->isPage()) {
13885e82846SNickeau
13921913ab3SNickeau            /**
14021913ab3SNickeau             * It should be only a page
14121913ab3SNickeau             * https://www.dokuwiki.org/devel:event:auth_acl_check
14221913ab3SNickeau             */
14385e82846SNickeau            $page = Page::createPageFromId($id);
14485e82846SNickeau
14585e82846SNickeau            if ($page->isLowQualityPage()) {
14685e82846SNickeau                if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE, true)) {
14785e82846SNickeau                    $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL);
14885e82846SNickeau                    if ($securityConf == PageProtection::CONF_VALUE_ACL) {
1495f891b7eSNickeau                        $event->result = AUTH_NONE;
15085e82846SNickeau                        return;
15185e82846SNickeau                    }
15285e82846SNickeau                }
15385e82846SNickeau            }
15485e82846SNickeau            if ($page->isLatePublication()) {
155*c3437056SNickeau                if ($this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_ENABLE, true)) {
156*c3437056SNickeau                    $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL);
15785e82846SNickeau                    if ($securityConf == PageProtection::CONF_VALUE_ACL) {
15885e82846SNickeau                        $event->result = AUTH_NONE;
15985e82846SNickeau                        return;
16085e82846SNickeau                    }
16185e82846SNickeau                }
16285e82846SNickeau            }
16385e82846SNickeau
16485e82846SNickeau        }
16585e82846SNickeau
16685e82846SNickeau    }
16785e82846SNickeau
16885e82846SNickeau    function handleSiteMapGenerate(&$event, $param)
16985e82846SNickeau    {
17085e82846SNickeau        $pageItems = $event->data["items"];
17185e82846SNickeau        foreach ($pageItems as $key => $pageItem) {
17285e82846SNickeau            $url = $pageItem->url;
17385e82846SNickeau            $dokuPath = DokuPath::createFromUrl($url);
174*c3437056SNickeau            $page = Page::createPageFromId($dokuPath->getDokuwikiId());
17585e82846SNickeau            if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) {
17685e82846SNickeau
17785e82846SNickeau                unset($event->data["items"][$key]);
17885e82846SNickeau                continue;
17985e82846SNickeau
18085e82846SNickeau            }
181*c3437056SNickeau            if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) {
18285e82846SNickeau                unset($event->data["items"][$key]);
1835f891b7eSNickeau            }
1845f891b7eSNickeau        }
1855f891b7eSNickeau
1865f891b7eSNickeau    }
1875f891b7eSNickeau
1885f891b7eSNickeau    /**
1895f891b7eSNickeau     * @param $event
1905f891b7eSNickeau     * @param $param
1915f891b7eSNickeau     * The autocomplete do a search on page name
1925f891b7eSNickeau     */
1935f891b7eSNickeau    function handleSearchPageLookup(&$event, $param)
1945f891b7eSNickeau    {
1955f891b7eSNickeau        $this->excludePageFromSearch($event);
1965f891b7eSNickeau    }
1975f891b7eSNickeau
1985f891b7eSNickeau    /**
1995f891b7eSNickeau     * @param $event
2005f891b7eSNickeau     * @param $param
2015f891b7eSNickeau     * The search page do a search on page name
2025f891b7eSNickeau     */
2035f891b7eSNickeau    function handleSearchFullPage(&$event, $param)
2045f891b7eSNickeau    {
2055f891b7eSNickeau
2065f891b7eSNickeau        $this->excludePageFromSearch($event);
2075f891b7eSNickeau    }
2085f891b7eSNickeau
2095f891b7eSNickeau    /**
2105f891b7eSNickeau     *
2115f891b7eSNickeau     * @param $event
2125f891b7eSNickeau     * @param $param
2135f891b7eSNickeau     * The Rss
2145f891b7eSNickeau     * https://www.dokuwiki.org/syndication
2155f891b7eSNickeau     * Example
2165f891b7eSNickeau     * https://example.com/feed.php?type=rss2&num=5
2175f891b7eSNickeau     */
2185f891b7eSNickeau    function handleRssFeed(&$event, $param)
2195f891b7eSNickeau    {
22085e82846SNickeau        $isLowQualityProtectionEnabled = LowQualityPage::isProtectionEnabled();
221*c3437056SNickeau        $isLatePublicationProtectionEnabled = PagePublicationDate::isLatePublicationProtectionEnabled();
22285e82846SNickeau        if (!$isLatePublicationProtectionEnabled && !$isLowQualityProtectionEnabled) {
22385e82846SNickeau            return;
22485e82846SNickeau        }
22585e82846SNickeau
22685e82846SNickeau        $pagesToBeAdded = &$event->data["data"];
22785e82846SNickeau        foreach ($pagesToBeAdded as $key => $data) {
22885e82846SNickeau
229e8b2ff59SNickeau            // To prevent an Illegal string offset 'id'
230e8b2ff59SNickeau            if(isset($data["id"])) {
231e8b2ff59SNickeau
23285e82846SNickeau                $page = Page::createPageFromId($data["id"]);
23385e82846SNickeau
23485e82846SNickeau                if ($page->isLowQualityPage() && $isLowQualityProtectionEnabled) {
23585e82846SNickeau                    $protectionMode = LowQualityPage::getLowQualityProtectionMode();
23685e82846SNickeau                    if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) {
23785e82846SNickeau                        unset($pagesToBeAdded[$key]);
23885e82846SNickeau                    }
23985e82846SNickeau                }
24085e82846SNickeau
24185e82846SNickeau                if ($page->isLatePublication() && $isLatePublicationProtectionEnabled) {
242*c3437056SNickeau                    $protectionMode = PagePublicationDate::getLatePublicationProtectionMode();
24385e82846SNickeau                    if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) {
24485e82846SNickeau                        unset($pagesToBeAdded[$key]);
24585e82846SNickeau                    }
24685e82846SNickeau                }
247e8b2ff59SNickeau
248e8b2ff59SNickeau            }
24985e82846SNickeau        }
25085e82846SNickeau
2515f891b7eSNickeau    }
2525f891b7eSNickeau
2535f891b7eSNickeau    /**
2545f891b7eSNickeau     * @param $event
25585e82846SNickeau     * @param array $protectionModes
2565f891b7eSNickeau     */
2575f891b7eSNickeau    private
25885e82846SNickeau    function excludePageFromSearch(&$event, $protectionModes = [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])
2595f891b7eSNickeau    {
2605f891b7eSNickeau
2615f891b7eSNickeau        /**
2625f891b7eSNickeau         * The value is always an array
2635f891b7eSNickeau         * but as we got this error:
2645f891b7eSNickeau         * ```
2655f891b7eSNickeau         * array_keys() expects parameter 1 to be array
2665f891b7eSNickeau         * ```
267e8b2ff59SNickeau         * The result is a list of page id
2685f891b7eSNickeau         */
269e8b2ff59SNickeau        if (is_array($event->result)) {
270e8b2ff59SNickeau            foreach (array_keys($event->result) as $idx) {
27185e82846SNickeau                $page = Page::createPageFromId($idx);
27285e82846SNickeau                if ($page->isLowQualityPage()) {
27385e82846SNickeau                    $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE);
27485e82846SNickeau                    if (in_array($securityConf, $protectionModes)) {
275e8b2ff59SNickeau                        unset($event->result[$idx]);
27685e82846SNickeau                        return;
27785e82846SNickeau                    }
27885e82846SNickeau                }
27985e82846SNickeau                if ($page->isLatePublication()) {
280*c3437056SNickeau                    $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE);
28185e82846SNickeau                    if (in_array($securityConf, [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])) {
282e8b2ff59SNickeau                        unset($event->result[$idx]);
28385e82846SNickeau                        return;
28485e82846SNickeau                    }
2855f891b7eSNickeau                }
2865f891b7eSNickeau            }
2875f891b7eSNickeau        }
2885f891b7eSNickeau
2895f891b7eSNickeau    }
2905f891b7eSNickeau
2915f891b7eSNickeau
29285e82846SNickeau    /**
29385e82846SNickeau     * Handle the meta robots
29485e82846SNickeau     * https://www.dokuwiki.org/devel:event:tpl_metaheader_output
29585e82846SNickeau     * @param $event
29685e82846SNickeau     * @param $param
29785e82846SNickeau     */
29885e82846SNickeau    function handleRobotsMeta(&$event, $param)
29985e82846SNickeau    {
30085e82846SNickeau
30185e82846SNickeau        global $ID;
30285e82846SNickeau        if (empty($ID)) {
30385e82846SNickeau            // $_SERVER['SCRIPT_NAME']== "/lib/exe/mediamanager.php"
30485e82846SNickeau            // $ID is null
30585e82846SNickeau            return;
30685e82846SNickeau        }
30785e82846SNickeau
30885e82846SNickeau        $page = Page::createPageFromId($ID);
30985e82846SNickeau
31085e82846SNickeau        /**
31185e82846SNickeau         * No management for slot page
31285e82846SNickeau         */
31385e82846SNickeau        if ($page->isSlot()) {
31485e82846SNickeau            return;
31585e82846SNickeau        }
31685e82846SNickeau
31785e82846SNickeau        $protected = false;
31885e82846SNickeau        $follow = "nofollow";
31985e82846SNickeau        if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) {
32085e82846SNickeau            $protected = true;
32185e82846SNickeau            if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_ACL) {
32285e82846SNickeau                $follow = "nofollow";
32385e82846SNickeau            } else {
32485e82846SNickeau                $follow = "follow";
32585e82846SNickeau            }
32685e82846SNickeau        }
327*c3437056SNickeau        if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) {
32885e82846SNickeau            $protected = true;
329*c3437056SNickeau            if (PagePublicationDate::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_ACL) {
33085e82846SNickeau                $follow = "nofollow";
33185e82846SNickeau            } else {
33285e82846SNickeau                $follow = "follow";
33385e82846SNickeau            }
33485e82846SNickeau        }
33585e82846SNickeau        if ($protected) {
33685e82846SNickeau            foreach ($event->data['meta'] as $key => $meta) {
33785e82846SNickeau                if (array_key_exists("name", $meta)) {
33885e82846SNickeau                    /**
33985e82846SNickeau                     * We may have several properties
34085e82846SNickeau                     */
34185e82846SNickeau                    if ($meta["name"] == "robots") {
34285e82846SNickeau                        $event->data['meta'][$key]["content"] = "noindex,$follow";
34385e82846SNickeau                    }
34485e82846SNickeau                }
34585e82846SNickeau            }
34685e82846SNickeau        }
34785e82846SNickeau    }
34885e82846SNickeau
3495f891b7eSNickeau}
350