html.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. <?php
  2. /**
  3. * HTML output functions
  4. *
  5. * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author Andreas Gohr <andi@splitbrain.org>
  7. */
  8. use dokuwiki\Action\Denied;
  9. use dokuwiki\Action\Locked;
  10. use dokuwiki\ChangeLog\PageChangeLog;
  11. use dokuwiki\Extension\AuthPlugin;
  12. use dokuwiki\Extension\Event;
  13. use dokuwiki\Ui\Backlinks;
  14. use dokuwiki\Ui\Editor;
  15. use dokuwiki\Ui\Index;
  16. use dokuwiki\Ui\Login;
  17. use dokuwiki\Ui\PageConflict;
  18. use dokuwiki\Ui\PageDiff;
  19. use dokuwiki\Ui\PageDraft;
  20. use dokuwiki\Ui\PageRevisions;
  21. use dokuwiki\Ui\PageView;
  22. use dokuwiki\Ui\Recent;
  23. use dokuwiki\Ui\UserProfile;
  24. use dokuwiki\Ui\UserRegister;
  25. use dokuwiki\Ui\UserResendPwd;
  26. use dokuwiki\Utf8\Clean;
  27. if (!defined('SEC_EDIT_PATTERN')) {
  28. define('SEC_EDIT_PATTERN', '#<!-- EDIT({.*?}) -->#');
  29. }
  30. /**
  31. * Convenience function to quickly build a wikilink
  32. *
  33. * @author Andreas Gohr <andi@splitbrain.org>
  34. * @param string $id id of the target page
  35. * @param string $name the name of the link, i.e. the text that is displayed
  36. * @param string|array $search search string(s) that shall be highlighted in the target page
  37. * @return string the HTML code of the link
  38. */
  39. function html_wikilink($id, $name = null, $search = '') {
  40. /** @var Doku_Renderer_xhtml $xhtml_renderer */
  41. static $xhtml_renderer = null;
  42. if (is_null($xhtml_renderer)) {
  43. $xhtml_renderer = p_get_renderer('xhtml');
  44. }
  45. return $xhtml_renderer->internallink($id,$name,$search,true,'navigation');
  46. }
  47. /**
  48. * The loginform
  49. *
  50. * @author Andreas Gohr <andi@splitbrain.org>
  51. *
  52. * @param bool $svg Whether to show svg icons in the register and resendpwd links or not
  53. * @deprecated 2020-07-18
  54. */
  55. function html_login($svg = false) {
  56. dbg_deprecated(Login::class .'::show()');
  57. (new dokuwiki\Ui\Login($svg))->show();
  58. }
  59. /**
  60. * Denied page content
  61. *
  62. * @deprecated 2020-07-18 not called anymore, see inc/Action/Denied::tplContent()
  63. */
  64. function html_denied() {
  65. dbg_deprecated(Denied::class .'::showBanner()');
  66. (new dokuwiki\Action\Denied())->showBanner();
  67. }
  68. /**
  69. * inserts section edit buttons if wanted or removes the markers
  70. *
  71. * @author Andreas Gohr <andi@splitbrain.org>
  72. *
  73. * @param string $text
  74. * @param bool $show show section edit buttons?
  75. * @return string
  76. */
  77. function html_secedit($text, $show = true) {
  78. global $INFO;
  79. if ((isset($INFO) && !$INFO['writable']) || !$show || (isset($INFO) && $INFO['rev'])) {
  80. return preg_replace(SEC_EDIT_PATTERN,'',$text);
  81. }
  82. return preg_replace_callback(SEC_EDIT_PATTERN,
  83. 'html_secedit_button', $text);
  84. }
  85. /**
  86. * prepares section edit button data for event triggering
  87. * used as a callback in html_secedit
  88. *
  89. * @author Andreas Gohr <andi@splitbrain.org>
  90. *
  91. * @param array $matches matches with regexp
  92. * @return string
  93. * @triggers HTML_SECEDIT_BUTTON
  94. */
  95. function html_secedit_button($matches){
  96. $json = htmlspecialchars_decode($matches[1], ENT_QUOTES);
  97. $data = json_decode($json, true);
  98. if ($data === null) {
  99. return '';
  100. }
  101. $data['target'] = strtolower($data['target']);
  102. $data['hid'] = strtolower($data['hid'] ?? '');
  103. return Event::createAndTrigger(
  104. 'HTML_SECEDIT_BUTTON',
  105. $data,
  106. 'html_secedit_get_button'
  107. );
  108. }
  109. /**
  110. * prints a section editing button
  111. * used as default action form HTML_SECEDIT_BUTTON
  112. *
  113. * @author Adrian Lang <lang@cosmocode.de>
  114. *
  115. * @param array $data name, section id and target
  116. * @return string html
  117. */
  118. function html_secedit_get_button($data) {
  119. global $ID;
  120. global $INFO;
  121. if (!isset($data['name']) || $data['name'] === '') return '';
  122. $name = $data['name'];
  123. unset($data['name']);
  124. $secid = $data['secid'];
  125. unset($data['secid']);
  126. $params = array_merge(
  127. array('do' => 'edit', 'rev' => $INFO['lastmod'], 'summary' => '['.$name.'] '),
  128. $data
  129. );
  130. $html = '<div class="secedit editbutton_'.$data['target'] .' editbutton_'.$secid .'">';
  131. $html.= html_btn('secedit', $ID, '', $params, 'post', $name);
  132. $html.= '</div>';
  133. return $html;
  134. }
  135. /**
  136. * Just the back to top button (in its own form)
  137. *
  138. * @author Andreas Gohr <andi@splitbrain.org>
  139. *
  140. * @return string html
  141. */
  142. function html_topbtn() {
  143. global $lang;
  144. return '<a class="nolink" href="#dokuwiki__top">'
  145. .'<button class="button" onclick="window.scrollTo(0, 0)" title="'. $lang['btn_top'] .'">'
  146. . $lang['btn_top']
  147. .'</button></a>';
  148. }
  149. /**
  150. * Displays a button (using its own form)
  151. * If tooltip exists, the access key tooltip is replaced.
  152. *
  153. * @author Andreas Gohr <andi@splitbrain.org>
  154. *
  155. * @param string $name
  156. * @param string $id
  157. * @param string $akey access key
  158. * @param string[] $params key-value pairs added as hidden inputs
  159. * @param string $method
  160. * @param string $tooltip
  161. * @param bool|string $label label text, false: lookup btn_$name in localization
  162. * @param string $svg (optional) svg code, inserted into the button
  163. * @return string
  164. */
  165. function html_btn($name, $id, $akey, $params, $method = 'get', $tooltip = '', $label = false, $svg = null) {
  166. global $conf;
  167. global $lang;
  168. if (!$label)
  169. $label = $lang['btn_'.$name];
  170. //filter id (without urlencoding)
  171. $id = idfilter($id,false);
  172. //make nice URLs even for buttons
  173. if ($conf['userewrite'] == 2) {
  174. $script = DOKU_BASE.DOKU_SCRIPT.'/'.$id;
  175. } elseif ($conf['userewrite']) {
  176. $script = DOKU_BASE.$id;
  177. } else {
  178. $script = DOKU_BASE.DOKU_SCRIPT;
  179. $params['id'] = $id;
  180. }
  181. $html = '<form class="button btn_'.$name.'" method="'.$method.'" action="'.$script.'"><div class="no">';
  182. if (is_array($params)) {
  183. foreach ($params as $key => $val) {
  184. $html .= '<input type="hidden" name="'.$key.'" value="'.hsc($val).'" />';
  185. }
  186. }
  187. $tip = empty($tooltip) ? hsc($label) : hsc($tooltip);
  188. $html .= '<button type="submit" ';
  189. if ($akey) {
  190. $tip .= ' ['.strtoupper($akey).']';
  191. $html .= 'accesskey="'.$akey.'" ';
  192. }
  193. $html .= 'title="'.$tip.'">';
  194. if ($svg) {
  195. $html .= '<span>'. hsc($label) .'</span>'. inlineSVG($svg);
  196. } else {
  197. $html .= hsc($label);
  198. }
  199. $html .= '</button>';
  200. $html .= '</div></form>';
  201. return $html;
  202. }
  203. /**
  204. * show a revision warning
  205. *
  206. * @author Szymon Olewniczak <dokuwiki@imz.re>
  207. * @deprecated 2020-07-18
  208. */
  209. function html_showrev() {
  210. dbg_deprecated(PageView::class .'::showrev()');
  211. }
  212. /**
  213. * Show a wiki page
  214. *
  215. * @author Andreas Gohr <andi@splitbrain.org>
  216. *
  217. * @param null|string $txt wiki text or null for showing $ID
  218. * @deprecated 2020-07-18
  219. */
  220. function html_show($txt=null) {
  221. dbg_deprecated(PageView::class .'::show()');
  222. (new dokuwiki\Ui\PageView($txt))->show();
  223. }
  224. /**
  225. * ask the user about how to handle an exisiting draft
  226. *
  227. * @author Andreas Gohr <andi@splitbrain.org>
  228. * @deprecated 2020-07-18
  229. */
  230. function html_draft() {
  231. dbg_deprecated(PageDraft::class .'::show()');
  232. (new dokuwiki\Ui\PageDraft)->show();
  233. }
  234. /**
  235. * Highlights searchqueries in HTML code
  236. *
  237. * @author Andreas Gohr <andi@splitbrain.org>
  238. * @author Harry Fuecks <hfuecks@gmail.com>
  239. *
  240. * @param string $html
  241. * @param array|string $phrases
  242. * @return string html
  243. */
  244. function html_hilight($html, $phrases) {
  245. $phrases = (array) $phrases;
  246. $phrases = array_map('preg_quote_cb', $phrases);
  247. $phrases = array_map('ft_snippet_re_preprocess', $phrases);
  248. $phrases = array_filter($phrases);
  249. $regex = join('|',$phrases);
  250. if ($regex === '') return $html;
  251. if (!Clean::isUtf8($regex)) return $html;
  252. return @preg_replace_callback("/((<[^>]*)|$regex)/ui", function ($match) {
  253. $hlight = unslash($match[0]);
  254. if (!isset($match[2])) {
  255. $hlight = '<span class="search_hit">'.$hlight.'</span>';
  256. }
  257. return $hlight;
  258. }, $html);
  259. }
  260. /**
  261. * Display error on locked pages
  262. *
  263. * @author Andreas Gohr <andi@splitbrain.org>
  264. * @deprecated 2020-07-18 not called anymore, see inc/Action/Locked::tplContent()
  265. */
  266. function html_locked() {
  267. dbg_deprecated(Locked::class .'::showBanner()');
  268. (new dokuwiki\Action\Locked())->showBanner();
  269. }
  270. /**
  271. * list old revisions
  272. *
  273. * @author Andreas Gohr <andi@splitbrain.org>
  274. * @author Ben Coburn <btcoburn@silicodon.net>
  275. * @author Kate Arzamastseva <pshns@ukr.net>
  276. *
  277. * @param int $first skip the first n changelog lines
  278. * @param string $media_id id of media, or empty for current page
  279. * @deprecated 2020-07-18
  280. */
  281. function html_revisions($first = -1, $media_id = '') {
  282. dbg_deprecated(PageRevisions::class .'::show()');
  283. if ($media_id) {
  284. (new dokuwiki\Ui\MediaRevisions($media_id))->show($first);
  285. } else {
  286. global $INFO;
  287. (new dokuwiki\Ui\PageRevisions($INFO['id']))->show($first);
  288. }
  289. }
  290. /**
  291. * display recent changes
  292. *
  293. * @author Andreas Gohr <andi@splitbrain.org>
  294. * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
  295. * @author Ben Coburn <btcoburn@silicodon.net>
  296. * @author Kate Arzamastseva <pshns@ukr.net>
  297. *
  298. * @param int $first
  299. * @param string $show_changes
  300. * @deprecated 2020-07-18
  301. */
  302. function html_recent($first = 0, $show_changes = 'both') {
  303. dbg_deprecated(Recent::class .'::show()');
  304. (new dokuwiki\Ui\Recent($first, $show_changes))->show();
  305. }
  306. /**
  307. * Display page index
  308. *
  309. * @author Andreas Gohr <andi@splitbrain.org>
  310. *
  311. * @param string $ns
  312. * @deprecated 2020-07-18
  313. */
  314. function html_index($ns) {
  315. dbg_deprecated(Index::class .'::show()');
  316. (new dokuwiki\Ui\Index($ns))->show();
  317. }
  318. /**
  319. * Index tree item formatter for html_buildlist()
  320. *
  321. * User function for html_buildlist()
  322. *
  323. * @author Andreas Gohr <andi@splitbrain.org>
  324. *
  325. * @param array $item
  326. * @return string
  327. * @deprecated 2020-07-18
  328. */
  329. function html_list_index($item) {
  330. dbg_deprecated(Index::class .'::formatListItem()');
  331. return (new dokuwiki\Ui\Index)->formatListItem($item);
  332. }
  333. /**
  334. * Index list item formatter for html_buildlist()
  335. *
  336. * This user function is used in html_buildlist to build the
  337. * <li> tags for namespaces when displaying the page index
  338. * it gives different classes to opened or closed "folders"
  339. *
  340. * @author Andreas Gohr <andi@splitbrain.org>
  341. *
  342. * @param array $item
  343. * @return string html
  344. * @deprecated 2020-07-18
  345. */
  346. function html_li_index($item) {
  347. dbg_deprecated(Index::class .'::tagListItem()');
  348. return (new dokuwiki\Ui\Index)->tagListItem($item);
  349. }
  350. /**
  351. * Default list item formatter for html_buildlist()
  352. *
  353. * @author Andreas Gohr <andi@splitbrain.org>
  354. *
  355. * @param array $item
  356. * @return string html
  357. * @deprecated 2020-07-18
  358. */
  359. function html_li_default($item){
  360. return '<li class="level'.$item['level'].'">';
  361. }
  362. /**
  363. * Build an unordered list
  364. *
  365. * Build an unordered list from the given $data array
  366. * Each item in the array has to have a 'level' property
  367. * the item itself gets printed by the given $func user
  368. * function. The second and optional function is used to
  369. * print the <li> tag. Both user function need to accept
  370. * a single item.
  371. *
  372. * Both user functions can be given as array to point to
  373. * a member of an object.
  374. *
  375. * @author Andreas Gohr <andi@splitbrain.org>
  376. *
  377. * @param array $data array with item arrays
  378. * @param string $class class of ul wrapper
  379. * @param callable $func callback to print an list item
  380. * @param callable $lifunc (optional) callback to the opening li tag
  381. * @param bool $forcewrapper (optional) Trigger building a wrapper ul if the first level is
  382. * 0 (we have a root object) or 1 (just the root content)
  383. * @return string html of an unordered list
  384. */
  385. function html_buildlist($data, $class, $func, $lifunc = null, $forcewrapper = false) {
  386. if (count($data) === 0) {
  387. return '';
  388. }
  389. $firstElement = reset($data);
  390. $start_level = $firstElement['level'];
  391. $level = $start_level;
  392. $html = '';
  393. $open = 0;
  394. // set callback function to build the <li> tag, formerly defined as html_li_default()
  395. if (!is_callable($lifunc)) {
  396. $lifunc = function ($item) {
  397. return '<li class="level'.$item['level'].'">';
  398. };
  399. }
  400. foreach ($data as $item) {
  401. if ($item['level'] > $level) {
  402. //open new list
  403. for ($i = 0; $i < ($item['level'] - $level); $i++) {
  404. if ($i) $html .= '<li class="clear">';
  405. $html .= "\n".'<ul class="'.$class.'">'."\n";
  406. $open++;
  407. }
  408. $level = $item['level'];
  409. } elseif ($item['level'] < $level) {
  410. //close last item
  411. $html .= '</li>'."\n";
  412. while ($level > $item['level'] && $open > 0 ) {
  413. //close higher lists
  414. $html .= '</ul>'."\n".'</li>'."\n";
  415. $level--;
  416. $open--;
  417. }
  418. } elseif ($html !== '') {
  419. //close previous item
  420. $html .= '</li>'."\n";
  421. }
  422. //print item
  423. $html .= call_user_func($lifunc, $item);
  424. $html .= '<div class="li">';
  425. $html .= call_user_func($func, $item);
  426. $html .= '</div>';
  427. }
  428. //close remaining items and lists
  429. $html .= '</li>'."\n";
  430. while ($open-- > 0) {
  431. $html .= '</ul></li>'."\n";
  432. }
  433. if ($forcewrapper || $start_level < 2) {
  434. // Trigger building a wrapper ul if the first level is
  435. // 0 (we have a root object) or 1 (just the root content)
  436. $html = "\n".'<ul class="'.$class.'">'."\n".$html.'</ul>'."\n";
  437. }
  438. return $html;
  439. }
  440. /**
  441. * display backlinks
  442. *
  443. * @author Andreas Gohr <andi@splitbrain.org>
  444. * @author Michael Klier <chi@chimeric.de>
  445. * @deprecated 2020-07-18
  446. */
  447. function html_backlinks() {
  448. dbg_deprecated(Backlinks::class .'::show()');
  449. (new dokuwiki\Ui\Backlinks)->show();
  450. }
  451. /**
  452. * Get header of diff HTML
  453. *
  454. * @param string $l_rev Left revisions
  455. * @param string $r_rev Right revision
  456. * @param string $id Page id, if null $ID is used
  457. * @param bool $media If it is for media files
  458. * @param bool $inline Return the header on a single line
  459. * @return string[] HTML snippets for diff header
  460. * @deprecated 2020-07-18
  461. */
  462. function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = false) {
  463. dbg_deprecated('see '. PageDiff::class .'::buildDiffHead()');
  464. return ['', '', '', ''];
  465. }
  466. /**
  467. * Show diff
  468. * between current page version and provided $text
  469. * or between the revisions provided via GET or POST
  470. *
  471. * @author Andreas Gohr <andi@splitbrain.org>
  472. * @param string $text when non-empty: compare with this text with most current version
  473. * @param bool $intro display the intro text
  474. * @param string $type type of the diff (inline or sidebyside)
  475. * @deprecated 2020-07-18
  476. */
  477. function html_diff($text = '', $intro = true, $type = null) {
  478. dbg_deprecated(PageDiff::class .'::show()');
  479. global $INFO;
  480. (new dokuwiki\Ui\PageDiff($INFO['id']))->compareWith($text)->preference([
  481. 'showIntro' => $intro,
  482. 'difftype' => $type,
  483. ])->show();
  484. }
  485. /**
  486. * Create html for revision navigation
  487. *
  488. * @param PageChangeLog $pagelog changelog object of current page
  489. * @param string $type inline vs sidebyside
  490. * @param int $l_rev left revision timestamp
  491. * @param int $r_rev right revision timestamp
  492. * @return string[] html of left and right navigation elements
  493. * @deprecated 2020-07-18
  494. */
  495. function html_diff_navigation($pagelog, $type, $l_rev, $r_rev) {
  496. dbg_deprecated('see '. PageDiff::class .'::buildRevisionsNavigation()');
  497. return ['', ''];
  498. }
  499. /**
  500. * Create html link to a diff defined by two revisions
  501. *
  502. * @param string $difftype display type
  503. * @param string $linktype
  504. * @param int $lrev oldest revision
  505. * @param int $rrev newest revision or null for diff with current revision
  506. * @return string html of link to a diff
  507. * @deprecated 2020-07-18
  508. */
  509. function html_diff_navigationlink($difftype, $linktype, $lrev, $rrev = null) {
  510. dbg_deprecated('see '. PageDiff::class .'::diffViewlink()');
  511. return '';
  512. }
  513. /**
  514. * Insert soft breaks in diff html
  515. *
  516. * @param string $diffhtml
  517. * @return string
  518. * @deprecated 2020-07-18
  519. */
  520. function html_insert_softbreaks($diffhtml) {
  521. dbg_deprecated(PageDiff::class .'::insertSoftbreaks()');
  522. return (new dokuwiki\Ui\PageDiff)->insertSoftbreaks($diffhtml);
  523. }
  524. /**
  525. * show warning on conflict detection
  526. *
  527. * @author Andreas Gohr <andi@splitbrain.org>
  528. *
  529. * @param string $text
  530. * @param string $summary
  531. * @deprecated 2020-07-18
  532. */
  533. function html_conflict($text, $summary) {
  534. dbg_deprecated(PageConflict::class .'::show()');
  535. (new dokuwiki\Ui\PageConflict($text, $summary))->show();
  536. }
  537. /**
  538. * Prints the global message array
  539. *
  540. * @author Andreas Gohr <andi@splitbrain.org>
  541. */
  542. function html_msgarea() {
  543. global $MSG, $MSG_shown;
  544. /** @var array $MSG */
  545. // store if the global $MSG has already been shown and thus HTML output has been started
  546. $MSG_shown = true;
  547. if (!isset($MSG)) return;
  548. $shown = array();
  549. foreach ($MSG as $msg) {
  550. $hash = md5($msg['msg']);
  551. if (isset($shown[$hash])) continue; // skip double messages
  552. if (info_msg_allowed($msg)) {
  553. print '<div class="'.$msg['lvl'].'">';
  554. print $msg['msg'];
  555. print '</div>';
  556. }
  557. $shown[$hash] = 1;
  558. }
  559. unset($GLOBALS['MSG']);
  560. }
  561. /**
  562. * Prints the registration form
  563. *
  564. * @author Andreas Gohr <andi@splitbrain.org>
  565. * @deprecated 2020-07-18
  566. */
  567. function html_register() {
  568. dbg_deprecated(UserRegister::class .'::show()');
  569. (new dokuwiki\Ui\UserRegister)->show();
  570. }
  571. /**
  572. * Print the update profile form
  573. *
  574. * @author Christopher Smith <chris@jalakai.co.uk>
  575. * @author Andreas Gohr <andi@splitbrain.org>
  576. * @deprecated 2020-07-18
  577. */
  578. function html_updateprofile() {
  579. dbg_deprecated(UserProfile::class .'::show()');
  580. (new dokuwiki\Ui\UserProfile)->show();
  581. }
  582. /**
  583. * Preprocess edit form data
  584. *
  585. * @author Andreas Gohr <andi@splitbrain.org>
  586. *
  587. * @deprecated 2020-07-18
  588. */
  589. function html_edit() {
  590. dbg_deprecated(Editor::class .'::show()');
  591. (new dokuwiki\Ui\Editor)->show();
  592. }
  593. /**
  594. * Display the default edit form
  595. *
  596. * Is the default action for HTML_EDIT_FORMSELECTION.
  597. *
  598. * @param array $param
  599. * @deprecated 2020-07-18
  600. */
  601. function html_edit_form($param) {
  602. dbg_deprecated(Editor::class .'::addTextarea()');
  603. (new dokuwiki\Ui\Editor)->addTextarea($param);
  604. }
  605. /**
  606. * prints some debug info
  607. *
  608. * @author Andreas Gohr <andi@splitbrain.org>
  609. */
  610. function html_debug() {
  611. global $conf;
  612. global $lang;
  613. /** @var AuthPlugin $auth */
  614. global $auth;
  615. global $INFO;
  616. //remove sensitive data
  617. $cnf = $conf;
  618. debug_guard($cnf);
  619. $nfo = $INFO;
  620. debug_guard($nfo);
  621. $ses = $_SESSION;
  622. debug_guard($ses);
  623. print '<html><body>';
  624. print '<p>When reporting bugs please send all the following ';
  625. print 'output as a mail to andi@splitbrain.org ';
  626. print 'The best way to do this is to save this page in your browser</p>';
  627. print '<b>$INFO:</b><pre>';
  628. print_r($nfo);
  629. print '</pre>';
  630. print '<b>$_SERVER:</b><pre>';
  631. print_r($_SERVER);
  632. print '</pre>';
  633. print '<b>$conf:</b><pre>';
  634. print_r($cnf);
  635. print '</pre>';
  636. print '<b>DOKU_BASE:</b><pre>';
  637. print DOKU_BASE;
  638. print '</pre>';
  639. print '<b>abs DOKU_BASE:</b><pre>';
  640. print DOKU_URL;
  641. print '</pre>';
  642. print '<b>rel DOKU_BASE:</b><pre>';
  643. print dirname($_SERVER['PHP_SELF']).'/';
  644. print '</pre>';
  645. print '<b>PHP Version:</b><pre>';
  646. print phpversion();
  647. print '</pre>';
  648. print '<b>locale:</b><pre>';
  649. print setlocale(LC_ALL,0);
  650. print '</pre>';
  651. print '<b>encoding:</b><pre>';
  652. print $lang['encoding'];
  653. print '</pre>';
  654. if ($auth) {
  655. print '<b>Auth backend capabilities:</b><pre>';
  656. foreach ($auth->getCapabilities() as $cando) {
  657. print ' '.str_pad($cando,16) .' => '. (int)$auth->canDo($cando) . DOKU_LF;
  658. }
  659. print '</pre>';
  660. }
  661. print '<b>$_SESSION:</b><pre>';
  662. print_r($ses);
  663. print '</pre>';
  664. print '<b>Environment:</b><pre>';
  665. print_r($_ENV);
  666. print '</pre>';
  667. print '<b>PHP settings:</b><pre>';
  668. $inis = ini_get_all();
  669. print_r($inis);
  670. print '</pre>';
  671. if (function_exists('apache_get_version')) {
  672. $apache = array();
  673. $apache['version'] = apache_get_version();
  674. if (function_exists('apache_get_modules')) {
  675. $apache['modules'] = apache_get_modules();
  676. }
  677. print '<b>Apache</b><pre>';
  678. print_r($apache);
  679. print '</pre>';
  680. }
  681. print '</body></html>';
  682. }
  683. /**
  684. * Form to request a new password for an existing account
  685. *
  686. * @author Benoit Chesneau <benoit@bchesneau.info>
  687. * @author Andreas Gohr <gohr@cosmocode.de>
  688. * @deprecated 2020-07-18
  689. */
  690. function html_resendpwd() {
  691. dbg_deprecated(UserResendPwd::class .'::show()');
  692. (new dokuwiki\Ui\UserResendPwd)->show();
  693. }
  694. /**
  695. * Return the TOC rendered to XHTML
  696. *
  697. * @author Andreas Gohr <andi@splitbrain.org>
  698. *
  699. * @param array $toc
  700. * @return string html
  701. */
  702. function html_TOC($toc) {
  703. if (!count($toc)) return '';
  704. global $lang;
  705. $out = '<!-- TOC START -->'.DOKU_LF;
  706. $out .= '<div id="dw__toc" class="dw__toc">'.DOKU_LF;
  707. $out .= '<h3 class="toggle">';
  708. $out .= $lang['toc'];
  709. $out .= '</h3>'.DOKU_LF;
  710. $out .= '<div>'.DOKU_LF;
  711. $out .= html_buildlist($toc, 'toc', 'html_list_toc', null, true);
  712. $out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
  713. $out .= '<!-- TOC END -->'.DOKU_LF;
  714. return $out;
  715. }
  716. /**
  717. * Callback for html_buildlist
  718. *
  719. * @param array $item
  720. * @return string html
  721. */
  722. function html_list_toc($item) {
  723. if (isset($item['hid'])){
  724. $link = '#'.$item['hid'];
  725. } else {
  726. $link = $item['link'];
  727. }
  728. return '<a href="'.$link.'">'.hsc($item['title']).'</a>';
  729. }
  730. /**
  731. * Helper function to build TOC items
  732. *
  733. * Returns an array ready to be added to a TOC array
  734. *
  735. * @param string $link - where to link (if $hash set to '#' it's a local anchor)
  736. * @param string $text - what to display in the TOC
  737. * @param int $level - nesting level
  738. * @param string $hash - is prepended to the given $link, set blank if you want full links
  739. * @return array the toc item
  740. */
  741. function html_mktocitem($link, $text, $level, $hash='#') {
  742. return array(
  743. 'link' => $hash.$link,
  744. 'title' => $text,
  745. 'type' => 'ul',
  746. 'level' => $level
  747. );
  748. }
  749. /**
  750. * Output a Doku_Form object.
  751. * Triggers an event with the form name: HTML_{$name}FORM_OUTPUT
  752. *
  753. * @author Tom N Harris <tnharris@whoopdedo.org>
  754. *
  755. * @param string $name The name of the form
  756. * @param Doku_Form $form The form
  757. * @return void
  758. * @deprecated 2020-07-18
  759. */
  760. function html_form($name, $form) {
  761. dbg_deprecated('use dokuwiki\Form\Form instead of Doku_Form');
  762. // Safety check in case the caller forgets.
  763. $form->endFieldset();
  764. Event::createAndTrigger('HTML_'.strtoupper($name).'FORM_OUTPUT', $form, 'html_form_output', false);
  765. }
  766. /**
  767. * Form print function.
  768. * Just calls printForm() on the form object.
  769. *
  770. * @param Doku_Form $form The form
  771. * @return void
  772. * @deprecated 2020-07-18
  773. */
  774. function html_form_output($form) {
  775. dbg_deprecated('use dokuwiki\Form\Form::toHTML()');
  776. $form->printForm();
  777. }
  778. /**
  779. * Embed a flash object in HTML
  780. *
  781. * This will create the needed HTML to embed a flash movie in a cross browser
  782. * compatble way using valid XHTML
  783. *
  784. * The parameters $params, $flashvars and $atts need to be associative arrays.
  785. * No escaping needs to be done for them. The alternative content *has* to be
  786. * escaped because it is used as is. If no alternative content is given
  787. * $lang['noflash'] is used.
  788. *
  789. * @author Andreas Gohr <andi@splitbrain.org>
  790. * @link http://latrine.dgx.cz/how-to-correctly-insert-a-flash-into-xhtml
  791. *
  792. * @param string $swf - the SWF movie to embed
  793. * @param int $width - width of the flash movie in pixels
  794. * @param int $height - height of the flash movie in pixels
  795. * @param array $params - additional parameters (<param>)
  796. * @param array $flashvars - parameters to be passed in the flashvar parameter
  797. * @param array $atts - additional attributes for the <object> tag
  798. * @param string $alt - alternative content (is NOT automatically escaped!)
  799. * @return string - the XHTML markup
  800. */
  801. function html_flashobject($swf,$width,$height,$params=null,$flashvars=null,$atts=null,$alt=''){
  802. global $lang;
  803. $out = '';
  804. // prepare the object attributes
  805. if(is_null($atts)) $atts = array();
  806. $atts['width'] = (int) $width;
  807. $atts['height'] = (int) $height;
  808. if(!$atts['width']) $atts['width'] = 425;
  809. if(!$atts['height']) $atts['height'] = 350;
  810. // add object attributes for standard compliant browsers
  811. $std = $atts;
  812. $std['type'] = 'application/x-shockwave-flash';
  813. $std['data'] = $swf;
  814. // add object attributes for IE
  815. $ie = $atts;
  816. $ie['classid'] = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
  817. // open object (with conditional comments)
  818. $out .= '<!--[if !IE]> -->'.NL;
  819. $out .= '<object '.buildAttributes($std).'>'.NL;
  820. $out .= '<!-- <![endif]-->'.NL;
  821. $out .= '<!--[if IE]>'.NL;
  822. $out .= '<object '.buildAttributes($ie).'>'.NL;
  823. $out .= ' <param name="movie" value="'.hsc($swf).'" />'.NL;
  824. $out .= '<!--><!-- -->'.NL;
  825. // print params
  826. if(is_array($params)) foreach($params as $key => $val){
  827. $out .= ' <param name="'.hsc($key).'" value="'.hsc($val).'" />'.NL;
  828. }
  829. // add flashvars
  830. if(is_array($flashvars)){
  831. $out .= ' <param name="FlashVars" value="'.buildURLparams($flashvars).'" />'.NL;
  832. }
  833. // alternative content
  834. if($alt){
  835. $out .= $alt.NL;
  836. }else{
  837. $out .= $lang['noflash'].NL;
  838. }
  839. // finish
  840. $out .= '</object>'.NL;
  841. $out .= '<!-- <![endif]-->'.NL;
  842. return $out;
  843. }
  844. /**
  845. * Prints HTML code for the given tab structure
  846. *
  847. * @param array $tabs tab structure
  848. * @param string $current_tab the current tab id
  849. * @return void
  850. */
  851. function html_tabs($tabs, $current_tab = null) {
  852. echo '<ul class="tabs">'.NL;
  853. foreach ($tabs as $id => $tab) {
  854. html_tab($tab['href'], $tab['caption'], $id === $current_tab);
  855. }
  856. echo '</ul>'.NL;
  857. }
  858. /**
  859. * Prints a single tab
  860. *
  861. * @author Kate Arzamastseva <pshns@ukr.net>
  862. * @author Adrian Lang <mail@adrianlang.de>
  863. *
  864. * @param string $href - tab href
  865. * @param string $caption - tab caption
  866. * @param boolean $selected - is tab selected
  867. * @return void
  868. */
  869. function html_tab($href, $caption, $selected = false) {
  870. $tab = '<li>';
  871. if ($selected) {
  872. $tab .= '<strong>';
  873. } else {
  874. $tab .= '<a href="' . hsc($href) . '">';
  875. }
  876. $tab .= hsc($caption)
  877. . '</' . ($selected ? 'strong' : 'a') . '>'
  878. . '</li>'.NL;
  879. echo $tab;
  880. }
  881. /**
  882. * Display size change
  883. *
  884. * @param int $sizechange - size of change in Bytes
  885. * @param Doku_Form $form - (optional) form to add elements to
  886. * @return void|string
  887. */
  888. function html_sizechange($sizechange, $form = null) {
  889. if (isset($sizechange)) {
  890. $class = 'sizechange';
  891. $value = filesize_h(abs($sizechange));
  892. if ($sizechange > 0) {
  893. $class .= ' positive';
  894. $value = '+' . $value;
  895. } elseif ($sizechange < 0) {
  896. $class .= ' negative';
  897. $value = '-' . $value;
  898. } else {
  899. $value = '±' . $value;
  900. }
  901. if (!isset($form)) {
  902. return '<span class="'.$class.'">'.$value.'</span>';
  903. } else { // Doku_Form
  904. $form->addElement(form_makeOpenTag('span', array('class' => $class)));
  905. $form->addElement($value);
  906. $form->addElement(form_makeCloseTag('span'));
  907. }
  908. }
  909. }