15f891b7eSNickeau<?php 25f891b7eSNickeau 35f891b7eSNickeau 4a6bf47aaSNickeauuse ComboStrap\Identity; 521913ab3SNickeauuse ComboStrap\DokuPath; 6*85e82846SNickeauuse ComboStrap\LatePublication; 75f891b7eSNickeauuse ComboStrap\LowQualityPage; 85f891b7eSNickeauuse ComboStrap\Page; 95f891b7eSNickeauuse ComboStrap\PageProtection; 10*85e82846SNickeauuse 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()); 32*85e82846SNickeau 335f891b7eSNickeau /** 345f891b7eSNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 355f891b7eSNickeau */ 365f891b7eSNickeau $controller->register_hook('AUTH_ACL_CHECK', 'AFTER', $this, 'handleAclCheck', array()); 37*85e82846SNickeau 38*85e82846SNickeau /** 39*85e82846SNickeau * https://www.dokuwiki.org/devel:event:sitemap_generate 40*85e82846SNickeau */ 41*85e82846SNickeau $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()); 52*85e82846SNickeau 535f891b7eSNickeau /** 545f891b7eSNickeau * https://www.dokuwiki.org/devel:event:feed_data_process 555f891b7eSNickeau */ 56*85e82846SNickeau $controller->register_hook('FEED_DATA_PROCESS', 'BEFORE', $this, 'handleRssFeed', array()); 575f891b7eSNickeau 585f891b7eSNickeau /** 59*85e82846SNickeau * Add logged in indicator for Javascript 605f891b7eSNickeau */ 615f891b7eSNickeau $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'handleAnonymousJsIndicator'); 625f891b7eSNickeau 63*85e82846SNickeau /** 64*85e82846SNickeau * Robots meta 65*85e82846SNickeau * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 66*85e82846SNickeau */ 67*85e82846SNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleRobotsMeta', array()); 68*85e82846SNickeau 695f891b7eSNickeau 705f891b7eSNickeau } 715f891b7eSNickeau 725f891b7eSNickeau /** 73*85e82846SNickeau * Set page has hidden 745f891b7eSNickeau * @param $event 755f891b7eSNickeau * @param $param 765f891b7eSNickeau */ 775f891b7eSNickeau function handleHiddenCheck(&$event, $param) 785f891b7eSNickeau { 795f891b7eSNickeau 80*85e82846SNickeau /** 81*85e82846SNickeau * Only for public 82*85e82846SNickeau */ 83*85e82846SNickeau if (Identity::isLoggedIn()) { 84*85e82846SNickeau return; 85*85e82846SNickeau } 865f891b7eSNickeau 87*85e82846SNickeau $id = $event->data['id']; 88*85e82846SNickeau if ($id == null) { 89*85e82846SNickeau /** 90*85e82846SNickeau * Happens in test when rendering 91*85e82846SNickeau * with instructions only 92*85e82846SNickeau */ 93*85e82846SNickeau return; 94*85e82846SNickeau } 95*85e82846SNickeau $page = Page::createPageFromId($id); 96*85e82846SNickeau 97*85e82846SNickeau if ($page->isLowQualityPage()) { 98*85e82846SNickeau if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) { 99*85e82846SNickeau $event->data['hidden'] = true; 100*85e82846SNickeau return; 101*85e82846SNickeau } 102*85e82846SNickeau } 103*85e82846SNickeau if ($page->isLatePublication()) { 104*85e82846SNickeau if (Publication::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) { 1055f891b7eSNickeau $event->data['hidden'] = true; 1065f891b7eSNickeau } 1075f891b7eSNickeau 1085f891b7eSNickeau } 1095f891b7eSNickeau 110*85e82846SNickeau } 111*85e82846SNickeau 1125f891b7eSNickeau /** 113*85e82846SNickeau * 114*85e82846SNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 1155f891b7eSNickeau * @param $event 1165f891b7eSNickeau * @param $param 1175f891b7eSNickeau */ 1185f891b7eSNickeau function handleAclCheck(&$event, $param) 1195f891b7eSNickeau { 120*85e82846SNickeau /** 121*85e82846SNickeau * Only for public 122*85e82846SNickeau * 123*85e82846SNickeau * Note: user is also 124*85e82846SNickeau * to be found at 125*85e82846SNickeau * $user = $event->data['user']; 126*85e82846SNickeau */ 127*85e82846SNickeau if (Identity::isLoggedIn()) { 128*85e82846SNickeau return; 129*85e82846SNickeau } 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()) { 145*85e82846SNickeau 14621913ab3SNickeau /** 14721913ab3SNickeau * It should be only a page 14821913ab3SNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 14921913ab3SNickeau */ 150*85e82846SNickeau $page = Page::createPageFromId($id); 151*85e82846SNickeau 152*85e82846SNickeau if ($page->isLowQualityPage()) { 153*85e82846SNickeau if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE, true)) { 154*85e82846SNickeau $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL); 155*85e82846SNickeau if ($securityConf == PageProtection::CONF_VALUE_ACL) { 1565f891b7eSNickeau $event->result = AUTH_NONE; 157*85e82846SNickeau return; 158*85e82846SNickeau } 159*85e82846SNickeau } 160*85e82846SNickeau } 161*85e82846SNickeau if ($page->isLatePublication()) { 162*85e82846SNickeau if ($this->getConf(Publication::CONF_LATE_PUBLICATION_PROTECTION_ENABLE, true)) { 163*85e82846SNickeau $securityConf = $this->getConf(Publication::CONF_LATE_PUBLICATION_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL); 164*85e82846SNickeau if ($securityConf == PageProtection::CONF_VALUE_ACL) { 165*85e82846SNickeau $event->result = AUTH_NONE; 166*85e82846SNickeau return; 167*85e82846SNickeau } 168*85e82846SNickeau } 169*85e82846SNickeau } 170*85e82846SNickeau 171*85e82846SNickeau } 172*85e82846SNickeau 173*85e82846SNickeau } 174*85e82846SNickeau 175*85e82846SNickeau function handleSiteMapGenerate(&$event, $param) 176*85e82846SNickeau { 177*85e82846SNickeau $pageItems = $event->data["items"]; 178*85e82846SNickeau foreach ($pageItems as $key => $pageItem) { 179*85e82846SNickeau $url = $pageItem->url; 180*85e82846SNickeau $dokuPath = DokuPath::createFromUrl($url); 181*85e82846SNickeau $page = Page::createPageFromId($dokuPath->getId()); 182*85e82846SNickeau if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) { 183*85e82846SNickeau 184*85e82846SNickeau unset($event->data["items"][$key]); 185*85e82846SNickeau continue; 186*85e82846SNickeau 187*85e82846SNickeau } 188*85e82846SNickeau if ($page->isLatePublication() && Publication::isLatePublicationProtectionEnabled()) { 189*85e82846SNickeau 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 { 227*85e82846SNickeau $isLowQualityProtectionEnabled = LowQualityPage::isProtectionEnabled(); 228*85e82846SNickeau $isLatePublicationProtectionEnabled = Publication::isLatePublicationProtectionEnabled(); 229*85e82846SNickeau if (!$isLatePublicationProtectionEnabled && !$isLowQualityProtectionEnabled) { 230*85e82846SNickeau return; 231*85e82846SNickeau } 232*85e82846SNickeau 233*85e82846SNickeau $pagesToBeAdded = &$event->data["data"]; 234*85e82846SNickeau foreach ($pagesToBeAdded as $key => $data) { 235*85e82846SNickeau 236*85e82846SNickeau $page = Page::createPageFromId($data["id"]); 237*85e82846SNickeau 238*85e82846SNickeau if ($page->isLowQualityPage() && $isLowQualityProtectionEnabled) { 239*85e82846SNickeau $protectionMode = LowQualityPage::getLowQualityProtectionMode(); 240*85e82846SNickeau if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) { 241*85e82846SNickeau unset($pagesToBeAdded[$key]); 242*85e82846SNickeau } 243*85e82846SNickeau } 244*85e82846SNickeau 245*85e82846SNickeau if ($page->isLatePublication() && $isLatePublicationProtectionEnabled) { 246*85e82846SNickeau $protectionMode = Publication::getLatePublicationProtectionMode(); 247*85e82846SNickeau if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) { 248*85e82846SNickeau unset($pagesToBeAdded[$key]); 249*85e82846SNickeau } 250*85e82846SNickeau } 251*85e82846SNickeau } 252*85e82846SNickeau 2535f891b7eSNickeau } 2545f891b7eSNickeau 2555f891b7eSNickeau /** 2565f891b7eSNickeau * @param $event 257*85e82846SNickeau * @param array $protectionModes 2585f891b7eSNickeau */ 2595f891b7eSNickeau private 260*85e82846SNickeau function excludePageFromSearch(&$event, $protectionModes = [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN]) 2615f891b7eSNickeau { 2625f891b7eSNickeau 2635f891b7eSNickeau $result = $event->result; 2645f891b7eSNickeau /** 2655f891b7eSNickeau * The value is always an array 2665f891b7eSNickeau * but as we got this error: 2675f891b7eSNickeau * ``` 2685f891b7eSNickeau * array_keys() expects parameter 1 to be array 2695f891b7eSNickeau * ``` 2705f891b7eSNickeau */ 2715f891b7eSNickeau if (is_array($result)) { 2725f891b7eSNickeau foreach (array_keys($result) as $idx) { 273*85e82846SNickeau $page = Page::createPageFromId($idx); 274*85e82846SNickeau if ($page->isLowQualityPage()) { 275*85e82846SNickeau $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE); 276*85e82846SNickeau if (in_array($securityConf, $protectionModes)) { 277*85e82846SNickeau $event->result = AUTH_NONE; 278*85e82846SNickeau return; 279*85e82846SNickeau } 280*85e82846SNickeau } 281*85e82846SNickeau if ($page->isLatePublication()) { 282*85e82846SNickeau $securityConf = $this->getConf(Publication::CONF_LATE_PUBLICATION_PROTECTION_MODE); 283*85e82846SNickeau if (in_array($securityConf, [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])) { 284*85e82846SNickeau $event->result = AUTH_NONE; 285*85e82846SNickeau return; 286*85e82846SNickeau } 2875f891b7eSNickeau } 2885f891b7eSNickeau } 2895f891b7eSNickeau } 2905f891b7eSNickeau 2915f891b7eSNickeau } 2925f891b7eSNickeau 293*85e82846SNickeau /** 294*85e82846SNickeau * @noinspection SpellCheckingInspection 295*85e82846SNickeau * Adding an information to know if the user is signed or not 296*85e82846SNickeau */ 2975f891b7eSNickeau function handleAnonymousJsIndicator(&$event, $param) 2985f891b7eSNickeau { 2995f891b7eSNickeau 3005f891b7eSNickeau global $JSINFO; 301*85e82846SNickeau if (!Identity::isLoggedIn()) { 302*85e82846SNickeau $navigation = Identity::JS_NAVIGATION_ANONYMOUS_VALUE; 303*85e82846SNickeau } else { 304*85e82846SNickeau $navigation = Identity::JS_NAVIGATION_SIGNED_VALUE; 305*85e82846SNickeau } 306*85e82846SNickeau $JSINFO[Identity::JS_NAVIGATION_INDICATOR] = $navigation; 3075f891b7eSNickeau 3085f891b7eSNickeau 3095f891b7eSNickeau } 3105f891b7eSNickeau 311*85e82846SNickeau /** 312*85e82846SNickeau * Handle the meta robots 313*85e82846SNickeau * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 314*85e82846SNickeau * @param $event 315*85e82846SNickeau * @param $param 316*85e82846SNickeau */ 317*85e82846SNickeau function handleRobotsMeta(&$event, $param) 318*85e82846SNickeau { 319*85e82846SNickeau 320*85e82846SNickeau global $ID; 321*85e82846SNickeau if (empty($ID)) { 322*85e82846SNickeau // $_SERVER['SCRIPT_NAME']== "/lib/exe/mediamanager.php" 323*85e82846SNickeau // $ID is null 324*85e82846SNickeau return; 325*85e82846SNickeau } 326*85e82846SNickeau 327*85e82846SNickeau $page = Page::createPageFromId($ID); 328*85e82846SNickeau 329*85e82846SNickeau /** 330*85e82846SNickeau * No management for slot page 331*85e82846SNickeau */ 332*85e82846SNickeau if ($page->isSlot()) { 333*85e82846SNickeau return; 334*85e82846SNickeau } 335*85e82846SNickeau 336*85e82846SNickeau $protected = false; 337*85e82846SNickeau $follow = "nofollow"; 338*85e82846SNickeau if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) { 339*85e82846SNickeau $protected = true; 340*85e82846SNickeau if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_ACL) { 341*85e82846SNickeau $follow = "nofollow"; 342*85e82846SNickeau } else { 343*85e82846SNickeau $follow = "follow"; 344*85e82846SNickeau } 345*85e82846SNickeau } 346*85e82846SNickeau if ($page->isLatePublication() && Publication::isLatePublicationProtectionEnabled()) { 347*85e82846SNickeau $protected = true; 348*85e82846SNickeau if (Publication::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_ACL) { 349*85e82846SNickeau $follow = "nofollow"; 350*85e82846SNickeau } else { 351*85e82846SNickeau $follow = "follow"; 352*85e82846SNickeau } 353*85e82846SNickeau } 354*85e82846SNickeau if ($protected) { 355*85e82846SNickeau foreach ($event->data['meta'] as $key => $meta) { 356*85e82846SNickeau if (array_key_exists("name", $meta)) { 357*85e82846SNickeau /** 358*85e82846SNickeau * We may have several properties 359*85e82846SNickeau */ 360*85e82846SNickeau if ($meta["name"] == "robots") { 361*85e82846SNickeau $event->data['meta'][$key]["content"] = "noindex,$follow"; 362*85e82846SNickeau } 363*85e82846SNickeau } 364*85e82846SNickeau } 365*85e82846SNickeau } 366*85e82846SNickeau } 367*85e82846SNickeau 3685f891b7eSNickeau} 369