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