15f891b7eSNickeau<?php 25f891b7eSNickeau 3c3437056SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 45f891b7eSNickeau 5*65e00826Sgerardnicouse ComboStrap\ExceptionBadArgument; 6*65e00826Sgerardnicouse ComboStrap\ExceptionBadSyntax; 704fd306cSNickeauuse ComboStrap\ExecutionContext; 8*65e00826Sgerardnicouse ComboStrap\FetcherPage; 904fd306cSNickeauuse ComboStrap\FileSystems; 10*65e00826Sgerardnicouse ComboStrap\LogUtility; 11*65e00826Sgerardnicouse ComboStrap\Web\Url; 1204fd306cSNickeauuse ComboStrap\WikiPath; 13c3437056SNickeauuse ComboStrap\Identity; 145f891b7eSNickeauuse ComboStrap\LowQualityPage; 1504fd306cSNickeauuse ComboStrap\MarkupPath; 165f891b7eSNickeauuse ComboStrap\PageProtection; 17c3437056SNickeauuse ComboStrap\PagePublicationDate; 185f891b7eSNickeau 19c3437056SNickeau 205f891b7eSNickeau/** 215f891b7eSNickeau * 225f891b7eSNickeau */ 235f891b7eSNickeauclass action_plugin_combo_pageprotection extends DokuWiki_Action_Plugin 245f891b7eSNickeau{ 255f891b7eSNickeau 265f891b7eSNickeau 275f891b7eSNickeau public function register(Doku_Event_Handler $controller) 285f891b7eSNickeau { 295f891b7eSNickeau 305f891b7eSNickeau 315f891b7eSNickeau /** 325f891b7eSNickeau * https://www.dokuwiki.org/devel:event:pageutils_id_hidepage 335f891b7eSNickeau */ 345f891b7eSNickeau $controller->register_hook('PAGEUTILS_ID_HIDEPAGE', 'BEFORE', $this, 'handleHiddenCheck', array()); 3585e82846SNickeau 365f891b7eSNickeau /** 375f891b7eSNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 385f891b7eSNickeau */ 395f891b7eSNickeau $controller->register_hook('AUTH_ACL_CHECK', 'AFTER', $this, 'handleAclCheck', array()); 4085e82846SNickeau 4185e82846SNickeau /** 4285e82846SNickeau * https://www.dokuwiki.org/devel:event:sitemap_generate 4385e82846SNickeau */ 4485e82846SNickeau $controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSiteMapGenerate', array()); 455f891b7eSNickeau 465f891b7eSNickeau /** 475f891b7eSNickeau * https://www.dokuwiki.org/devel:event:search_query_pagelookup 485f891b7eSNickeau */ 495f891b7eSNickeau $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'handleSearchPageLookup', array()); 505f891b7eSNickeau 515f891b7eSNickeau /** 525f891b7eSNickeau * https://www.dokuwiki.org/devel:event:search_query_fullpage 535f891b7eSNickeau */ 545f891b7eSNickeau $controller->register_hook('SEARCH_QUERY_FULLPAGE', 'AFTER', $this, 'handleSearchFullPage', array()); 5585e82846SNickeau 565f891b7eSNickeau /** 575f891b7eSNickeau * https://www.dokuwiki.org/devel:event:feed_data_process 585f891b7eSNickeau */ 5985e82846SNickeau $controller->register_hook('FEED_DATA_PROCESS', 'BEFORE', $this, 'handleRssFeed', array()); 605f891b7eSNickeau 615f891b7eSNickeau 6285e82846SNickeau /** 6385e82846SNickeau * Robots meta 6485e82846SNickeau * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 6585e82846SNickeau */ 6685e82846SNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleRobotsMeta', array()); 6785e82846SNickeau 685f891b7eSNickeau 695f891b7eSNickeau } 705f891b7eSNickeau 715f891b7eSNickeau /** 7285e82846SNickeau * Set page has hidden 735f891b7eSNickeau * @param $event 745f891b7eSNickeau * @param $param 755f891b7eSNickeau */ 765f891b7eSNickeau function handleHiddenCheck(&$event, $param) 775f891b7eSNickeau { 785f891b7eSNickeau 7985e82846SNickeau /** 8085e82846SNickeau * Only for public 8185e82846SNickeau */ 8285e82846SNickeau if (Identity::isLoggedIn()) { 8385e82846SNickeau return; 8485e82846SNickeau } 855f891b7eSNickeau 8685e82846SNickeau $id = $event->data['id']; 8785e82846SNickeau if ($id == null) { 8885e82846SNickeau /** 8985e82846SNickeau * Happens in test when rendering 9085e82846SNickeau * with instructions only 9185e82846SNickeau */ 9285e82846SNickeau return; 9385e82846SNickeau } 9404fd306cSNickeau $page = MarkupPath::createMarkupFromId($id); 9585e82846SNickeau 9685e82846SNickeau if ($page->isLowQualityPage()) { 9785e82846SNickeau if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) { 9885e82846SNickeau $event->data['hidden'] = true; 9985e82846SNickeau return; 10085e82846SNickeau } 10185e82846SNickeau } 10285e82846SNickeau if ($page->isLatePublication()) { 103c3437056SNickeau if (PagePublicationDate::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) { 1045f891b7eSNickeau $event->data['hidden'] = true; 1055f891b7eSNickeau } 1065f891b7eSNickeau 1075f891b7eSNickeau } 1085f891b7eSNickeau 10985e82846SNickeau } 11085e82846SNickeau 1115f891b7eSNickeau /** 11285e82846SNickeau * 11385e82846SNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 1145f891b7eSNickeau * @param $event 1155f891b7eSNickeau * @param $param 1165f891b7eSNickeau */ 1175f891b7eSNickeau function handleAclCheck(&$event, $param) 1185f891b7eSNickeau { 11985e82846SNickeau /** 12085e82846SNickeau * Only for public 12185e82846SNickeau * 12285e82846SNickeau * Note: user is also 12385e82846SNickeau * to be found at 12485e82846SNickeau * $user = $event->data['user']; 12585e82846SNickeau */ 12685e82846SNickeau if (Identity::isLoggedIn()) { 12785e82846SNickeau return; 12885e82846SNickeau } 1295f891b7eSNickeau 13032b85071SNickeau /** 13121913ab3SNickeau * Are we on a page script 13232b85071SNickeau */ 13321913ab3SNickeau $imageScript = ["/lib/exe/mediamanager.php", "/lib/exe/detail.php"]; 13421913ab3SNickeau if (in_array($_SERVER['SCRIPT_NAME'], $imageScript)) { 13521913ab3SNickeau // id may be null or end with a star 13621913ab3SNickeau // this is not a image 1375f891b7eSNickeau return; 13821913ab3SNickeau } 13932b85071SNickeau 14021913ab3SNickeau $id = $event->data['id']; 14104fd306cSNickeau if ($id == null) { 14204fd306cSNickeau /** 14304fd306cSNickeau * Happens in test when rendering 14404fd306cSNickeau * with instructions only 14504fd306cSNickeau */ 14604fd306cSNickeau return; 14704fd306cSNickeau } 14832b85071SNickeau 14904fd306cSNickeau $dokuPath = WikiPath::createFromUnknownRoot($id); 15021913ab3SNickeau if ($dokuPath->isPage()) { 15185e82846SNickeau 15221913ab3SNickeau /** 15321913ab3SNickeau * It should be only a page 15421913ab3SNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 15521913ab3SNickeau */ 15604fd306cSNickeau $page = MarkupPath::createMarkupFromId($id); 15785e82846SNickeau 15885e82846SNickeau if ($page->isLowQualityPage()) { 15985e82846SNickeau if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE, true)) { 16085e82846SNickeau $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL); 16185e82846SNickeau if ($securityConf == PageProtection::CONF_VALUE_ACL) { 1625f891b7eSNickeau $event->result = AUTH_NONE; 16385e82846SNickeau return; 16485e82846SNickeau } 16585e82846SNickeau } 16685e82846SNickeau } 16785e82846SNickeau if ($page->isLatePublication()) { 168c3437056SNickeau if ($this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_ENABLE, true)) { 169c3437056SNickeau $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL); 17085e82846SNickeau if ($securityConf == PageProtection::CONF_VALUE_ACL) { 17185e82846SNickeau $event->result = AUTH_NONE; 17285e82846SNickeau return; 17385e82846SNickeau } 17485e82846SNickeau } 17585e82846SNickeau } 17685e82846SNickeau 17785e82846SNickeau } 17885e82846SNickeau 17985e82846SNickeau } 18085e82846SNickeau 18185e82846SNickeau function handleSiteMapGenerate(&$event, $param) 18285e82846SNickeau { 18385e82846SNickeau $pageItems = $event->data["items"]; 18485e82846SNickeau foreach ($pageItems as $key => $pageItem) { 185*65e00826Sgerardnico 186*65e00826Sgerardnico try { 187*65e00826Sgerardnico $url = Url::createFromString($pageItem->url); 188*65e00826Sgerardnico $fetcherPage = FetcherPage::createPageFragmentFetcherFromUrl($url); 189*65e00826Sgerardnico } catch (ExceptionBadArgument|ExceptionBadSyntax $e) { 190*65e00826Sgerardnico LogUtility::internalError("We were unable to build the page fetcher. Error: " . $e->getMessage(), "sitemap", $e); 191*65e00826Sgerardnico continue; 192*65e00826Sgerardnico } 193*65e00826Sgerardnico 194*65e00826Sgerardnico $page = MarkupPath::createPageFromPathObject($fetcherPage->getSourcePath()); 19585e82846SNickeau if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) { 19685e82846SNickeau 19785e82846SNickeau unset($event->data["items"][$key]); 19885e82846SNickeau continue; 19985e82846SNickeau 20085e82846SNickeau } 201c3437056SNickeau if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) { 20285e82846SNickeau unset($event->data["items"][$key]); 2035f891b7eSNickeau } 204*65e00826Sgerardnico /** 205*65e00826Sgerardnico * Url rewrite 206*65e00826Sgerardnico */ 207*65e00826Sgerardnico $urlAfterRewrite = $page->getCanonicalUrl()->toString(); 208*65e00826Sgerardnico $event->data["items"][$key]->url = $urlAfterRewrite; 2095f891b7eSNickeau } 2105f891b7eSNickeau 2115f891b7eSNickeau } 2125f891b7eSNickeau 2135f891b7eSNickeau /** 2145f891b7eSNickeau * @param $event 2155f891b7eSNickeau * @param $param 2165f891b7eSNickeau * The autocomplete do a search on page name 2175f891b7eSNickeau */ 2185f891b7eSNickeau function handleSearchPageLookup(&$event, $param) 2195f891b7eSNickeau { 2205f891b7eSNickeau $this->excludePageFromSearch($event); 2215f891b7eSNickeau } 2225f891b7eSNickeau 2235f891b7eSNickeau /** 2245f891b7eSNickeau * @param $event 2255f891b7eSNickeau * @param $param 2265f891b7eSNickeau * The search page do a search on page name 2275f891b7eSNickeau */ 2285f891b7eSNickeau function handleSearchFullPage(&$event, $param) 2295f891b7eSNickeau { 2305f891b7eSNickeau 2315f891b7eSNickeau $this->excludePageFromSearch($event); 2325f891b7eSNickeau } 2335f891b7eSNickeau 2345f891b7eSNickeau /** 2355f891b7eSNickeau * 2365f891b7eSNickeau * @param $event 2375f891b7eSNickeau * @param $param 2385f891b7eSNickeau * The Rss 2395f891b7eSNickeau * https://www.dokuwiki.org/syndication 2405f891b7eSNickeau * Example 2415f891b7eSNickeau * https://example.com/feed.php?type=rss2&num=5 2425f891b7eSNickeau */ 2435f891b7eSNickeau function handleRssFeed(&$event, $param) 2445f891b7eSNickeau { 24585e82846SNickeau $isLowQualityProtectionEnabled = LowQualityPage::isProtectionEnabled(); 246c3437056SNickeau $isLatePublicationProtectionEnabled = PagePublicationDate::isLatePublicationProtectionEnabled(); 24785e82846SNickeau if (!$isLatePublicationProtectionEnabled && !$isLowQualityProtectionEnabled) { 24885e82846SNickeau return; 24985e82846SNickeau } 25085e82846SNickeau 25185e82846SNickeau $pagesToBeAdded = &$event->data["data"]; 25285e82846SNickeau foreach ($pagesToBeAdded as $key => $data) { 25385e82846SNickeau 254e8b2ff59SNickeau // To prevent an Illegal string offset 'id' 255e8b2ff59SNickeau if (isset($data["id"])) { 256e8b2ff59SNickeau 25704fd306cSNickeau $page = MarkupPath::createMarkupFromId($data["id"]); 25885e82846SNickeau 25985e82846SNickeau if ($page->isLowQualityPage() && $isLowQualityProtectionEnabled) { 26085e82846SNickeau $protectionMode = LowQualityPage::getLowQualityProtectionMode(); 26185e82846SNickeau if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) { 26285e82846SNickeau unset($pagesToBeAdded[$key]); 26385e82846SNickeau } 26485e82846SNickeau } 26585e82846SNickeau 26685e82846SNickeau if ($page->isLatePublication() && $isLatePublicationProtectionEnabled) { 267c3437056SNickeau $protectionMode = PagePublicationDate::getLatePublicationProtectionMode(); 26885e82846SNickeau if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) { 26985e82846SNickeau unset($pagesToBeAdded[$key]); 27085e82846SNickeau } 27185e82846SNickeau } 272e8b2ff59SNickeau 273e8b2ff59SNickeau } 27485e82846SNickeau } 27585e82846SNickeau 2765f891b7eSNickeau } 2775f891b7eSNickeau 2785f891b7eSNickeau /** 2795f891b7eSNickeau * @param $event 28085e82846SNickeau * @param array $protectionModes 2815f891b7eSNickeau */ 2825f891b7eSNickeau private 28385e82846SNickeau function excludePageFromSearch(&$event, $protectionModes = [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN]) 2845f891b7eSNickeau { 2855f891b7eSNickeau 2865f891b7eSNickeau /** 2875f891b7eSNickeau * The value is always an array 2885f891b7eSNickeau * but as we got this error: 2895f891b7eSNickeau * ``` 2905f891b7eSNickeau * array_keys() expects parameter 1 to be array 2915f891b7eSNickeau * ``` 292e8b2ff59SNickeau * The result is a list of page id 2935f891b7eSNickeau */ 294e8b2ff59SNickeau if (is_array($event->result)) { 295e8b2ff59SNickeau foreach (array_keys($event->result) as $idx) { 29604fd306cSNickeau $page = MarkupPath::createMarkupFromId($idx); 29785e82846SNickeau if ($page->isLowQualityPage()) { 29885e82846SNickeau $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE); 29985e82846SNickeau if (in_array($securityConf, $protectionModes)) { 300e8b2ff59SNickeau unset($event->result[$idx]); 30185e82846SNickeau return; 30285e82846SNickeau } 30385e82846SNickeau } 30485e82846SNickeau if ($page->isLatePublication()) { 305c3437056SNickeau $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE); 30685e82846SNickeau if (in_array($securityConf, [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])) { 307e8b2ff59SNickeau unset($event->result[$idx]); 30885e82846SNickeau return; 30985e82846SNickeau } 3105f891b7eSNickeau } 3115f891b7eSNickeau } 3125f891b7eSNickeau } 3135f891b7eSNickeau 3145f891b7eSNickeau } 3155f891b7eSNickeau 3165f891b7eSNickeau 31785e82846SNickeau /** 31885e82846SNickeau * Handle the meta robots 31985e82846SNickeau * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 32085e82846SNickeau * @param $event 32185e82846SNickeau * @param $param 32285e82846SNickeau */ 32385e82846SNickeau function handleRobotsMeta(&$event, $param) 32485e82846SNickeau { 32585e82846SNickeau 32604fd306cSNickeau $requestedPath = ExecutionContext::getActualOrCreateFromEnv()->getRequestedPath(); 32704fd306cSNickeau 32804fd306cSNickeau if (!FileSystems::exists($requestedPath)) { 32985e82846SNickeau return; 33085e82846SNickeau } 33185e82846SNickeau 33204fd306cSNickeau $page = MarkupPath::createPageFromPathObject($requestedPath); 33385e82846SNickeau 33485e82846SNickeau /** 33585e82846SNickeau * No management for slot page 33685e82846SNickeau */ 33704fd306cSNickeau 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 } 351c3437056SNickeau if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) { 35285e82846SNickeau $protected = true; 353c3437056SNickeau if (PagePublicationDate::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