syntax.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. /**
  3. * DokuWiki Plugin pageredirect (Syntax Component)
  4. *
  5. * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
  6. * @author Elan Ruusamäe <glen@delfi.ee>
  7. * @author David Lorentsen <zyberdog@quakenet.org>
  8. */
  9. // must be run within Dokuwiki
  10. if(!defined('DOKU_INC')) die();
  11. class syntax_plugin_pageredirect extends DokuWiki_Syntax_Plugin {
  12. /**
  13. * @return string Syntax mode type
  14. */
  15. public function getType() {
  16. return 'substition';
  17. }
  18. /**
  19. * @return string Paragraph type
  20. */
  21. public function getPType() {
  22. return 'block';
  23. }
  24. /**
  25. * @return int Sort order - Low numbers go before high numbers
  26. */
  27. public function getSort() {
  28. return 1;
  29. }
  30. /**
  31. * Connect lookup pattern to lexer.
  32. *
  33. * @param string $mode Parser mode
  34. */
  35. public function connectTo($mode) {
  36. // NOTE: each document is surrounted with \n by dokuwiki parser
  37. // so it's safe to use \n in the pattern
  38. // this fixes creole greedyness:
  39. // https://github.com/glensc/dokuwiki-plugin-pageredirect/issues/18#issuecomment-249386268
  40. $this->Lexer->addSpecialPattern('(?:~~REDIRECT>.+?~~|\n#(?i:redirect) [^\r\n]+)', $mode, 'plugin_pageredirect');
  41. }
  42. /**
  43. * Handler to prepare matched data for the rendering process
  44. *
  45. * This function can only pass data to render() via its return value
  46. * render() may be not be run during the object's current life.
  47. *
  48. * Usually you should only need the $match param.
  49. *
  50. * @param string $match The text matched by the patterns
  51. * @param int $state The lexer state for the match
  52. * @param int $pos The character position of the matched text
  53. * @param Doku_Handler $handler Reference to the Doku_Handler object
  54. * @return array Return an array with all data you want to use in render
  55. */
  56. public function handle($match, $state, $pos, Doku_Handler $handler) {
  57. // strip leading "\n" from creole-compatible pattern
  58. $match = trim($match);
  59. // extract target page from match pattern
  60. if($match[0] == '#') {
  61. # #REDIRECT PAGE
  62. $id = substr($match, 10);
  63. } else {
  64. # ~~REDIRECT>PAGE~~
  65. $id = substr($match, 11, -2);
  66. }
  67. $id = trim($id);
  68. $is_external = preg_match('#^https?://#i', $id);
  69. // resolve and clean the $id if it is not external
  70. if(!$is_external) {
  71. global $ID;
  72. resolve_pageid(getNS($ID), $id, $exists);
  73. }
  74. return array($id, $is_external);
  75. }
  76. /**
  77. * Handles the actual output creation.
  78. *
  79. * The function must not assume any other of the classes methods have been run
  80. * during the object's current life. The only reliable data it receives are its
  81. * parameters.
  82. *
  83. * The function should always check for the given output format and return false
  84. * when a format isn't supported.
  85. *
  86. * $renderer contains a reference to the renderer object which is
  87. * currently handling the rendering. You need to use it for writing
  88. * the output. How this is done depends on the renderer used (specified
  89. * by $format
  90. *
  91. * The contents of the $data array depends on what the handler() function above
  92. * created
  93. *
  94. * @param string $format output format being rendered
  95. * @param Doku_Renderer $renderer reference to the current renderer object
  96. * @param array $data data created by handler()
  97. * @return boolean return true if rendered correctly
  98. */
  99. public function render($format, Doku_Renderer $renderer, $data) {
  100. if($format == 'xhtml') {
  101. // add prepared note about redirection
  102. $renderer->doc .= $this->redirect_message($data);
  103. // hook into the post render event to allow the page to be redirected
  104. global $EVENT_HANDLER;
  105. /** @var action_plugin_pageredirect $action */
  106. $action = plugin_load('action', 'pageredirect');
  107. $EVENT_HANDLER->register_hook('TPL_ACT_RENDER', 'AFTER', $action, 'handle_dokuwiki_started');
  108. return true;
  109. }
  110. if($format == 'metadata') {
  111. // add redirection to metadata
  112. $renderer->meta['relation']['isreplacedby'] = $data;
  113. if (!$data[1]) {
  114. $page = preg_split("/\?|#/", $data[0])[0];
  115. $renderer->meta['relation']['references'][$page] = page_exists($page);
  116. }
  117. return true;
  118. }
  119. return false;
  120. }
  121. /**
  122. * Create redirection message html
  123. *
  124. * @param string $page
  125. * @return string
  126. */
  127. private function redirect_message($metadata) {
  128. list($page, $is_external) = $metadata;
  129. if(!$is_external) {
  130. $link = html_wikilink($page);
  131. } else {
  132. $link = '<a href="' . hsc($page) . '" class="urlextern">' . hsc($page) . '</a>';
  133. }
  134. // prepare message here instead of in render
  135. $message = '<div class="noteredirect">' . sprintf($this->getLang('redirect_to'), $link) . '</div>';
  136. return $message;
  137. }
  138. }