15f891b7eSNickeau<?php 25f891b7eSNickeau 3c3437056SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 45f891b7eSNickeau 5*04fd306cSNickeauuse ComboStrap\ExecutionContext; 6*04fd306cSNickeauuse ComboStrap\FileSystems; 7*04fd306cSNickeauuse ComboStrap\WikiPath; 8c3437056SNickeauuse ComboStrap\Identity; 95f891b7eSNickeauuse ComboStrap\LowQualityPage; 10*04fd306cSNickeauuse ComboStrap\MarkupPath; 115f891b7eSNickeauuse ComboStrap\PageProtection; 12c3437056SNickeauuse ComboStrap\PagePublicationDate; 135f891b7eSNickeau 14c3437056SNickeau 155f891b7eSNickeau/** 165f891b7eSNickeau * 175f891b7eSNickeau */ 185f891b7eSNickeauclass action_plugin_combo_pageprotection extends DokuWiki_Action_Plugin 195f891b7eSNickeau{ 205f891b7eSNickeau 215f891b7eSNickeau 225f891b7eSNickeau public function register(Doku_Event_Handler $controller) 235f891b7eSNickeau { 245f891b7eSNickeau 255f891b7eSNickeau 265f891b7eSNickeau /** 275f891b7eSNickeau * https://www.dokuwiki.org/devel:event:pageutils_id_hidepage 285f891b7eSNickeau */ 295f891b7eSNickeau $controller->register_hook('PAGEUTILS_ID_HIDEPAGE', 'BEFORE', $this, 'handleHiddenCheck', array()); 3085e82846SNickeau 315f891b7eSNickeau /** 325f891b7eSNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 335f891b7eSNickeau */ 345f891b7eSNickeau $controller->register_hook('AUTH_ACL_CHECK', 'AFTER', $this, 'handleAclCheck', array()); 3585e82846SNickeau 3685e82846SNickeau /** 3785e82846SNickeau * https://www.dokuwiki.org/devel:event:sitemap_generate 3885e82846SNickeau */ 3985e82846SNickeau $controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSiteMapGenerate', array()); 405f891b7eSNickeau 415f891b7eSNickeau /** 425f891b7eSNickeau * https://www.dokuwiki.org/devel:event:search_query_pagelookup 435f891b7eSNickeau */ 445f891b7eSNickeau $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'handleSearchPageLookup', array()); 455f891b7eSNickeau 465f891b7eSNickeau /** 475f891b7eSNickeau * https://www.dokuwiki.org/devel:event:search_query_fullpage 485f891b7eSNickeau */ 495f891b7eSNickeau $controller->register_hook('SEARCH_QUERY_FULLPAGE', 'AFTER', $this, 'handleSearchFullPage', array()); 5085e82846SNickeau 515f891b7eSNickeau /** 525f891b7eSNickeau * https://www.dokuwiki.org/devel:event:feed_data_process 535f891b7eSNickeau */ 5485e82846SNickeau $controller->register_hook('FEED_DATA_PROCESS', 'BEFORE', $this, 'handleRssFeed', array()); 555f891b7eSNickeau 565f891b7eSNickeau 5785e82846SNickeau /** 5885e82846SNickeau * Robots meta 5985e82846SNickeau * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 6085e82846SNickeau */ 6185e82846SNickeau $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleRobotsMeta', array()); 6285e82846SNickeau 635f891b7eSNickeau 645f891b7eSNickeau } 655f891b7eSNickeau 665f891b7eSNickeau /** 6785e82846SNickeau * Set page has hidden 685f891b7eSNickeau * @param $event 695f891b7eSNickeau * @param $param 705f891b7eSNickeau */ 715f891b7eSNickeau function handleHiddenCheck(&$event, $param) 725f891b7eSNickeau { 735f891b7eSNickeau 7485e82846SNickeau /** 7585e82846SNickeau * Only for public 7685e82846SNickeau */ 7785e82846SNickeau if (Identity::isLoggedIn()) { 7885e82846SNickeau return; 7985e82846SNickeau } 805f891b7eSNickeau 8185e82846SNickeau $id = $event->data['id']; 8285e82846SNickeau if ($id == null) { 8385e82846SNickeau /** 8485e82846SNickeau * Happens in test when rendering 8585e82846SNickeau * with instructions only 8685e82846SNickeau */ 8785e82846SNickeau return; 8885e82846SNickeau } 89*04fd306cSNickeau $page = MarkupPath::createMarkupFromId($id); 9085e82846SNickeau 9185e82846SNickeau if ($page->isLowQualityPage()) { 9285e82846SNickeau if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) { 9385e82846SNickeau $event->data['hidden'] = true; 9485e82846SNickeau return; 9585e82846SNickeau } 9685e82846SNickeau } 9785e82846SNickeau if ($page->isLatePublication()) { 98c3437056SNickeau if (PagePublicationDate::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_HIDDEN) { 995f891b7eSNickeau $event->data['hidden'] = true; 1005f891b7eSNickeau } 1015f891b7eSNickeau 1025f891b7eSNickeau } 1035f891b7eSNickeau 10485e82846SNickeau } 10585e82846SNickeau 1065f891b7eSNickeau /** 10785e82846SNickeau * 10885e82846SNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 1095f891b7eSNickeau * @param $event 1105f891b7eSNickeau * @param $param 1115f891b7eSNickeau */ 1125f891b7eSNickeau function handleAclCheck(&$event, $param) 1135f891b7eSNickeau { 11485e82846SNickeau /** 11585e82846SNickeau * Only for public 11685e82846SNickeau * 11785e82846SNickeau * Note: user is also 11885e82846SNickeau * to be found at 11985e82846SNickeau * $user = $event->data['user']; 12085e82846SNickeau */ 12185e82846SNickeau if (Identity::isLoggedIn()) { 12285e82846SNickeau return; 12385e82846SNickeau } 1245f891b7eSNickeau 12532b85071SNickeau /** 12621913ab3SNickeau * Are we on a page script 12732b85071SNickeau */ 12821913ab3SNickeau $imageScript = ["/lib/exe/mediamanager.php", "/lib/exe/detail.php"]; 12921913ab3SNickeau if (in_array($_SERVER['SCRIPT_NAME'], $imageScript)) { 13021913ab3SNickeau // id may be null or end with a star 13121913ab3SNickeau // this is not a image 1325f891b7eSNickeau return; 13321913ab3SNickeau } 13432b85071SNickeau 13521913ab3SNickeau $id = $event->data['id']; 136*04fd306cSNickeau if ($id == null) { 137*04fd306cSNickeau /** 138*04fd306cSNickeau * Happens in test when rendering 139*04fd306cSNickeau * with instructions only 140*04fd306cSNickeau */ 141*04fd306cSNickeau return; 142*04fd306cSNickeau } 14332b85071SNickeau 144*04fd306cSNickeau $dokuPath = WikiPath::createFromUnknownRoot($id); 14521913ab3SNickeau if ($dokuPath->isPage()) { 14685e82846SNickeau 14721913ab3SNickeau /** 14821913ab3SNickeau * It should be only a page 14921913ab3SNickeau * https://www.dokuwiki.org/devel:event:auth_acl_check 15021913ab3SNickeau */ 151*04fd306cSNickeau $page = MarkupPath::createMarkupFromId($id); 15285e82846SNickeau 15385e82846SNickeau if ($page->isLowQualityPage()) { 15485e82846SNickeau if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE, true)) { 15585e82846SNickeau $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL); 15685e82846SNickeau if ($securityConf == PageProtection::CONF_VALUE_ACL) { 1575f891b7eSNickeau $event->result = AUTH_NONE; 15885e82846SNickeau return; 15985e82846SNickeau } 16085e82846SNickeau } 16185e82846SNickeau } 16285e82846SNickeau if ($page->isLatePublication()) { 163c3437056SNickeau if ($this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_ENABLE, true)) { 164c3437056SNickeau $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE, PageProtection::CONF_VALUE_ACL); 16585e82846SNickeau if ($securityConf == PageProtection::CONF_VALUE_ACL) { 16685e82846SNickeau $event->result = AUTH_NONE; 16785e82846SNickeau return; 16885e82846SNickeau } 16985e82846SNickeau } 17085e82846SNickeau } 17185e82846SNickeau 17285e82846SNickeau } 17385e82846SNickeau 17485e82846SNickeau } 17585e82846SNickeau 17685e82846SNickeau function handleSiteMapGenerate(&$event, $param) 17785e82846SNickeau { 17885e82846SNickeau $pageItems = $event->data["items"]; 17985e82846SNickeau foreach ($pageItems as $key => $pageItem) { 18085e82846SNickeau $url = $pageItem->url; 181*04fd306cSNickeau $dokuPath = WikiPath::createFromUrl($url); 182*04fd306cSNickeau $page = MarkupPath::createMarkupFromId($dokuPath->getWikiId()); 18385e82846SNickeau if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) { 18485e82846SNickeau 18585e82846SNickeau unset($event->data["items"][$key]); 18685e82846SNickeau continue; 18785e82846SNickeau 18885e82846SNickeau } 189c3437056SNickeau if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) { 19085e82846SNickeau unset($event->data["items"][$key]); 1915f891b7eSNickeau } 1925f891b7eSNickeau } 1935f891b7eSNickeau 1945f891b7eSNickeau } 1955f891b7eSNickeau 1965f891b7eSNickeau /** 1975f891b7eSNickeau * @param $event 1985f891b7eSNickeau * @param $param 1995f891b7eSNickeau * The autocomplete do a search on page name 2005f891b7eSNickeau */ 2015f891b7eSNickeau function handleSearchPageLookup(&$event, $param) 2025f891b7eSNickeau { 2035f891b7eSNickeau $this->excludePageFromSearch($event); 2045f891b7eSNickeau } 2055f891b7eSNickeau 2065f891b7eSNickeau /** 2075f891b7eSNickeau * @param $event 2085f891b7eSNickeau * @param $param 2095f891b7eSNickeau * The search page do a search on page name 2105f891b7eSNickeau */ 2115f891b7eSNickeau function handleSearchFullPage(&$event, $param) 2125f891b7eSNickeau { 2135f891b7eSNickeau 2145f891b7eSNickeau $this->excludePageFromSearch($event); 2155f891b7eSNickeau } 2165f891b7eSNickeau 2175f891b7eSNickeau /** 2185f891b7eSNickeau * 2195f891b7eSNickeau * @param $event 2205f891b7eSNickeau * @param $param 2215f891b7eSNickeau * The Rss 2225f891b7eSNickeau * https://www.dokuwiki.org/syndication 2235f891b7eSNickeau * Example 2245f891b7eSNickeau * https://example.com/feed.php?type=rss2&num=5 2255f891b7eSNickeau */ 2265f891b7eSNickeau function handleRssFeed(&$event, $param) 2275f891b7eSNickeau { 22885e82846SNickeau $isLowQualityProtectionEnabled = LowQualityPage::isProtectionEnabled(); 229c3437056SNickeau $isLatePublicationProtectionEnabled = PagePublicationDate::isLatePublicationProtectionEnabled(); 23085e82846SNickeau if (!$isLatePublicationProtectionEnabled && !$isLowQualityProtectionEnabled) { 23185e82846SNickeau return; 23285e82846SNickeau } 23385e82846SNickeau 23485e82846SNickeau $pagesToBeAdded = &$event->data["data"]; 23585e82846SNickeau foreach ($pagesToBeAdded as $key => $data) { 23685e82846SNickeau 237e8b2ff59SNickeau // To prevent an Illegal string offset 'id' 238e8b2ff59SNickeau if (isset($data["id"])) { 239e8b2ff59SNickeau 240*04fd306cSNickeau $page = MarkupPath::createMarkupFromId($data["id"]); 24185e82846SNickeau 24285e82846SNickeau if ($page->isLowQualityPage() && $isLowQualityProtectionEnabled) { 24385e82846SNickeau $protectionMode = LowQualityPage::getLowQualityProtectionMode(); 24485e82846SNickeau if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) { 24585e82846SNickeau unset($pagesToBeAdded[$key]); 24685e82846SNickeau } 24785e82846SNickeau } 24885e82846SNickeau 24985e82846SNickeau if ($page->isLatePublication() && $isLatePublicationProtectionEnabled) { 250c3437056SNickeau $protectionMode = PagePublicationDate::getLatePublicationProtectionMode(); 25185e82846SNickeau if ($protectionMode != PageProtection::CONF_VALUE_ROBOT) { 25285e82846SNickeau unset($pagesToBeAdded[$key]); 25385e82846SNickeau } 25485e82846SNickeau } 255e8b2ff59SNickeau 256e8b2ff59SNickeau } 25785e82846SNickeau } 25885e82846SNickeau 2595f891b7eSNickeau } 2605f891b7eSNickeau 2615f891b7eSNickeau /** 2625f891b7eSNickeau * @param $event 26385e82846SNickeau * @param array $protectionModes 2645f891b7eSNickeau */ 2655f891b7eSNickeau private 26685e82846SNickeau function excludePageFromSearch(&$event, $protectionModes = [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN]) 2675f891b7eSNickeau { 2685f891b7eSNickeau 2695f891b7eSNickeau /** 2705f891b7eSNickeau * The value is always an array 2715f891b7eSNickeau * but as we got this error: 2725f891b7eSNickeau * ``` 2735f891b7eSNickeau * array_keys() expects parameter 1 to be array 2745f891b7eSNickeau * ``` 275e8b2ff59SNickeau * The result is a list of page id 2765f891b7eSNickeau */ 277e8b2ff59SNickeau if (is_array($event->result)) { 278e8b2ff59SNickeau foreach (array_keys($event->result) as $idx) { 279*04fd306cSNickeau $page = MarkupPath::createMarkupFromId($idx); 28085e82846SNickeau if ($page->isLowQualityPage()) { 28185e82846SNickeau $securityConf = $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_MODE); 28285e82846SNickeau if (in_array($securityConf, $protectionModes)) { 283e8b2ff59SNickeau unset($event->result[$idx]); 28485e82846SNickeau return; 28585e82846SNickeau } 28685e82846SNickeau } 28785e82846SNickeau if ($page->isLatePublication()) { 288c3437056SNickeau $securityConf = $this->getConf(PagePublicationDate::CONF_LATE_PUBLICATION_PROTECTION_MODE); 28985e82846SNickeau if (in_array($securityConf, [PageProtection::CONF_VALUE_ACL, PageProtection::CONF_VALUE_HIDDEN])) { 290e8b2ff59SNickeau unset($event->result[$idx]); 29185e82846SNickeau return; 29285e82846SNickeau } 2935f891b7eSNickeau } 2945f891b7eSNickeau } 2955f891b7eSNickeau } 2965f891b7eSNickeau 2975f891b7eSNickeau } 2985f891b7eSNickeau 2995f891b7eSNickeau 30085e82846SNickeau /** 30185e82846SNickeau * Handle the meta robots 30285e82846SNickeau * https://www.dokuwiki.org/devel:event:tpl_metaheader_output 30385e82846SNickeau * @param $event 30485e82846SNickeau * @param $param 30585e82846SNickeau */ 30685e82846SNickeau function handleRobotsMeta(&$event, $param) 30785e82846SNickeau { 30885e82846SNickeau 309*04fd306cSNickeau $requestedPath = ExecutionContext::getActualOrCreateFromEnv()->getRequestedPath(); 310*04fd306cSNickeau 311*04fd306cSNickeau if (!FileSystems::exists($requestedPath)) { 31285e82846SNickeau return; 31385e82846SNickeau } 31485e82846SNickeau 315*04fd306cSNickeau $page = MarkupPath::createPageFromPathObject($requestedPath); 31685e82846SNickeau 31785e82846SNickeau /** 31885e82846SNickeau * No management for slot page 31985e82846SNickeau */ 320*04fd306cSNickeau if ($page->isSlot()) { 32185e82846SNickeau return; 32285e82846SNickeau } 32385e82846SNickeau 32485e82846SNickeau $protected = false; 32585e82846SNickeau $follow = "nofollow"; 32685e82846SNickeau if ($page->isLowQualityPage() && LowQualityPage::isProtectionEnabled()) { 32785e82846SNickeau $protected = true; 32885e82846SNickeau if (LowQualityPage::getLowQualityProtectionMode() == PageProtection::CONF_VALUE_ACL) { 32985e82846SNickeau $follow = "nofollow"; 33085e82846SNickeau } else { 33185e82846SNickeau $follow = "follow"; 33285e82846SNickeau } 33385e82846SNickeau } 334c3437056SNickeau if ($page->isLatePublication() && PagePublicationDate::isLatePublicationProtectionEnabled()) { 33585e82846SNickeau $protected = true; 336c3437056SNickeau if (PagePublicationDate::getLatePublicationProtectionMode() == PageProtection::CONF_VALUE_ACL) { 33785e82846SNickeau $follow = "nofollow"; 33885e82846SNickeau } else { 33985e82846SNickeau $follow = "follow"; 34085e82846SNickeau } 34185e82846SNickeau } 34285e82846SNickeau if ($protected) { 34385e82846SNickeau foreach ($event->data['meta'] as $key => $meta) { 34485e82846SNickeau if (array_key_exists("name", $meta)) { 34585e82846SNickeau /** 34685e82846SNickeau * We may have several properties 34785e82846SNickeau */ 34885e82846SNickeau if ($meta["name"] == "robots") { 34985e82846SNickeau $event->data['meta'][$key]["content"] = "noindex,$follow"; 35085e82846SNickeau } 35185e82846SNickeau } 35285e82846SNickeau } 35385e82846SNickeau } 35485e82846SNickeau } 35585e82846SNickeau 3565f891b7eSNickeau} 357