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