xref: /plugin/combo/action/pageprotection.php (revision e8b2ff590c848541e718216df3a67061e98c1761)
15f891b7eSNickeau<?php
25f891b7eSNickeau
35f891b7eSNickeau
4a6bf47aaSNickeauuse ComboStrap\Identity;
521913ab3SNickeauuse ComboStrap\DokuPath;
685e82846SNickeauuse ComboStrap\LatePublication;
75f891b7eSNickeauuse ComboStrap\LowQualityPage;
85f891b7eSNickeauuse ComboStrap\Page;
95f891b7eSNickeauuse ComboStrap\PageProtection;
1085e82846SNickeauuse ComboStrap\Publication;
1121913ab3SNickeauuse ComboStrap\StringUtility;
125f891b7eSNickeau
135f891b7eSNickeaurequire_once(__DIR__ . '/../class/LowQualityPage.php');
145f891b7eSNickeaurequire_once(__DIR__ . '/../class/PageProtection.php');
1521913ab3SNickeaurequire_once(__DIR__ . '/../class/DokuPath.php');
165f891b7eSNickeau
175f891b7eSNickeau/**
185f891b7eSNickeau *
195f891b7eSNickeau */
205f891b7eSNickeauclass action_plugin_combo_pageprotection extends DokuWiki_Action_Plugin
215f891b7eSNickeau{
225f891b7eSNickeau
235f891b7eSNickeau
245f891b7eSNickeau    public function register(Doku_Event_Handler $controller)
255f891b7eSNickeau    {
265f891b7eSNickeau
275f891b7eSNickeau
285f891b7eSNickeau        /**
295f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:pageutils_id_hidepage
305f891b7eSNickeau         */
315f891b7eSNickeau        $controller->register_hook('PAGEUTILS_ID_HIDEPAGE', 'BEFORE', $this, 'handleHiddenCheck', array());
3285e82846SNickeau
335f891b7eSNickeau        /**
345f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:auth_acl_check
355f891b7eSNickeau         */
365f891b7eSNickeau        $controller->register_hook('AUTH_ACL_CHECK', 'AFTER', $this, 'handleAclCheck', array());
3785e82846SNickeau
3885e82846SNickeau        /**
3985e82846SNickeau         * https://www.dokuwiki.org/devel:event:sitemap_generate
4085e82846SNickeau         */
4185e82846SNickeau        $controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSiteMapGenerate', array());
425f891b7eSNickeau
435f891b7eSNickeau        /**
445f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:search_query_pagelookup
455f891b7eSNickeau         */
465f891b7eSNickeau        $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'handleSearchPageLookup', array());
475f891b7eSNickeau
485f891b7eSNickeau        /**
495f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:search_query_fullpage
505f891b7eSNickeau         */
515f891b7eSNickeau        $controller->register_hook('SEARCH_QUERY_FULLPAGE', 'AFTER', $this, 'handleSearchFullPage', array());
5285e82846SNickeau
535f891b7eSNickeau        /**
545f891b7eSNickeau         * https://www.dokuwiki.org/devel:event:feed_data_process
555f891b7eSNickeau         */
5685e82846SNickeau        $controller->register_hook('FEED_DATA_PROCESS', 'BEFORE', $this, 'handleRssFeed', array());
575f891b7eSNickeau
585f891b7eSNickeau        /**
5985e82846SNickeau         * Add logged in indicator for Javascript
605f891b7eSNickeau         */
615f891b7eSNickeau        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'handleAnonymousJsIndicator');
625f891b7eSNickeau
6385e82846SNickeau        /**
6485e82846SNickeau         * Robots meta
6585e82846SNickeau         * https://www.dokuwiki.org/devel:event:tpl_metaheader_output
6685e82846SNickeau         */
6785e82846SNickeau        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleRobotsMeta', array());
6885e82846SNickeau
695f891b7eSNickeau
705f891b7eSNickeau    }
715f891b7eSNickeau
725f891b7eSNickeau    /**
7385e82846SNickeau     * Set page has hidden
745f891b7eSNickeau     * @param $event
755f891b7eSNickeau     * @param $param
765f891b7eSNickeau     */
775f891b7eSNickeau    function handleHiddenCheck(&$event, $param)
785f891b7eSNickeau    {
795f891b7eSNickeau
8085e82846SNickeau        /**
8185e82846SNickeau         * Only for public
8285e82846SNickeau         */
8385e82846SNickeau        if (Identity::isLoggedIn()) {
8485e82846SNickeau            return;
8585e82846SNickeau        }
865f891b7eSNickeau
8785e82846SNickeau        $id = $event->data['id'];
8885e82846SNickeau        if ($id == null) {
8985e82846SNickeau            /**
9085e82846SNickeau             * Happens in test when rendering
9185e82846SNickeau             * with instructions only
9285e82846SNickeau             */
9385e82846SNickeau            return;
9485e82846SNickeau        }
9585e82846SNickeau        $page = Page::createPageFromId($id);
9685e82846SNickeau
9785e82846SNickeau        if ($page->isLowQualityPage()) {
9885e82846SNickeau            if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) {
9985e82846SNickeau                $event->data['hidden'] = true;
10085e82846SNickeau                return;
10185e82846SNickeau            }
10285e82846SNickeau        }
10385e82846SNickeau        if ($page->isLatePublication()) {
10485e82846SNickeau            if (Publication::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) {
1055f891b7eSNickeau                $event->data['hidden'] = true;
1065f891b7eSNickeau            }
1075f891b7eSNickeau
1085f891b7eSNickeau        }
1095f891b7eSNickeau
11085e82846SNickeau    }
11185e82846SNickeau
1125f891b7eSNickeau    /**
11385e82846SNickeau     *
11485e82846SNickeau     * https://www.dokuwiki.org/devel:event:auth_acl_check
1155f891b7eSNickeau     * @param $event
1165f891b7eSNickeau     * @param $param
1175f891b7eSNickeau     */
1185f891b7eSNickeau    function handleAclCheck(&$event, $param)
1195f891b7eSNickeau    {
12085e82846SNickeau        /**
12185e82846SNickeau         * Only for public
12285e82846SNickeau         *
12385e82846SNickeau         * Note: user is also
12485e82846SNickeau         * to be found at
12585e82846SNickeau         * $user = $event->data['user'];
12685e82846SNickeau         */
12785e82846SNickeau        if (Identity::isLoggedIn()) {
12885e82846SNickeau            return;
12985e82846SNickeau        }
1305f891b7eSNickeau
13132b85071SNickeau        /**
13221913ab3SNickeau         * Are we on a page script
13332b85071SNickeau         */
13421913ab3SNickeau        $imageScript = ["/lib/exe/mediamanager.php", "/lib/exe/detail.php"];
13521913ab3SNickeau        if (in_array($_SERVER['SCRIPT_NAME'], $imageScript)) {
13621913ab3SNickeau            // id may be null or end with a star
13721913ab3SNickeau            // this is not a image
1385f891b7eSNickeau            return;
13921913ab3SNickeau        }
14032b85071SNickeau
14121913ab3SNickeau        $id = $event->data['id'];
14232b85071SNickeau
14321913ab3SNickeau        $dokuPath = DokuPath::createUnknownFromId($id);
14421913ab3SNickeau        if ($dokuPath->isPage()) {
14585e82846SNickeau
14621913ab3SNickeau            /**
14721913ab3SNickeau             * It should be only a page
14821913ab3SNickeau             * https://www.dokuwiki.org/devel:event:auth_acl_check
14921913ab3SNickeau             */
15085e82846SNickeau            $page = Page::createPageFromId($id);
15185e82846SNickeau
15285e82846SNickeau            if ($page->isLowQualityPage()) {
15385e82846SNickeau                if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE, true)) {
15485e82846SNickeau                    $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL);
15585e82846SNickeau                    if ($securityConf == PageProtection::CONF_VALUE_ACL) {
1565f891b7eSNickeau                        $event->result = AUTH_NONE;
15785e82846SNickeau                        return;
15885e82846SNickeau                    }
15985e82846SNickeau                }
16085e82846SNickeau            }
16185e82846SNickeau            if ($page->isLatePublication()) {
16285e82846SNickeau                if ($this->getConf(Publication::CONF_LATE_PUBLICATION_PROTECTION_ENABLE, true)) {
16385e82846SNickeau                    $securityConf = $this->getConf(Publication::CONF_LATE_PUBLICATION_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL);
16485e82846SNickeau                    if ($securityConf == PageProtection::CONF_VALUE_ACL) {
16585e82846SNickeau                        $event->result = AUTH_NONE;
16685e82846SNickeau                        return;
16785e82846SNickeau                    }
16885e82846SNickeau                }
16985e82846SNickeau            }
17085e82846SNickeau
17185e82846SNickeau        }
17285e82846SNickeau
17385e82846SNickeau    }
17485e82846SNickeau
17585e82846SNickeau    function handleSiteMapGenerate(&$event, $param)
17685e82846SNickeau    {
17785e82846SNickeau        $pageItems = $event->data["items"];
17885e82846SNickeau        foreach ($pageItems as $key => $pageItem) {
17985e82846SNickeau            $url = $pageItem->url;
18085e82846SNickeau            $dokuPath = DokuPath::createFromUrl($url);
18185e82846SNickeau            $page = Page::createPageFromId($dokuPath->getId());
18285e82846SNickeau            if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) {
18385e82846SNickeau
18485e82846SNickeau                unset($event->data["items"][$key]);
18585e82846SNickeau                continue;
18685e82846SNickeau
18785e82846SNickeau            }
18885e82846SNickeau            if ($page->isLatePublication() && Publication::isLatePublicationProtectionEnabled()) {
18985e82846SNickeau                unset($event->data["items"][$key]);
1905f891b7eSNickeau            }
1915f891b7eSNickeau        }
1925f891b7eSNickeau
1935f891b7eSNickeau    }
1945f891b7eSNickeau
1955f891b7eSNickeau    /**
1965f891b7eSNickeau     * @param $event
1975f891b7eSNickeau     * @param $param
1985f891b7eSNickeau     * The autocomplete do a search on page name
1995f891b7eSNickeau     */
2005f891b7eSNickeau    function handleSearchPageLookup(&$event, $param)
2015f891b7eSNickeau    {
2025f891b7eSNickeau        $this->excludePageFromSearch($event);
2035f891b7eSNickeau    }
2045f891b7eSNickeau
2055f891b7eSNickeau    /**
2065f891b7eSNickeau     * @param $event
2075f891b7eSNickeau     * @param $param
2085f891b7eSNickeau     * The search page do a search on page name
2095f891b7eSNickeau     */
2105f891b7eSNickeau    function handleSearchFullPage(&$event, $param)
2115f891b7eSNickeau    {
2125f891b7eSNickeau
2135f891b7eSNickeau        $this->excludePageFromSearch($event);
2145f891b7eSNickeau    }
2155f891b7eSNickeau
2165f891b7eSNickeau    /**
2175f891b7eSNickeau     *
2185f891b7eSNickeau     * @param $event
2195f891b7eSNickeau     * @param $param
2205f891b7eSNickeau     * The Rss
2215f891b7eSNickeau     * https://www.dokuwiki.org/syndication
2225f891b7eSNickeau     * Example
2235f891b7eSNickeau     * https://example.com/feed.php?type=rss2&num=5
2245f891b7eSNickeau     */
2255f891b7eSNickeau    function handleRssFeed(&$event, $param)
2265f891b7eSNickeau    {
22785e82846SNickeau        $isLowQualityProtectionEnabled = LowQualityPage::isProtectionEnabled();
22885e82846SNickeau        $isLatePublicationProtectionEnabled = Publication::isLatePublicationProtectionEnabled();
22985e82846SNickeau        if (!$isLatePublicationProtectionEnabled && !$isLowQualityProtectionEnabled) {
23085e82846SNickeau            return;
23185e82846SNickeau        }
23285e82846SNickeau
23385e82846SNickeau        $pagesToBeAdded = &$event->data["data"];
23485e82846SNickeau        foreach ($pagesToBeAdded as $key => $data) {
23585e82846SNickeau
236*e8b2ff59SNickeau            // To prevent an Illegal string offset 'id'
237*e8b2ff59SNickeau            if(isset($data["id"])) {
238*e8b2ff59SNickeau
23985e82846SNickeau                $page = Page::createPageFromId($data["id"]);
24085e82846SNickeau
24185e82846SNickeau                if ($page->isLowQualityPage() && $isLowQualityProtectionEnabled) {
24285e82846SNickeau                    $protectionMode = LowQualityPage::getLowQualityProtectionMode();
24385e82846SNickeau                    if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) {
24485e82846SNickeau                        unset($pagesToBeAdded[$key]);
24585e82846SNickeau                    }
24685e82846SNickeau                }
24785e82846SNickeau
24885e82846SNickeau                if ($page->isLatePublication() && $isLatePublicationProtectionEnabled) {
24985e82846SNickeau                    $protectionMode = Publication::getLatePublicationProtectionMode();
25085e82846SNickeau                    if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) {
25185e82846SNickeau                        unset($pagesToBeAdded[$key]);
25285e82846SNickeau                    }
25385e82846SNickeau                }
254*e8b2ff59SNickeau
255*e8b2ff59SNickeau            }
25685e82846SNickeau        }
25785e82846SNickeau
2585f891b7eSNickeau    }
2595f891b7eSNickeau
2605f891b7eSNickeau    /**
2615f891b7eSNickeau     * @param $event
26285e82846SNickeau     * @param array $protectionModes
2635f891b7eSNickeau     */
2645f891b7eSNickeau    private
26585e82846SNickeau    function excludePageFromSearch(&$event, $protectionModes = [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])
2665f891b7eSNickeau    {
2675f891b7eSNickeau
2685f891b7eSNickeau        /**
2695f891b7eSNickeau         * The value is always an array
2705f891b7eSNickeau         * but as we got this error:
2715f891b7eSNickeau         * ```
2725f891b7eSNickeau         * array_keys() expects parameter 1 to be array
2735f891b7eSNickeau         * ```
274*e8b2ff59SNickeau         * The result is a list of page id
2755f891b7eSNickeau         */
276*e8b2ff59SNickeau        if (is_array($event->result)) {
277*e8b2ff59SNickeau            foreach (array_keys($event->result) as $idx) {
27885e82846SNickeau                $page = Page::createPageFromId($idx);
27985e82846SNickeau                if ($page->isLowQualityPage()) {
28085e82846SNickeau                    $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE);
28185e82846SNickeau                    if (in_array($securityConf, $protectionModes)) {
282*e8b2ff59SNickeau                        unset($event->result[$idx]);
28385e82846SNickeau                        return;
28485e82846SNickeau                    }
28585e82846SNickeau                }
28685e82846SNickeau                if ($page->isLatePublication()) {
28785e82846SNickeau                    $securityConf = $this->getConf(Publication::CONF_LATE_PUBLICATION_PROTECTION_MODE);
28885e82846SNickeau                    if (in_array($securityConf, [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])) {
289*e8b2ff59SNickeau                        unset($event->result[$idx]);
29085e82846SNickeau                        return;
29185e82846SNickeau                    }
2925f891b7eSNickeau                }
2935f891b7eSNickeau            }
2945f891b7eSNickeau        }
2955f891b7eSNickeau
2965f891b7eSNickeau    }
2975f891b7eSNickeau
29885e82846SNickeau    /**
29985e82846SNickeau     * @noinspection SpellCheckingInspection
30085e82846SNickeau     * Adding an information to know if the user is signed or not
30185e82846SNickeau     */
3025f891b7eSNickeau    function handleAnonymousJsIndicator(&$event, $param)
3035f891b7eSNickeau    {
3045f891b7eSNickeau
3055f891b7eSNickeau        global $JSINFO;
30685e82846SNickeau        if (!Identity::isLoggedIn()) {
30785e82846SNickeau            $navigation = Identity::JS_NAVIGATION_ANONYMOUS_VALUE;
30885e82846SNickeau        } else {
30985e82846SNickeau            $navigation = Identity::JS_NAVIGATION_SIGNED_VALUE;
31085e82846SNickeau        }
31185e82846SNickeau        $JSINFO[Identity::JS_NAVIGATION_INDICATOR] = $navigation;
3125f891b7eSNickeau
3135f891b7eSNickeau
3145f891b7eSNickeau    }
3155f891b7eSNickeau
31685e82846SNickeau    /**
31785e82846SNickeau     * Handle the meta robots
31885e82846SNickeau     * https://www.dokuwiki.org/devel:event:tpl_metaheader_output
31985e82846SNickeau     * @param $event
32085e82846SNickeau     * @param $param
32185e82846SNickeau     */
32285e82846SNickeau    function handleRobotsMeta(&$event, $param)
32385e82846SNickeau    {
32485e82846SNickeau
32585e82846SNickeau        global $ID;
32685e82846SNickeau        if (empty($ID)) {
32785e82846SNickeau            // $_SERVER['SCRIPT_NAME']== "/lib/exe/mediamanager.php"
32885e82846SNickeau            // $ID is null
32985e82846SNickeau            return;
33085e82846SNickeau        }
33185e82846SNickeau
33285e82846SNickeau        $page = Page::createPageFromId($ID);
33385e82846SNickeau
33485e82846SNickeau        /**
33585e82846SNickeau         * No management for slot page
33685e82846SNickeau         */
33785e82846SNickeau        if ($page->isSlot()) {
33885e82846SNickeau            return;
33985e82846SNickeau        }
34085e82846SNickeau
34185e82846SNickeau        $protected = false;
34285e82846SNickeau        $follow = "nofollow";
34385e82846SNickeau        if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) {
34485e82846SNickeau            $protected = true;
34585e82846SNickeau            if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_ACL) {
34685e82846SNickeau                $follow = "nofollow";
34785e82846SNickeau            } else {
34885e82846SNickeau                $follow = "follow";
34985e82846SNickeau            }
35085e82846SNickeau        }
35185e82846SNickeau        if ($page->isLatePublication() && Publication::isLatePublicationProtectionEnabled()) {
35285e82846SNickeau            $protected = true;
35385e82846SNickeau            if (Publication::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_ACL) {
35485e82846SNickeau                $follow = "nofollow";
35585e82846SNickeau            } else {
35685e82846SNickeau                $follow = "follow";
35785e82846SNickeau            }
35885e82846SNickeau        }
35985e82846SNickeau        if ($protected) {
36085e82846SNickeau            foreach ($event->data['meta'] as $key => $meta) {
36185e82846SNickeau                if (array_key_exists("name", $meta)) {
36285e82846SNickeau                    /**
36385e82846SNickeau                     * We may have several properties
36485e82846SNickeau                     */
36585e82846SNickeau                    if ($meta["name"] == "robots") {
36685e82846SNickeau                        $event->data['meta'][$key]["content"] = "noindex,$follow";
36785e82846SNickeau                    }
36885e82846SNickeau                }
36985e82846SNickeau            }
37085e82846SNickeau        }
37185e82846SNickeau    }
37285e82846SNickeau
3735f891b7eSNickeau}
374