1c3437056SNickeau<?php 2c3437056SNickeau 3c3437056SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 4c3437056SNickeau 5*86ec4045Sgerardnicouse ComboStrap\Identity; 6c3437056SNickeauuse ComboStrap\Index; 7c3437056SNickeauuse ComboStrap\LogUtility; 8c3437056SNickeauuse ComboStrap\Message; 9c3437056SNickeauuse dokuwiki\Extension\ActionPlugin; 10c3437056SNickeau 11c3437056SNickeau 12c3437056SNickeau/** 13c3437056SNickeau * 14c3437056SNickeau * To show a message after redirection or rewriting 15c3437056SNickeau * 16c3437056SNickeau * 17c3437056SNickeau * 18c3437056SNickeau */ 19c3437056SNickeauclass action_plugin_combo_routermessage extends ActionPlugin 20c3437056SNickeau{ 21c3437056SNickeau 22c3437056SNickeau // a class can not start with a number then webcomponent is not a valid class name 23c3437056SNickeau const REDIRECT_MANAGER_BOX_CLASS = "redirect-manager"; 24c3437056SNickeau 25c3437056SNickeau // Property key 26c3437056SNickeau const ORIGIN_PAGE = 'redirectId'; 27c3437056SNickeau const ORIGIN_TYPE = 'redirectOrigin'; 28c3437056SNickeau const CONF_SHOW_PAGE_NAME_IS_NOT_UNIQUE = 'ShowPageNameIsNotUnique'; 29*86ec4045Sgerardnico const CONF_SHOW_MESSAGE_CLASSIC = 'ShowMessageClassic'; 30*86ec4045Sgerardnico const CONF_SHOW_MESSAGE_CLASSIC_DEFAULT = 1; 31c3437056SNickeau 32c3437056SNickeau function __construct() 33c3437056SNickeau { 34c3437056SNickeau // enable direct access to language strings 35c3437056SNickeau // ie $this->lang 36c3437056SNickeau $this->setupLocale(); 37c3437056SNickeau } 38c3437056SNickeau 39c3437056SNickeau /** 40c3437056SNickeau * 41c3437056SNickeau * Return the message properties from a query string 42c3437056SNickeau * 43c3437056SNickeau * An internal HTTP redirect pass them via query string 44c3437056SNickeau */ 45c3437056SNickeau private static function getMessageQueryStringProperties(): array 46c3437056SNickeau { 47c3437056SNickeau 48c3437056SNickeau $returnValues = array(); 49c3437056SNickeau 50c3437056SNickeau global $INPUT; 51c3437056SNickeau $origin = $INPUT->str(self::ORIGIN_PAGE, null); 52c3437056SNickeau if ($origin != null) { 53c3437056SNickeau $returnValues = array( 54c3437056SNickeau $origin, 55c3437056SNickeau $INPUT->str(self::ORIGIN_TYPE, null) 56c3437056SNickeau ); 57c3437056SNickeau } 58c3437056SNickeau return $returnValues; 59c3437056SNickeau 60c3437056SNickeau } 61c3437056SNickeau 62c3437056SNickeau 63c3437056SNickeau function register(Doku_Event_Handler $controller) 64c3437056SNickeau { 65c3437056SNickeau 66c3437056SNickeau /* This will call the function _displayRedirectMessage */ 67c3437056SNickeau $controller->register_hook( 68c3437056SNickeau 'TPL_ACT_RENDER', 69c3437056SNickeau 'BEFORE', 70c3437056SNickeau $this, 71c3437056SNickeau '_displayRedirectMessage', 72c3437056SNickeau array() 73c3437056SNickeau ); 74c3437056SNickeau 75c3437056SNickeau 76c3437056SNickeau } 77c3437056SNickeau 78c3437056SNickeau 79c3437056SNickeau /** 80c3437056SNickeau * Main function; dispatches the visual comment actions 81c3437056SNickeau * @param $event Doku_Event 82c3437056SNickeau */ 83c3437056SNickeau function _displayRedirectMessage(&$event, $param) 84c3437056SNickeau { 85c3437056SNickeau 86c3437056SNickeau $pageIdOrigin = null; 87c3437056SNickeau $redirectSource = null; 88c3437056SNickeau 89c3437056SNickeau $messageQueryStringProperties = self::getMessageQueryStringProperties(); 90c3437056SNickeau if (!empty($messageQueryStringProperties)) { 91c3437056SNickeau list($pageIdOrigin, $redirectSource) = $messageQueryStringProperties; 92c3437056SNickeau } 93c3437056SNickeau 94c3437056SNickeau if ($pageIdOrigin) { 95c3437056SNickeau 96c3437056SNickeau switch ($redirectSource) { 97c3437056SNickeau 98c3437056SNickeau case action_plugin_combo_router::TARGET_ORIGIN_PAGE_RULES: 99*86ec4045Sgerardnico if (!$this->showMessageIfPublicAndPlanned()) { 100*86ec4045Sgerardnico return; 101*86ec4045Sgerardnico } 102c3437056SNickeau $message = Message::createInfoMessage() 103c3437056SNickeau ->addHtmlContent("<p>" . sprintf($this->getLang('message_redirected_by_redirect'), hsc($pageIdOrigin)) . "</p>"); 104c3437056SNickeau break; 105c3437056SNickeau 106c3437056SNickeau case action_plugin_combo_router::TARGET_ORIGIN_START_PAGE: 107c3437056SNickeau $message = Message::createWarningMessage() 108c3437056SNickeau ->addHtmlContent("<p>" . sprintf($this->lang['message_redirected_to_startpage'], hsc($pageIdOrigin)) . "</p>"); 109c3437056SNickeau break; 110c3437056SNickeau case action_plugin_combo_router::TARGET_ORIGIN_BEST_PAGE_NAME: 111c3437056SNickeau $message = Message::createWarningMessage() 112c3437056SNickeau ->addHtmlContent("<p>" . sprintf($this->lang['message_redirected_to_bestpagename'], hsc($pageIdOrigin)) . "</p>"); 113c3437056SNickeau break; 114c3437056SNickeau case action_plugin_combo_router::TARGET_ORIGIN_BEST_NAMESPACE: 115c3437056SNickeau $message = Message::createWarningMessage() 116c3437056SNickeau ->addHtmlContent("<p>" . sprintf($this->lang['message_redirected_to_bestnamespace'], hsc($pageIdOrigin)) . "</p>"); 117c3437056SNickeau break; 118c3437056SNickeau 119c3437056SNickeau case action_plugin_combo_router::TARGET_ORIGIN_SEARCH_ENGINE: 120c3437056SNickeau $message = Message::createWarningMessage() 121c3437056SNickeau ->addHtmlContent("<p>" . sprintf($this->lang['message_redirected_to_searchengine'], hsc($pageIdOrigin)) . "</p>"); 122c3437056SNickeau break; 123c3437056SNickeau 124c3437056SNickeau case action_plugin_combo_router::GO_TO_EDIT_MODE: 125c3437056SNickeau $message = Message::createInfoMessage() 126c3437056SNickeau ->addHtmlContent("<p>" . $this->lang['message_redirected_to_edit_mode'] . "</p>"); 127c3437056SNickeau break; 128c3437056SNickeau case action_plugin_combo_router::TARGET_ORIGIN_PERMALINK_EXTENDED: 129c3437056SNickeau case action_plugin_combo_router::TARGET_ORIGIN_PERMALINK: 130c3437056SNickeau $message = Message::createInfoMessage() 131c3437056SNickeau ->addHtmlContent("<p>" . $this->lang['message_redirected_from_permalink'] . "</p>"); 132c3437056SNickeau break; 133561faa65Sgerardnico case action_plugin_combo_router::TARGET_ORIGIN_CANONICAL: 134*86ec4045Sgerardnico if (!$this->showMessageIfPublicAndPlanned()) { 135*86ec4045Sgerardnico return; 136*86ec4045Sgerardnico } 137561faa65Sgerardnico $message = Message::createInfoMessage() 138561faa65Sgerardnico ->addHtmlContent("<p>" . $this->lang['message_redirected_from_canonical'] . "</p>"); 139561faa65Sgerardnico break; 140c3437056SNickeau default: 141c3437056SNickeau LogUtility::msg("The redirection source ($redirectSource) is unknown. It was not expected", LogUtility::LVL_MSG_ERROR, action_plugin_combo_router::CANONICAL); 142c3437056SNickeau return; 143c3437056SNickeau 144c3437056SNickeau } 145c3437056SNickeau 146c3437056SNickeau 147c3437056SNickeau // Add a list of page with the same name to the message 148c3437056SNickeau // if the redirections is not planned 149*86ec4045Sgerardnico if ($redirectSource !== action_plugin_combo_router::TARGET_ORIGIN_PAGE_RULES) { 150c3437056SNickeau $this->addToMessagePagesWithSameName($message, $pageIdOrigin); 151c3437056SNickeau } 152c3437056SNickeau 153c3437056SNickeau if ($event->data === 'show' || $event->data === 'edit' || $event->data === 'search') { 154c3437056SNickeau $html = $message 155c3437056SNickeau ->setPlugin($this) 156c3437056SNickeau ->setClass(action_plugin_combo_routermessage::REDIRECT_MANAGER_BOX_CLASS) 157c3437056SNickeau ->setCanonical(action_plugin_combo_router::CANONICAL) 158c3437056SNickeau ->setSignatureName(action_plugin_combo_router::URL_MANAGER_NAME) 159c3437056SNickeau ->toHtmlBox(); 160c3437056SNickeau ptln($html); 161c3437056SNickeau } 162c3437056SNickeau 163c3437056SNickeau 164c3437056SNickeau } 165c3437056SNickeau 166c3437056SNickeau 167c3437056SNickeau } 168c3437056SNickeau 169c3437056SNickeau 170c3437056SNickeau /** 171c3437056SNickeau * Add the page with the same page name but in an other location 172c3437056SNickeau * @param Message $message 173c3437056SNickeau * @param $pageIdOrigin 174c3437056SNickeau */ 175c3437056SNickeau function addToMessagePagesWithSameName(Message $message, $pageIdOrigin) 176c3437056SNickeau { 177c3437056SNickeau 178*86ec4045Sgerardnico if (!$this->getConf(self::CONF_SHOW_PAGE_NAME_IS_NOT_UNIQUE) == 1) { 179*86ec4045Sgerardnico return; 180*86ec4045Sgerardnico } 181c3437056SNickeau 182c3437056SNickeau global $ID; 183c3437056SNickeau // The page name 184c3437056SNickeau $pageName = noNS($pageIdOrigin); 185c3437056SNickeau $pagesWithSameName = Index::getOrCreate()->getPagesWithSameLastName($pageIdOrigin); 186c3437056SNickeau 187c3437056SNickeau if (count($pagesWithSameName) > 0) { 188c3437056SNickeau 189c3437056SNickeau $message->setType(Message::TYPE_WARNING); 190c3437056SNickeau 191c3437056SNickeau // Assign the value to a variable to be able to use the construct .= 192c3437056SNickeau if ($message->getPlainTextContent() <> '') { 193c3437056SNickeau $message->addHtmlContent('<br/><br/>'); 194c3437056SNickeau } 195c3437056SNickeau $message->addHtmlContent($this->lang['message_pagename_exist_one']); 196c3437056SNickeau $message->addHtmlContent('<ul>'); 197c3437056SNickeau 198c3437056SNickeau $i = 0; 199c3437056SNickeau foreach ($pagesWithSameName as $pageId => $title) { 200c3437056SNickeau if ($pageId === $ID) { 201c3437056SNickeau continue; 202c3437056SNickeau } 203c3437056SNickeau $i++; 204c3437056SNickeau if ($i > 10) { 205c3437056SNickeau $message->addHtmlContent('<li>' . 206c3437056SNickeau tpl_link( 207c3437056SNickeau wl($pageIdOrigin) . "?do=search&q=" . rawurldecode($pageName), 208c3437056SNickeau "More ...", 209c3437056SNickeau 'class="" rel="nofollow" title="More..."', 210c3437056SNickeau $return = true 211c3437056SNickeau ) . '</li>'); 212c3437056SNickeau break; 213c3437056SNickeau } 214c3437056SNickeau if ($title == null) { 215c3437056SNickeau $title = $pageId; 216c3437056SNickeau } 217c3437056SNickeau $message->addHtmlContent('<li>' . 218c3437056SNickeau tpl_link( 219c3437056SNickeau wl($pageId), 220c3437056SNickeau $title, 221c3437056SNickeau 'class="" rel="nofollow" title="' . $title . '"', 222c3437056SNickeau $return = true 223c3437056SNickeau ) . '</li>'); 224c3437056SNickeau } 225c3437056SNickeau $message->addHtmlContent('</ul>'); 226c3437056SNickeau } 227*86ec4045Sgerardnico 228c3437056SNickeau } 229c3437056SNickeau 230c3437056SNickeau 231c3437056SNickeau /** 232c3437056SNickeau * Set the redirect in a session that will be be read after the redirect 233c3437056SNickeau * in order to show a message to the user 234c3437056SNickeau * @param string $id 235c3437056SNickeau * @param string $redirectSource 236c3437056SNickeau */ 237c3437056SNickeau static function notify($id, $redirectSource) 238c3437056SNickeau { 239c3437056SNickeau // Msg via session 240c3437056SNickeau if (!defined('NOSESSION')) { 241c3437056SNickeau //reopen session, store data and close session again 242c3437056SNickeau self::sessionStart(); 243c3437056SNickeau $_SESSION[DOKU_COOKIE][self::ORIGIN_PAGE] = $id; 244c3437056SNickeau $_SESSION[DOKU_COOKIE][self::ORIGIN_TYPE] = $redirectSource; 245c3437056SNickeau self::sessionClose(); 246c3437056SNickeau 247c3437056SNickeau } 248c3437056SNickeau } 249c3437056SNickeau 250c3437056SNickeau 251c3437056SNickeau private static function sessionStart() 252c3437056SNickeau { 253c3437056SNickeau $sessionStatus = session_status(); 254c3437056SNickeau switch ($sessionStatus) { 255c3437056SNickeau case PHP_SESSION_DISABLED: 256c3437056SNickeau throw new RuntimeException("Sessions are disabled"); 257c3437056SNickeau 258c3437056SNickeau case PHP_SESSION_NONE: 259c3437056SNickeau $result = @session_start(); 260c3437056SNickeau if (!$result) { 261c3437056SNickeau throw new RuntimeException("The session was not successfully started"); 262c3437056SNickeau } 263c3437056SNickeau break; 264c3437056SNickeau case PHP_SESSION_ACTIVE: 265c3437056SNickeau break; 266c3437056SNickeau } 267c3437056SNickeau } 268c3437056SNickeau 269c3437056SNickeau private static function sessionClose() 270c3437056SNickeau { 271c3437056SNickeau // Close the session 272c3437056SNickeau $phpVersion = phpversion(); 273c3437056SNickeau if ($phpVersion > "7.2.0") { 274c3437056SNickeau $result = session_write_close(); 275c3437056SNickeau if (!$result) { 276c3437056SNickeau // Session is really not a well known mechanism 277c3437056SNickeau // Set this error in a info level to not fail the test 278c3437056SNickeau LogUtility::msg("Failure to write the session", LogUtility::LVL_MSG_INFO); 279c3437056SNickeau } 280c3437056SNickeau } else { 281c3437056SNickeau session_write_close(); 282c3437056SNickeau } 283c3437056SNickeau 284c3437056SNickeau } 285c3437056SNickeau 286*86ec4045Sgerardnico /** 287*86ec4045Sgerardnico * We don't saw the message if it was planned and 288*86ec4045Sgerardnico * it's a reader 289*86ec4045Sgerardnico * @return bool 290*86ec4045Sgerardnico */ 291*86ec4045Sgerardnico private function showMessageIfPublicAndPlanned(): bool 292*86ec4045Sgerardnico { 293*86ec4045Sgerardnico if (Identity::isWriter()){ 294*86ec4045Sgerardnico return true; 295*86ec4045Sgerardnico } 296*86ec4045Sgerardnico return $this->getConf(self::CONF_SHOW_MESSAGE_CLASSIC, self::CONF_SHOW_MESSAGE_CLASSIC_DEFAULT) == 1; 297*86ec4045Sgerardnico } 298*86ec4045Sgerardnico 299c3437056SNickeau} 300