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 case action_plugin_combo_router::TARGET_ORIGIN_CANONICAL: 133 $message = Message::createInfoMessage() 134 ->addHtmlContent("<p>" . $this->lang['message_redirected_from_canonical'] . "</p>"); 135 break; 136 default: 137 LogUtility::msg("The redirection source ($redirectSource) is unknown. It was not expected", LogUtility::LVL_MSG_ERROR, action_plugin_combo_router::CANONICAL); 138 return; 139 140 } 141 142 143 // Add a list of page with the same name to the message 144 // if the redirections is not planned 145 if ($redirectSource != action_plugin_combo_router::TARGET_ORIGIN_PAGE_RULES) { 146 $this->addToMessagePagesWithSameName($message, $pageIdOrigin); 147 } 148 149 if ($event->data === 'show' || $event->data === 'edit' || $event->data === 'search') { 150 $html = $message 151 ->setPlugin($this) 152 ->setClass(action_plugin_combo_routermessage::REDIRECT_MANAGER_BOX_CLASS) 153 ->setCanonical(action_plugin_combo_router::CANONICAL) 154 ->setSignatureName(action_plugin_combo_router::URL_MANAGER_NAME) 155 ->toHtmlBox(); 156 ptln($html); 157 } 158 159 160 } 161 162 163 } 164 165 166 /** 167 * Add the page with the same page name but in an other location 168 * @param Message $message 169 * @param $pageIdOrigin 170 */ 171 function addToMessagePagesWithSameName(Message $message, $pageIdOrigin) 172 { 173 174 if ($this->getConf(self::CONF_SHOW_PAGE_NAME_IS_NOT_UNIQUE) == 1) { 175 176 global $ID; 177 // The page name 178 $pageName = noNS($pageIdOrigin); 179 $pagesWithSameName = Index::getOrCreate()->getPagesWithSameLastName($pageIdOrigin); 180 181 if (count($pagesWithSameName) > 0) { 182 183 $message->setType(Message::TYPE_WARNING); 184 185 // Assign the value to a variable to be able to use the construct .= 186 if ($message->getPlainTextContent() <> '') { 187 $message->addHtmlContent('<br/><br/>'); 188 } 189 $message->addHtmlContent($this->lang['message_pagename_exist_one']); 190 $message->addHtmlContent('<ul>'); 191 192 $i = 0; 193 foreach ($pagesWithSameName as $pageId => $title) { 194 if ($pageId === $ID) { 195 continue; 196 } 197 $i++; 198 if ($i > 10) { 199 $message->addHtmlContent('<li>' . 200 tpl_link( 201 wl($pageIdOrigin) . "?do=search&q=" . rawurldecode($pageName), 202 "More ...", 203 'class="" rel="nofollow" title="More..."', 204 $return = true 205 ) . '</li>'); 206 break; 207 } 208 if ($title == null) { 209 $title = $pageId; 210 } 211 $message->addHtmlContent('<li>' . 212 tpl_link( 213 wl($pageId), 214 $title, 215 'class="" rel="nofollow" title="' . $title . '"', 216 $return = true 217 ) . '</li>'); 218 } 219 $message->addHtmlContent('</ul>'); 220 } 221 } 222 } 223 224 225 /** 226 * Set the redirect in a session that will be be read after the redirect 227 * in order to show a message to the user 228 * @param string $id 229 * @param string $redirectSource 230 */ 231 static function notify($id, $redirectSource) 232 { 233 // Msg via session 234 if (!defined('NOSESSION')) { 235 //reopen session, store data and close session again 236 self::sessionStart(); 237 $_SESSION[DOKU_COOKIE][self::ORIGIN_PAGE] = $id; 238 $_SESSION[DOKU_COOKIE][self::ORIGIN_TYPE] = $redirectSource; 239 self::sessionClose(); 240 241 } 242 } 243 244 245 private static function sessionStart() 246 { 247 $sessionStatus = session_status(); 248 switch ($sessionStatus) { 249 case PHP_SESSION_DISABLED: 250 throw new RuntimeException("Sessions are disabled"); 251 252 case PHP_SESSION_NONE: 253 $result = @session_start(); 254 if (!$result) { 255 throw new RuntimeException("The session was not successfully started"); 256 } 257 break; 258 case PHP_SESSION_ACTIVE: 259 break; 260 } 261 } 262 263 private static function sessionClose() 264 { 265 // Close the session 266 $phpVersion = phpversion(); 267 if ($phpVersion > "7.2.0") { 268 /** @noinspection PhpVoidFunctionResultUsedInspection */ 269 $result = session_write_close(); 270 if (!$result) { 271 // Session is really not a well known mechanism 272 // Set this error in a info level to not fail the test 273 LogUtility::msg("Failure to write the session", LogUtility::LVL_MSG_INFO); 274 } 275 } else { 276 session_write_close(); 277 } 278 279 } 280 281} 282