Add script 'get-openssl-version.sh'.
This commit is contained in:
		
							
								
								
									
										170
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Admin.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Admin.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,170 @@ | ||||
| <?php | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Extension\AdminPlugin; | ||||
| use dokuwiki\Utf8\Sort; | ||||
|  | ||||
| /** | ||||
|  * Class Admin | ||||
|  * | ||||
|  * Displays the Admin screen | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  * @author Andreas Gohr <andi@splitbrain.org> | ||||
|  * @author Håkan Sandell <hakan.sandell@home.se> | ||||
|  */ | ||||
| class Admin extends Ui { | ||||
|  | ||||
|     protected $forAdmins = array('usermanager', 'acl', 'extension', 'config', 'logviewer', 'styling'); | ||||
|     protected $forManagers = array('revert', 'popularity'); | ||||
|     /** @var array[] */ | ||||
|     protected $menu; | ||||
|  | ||||
|     /** | ||||
|      * Display the UI element | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() { | ||||
|         $this->menu = $this->getPluginList(); | ||||
|         echo '<div class="ui-admin">'; | ||||
|         echo p_locale_xhtml('admin'); | ||||
|  | ||||
|         $this->showMenu('admin'); | ||||
|         $this->showMenu('manager'); | ||||
|         $this->showSecurityCheck(); | ||||
|         $this->showVersion(); | ||||
|         $this->showMenu('other'); | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show the given menu of available plugins | ||||
|      * | ||||
|      * @param string $type admin|manager|other | ||||
|      */ | ||||
|     protected function showMenu($type) { | ||||
|         if (!$this->menu[$type]) return; | ||||
|  | ||||
|         if ($type === 'other') { | ||||
|             echo p_locale_xhtml('adminplugins'); | ||||
|             $class = 'admin_plugins'; | ||||
|         } else { | ||||
|             $class = 'admin_tasks'; | ||||
|         } | ||||
|  | ||||
|         echo "<ul class=\"$class\">"; | ||||
|         foreach ($this->menu[$type] as $item) { | ||||
|             $this->showMenuItem($item); | ||||
|         } | ||||
|         echo '</ul>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display the DokuWiki version | ||||
|      */ | ||||
|     protected function showVersion() { | ||||
|         echo '<div id="admin__version">'; | ||||
|         echo getVersion(); | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * data security check | ||||
|      * | ||||
|      * simple check if the 'savedir' is relative and accessible when appended to DOKU_URL | ||||
|      * | ||||
|      * it verifies either: | ||||
|      *   'savedir' has been moved elsewhere, or | ||||
|      *   has protection to prevent the webserver serving files from it | ||||
|      * | ||||
|      * The actual check is carried out via JavaScript. See behaviour.js | ||||
|      */ | ||||
|     protected function showSecurityCheck() { | ||||
|         global $conf; | ||||
|         if(substr($conf['savedir'], 0, 2) !== './') return; | ||||
|         $img = DOKU_URL . $conf['savedir'] . | ||||
|             '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png'; | ||||
|         echo '<div id="security__check" data-src="' . $img . '"></div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a single Admin menu item | ||||
|      * | ||||
|      * @param array $item | ||||
|      */ | ||||
|     protected function showMenuItem($item) { | ||||
|         global $ID; | ||||
|         if(blank($item['prompt'])) return; | ||||
|         echo '<li><div class="li">'; | ||||
|         echo '<a href="' . wl($ID, 'do=admin&page=' . $item['plugin']) . '">'; | ||||
|         echo '<span class="icon">'; | ||||
|         echo inlineSVG($item['icon']); | ||||
|         echo '</span>'; | ||||
|         echo '<span class="prompt">'; | ||||
|         echo $item['prompt']; | ||||
|         echo '</span>'; | ||||
|         echo '</a>'; | ||||
|         echo '</div></li>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Build  list of admin functions from the plugins that handle them | ||||
|      * | ||||
|      * Checks the current permissions to decide on manager or admin plugins | ||||
|      * | ||||
|      * @return array list of plugins with their properties | ||||
|      */ | ||||
|     protected function getPluginList() { | ||||
|         global $conf; | ||||
|  | ||||
|         $pluginlist = plugin_list('admin'); | ||||
|         $menu = ['admin' => [], 'manager' => [], 'other' => []]; | ||||
|  | ||||
|         foreach($pluginlist as $p) { | ||||
|             /** @var AdminPlugin $obj */ | ||||
|             if(($obj = plugin_load('admin', $p)) === null) continue; | ||||
|  | ||||
|             // check permissions | ||||
|             if (!$obj->isAccessibleByCurrentUser()) continue; | ||||
|  | ||||
|             if (in_array($p, $this->forAdmins, true)) { | ||||
|                 $type = 'admin'; | ||||
|             } elseif (in_array($p, $this->forManagers, true)){ | ||||
|                 $type = 'manager'; | ||||
|             } else { | ||||
|                 $type = 'other'; | ||||
|             } | ||||
|  | ||||
|             $menu[$type][$p] = array( | ||||
|                 'plugin' => $p, | ||||
|                 'prompt' => $obj->getMenuText($conf['lang']), | ||||
|                 'icon' => $obj->getMenuIcon(), | ||||
|                 'sort' => $obj->getMenuSort(), | ||||
|             ); | ||||
|         } | ||||
|  | ||||
|         // sort by name, then sort | ||||
|         uasort($menu['admin'], [$this, 'menuSort']); | ||||
|         uasort($menu['manager'], [$this, 'menuSort']); | ||||
|         uasort($menu['other'], [$this, 'menuSort']); | ||||
|  | ||||
|         return $menu; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Custom sorting for admin menu | ||||
|      * | ||||
|      * We sort alphabetically first, then by sort value | ||||
|      * | ||||
|      * @param array $a | ||||
|      * @param array $b | ||||
|      * @return int | ||||
|      */ | ||||
|     protected function menuSort($a, $b) { | ||||
|         $strcmp = Sort::strcmp($a['prompt'], $b['prompt']); | ||||
|         if($strcmp != 0) return $strcmp; | ||||
|         if($a['sort'] === $b['sort']) return 0; | ||||
|         return ($a['sort'] < $b['sort']) ? -1 : 1; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Backlinks.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Backlinks.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Backlinks Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class Backlinks extends Ui | ||||
| { | ||||
|     /** | ||||
|      * Display backlinks | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * @author   Michael Klier <chi@chimeric.de> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $ID; | ||||
|         global $lang; | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('backlinks'); | ||||
|  | ||||
|         $data = ft_backlinks($ID); | ||||
|  | ||||
|         if (!empty($data)) { | ||||
|             print '<ul class="idx">'; | ||||
|             foreach ($data as $blink) { | ||||
|                 print '<li><div class="li">'; | ||||
|                 print html_wikilink(':'.$blink,useHeading('navigation') ? null : $blink); | ||||
|                 print '</div></li>'; | ||||
|             } | ||||
|             print '</ul>'; | ||||
|         } else { | ||||
|             print '<div class="level1"><p>'. $lang['nothingfound'] .'</p></div>'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										129
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Diff.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Diff.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\ChangeLog\ChangeLog; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Diff Interface | ||||
|  * parent class of PageDiff and MediaDiff | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| abstract class Diff extends Ui | ||||
| { | ||||
|     /* @var string */ | ||||
|     protected $id;   // page id or media id | ||||
|  | ||||
|     /* @var int|false */ | ||||
|     protected $rev1;  // timestamp of older revision | ||||
|     /* @var int|false */ | ||||
|     protected $rev2;  // timestamp of newer revision | ||||
|  | ||||
|     /* @var array */ | ||||
|     protected $preference = []; | ||||
|  | ||||
|     /* @var ChangeLog */ | ||||
|     protected $changelog; // PageChangeLog or MediaChangeLog object | ||||
|  | ||||
|     /** | ||||
|      * Diff Ui constructor | ||||
|      * | ||||
|      * @param string $id  page id or media id | ||||
|      */ | ||||
|     public function __construct($id) | ||||
|     { | ||||
|         $this->id = $id; | ||||
|         $this->setChangeLog(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * set class property changelog | ||||
|      */ | ||||
|     abstract protected function setChangeLog(); | ||||
|  | ||||
|     /** | ||||
|      * Prepare revision info of comparison pair | ||||
|      */ | ||||
|     abstract protected function preProcess(); | ||||
|  | ||||
|     /** | ||||
|      * Set a pair of revisions to be compared | ||||
|      * | ||||
|      * @param int $rev1 older revision | ||||
|      * @param int $rev2 newer revision | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function compare($rev1, $rev2) | ||||
|     { | ||||
|         if ($rev2 < $rev1) [$rev1, $rev2] = [$rev2, $rev1]; | ||||
|         $this->rev1 = (int)$rev1; | ||||
|         $this->rev2 = (int)$this->changelog->traceCurrentRevision($rev2); | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Gets or Sets preference of the Ui\Diff object | ||||
|      * | ||||
|      * @param string|array $prefs  a key name or key-value pair(s) | ||||
|      * @param mixed $value         value used when the first args is string | ||||
|      * @return array|$this | ||||
|      */ | ||||
|     public function preference($prefs = null, $value = null) | ||||
|     { | ||||
|         // set | ||||
|         if (is_string($prefs) && isset($value)) { | ||||
|             $this->preference[$prefs] = $value; | ||||
|             return $this; | ||||
|         } elseif (is_array($prefs)) { | ||||
|             foreach ($prefs as $name => $value) { | ||||
|                 $this->preference[$name] = $value; | ||||
|             } | ||||
|             return $this; | ||||
|         } | ||||
|         // get | ||||
|         return $this->preference; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle requested revision(s) | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function handle() | ||||
|     { | ||||
|         global $INPUT; | ||||
|  | ||||
|         // diff link icon click, eg. &do=diff&rev=# | ||||
|         if ($INPUT->has('rev')) { | ||||
|             $this->rev1 = $INPUT->int('rev'); | ||||
|             $this->rev2 = $this->changelog->currentRevision(); | ||||
|             if ($this->rev2 <= $this->rev1) { | ||||
|                 // fallback to compare previous with current | ||||
|                  unset($this->rev1, $this->rev2); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // submit button with two checked boxes, eg. &do=diff&rev2[0]=#&rev2[1]=# | ||||
|         $revs = $INPUT->arr('rev2', []); | ||||
|         if (count($revs) > 1) { | ||||
|             list($rev1, $rev2) = $revs; | ||||
|             if ($rev2 < $rev1) [$rev1, $rev2] = [$rev2, $rev1]; | ||||
|             $this->rev1 = (int)$rev1; | ||||
|             $this->rev2 = (int)$this->changelog->traceCurrentRevision($rev2); | ||||
|         } | ||||
|  | ||||
|        // no revision was given, compare previous to current | ||||
|         if (!isset($this->rev1, $this->rev2)) { | ||||
|             $rev2 = $this->changelog->currentRevision(); | ||||
|             if ($rev2 > $this->changelog->lastRevision()) { | ||||
|                 $rev1 = $this->changelog->lastRevision(); | ||||
|             } else { | ||||
|                 $revs = $this->changelog->getRevisions(0, 1); | ||||
|                 $rev1 = count($revs) ? $revs[0] : false; | ||||
|             } | ||||
|             $this->rev1 = $rev1; | ||||
|             $this->rev2 = $rev2; | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										212
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Editor.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Editor.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,212 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Draft; | ||||
| use dokuwiki\Extension\Event; | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Page Editor | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class Editor extends Ui | ||||
| { | ||||
|     /** | ||||
|      * Display the Edit Window | ||||
|      * preprocess edit form data | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @triggers EDIT_FORM_ADDTEXTAREA | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $INPUT; | ||||
|         global $ID; | ||||
|         global $REV; | ||||
|         global $DATE; | ||||
|         global $PRE; | ||||
|         global $SUF; | ||||
|         global $INFO; | ||||
|         global $SUM; | ||||
|         global $lang; | ||||
|         global $conf; | ||||
|         global $TEXT; | ||||
|  | ||||
|         global $license; | ||||
|  | ||||
|         if ($INPUT->has('changecheck')) { | ||||
|             $check = $INPUT->str('changecheck'); | ||||
|         } elseif (!$INFO['exists']) { | ||||
|             // $TEXT has been loaded from page template | ||||
|             $check = md5(''); | ||||
|         } else { | ||||
|             $check = md5($TEXT); | ||||
|         } | ||||
|         $mod = (md5($TEXT) !== $check); | ||||
|  | ||||
|         $wr = $INFO['writable'] && !$INFO['locked']; | ||||
|  | ||||
|         // intro locale text (edit, rditrev, or read) | ||||
|         if ($wr) { | ||||
|             $intro = ($REV) ? 'editrev' : 'edit'; | ||||
|         } else { | ||||
|             // check pseudo action 'source' | ||||
|             if (!actionOK('source')) { | ||||
|                 msg('Command disabled: source', -1); | ||||
|                 return; | ||||
|             } | ||||
|             $intro = 'read'; | ||||
|         } | ||||
|  | ||||
|         // create the Editor form | ||||
|         $form = new Form(['id' => 'dw__editform']); | ||||
|         $form->setHiddenField('id', $ID); | ||||
|         $form->setHiddenField('rev', $REV); | ||||
|         $form->setHiddenField('date', $DATE); | ||||
|         $form->setHiddenField('prefix', $PRE .'.'); | ||||
|         $form->setHiddenField('suffix', $SUF); | ||||
|         $form->setHiddenField('changecheck', $check); | ||||
|  | ||||
|         // prepare data for EDIT_FORM_ALTERNATE event | ||||
|         $data = array( | ||||
|             'form' => $form, | ||||
|             'wr'   => $wr, | ||||
|             'media_manager' => true, | ||||
|             'target' => ($INPUT->has('target') && $wr) ? $INPUT->str('target') : 'section', | ||||
|             'intro_locale' => $intro, | ||||
|         ); | ||||
|  | ||||
|         if ($data['target'] !== 'section') { | ||||
|             // Only emit event if page is writable, section edit data is valid and | ||||
|             // edit target is not section. | ||||
|             Event::createAndTrigger('EDIT_FORM_ADDTEXTAREA', $data, [$this,'addTextarea'], true); | ||||
|         } else { | ||||
|             $this->addTextarea($data); | ||||
|         } | ||||
|  | ||||
|         $form->setHiddenField('target', $data['target']); | ||||
|  | ||||
|         if ($INPUT->has('hid')) { | ||||
|             $form->setHiddenField('hid', $INPUT->str('hid')); | ||||
|         } | ||||
|         if ($INPUT->has('codeblockOffset')) { | ||||
|             $form->setHiddenField('codeblockOffset', $INPUT->str('codeblockOffset')); | ||||
|         } | ||||
|  | ||||
|         $form->addTagOpen('div')->id('wiki__editbar')->addClass('editBar'); | ||||
|  | ||||
|         $form->addTagOpen('div')->id('size__ctl'); | ||||
|         $form->addTagClose('div'); | ||||
|  | ||||
|         if ($wr) { | ||||
|             // add edit buttons: save, preview, cancel | ||||
|             $form->addTagOpen('div')->addClass('editButtons'); | ||||
|             $form->addButton('do[save]', $lang['btn_save'])->attr('type', 'submit') | ||||
|                 ->attrs(['accesskey' => 's', 'tabindex' => '4']) | ||||
|                 ->id('edbtn__save'); | ||||
|             $form->addButton('do[preview]', $lang['btn_preview'])->attr('type', 'submit') | ||||
|                 ->attrs(['accesskey' => 'p', 'tabindex' => '5']) | ||||
|                 ->id('edbtn__preview'); | ||||
|             $form->addButton('do[cancel]', $lang['btn_cancel'])->attr('type', 'submit') | ||||
|                 ->attrs(['tabindex' => '6']); | ||||
|             $form->addTagClose('div'); // close div editButtons class | ||||
|  | ||||
|             // add a textbox for edit summary | ||||
|             $form->addTagOpen('div')->addClass('summary'); | ||||
|             $input = $form->addTextInput('summary', $lang['summary']) | ||||
|                 ->attrs(['size' => '50', 'tabindex' => '2']) | ||||
|                 ->id('edit__summary')->addClass('edit') | ||||
|                 ->val($SUM); | ||||
|             $input->getLabel()->attr('class', 'nowrap'); | ||||
|  | ||||
|             // adds a checkbox for minor edits for logged in users | ||||
|             if ($conf['useacl'] && $INPUT->server->str('REMOTE_USER')) { | ||||
|                 $form->addHTML(' '); | ||||
|                 $form->addCheckbox('minor', $lang['minoredit'])->id('edit__minoredit')->addClass('nowrap')->val('1'); | ||||
|             } | ||||
|             $form->addTagClose('div'); // close div summary class | ||||
|         } | ||||
|  | ||||
|         $form->addTagClose('div'); // close div editBar class | ||||
|  | ||||
|         // license note | ||||
|         if ($wr && $conf['license']) { | ||||
|             $attr = array( | ||||
|                 'href'   => $license[$conf['license']]['url'], | ||||
|                 'rel'    => 'license', | ||||
|                 'class'  => 'urlextern', | ||||
|                 'target' => $conf['target']['extern'] ?: '', | ||||
|             ); | ||||
|             $form->addTagOpen('div')->addClass('license'); | ||||
|             $form->addHTML($lang['licenseok'] | ||||
|                 .' <a '.buildAttributes($attr, true).'>'.$license[$conf['license']]['name'].'</a>' | ||||
|             ); | ||||
|             $form->addTagClose('div'); | ||||
|         } | ||||
|  | ||||
|         // start editor html output | ||||
|         if ($wr) { | ||||
|             // sets changed to true when previewed | ||||
|             echo '<script>/*<![CDATA[*/'.'textChanged = '. ($mod ? 'true' : 'false') .'/*!]]>*/</script>'; | ||||
|         } | ||||
|  | ||||
|         // print intro locale text (edit, rditrev, or read.txt) | ||||
|         if (isset($data['intro_locale'])) { | ||||
|             echo p_locale_xhtml($data['intro_locale']); | ||||
|         } | ||||
|  | ||||
|         echo '<div class="editBox" role="application">'; | ||||
|  | ||||
|         echo '<div class="toolbar group">'; | ||||
|         echo '<div id="tool__bar" class="tool__bar">'; | ||||
|         if ($wr && $data['media_manager']) { | ||||
|             echo '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.$INFO['namespace'].'" target="_blank">'; | ||||
|             echo $lang['mediaselect']; | ||||
|             echo '</a>'; | ||||
|         } | ||||
|         echo '</div>'; | ||||
|         echo '</div>'; | ||||
|  | ||||
|         echo '<div id="draft__status" class="draft__status">'; | ||||
|         $draft = new Draft($ID, $INFO['client']); | ||||
|         if ($draft->isDraftAvailable()) { | ||||
|             echo $draft->getDraftMessage(); | ||||
|         } | ||||
|         echo '</div>'; | ||||
|  | ||||
|         echo $form->toHTML('Edit'); | ||||
|  | ||||
|         echo '</div>'; // close div editBox class | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display the default edit form (textarea) | ||||
|      * | ||||
|      * the default action for EDIT_FORM_ADDTEXTAREA | ||||
|      * | ||||
|      * @param array{wr: bool, media_manager: bool, target: string, intro_locale: string, form: Form} $data | ||||
|      */ | ||||
|     public function addTextarea(&$data) | ||||
|     { | ||||
|         global $TEXT; | ||||
|  | ||||
|         if ($data['target'] !== 'section') { | ||||
|             msg('No editor for edit target '. hsc($data['target']) .' found.', -1); | ||||
|         } | ||||
|  | ||||
|         // set textarea attributes | ||||
|         $attr = array('tabindex' => '1'); | ||||
|         if (!$data['wr']) $attr['readonly'] = 'readonly'; | ||||
|         $attr['dir']  = 'auto'; | ||||
|         $attr['cols'] = '80'; | ||||
|         $attr['rows'] = '10'; | ||||
|  | ||||
|         $data['form']->addTextarea('wikitext','')->attrs($attr)->val($TEXT) | ||||
|                 ->id('wiki__text')->addClass('edit'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										131
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Index.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Index Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class Index extends Ui | ||||
| { | ||||
|     protected $ns; | ||||
|  | ||||
|     /** | ||||
|      * Index Ui constructor | ||||
|      * | ||||
|      * @param string $ns  namespace | ||||
|     */ | ||||
|     public function __construct($ns = '') | ||||
|     { | ||||
|         $this->ns = $ns; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Display page index | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         // print intro | ||||
|         print p_locale_xhtml('index'); | ||||
|  | ||||
|         print $this->sitemap(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Build html of sitemap, unordered list of pages under the namespace | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function sitemap() | ||||
|     { | ||||
|         global $conf; | ||||
|         global $ID; | ||||
|  | ||||
|         $ns = cleanID($this->ns); | ||||
|         if (empty($ns)){ | ||||
|             $ns = getNS($ID); | ||||
|             if ($ns === false) $ns = ''; | ||||
|         } | ||||
|         $ns = utf8_encodeFN(str_replace(':', '/', $ns)); | ||||
|         $data = array(); | ||||
|         search($data, $conf['datadir'], 'search_index', array('ns' => $ns)); | ||||
|  | ||||
|         return '<div id="index__tree" class="index__tree">' | ||||
|               . html_buildlist($data, 'idx', [$this,'formatListItem'], [$this,'tagListItem']) | ||||
|               . '</div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Index item formatter | ||||
|      * | ||||
|      * User function for html_buildlist() | ||||
|      * | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @param array $item | ||||
|      * @return string | ||||
|      */ | ||||
|     public function formatListItem($item)    // RENAMED from html_list_index() | ||||
|     { | ||||
|         global $ID, $conf; | ||||
|  | ||||
|         // prevent searchbots needlessly following links | ||||
|         $nofollow = ($ID != $conf['start'] || $conf['sitemap']) ? 'rel="nofollow"' : ''; | ||||
|  | ||||
|         $html = ''; | ||||
|         $base = ':'.$item['id']; | ||||
|         $base = substr($base, strrpos($base,':') +1); | ||||
|         if ($item['type'] == 'd') { | ||||
|             // FS#2766, no need for search bots to follow namespace links in the index | ||||
|             $link = wl($ID, 'idx='. rawurlencode($item['id'])); | ||||
|             $html .= '<a href="'. $link .'" title="'. $item['id'] .'" class="idx_dir"' . $nofollow .'><strong>'; | ||||
|             $html .= $base; | ||||
|             $html .= '</strong></a>'; | ||||
|         } else { | ||||
|             // default is noNSorNS($id), but we want noNS($id) when useheading is off FS#2605 | ||||
|             $html .= html_wikilink(':'.$item['id'], useHeading('navigation') ? null : noNS($item['id'])); | ||||
|         } | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Index List item | ||||
|      * | ||||
|      * This user function is used in html_buildlist to build the | ||||
|      * <li> tags for namespaces when displaying the page index | ||||
|      * it gives different classes to opened or closed "folders" | ||||
|      * | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @param array $item | ||||
|      * @return string html | ||||
|      */ | ||||
|     public function tagListItem($item)    // RENAMED from html_li_index() | ||||
|     { | ||||
|         global $INFO; | ||||
|         global $ACT; | ||||
|  | ||||
|         $class = ''; | ||||
|         $id = ''; | ||||
|  | ||||
|         if ($item['type'] == 'f') { | ||||
|             // scroll to the current item | ||||
|             if (isset($INFO) && $item['id'] == $INFO['id'] && $ACT == 'index') { | ||||
|                 $id = ' id="scroll__here"'; | ||||
|                 $class = ' bounce'; | ||||
|             } | ||||
|             return '<li class="level'.$item['level'].$class.'" '.$id.'>'; | ||||
|         } elseif ($item['open']) { | ||||
|             return '<li class="open">'; | ||||
|         } else { | ||||
|             return '<li class="closed">'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										82
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Login.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Login.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki User Login Interface (Login Form) | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class Login extends Ui | ||||
| { | ||||
|     protected $showIcon = false; | ||||
|  | ||||
|     /**  | ||||
|      * Login Ui constructor | ||||
|      * | ||||
|      * @param bool $showIcon  Whether to show svg icons in the register and resendpwd links or not | ||||
|      */ | ||||
|     public function __construct($showIcon = false) | ||||
|     { | ||||
|         $this->showIcon = (bool)$showIcon; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display the Login Form Panel | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $lang; | ||||
|         global $conf; | ||||
|         global $ID; | ||||
|         global $INPUT; | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('login'); | ||||
|         print '<div class="centeralign">'.NL; | ||||
|  | ||||
|         // create the login form | ||||
|         $form = new Form(['id' => 'dw__login', 'action' => wl($ID)]); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->addFieldsetOpen($lang['btn_login']); | ||||
|         $form->setHiddenField('id', $ID); | ||||
|         $form->setHiddenField('do', 'login'); | ||||
|  | ||||
|         $input = $form->addTextInput('u', $lang['user'])->id('focus__this')->addClass('edit') | ||||
|             ->val((!$INPUT->bool('http_credentials')) ? $INPUT->str('u') : ''); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         $input = $form->addPasswordInput('p', $lang['pass'])->addClass('block edit'); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         if ($conf['rememberme']) { | ||||
|             $form->addCheckbox('r', $lang['remember'])->id('remember__me')->val('1'); | ||||
|         } | ||||
|         $form->addButton('', $lang['btn_login'])->attr('type', 'submit'); | ||||
|         $form->addFieldsetClose(); | ||||
|         $form->addTagClose('div'); | ||||
|  | ||||
|         if(actionOK('register')){ | ||||
|             $registerLink = (new \dokuwiki\Menu\Item\Register())->asHtmlLink('', $this->showIcon); | ||||
|             $form->addHTML('<p>'.$lang['reghere'].': '. $registerLink .'</p>'); | ||||
|         } | ||||
|  | ||||
|         if (actionOK('resendpwd')) { | ||||
|             $resendPwLink = (new \dokuwiki\Menu\Item\Resendpwd())->asHtmlLink('', $this->showIcon); | ||||
|             $form->addHTML('<p>'.$lang['pwdforget'].': '. $resendPwLink .'</p>'); | ||||
|         } | ||||
|  | ||||
|         print $form->toHTML('Login'); | ||||
|  | ||||
|         print '</div>'; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										126
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Media/Display.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Media/Display.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui\Media; | ||||
|  | ||||
| use dokuwiki\File\MediaFile; | ||||
|  | ||||
| class Display | ||||
| { | ||||
|     /** @var MediaFile */ | ||||
|     protected $mediaFile; | ||||
|  | ||||
|     /** @var string should IDs be shown relative to this namespace? Used in search results */ | ||||
|     protected $relativeDisplay = null; | ||||
|  | ||||
|     /** @var bool scroll to this file on display? */ | ||||
|     protected $scrollIntoView = false; | ||||
|  | ||||
|     /** | ||||
|      * Display constructor. | ||||
|      * @param MediaFile $mediaFile | ||||
|      */ | ||||
|     public function __construct(MediaFile $mediaFile) | ||||
|     { | ||||
|         $this->mediaFile = $mediaFile; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the HTML to display a preview image if possible, otherwise show an icon | ||||
|      * | ||||
|      * @param int $w bounding box width to resize pixel based images to | ||||
|      * @param int $h bounding box height to resize pixel based images to | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getPreviewHtml($w, $h) | ||||
|     { | ||||
|         if ($this->mediaFile->isImage()) { | ||||
|             $src = ml($this->mediaFile->getId(), ['w' => $w, 'h' => $h]); | ||||
|         } else { | ||||
|             $src = $this->getIconUrl(); | ||||
|         } | ||||
|  | ||||
|         $attr = [ | ||||
|             'alt' => $this->mediaFile->getDisplayName(), | ||||
|             'loading' => 'lazy', | ||||
|             'width' => $w, | ||||
|             'height' => $h, | ||||
|         ]; | ||||
|  | ||||
|         return '<img src="' . $src . '" ' . buildAttributes($attr) . ' />'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Return the URL to the icon for this file | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getIconUrl() | ||||
|     { | ||||
|         $link = 'lib/images/fileicons/svg/' . $this->mediaFile->getIcoClass() . '.svg'; | ||||
|         if (!file_exists(DOKU_INC . $link)) $link = 'lib/images/fileicons/svg/file.svg'; | ||||
|         return DOKU_BASE . $link; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show IDs relative to this namespace | ||||
|      * | ||||
|      * @param string|null $ns Use null to disable | ||||
|      */ | ||||
|     public function relativeDisplay($ns) | ||||
|     { | ||||
|         $this->relativeDisplay = $ns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Scroll to this file on display? | ||||
|      * | ||||
|      * @param bool $set | ||||
|      */ | ||||
|     public function scrollIntoView($set = true) | ||||
|     { | ||||
|         $this->scrollIntoView = $set; | ||||
|     } | ||||
|  | ||||
|     /** @return string */ | ||||
|     protected function formatDate() | ||||
|     { | ||||
|         return dformat($this->mediaFile->getLastModified()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Output the image dimension if any | ||||
|      * | ||||
|      * @param string $empty what to show when no dimensions are available | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function formatDimensions($empty = ' ') | ||||
|     { | ||||
|         $w = $this->mediaFile->getWidth(); | ||||
|         $h = $this->mediaFile->getHeight(); | ||||
|         if ($w && $h) { | ||||
|             return $w . '×' . $h; | ||||
|         } else { | ||||
|             return $empty; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** @return string */ | ||||
|     protected function formatFileSize() | ||||
|     { | ||||
|         return filesize_h($this->mediaFile->getFileSize()); | ||||
|     } | ||||
|  | ||||
|     /** @return string */ | ||||
|     protected function formatDisplayName() | ||||
|     { | ||||
|         if ($this->relativeDisplay !== null) { | ||||
|             $id = $this->mediaFile->getId(); | ||||
|             if (substr($id, 0, strlen($this->relativeDisplay)) == $this->relativeDisplay) { | ||||
|                 $id = substr($id, strlen($this->relativeDisplay)); | ||||
|             } | ||||
|             return ltrim($id, ':'); | ||||
|         } else { | ||||
|             return $this->mediaFile->getDisplayName(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										93
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Media/DisplayRow.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Media/DisplayRow.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui\Media; | ||||
|  | ||||
| use dokuwiki\Utf8\PhpString; | ||||
|  | ||||
| /** | ||||
|  * Display a MediaFile in the Media Popup | ||||
|  */ | ||||
| class DisplayRow extends DisplayTile | ||||
| { | ||||
|     /** @inheritDoc */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $lang; | ||||
|         // FIXME Zebra classes have been dropped and need to be readded via CSS | ||||
|  | ||||
|         $id = $this->mediaFile->getId(); | ||||
|         $class = 'select mediafile mf_' . $this->mediaFile->getIcoClass(); | ||||
|         $info = trim($this->formatDimensions('') . ' ' . $this->formatDate() . ' ' . $this->formatFileSize()); | ||||
|         $jump = $this->scrollIntoView ? 'id="scroll__here"' : ''; | ||||
|  | ||||
|         echo '<div title="' . $id . '" ' . $jump . '>'; | ||||
|         echo '<a id="h_:' . $id . '" class="' . $class . '">' . | ||||
|             $this->formatDisplayName() . | ||||
|             '</a> '; | ||||
|         echo '<span class="info">(' . $info . ')</span>' . NL; | ||||
|  | ||||
|         // view button | ||||
|         $link = ml($id, '', true); | ||||
|         echo ' <a href="' . $link . '" target="_blank"><img src="' . DOKU_BASE . 'lib/images/magnifier.png" ' . | ||||
|             'alt="' . $lang['mediaview'] . '" title="' . $lang['mediaview'] . '" class="btn" /></a>'; | ||||
|  | ||||
|         // mediamanager button | ||||
|         $link = wl('', array('do' => 'media', 'image' => $id, 'ns' => getNS($id))); | ||||
|         echo ' <a href="' . $link . '" target="_blank"><img src="' . DOKU_BASE . 'lib/images/mediamanager.png" ' . | ||||
|             'alt="' . $lang['btn_media'] . '" title="' . $lang['btn_media'] . '" class="btn" /></a>'; | ||||
|  | ||||
|         // delete button | ||||
|         if ($this->mediaFile->isWritable() && $this->mediaFile->userPermission() >= AUTH_DELETE) { | ||||
|             $link = DOKU_BASE . 'lib/exe/mediamanager.php?delete=' . rawurlencode($id) . | ||||
|                 '&sectok=' . getSecurityToken(); | ||||
|             echo ' <a href="' . $link . '" class="btn_media_delete" title="' . $id . '">' . | ||||
|                 '<img src="' . DOKU_BASE . 'lib/images/trash.png" alt="' . $lang['btn_delete'] . '" ' . | ||||
|                 'title="' . $lang['btn_delete'] . '" class="btn" /></a>'; | ||||
|         } | ||||
|  | ||||
|         echo '<div class="example" id="ex_' . str_replace(':', '_', $id) . '">'; | ||||
|         echo $lang['mediausage'] . ' <code>{{:' . $id . '}}</code>'; | ||||
|         echo '</div>'; | ||||
|         if ($this->mediaFile->isImage()) $this->showDetails(); | ||||
|         echo '<div class="clearer"></div>' . NL; | ||||
|         echo '</div>' . NL; | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show Thumbnail and EXIF data | ||||
|      */ | ||||
|     protected function showDetails() | ||||
|     { | ||||
|         $id = $this->mediaFile->getId(); | ||||
|  | ||||
|         echo '<div class="detail">'; | ||||
|         echo '<div class="thumb">'; | ||||
|         echo '<a id="d_:' . $id . '" class="select">'; | ||||
|         echo $this->getPreviewHtml(120, 120); | ||||
|         echo '</a>'; | ||||
|         echo '</div>'; | ||||
|  | ||||
|         // read EXIF/IPTC data | ||||
|         $t = $this->mediaFile->getMeta()->getField(array('IPTC.Headline', 'xmp.dc:title')); | ||||
|         $d = $this->mediaFile->getMeta()->getField(array( | ||||
|             'IPTC.Caption', | ||||
|             'EXIF.UserComment', | ||||
|             'EXIF.TIFFImageDescription', | ||||
|             'EXIF.TIFFUserComment', | ||||
|         )); | ||||
|         if (PhpString::strlen($d) > 250) $d = PhpString::substr($d, 0, 250) . '...'; | ||||
|         $k = $this->mediaFile->getMeta()->getField(array('IPTC.Keywords', 'IPTC.Category', 'xmp.dc:subject')); | ||||
|  | ||||
|         // print EXIF/IPTC data | ||||
|         if ($t || $d || $k) { | ||||
|             echo '<p>'; | ||||
|             if ($t) echo '<strong>' . hsc($t) . '</strong><br />'; | ||||
|             if ($d) echo hsc($d) . '<br />'; | ||||
|             if ($t) echo '<em>' . hsc($k) . '</em>'; | ||||
|             echo '</p>'; | ||||
|         } | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										54
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Media/DisplayTile.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Media/DisplayTile.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui\Media; | ||||
|  | ||||
| use dokuwiki\File\MediaFile; | ||||
|  | ||||
| /** | ||||
|  * Display a MediaFile in the FullScreen MediaManager | ||||
|  */ | ||||
| class DisplayTile extends Display | ||||
| { | ||||
|     /** @var string URL to open this file in the media manager */ | ||||
|     protected $mmUrl; | ||||
|  | ||||
|     /** @inheritDoc */ | ||||
|     public function __construct(MediaFile $mediaFile) | ||||
|     { | ||||
|         parent::__construct($mediaFile); | ||||
|  | ||||
|         // FIXME we may want to integrate this function here or in another class | ||||
|         $this->mmUrl = media_managerURL([ | ||||
|             'image' => $this->mediaFile->getId(), | ||||
|             'ns' => getNS($this->mediaFile->getId()), | ||||
|             'tab_details' => 'view', | ||||
|         ]); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display the tile | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         $jump = $this->scrollIntoView ? 'id="scroll__here"' : ''; | ||||
|  | ||||
|         echo '<dl title="' . $this->mediaFile->getDisplayName() . '"' . $jump . '>'; | ||||
|         echo '<dt>'; | ||||
|         echo '<a id="l_:' . $this->mediaFile->getId() . '" class="image thumb" href="' . $this->mmUrl . '">'; | ||||
|         echo $this->getPreviewHtml(90, 90); | ||||
|         echo '</a>'; | ||||
|         echo '</dt>'; | ||||
|  | ||||
|         echo '<dd class="name">'; | ||||
|         echo '<a href="' . $this->mmUrl . '" id="h_:' . $this->mediaFile->getId() . '">' . | ||||
|             $this->formatDisplayName() . | ||||
|             '</a>'; | ||||
|         echo '</dd>'; | ||||
|  | ||||
|         echo '<dd class="size">' . $this->formatDimensions() . '</dd>'; | ||||
|         echo '<dd class="date">' . $this->formatDate() . '</dd>'; | ||||
|         echo '<dd class="filesize">' . $this->formatFileSize() . '</dd>'; | ||||
|  | ||||
|         echo '</dl>'; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										328
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/MediaDiff.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/MediaDiff.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,328 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\ChangeLog\MediaChangeLog; | ||||
| use dokuwiki\ChangeLog\RevisionInfo; | ||||
| use dokuwiki\Form\Form; | ||||
| use InvalidArgumentException; | ||||
| use JpegMeta; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki MediaDiff Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class MediaDiff extends Diff | ||||
| { | ||||
|     /* @var MediaChangeLog */ | ||||
|     protected $changelog; | ||||
|  | ||||
|     /* @var RevisionInfo older revision */ | ||||
|     protected $RevInfo1; | ||||
|     /* @var RevisionInfo newer revision */ | ||||
|     protected $RevInfo2; | ||||
|  | ||||
|     /* @var bool */ | ||||
|     protected $is_img; | ||||
|  | ||||
|     /** | ||||
|      * MediaDiff Ui constructor | ||||
|      * | ||||
|      * @param string $id  media id | ||||
|      */ | ||||
|     public function __construct($id) | ||||
|     { | ||||
|         if (!isset($id)) { | ||||
|             throw new InvalidArgumentException('media id should not be empty!'); | ||||
|         } | ||||
|  | ||||
|         // init preference | ||||
|         $this->preference['fromAjax'] = false;  // see dokuwiki\Ajax::callMediadiff() | ||||
|         $this->preference['showIntro'] = false; | ||||
|         $this->preference['difftype'] = 'both'; // diff view type: both, opacity or portions | ||||
|  | ||||
|         parent::__construct($id); | ||||
|     } | ||||
|  | ||||
|     /** @inheritdoc */ | ||||
|     protected function setChangeLog() | ||||
|     { | ||||
|         $this->changelog = new MediaChangeLog($this->id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle requested revision(s) and diff view preferences | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function handle() | ||||
|     { | ||||
|         global $INPUT; | ||||
|  | ||||
|         // retrieve requested rev or rev2 | ||||
|         parent::handle(); | ||||
|  | ||||
|         // requested diff view type | ||||
|         if ($INPUT->has('difftype')) { | ||||
|             $this->preference['difftype'] = $INPUT->str('difftype'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prepare revision info of comparison pair | ||||
|      */ | ||||
|     protected function preProcess() | ||||
|     { | ||||
|         $changelog =& $this->changelog; | ||||
|  | ||||
|         // create revision info object for older and newer sides | ||||
|         // RevInfo1 : older, left side | ||||
|         // RevInfo2 : newer, right side | ||||
|          | ||||
|         $changelogRev1 = $changelog->getRevisionInfo($this->rev1); | ||||
|         $changelogRev2 = $changelog->getRevisionInfo($this->rev2); | ||||
|         $changelogRev1['media'] = $changelogRev2['media'] = true; | ||||
|  | ||||
|         $this->RevInfo1 = new RevisionInfo($changelogRev1); | ||||
|         $this->RevInfo2 = new RevisionInfo($changelogRev2); | ||||
|  | ||||
|         $this->is_img = preg_match('/\.(jpe?g|gif|png)$/', $this->id); | ||||
|  | ||||
|         foreach ([$this->RevInfo1, $this->RevInfo2] as $RevInfo) { | ||||
|             $isCurrent = $changelog->isCurrentRevision($RevInfo->val('date')); | ||||
|             $RevInfo->isCurrent($isCurrent); | ||||
|  | ||||
|             if ($this->is_img) { | ||||
|                 $rev = $isCurrent ? '' : $RevInfo->val('date'); | ||||
|                 $meta = new JpegMeta(mediaFN($this->id, $rev)); | ||||
|                 // get image width and height for the media manager preview panel | ||||
|                 $RevInfo->append([ | ||||
|                     'previewSize' => media_image_preview_size($this->id, $rev, $meta) | ||||
|                 ]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // re-check image, ensure minimum image width for showImageDiff() | ||||
|         $this->is_img = ($this->is_img | ||||
|             && ($this->RevInfo1->val('previewSize')[0] ?? 0) >= 30 | ||||
|             && ($this->RevInfo2->val('previewSize')[0] ?? 0) >= 30 | ||||
|         ); | ||||
|         // adjust requested diff view type | ||||
|         if (!$this->is_img) { | ||||
|             $this->preference['difftype'] = 'both'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Shows difference between two revisions of media | ||||
|      * | ||||
|      * @author Kate Arzamastseva <pshns@ukr.net> | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $conf; | ||||
|  | ||||
|         $ns = getNS($this->id); | ||||
|         $auth = auth_quickaclcheck("$ns:*"); | ||||
|  | ||||
|         if ($auth < AUTH_READ || !$this->id || !$conf['mediarevisions']) return; | ||||
|  | ||||
|         // retrieve form parameters: rev, rev2, difftype | ||||
|         $this->handle(); | ||||
|         // prepare revision info of comparison pair | ||||
|         $this->preProcess(); | ||||
|  | ||||
|         // display intro | ||||
|         if ($this->preference['showIntro']) echo p_locale_xhtml('diff'); | ||||
|  | ||||
|         // print form to choose diff view type | ||||
|         if ($this->is_img && !$this->preference['fromAjax']) { | ||||
|             $this->showDiffViewSelector(); | ||||
|             echo '<div id="mediamanager__diff" >'; | ||||
|         } | ||||
|  | ||||
|         switch ($this->preference['difftype']) { | ||||
|             case 'opacity': | ||||
|             case 'portions': | ||||
|                 $this->showImageDiff(); | ||||
|                 break; | ||||
|             case 'both': | ||||
|             default: | ||||
|                 $this->showFileDiff(); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         if ($this->is_img && !$this->preference['fromAjax']) { | ||||
|             echo '</div>'; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Print form to choose diff view type | ||||
|      * the dropdown is to be added through JavaScript, see lib/scripts/media.js | ||||
|      */ | ||||
|     protected function showDiffViewSelector() | ||||
|     { | ||||
|         // use timestamp for current revision, date may be false when revisions < 2 | ||||
|         [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')]; | ||||
|  | ||||
|         echo '<div class="diffoptions group">'; | ||||
|  | ||||
|         $form = new Form([ | ||||
|             'id' => 'mediamanager__form_diffview', | ||||
|             'action' => media_managerURL([], '&'), | ||||
|             'method' => 'get', | ||||
|             'class' => 'diffView', | ||||
|         ]); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->setHiddenField('sectok', null); | ||||
|         $form->setHiddenField('mediado', 'diff'); | ||||
|         $form->setHiddenField('rev2[0]', $rev1); | ||||
|         $form->setHiddenField('rev2[1]', $rev2); | ||||
|         $form->addTagClose('div'); | ||||
|         echo $form->toHTML(); | ||||
|  | ||||
|         echo '</div>'; // .diffoptions | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prints two images side by side | ||||
|      * and slider | ||||
|      * | ||||
|      * @author Kate Arzamastseva <pshns@ukr.net> | ||||
|      */ | ||||
|     protected function showImageDiff() | ||||
|     { | ||||
|         $rev1 = $this->RevInfo1->isCurrent() ? '' : $this->RevInfo1->val('date'); | ||||
|         $rev2 = $this->RevInfo2->isCurrent() ? '' : $this->RevInfo2->val('date'); | ||||
|  | ||||
|         // diff view type: opacity or portions | ||||
|         $type = $this->preference['difftype']; | ||||
|  | ||||
|         // adjust image width, right side (newer) has priority | ||||
|         $rev1Size = $this->RevInfo1->val('previewSize'); | ||||
|         $rev2Size = $this->RevInfo2->val('previewSize'); | ||||
|         if ($rev1Size != $rev2Size) { | ||||
|             if ($rev2Size[0] > $rev1Size[0]) { | ||||
|                 $rev1Size = $rev2Size; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $rev1Src = ml($this->id, ['rev' => $rev1, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); | ||||
|         $rev2Src = ml($this->id, ['rev' => $rev2, 'h' => $rev1Size[1], 'w' => $rev1Size[0]]); | ||||
|  | ||||
|         // slider | ||||
|         echo '<div class="slider" style="max-width: '.($rev1Size[0]-20).'px;" ></div>'; | ||||
|  | ||||
|         // two images in divs | ||||
|         echo '<div class="imageDiff '.$type.'">'; | ||||
|         echo '<div class="image1" style="max-width: '.$rev1Size[0].'px;">'; | ||||
|         echo '<img src="'.$rev1Src.'" alt="" />'; | ||||
|         echo '</div>'; | ||||
|         echo '<div class="image2" style="max-width: '.$rev1Size[0].'px;">'; | ||||
|         echo '<img src="'.$rev2Src.'" alt="" />'; | ||||
|         echo '</div>'; | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Shows difference between two revisions of media file | ||||
|      * | ||||
|      * @author Kate Arzamastseva <pshns@ukr.net> | ||||
|      */ | ||||
|     protected function showFileDiff() | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         $ns = getNS($this->id); | ||||
|         $auth = auth_quickaclcheck("$ns:*"); | ||||
|  | ||||
|         $rev1 = $this->RevInfo1->isCurrent() ? '' : (int)$this->RevInfo1->val('date'); | ||||
|         $rev2 = $this->RevInfo2->isCurrent() ? '' : (int)$this->RevInfo2->val('date'); | ||||
|  | ||||
|         // revision title | ||||
|         $rev1Title = trim($this->RevInfo1->showRevisionTitle() .' '. $this->RevInfo1->showCurrentIndicator()); | ||||
|         $rev1Summary = ($this->RevInfo1->val('date')) | ||||
|             ? $this->RevInfo1->showEditSummary() .' '. $this->RevInfo1->showEditor() | ||||
|             : ''; | ||||
|         $rev2Title = trim($this->RevInfo2->showRevisionTitle() .' '. $this->RevInfo2->showCurrentIndicator()); | ||||
|         $rev2Summary = ($this->RevInfo2->val('date')) | ||||
|             ? $this->RevInfo2->showEditSummary() .' '. $this->RevInfo2->showEditor() | ||||
|             : ''; | ||||
|  | ||||
|         $rev1Meta = new JpegMeta(mediaFN($this->id, $rev1)); | ||||
|         $rev2Meta = new JpegMeta(mediaFN($this->id, $rev2)); | ||||
|  | ||||
|         // display diff view table | ||||
|         echo '<div class="table">'; | ||||
|         echo '<table>'; | ||||
|         echo '<tr>'; | ||||
|         echo '<th>'. $rev1Title .' '. $rev1Summary .'</th>'; | ||||
|         echo '<th>'. $rev2Title .' '. $rev2Summary .'</th>'; | ||||
|         echo '</tr>'; | ||||
|  | ||||
|         echo '<tr class="image">'; | ||||
|         echo '<td>'; | ||||
|         media_preview($this->id, $auth, $rev1, $rev1Meta); // $auth not used in media_preview()? | ||||
|         echo '</td>'; | ||||
|  | ||||
|         echo '<td>'; | ||||
|         media_preview($this->id, $auth, $rev2, $rev2Meta); | ||||
|         echo '</td>'; | ||||
|         echo '</tr>'; | ||||
|  | ||||
|         echo '<tr class="actions">'; | ||||
|         echo '<td>'; | ||||
|         media_preview_buttons($this->id, $auth, $rev1); // $auth used in media_preview_buttons() | ||||
|         echo '</td>'; | ||||
|  | ||||
|         echo '<td>'; | ||||
|         media_preview_buttons($this->id, $auth, $rev2); | ||||
|         echo '</td>'; | ||||
|         echo '</tr>'; | ||||
|  | ||||
|         $rev1Tags = media_file_tags($rev1Meta); | ||||
|         $rev2Tags = media_file_tags($rev2Meta); | ||||
|         // FIXME rev2Tags-only stuff ignored | ||||
|         foreach ($rev1Tags as $key => $tag) { | ||||
|             if ($tag['value'] != $rev2Tags[$key]['value']) { | ||||
|                 $rev2Tags[$key]['highlighted'] = true; | ||||
|                 $rev1Tags[$key]['highlighted'] = true; | ||||
|             } elseif (!$tag['value'] || !$rev2Tags[$key]['value']) { | ||||
|                 unset($rev2Tags[$key]); | ||||
|                 unset($rev1Tags[$key]); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         echo '<tr>'; | ||||
|         foreach ([$rev1Tags, $rev2Tags] as $tags) { | ||||
|             echo '<td>'; | ||||
|  | ||||
|             echo '<dl class="img_tags">'; | ||||
|             foreach ($tags as $tag) { | ||||
|                 $value = cleanText($tag['value']); | ||||
|                 if (!$value) $value = '-'; | ||||
|                 echo '<dt>'.$lang[$tag['tag'][1]].'</dt>'; | ||||
|                 echo '<dd>'; | ||||
|                 if (!empty($tag['highlighted'])) echo '<strong>'; | ||||
|                 if ($tag['tag'][2] == 'date') { | ||||
|                     echo dformat($value); | ||||
|                 } else { | ||||
|                     echo hsc($value); | ||||
|                 } | ||||
|                 if (!empty($tag['highlighted'])) echo '</strong>'; | ||||
|                 echo '</dd>'; | ||||
|             } | ||||
|             echo '</dl>'; | ||||
|  | ||||
|             echo '</td>'; | ||||
|         } | ||||
|         echo '</tr>'; | ||||
|  | ||||
|         echo '</table>'; | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										121
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/MediaRevisions.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/MediaRevisions.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\ChangeLog\MediaChangeLog; | ||||
| use dokuwiki\ChangeLog\RevisionInfo; | ||||
| use dokuwiki\Form\Form; | ||||
| use InvalidArgumentException; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki MediaRevisions Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class MediaRevisions extends Revisions | ||||
| { | ||||
|     /* @var MediaChangeLog */ | ||||
|     protected $changelog; | ||||
|  | ||||
|     /** | ||||
|      * MediaRevisions Ui constructor | ||||
|      * | ||||
|      * @param string $id  id of media | ||||
|      */ | ||||
|     public function __construct($id) | ||||
|     { | ||||
|         if (!$id) { | ||||
|             throw new InvalidArgumentException('media id should not be empty!'); | ||||
|         } | ||||
|         parent::__construct($id); | ||||
|     } | ||||
|  | ||||
|     /** @inheritdoc */ | ||||
|     protected function setChangeLog() | ||||
|     { | ||||
|         $this->changelog = new MediaChangeLog($this->id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display a list of Media Revisions in the MediaManager | ||||
|      * | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * @author Ben Coburn <btcoburn@silicodon.net> | ||||
|      * @author Kate Arzamastseva <pshns@ukr.net> | ||||
|      * @author Satoshi Sahara <sahara.satoshi@gmail.com> | ||||
|      * | ||||
|      * @param int $first  skip the first n changelog lines | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show($first = -1) | ||||
|     { | ||||
|         global $lang; | ||||
|         $changelog =& $this->changelog; | ||||
|  | ||||
|         // get revisions, and set correct pagination parameters (first, hasNext) | ||||
|         if ($first === null) $first = -1; | ||||
|         $hasNext = false; | ||||
|         $revisions = $this->getRevisions($first, $hasNext); | ||||
|  | ||||
|         // create the form | ||||
|         $form = new Form([ | ||||
|                 'id' => 'page__revisions', // must not be "media__revisions" | ||||
|                 'action' => media_managerURL(['image' => $this->id], '&'), | ||||
|                 'class'  => 'changes', | ||||
|         ]); | ||||
|         $form->setHiddenField('mediado', 'diff'); // required for media revisions | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|  | ||||
|         // start listing | ||||
|         $form->addTagOpen('ul'); | ||||
|         foreach ($revisions as $info) { | ||||
|             $rev = $info['date']; | ||||
|             $info['media'] = true; | ||||
|             $RevInfo = new RevisionInfo($info); | ||||
|             $RevInfo->isCurrent($changelog->isCurrentRevision($rev)); | ||||
|  | ||||
|             $class = ($RevInfo->val('type') === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : ''; | ||||
|             $form->addTagOpen('li')->addClass($class); | ||||
|             $form->addTagOpen('div')->addClass('li'); | ||||
|  | ||||
|             if ($RevInfo->isCurrent()) { | ||||
|                 $form->addCheckbox('rev2[]')->val($rev); | ||||
|             } elseif (file_exists(mediaFN($this->id, $rev))) { | ||||
|                 $form->addCheckbox('rev2[]')->val($rev); | ||||
|             } else { | ||||
|                 $form->addCheckbox('')->val($rev)->attr('disabled','disabled'); | ||||
|             } | ||||
|             $form->addHTML(' '); | ||||
|  | ||||
|             $html = implode(' ', [ | ||||
|                 $RevInfo->showEditDate(),          // edit date and time | ||||
|                 $RevInfo->showIconCompareWithCurrent(),  // link to diff view icon | ||||
|                 $RevInfo->showFileName(),          // name of page or media | ||||
|                 '<div>', | ||||
|                 $RevInfo->showEditSummary(),       // edit summary | ||||
|                 $RevInfo->showEditor(),            // editor info | ||||
|                 $RevInfo->showSizechange(),        // size change indicator | ||||
|                 $RevInfo->showCurrentIndicator(),  // current indicator (only when k=1) | ||||
|                 '</div>', | ||||
|             ]); | ||||
|             $form->addHTML($html); | ||||
|  | ||||
|             $form->addTagClose('div'); | ||||
|             $form->addTagClose('li'); | ||||
|         } | ||||
|         $form->addTagClose('ul');  // end of revision list | ||||
|  | ||||
|         // show button for diff view | ||||
|         $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit'); | ||||
|  | ||||
|         $form->addTagClose('div'); // close div class=no | ||||
|  | ||||
|         print $form->toHTML('Revisions'); | ||||
|  | ||||
|         // provide navigation for paginated revision list (of pages and/or media files) | ||||
|         print $this->navigation($first, $hasNext, function ($n) { | ||||
|             return media_managerURL(['first' => $n], '&', false, true); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										63
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageConflict.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageConflict.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Page Conflict Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class PageConflict extends Ui | ||||
| { | ||||
|     protected $text; | ||||
|     protected $summary; | ||||
|  | ||||
|     /**  | ||||
|      * PageConflict Ui constructor | ||||
|      * | ||||
|      * @param string $text     wiki text | ||||
|      * @param string $summary  edit summary | ||||
|     */ | ||||
|     public function __construct($text = '', $summary = '') | ||||
|     { | ||||
|         $this->text    = $text; | ||||
|         $this->summary = $summary; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show conflict form to ask whether save anyway or cancel the page edits | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $INFO; | ||||
|         global $lang; | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('conflict'); | ||||
|  | ||||
|         // create the form | ||||
|         $form = new Form(['id' => 'dw__editform']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->setHiddenField('id', $INFO['id']); | ||||
|         $form->setHiddenField('wikitext', $this->text); | ||||
|         $form->setHiddenField('summary', $this->summary); | ||||
|  | ||||
|         $form->addButton('do[save]', $lang['btn_save'] )->attrs(['type' => 'submit', 'accesskey' => 's']); | ||||
|         $form->addButton('do[cancel]', $lang['btn_cancel'] )->attrs(['type' => 'submit']); | ||||
|         $form->addTagClose('div'); | ||||
|  | ||||
|         print $form->toHTML('Conflict'); | ||||
|  | ||||
|         print '<br /><br /><br /><br />'; | ||||
|  | ||||
|         // print difference | ||||
|         (new PageDiff($INFO['id']))->compareWith($this->text)->preference('showIntro', false)->show(); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										551
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageDiff.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										551
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageDiff.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,551 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\ChangeLog\PageChangeLog; | ||||
| use dokuwiki\ChangeLog\RevisionInfo; | ||||
| use dokuwiki\Form\Form; | ||||
| use InlineDiffFormatter; | ||||
| use TableDiffFormatter; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki PageDiff Interface | ||||
|  * | ||||
|  * @author Andreas Gohr <andi@splitbrain.org> | ||||
|  * @author Satoshi Sahara <sahara.satoshi@gmail.com> | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class PageDiff extends Diff | ||||
| { | ||||
|     /* @var PageChangeLog */ | ||||
|     protected $changelog; | ||||
|  | ||||
|     /* @var RevisionInfo older revision */ | ||||
|     protected $RevInfo1; | ||||
|     /* @var RevisionInfo newer revision */ | ||||
|     protected $RevInfo2; | ||||
|  | ||||
|     /* @var string */ | ||||
|     protected $text; | ||||
|  | ||||
|     /** | ||||
|      * PageDiff Ui constructor | ||||
|      * | ||||
|      * @param string $id  page id | ||||
|      */ | ||||
|     public function __construct($id = null) | ||||
|     { | ||||
|         global $INFO; | ||||
|         if (!isset($id)) $id = $INFO['id']; | ||||
|  | ||||
|         // init preference | ||||
|         $this->preference['showIntro'] = true; | ||||
|         $this->preference['difftype'] = 'sidebyside'; // diff view type: inline or sidebyside | ||||
|  | ||||
|         parent::__construct($id); | ||||
|     } | ||||
|  | ||||
|     /** @inheritdoc */ | ||||
|     protected function setChangeLog() | ||||
|     { | ||||
|         $this->changelog = new PageChangeLog($this->id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set text to be compared with most current version | ||||
|      * when it has been externally edited | ||||
|      * exclusively use of the compare($old, $new) method | ||||
|      * | ||||
|      * @param string $text | ||||
|      * @return $this | ||||
|      */ | ||||
|     public function compareWith($text = null) | ||||
|     { | ||||
|         if (isset($text)) { | ||||
|             $this->text = $text; | ||||
|             $changelog =& $this->changelog; | ||||
|  | ||||
|             // revision info object of older file (left side) | ||||
|             $this->RevInfo1 = new RevisionInfo($changelog->getCurrentRevisionInfo()); | ||||
|             $this->RevInfo1->append([ | ||||
|                 'current' => true, | ||||
|                 'text' => rawWiki($this->id), | ||||
|             ]); | ||||
|  | ||||
|             // revision info object of newer file (right side) | ||||
|             $this->RevInfo2 = new RevisionInfo(); | ||||
|             $this->RevInfo2->append([ | ||||
|                 'date' => false, | ||||
|               //'ip'   => '127.0.0.1', | ||||
|               //'type' => DOKU_CHANGE_TYPE_CREATE, | ||||
|                 'id'   => $this->id, | ||||
|               //'user' => '', | ||||
|               //'sum'  => '', | ||||
|                 'extra' => 'compareWith', | ||||
|               //'sizechange' => strlen($this->text) - io_getSizeFile(wikiFN($this->id)), | ||||
|                 'current' => false, | ||||
|                 'text' => cleanText($this->text), | ||||
|             ]); | ||||
|         } | ||||
|         return $this; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Handle requested revision(s) and diff view preferences | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function handle() | ||||
|     { | ||||
|         global $INPUT; | ||||
|  | ||||
|         // retrieve requested rev or rev2 | ||||
|         if (!isset($this->RevInfo1, $this->RevInfo2)) { | ||||
|             parent::handle(); | ||||
|         } | ||||
|  | ||||
|         // requested diff view type | ||||
|         $mode = ''; | ||||
|         if ($INPUT->has('difftype')) { | ||||
|             $mode = $INPUT->str('difftype'); | ||||
|         } else { | ||||
|             // read preference from DokuWiki cookie. PageDiff only | ||||
|             $mode = get_doku_pref('difftype', null); | ||||
|         } | ||||
|         if(in_array($mode, ['inline','sidebyside'])) $this->preference['difftype'] = $mode; | ||||
|  | ||||
|         if (!$INPUT->has('rev') && !$INPUT->has('rev2')) { | ||||
|             global $INFO, $REV; | ||||
|             if ($this->id == $INFO['id']) | ||||
|                 $REV = $this->rev1; // store revision back in $REV | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Prepare revision info of comparison pair | ||||
|      */ | ||||
|     protected function preProcess() | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         $changelog =& $this->changelog; | ||||
|  | ||||
|         // create revision info object for older and newer sides | ||||
|         // RevInfo1 : older, left side | ||||
|         // RevInfo2 : newer, right side | ||||
|          | ||||
|         $changelogRev1 = $changelog->getRevisionInfo($this->rev1); | ||||
|         $changelogRev2 = $changelog->getRevisionInfo($this->rev2); | ||||
|         $changelogRev1['media'] = $changelogRev2['media'] = false; | ||||
|  | ||||
|         $this->RevInfo1 = new RevisionInfo($changelogRev1); | ||||
|         $this->RevInfo2 = new RevisionInfo($changelogRev2); | ||||
|          | ||||
|         foreach ([$this->RevInfo1, $this->RevInfo2] as $RevInfo) { | ||||
|             $isCurrent = $changelog->isCurrentRevision($RevInfo->val('date')); | ||||
|             $RevInfo->isCurrent($isCurrent); | ||||
|  | ||||
|             if ($RevInfo->val('type') == DOKU_CHANGE_TYPE_DELETE || empty($RevInfo->val('type'))) { | ||||
|                 $text = ''; | ||||
|             } else { | ||||
|                 $rev = $isCurrent ? '' : $RevInfo->val('date'); | ||||
|                 $text = rawWiki($this->id, $rev); | ||||
|             } | ||||
|             $RevInfo->append(['text' => $text]); | ||||
|         } | ||||
|  | ||||
|         // msg could displayed only when wrong url typed in browser address bar | ||||
|         if ($this->rev2 === false) { | ||||
|             msg(sprintf($lang['page_nonexist_rev'], | ||||
|                 $this->id, | ||||
|                 wl($this->id, ['do'=>'edit']), | ||||
|                 $this->id), -1); | ||||
|         } elseif (!$this->rev1 || $this->rev1 == $this->rev2) { | ||||
|             msg('no way to compare when less than two revisions', -1); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show diff | ||||
|      * between current page version and provided $text | ||||
|      * or between the revisions provided via GET or POST | ||||
|      * | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         if (!isset($this->RevInfo1, $this->RevInfo2)) { | ||||
|             // retrieve form parameters: rev, rev2, difftype | ||||
|             $this->handle(); | ||||
|             // prepare revision info of comparison pair, except PageConfrict or PageDraft | ||||
|             $this->preProcess(); | ||||
|         } | ||||
|  | ||||
|         // revision title | ||||
|         $rev1Title = trim($this->RevInfo1->showRevisionTitle() .' '. $this->RevInfo1->showCurrentIndicator()); | ||||
|         $rev1Summary = ($this->RevInfo1->val('date')) | ||||
|             ? $this->RevInfo1->showEditSummary() .' '. $this->RevInfo1->showEditor() | ||||
|             : ''; | ||||
|  | ||||
|         if ($this->RevInfo2->val('extra') == 'compareWith') { | ||||
|             $rev2Title = $lang['yours']; | ||||
|             $rev2Summary = ''; | ||||
|         } else { | ||||
|             $rev2Title = trim($this->RevInfo2->showRevisionTitle() .' '. $this->RevInfo2->showCurrentIndicator()); | ||||
|             $rev2Summary = ($this->RevInfo2->val('date')) | ||||
|                 ? $this->RevInfo2->showEditSummary() .' '. $this->RevInfo2->showEditor() | ||||
|                 : ''; | ||||
|         } | ||||
|  | ||||
|         // create difference engine object | ||||
|         $Difference = new \Diff( | ||||
|                 explode("\n", $this->RevInfo1->val('text')), | ||||
|                 explode("\n", $this->RevInfo2->val('text')) | ||||
|         ); | ||||
|  | ||||
|         // build paired navigation | ||||
|         [$rev1Navi, $rev2Navi] = $this->buildRevisionsNavigation(); | ||||
|  | ||||
|         // display intro | ||||
|         if ($this->preference['showIntro']) echo p_locale_xhtml('diff'); | ||||
|  | ||||
|         // print form to choose diff view type, and exact url reference to the view | ||||
|         $this->showDiffViewSelector(); | ||||
|  | ||||
|         // assign minor edit checker to the variable | ||||
|         $classEditType = function ($changeType) { | ||||
|             return ($changeType === DOKU_CHANGE_TYPE_MINOR_EDIT) ? ' class="minor"' : ''; | ||||
|         }; | ||||
|  | ||||
|         // display diff view table | ||||
|         echo '<div class="table">'; | ||||
|         echo '<table class="diff diff_'.hsc($this->preference['difftype']) .'">'; | ||||
|  | ||||
|         //navigation and header | ||||
|         switch ($this->preference['difftype']) { | ||||
|             case 'inline': | ||||
|                 $title1 = $rev1Title . ($rev1Summary ? '<br />'.$rev1Summary : ''); | ||||
|                 $title2 = $rev2Title . ($rev2Summary ? '<br />'.$rev2Summary : ''); | ||||
|                 // no navigation for PageConflict or PageDraft | ||||
|                 if ($this->RevInfo2->val('extra') !== 'compareWith') { | ||||
|                     echo '<tr>' | ||||
|                         .'<td class="diff-lineheader">-</td>' | ||||
|                         .'<td class="diffnav">'. $rev1Navi .'</td>' | ||||
|                         .'</tr>'; | ||||
|                     echo '<tr>' | ||||
|                         .'<th class="diff-lineheader">-</th>' | ||||
|                         .'<th'.$classEditType($this->RevInfo1->val('type')).'>'. $title1 .'</th>' | ||||
|                         .'</tr>'; | ||||
|                 } | ||||
|                 echo '<tr>' | ||||
|                     .'<td class="diff-lineheader">+</td>' | ||||
|                     .'<td class="diffnav">'. $rev2Navi .'</td>' | ||||
|                     .'</tr>'; | ||||
|                 echo '<tr>' | ||||
|                     .'<th class="diff-lineheader">+</th>' | ||||
|                     .'<th'.$classEditType($this->RevInfo2->val('type')).'>'. $title2 .'</th>' | ||||
|                     .'</tr>'; | ||||
|                 // create formatter object | ||||
|                 $DiffFormatter = new InlineDiffFormatter(); | ||||
|                 break; | ||||
|  | ||||
|             case 'sidebyside': | ||||
|             default: | ||||
|                 $title1 = $rev1Title . ($rev1Summary ? ' '.$rev1Summary : ''); | ||||
|                 $title2 = $rev2Title . ($rev2Summary ? ' '.$rev2Summary : ''); | ||||
|                 // no navigation for PageConflict or PageDraft | ||||
|                 if ($this->RevInfo2->val('extra') !== 'compareWith') { | ||||
|                     echo '<tr>' | ||||
|                         .'<td colspan="2" class="diffnav">'. $rev1Navi .'</td>' | ||||
|                         .'<td colspan="2" class="diffnav">'. $rev2Navi .'</td>' | ||||
|                         .'</tr>'; | ||||
|                 } | ||||
|                 echo '<tr>' | ||||
|                     .'<th colspan="2"'.$classEditType($this->RevInfo1->val('type')).'>'.$title1.'</th>' | ||||
|                     .'<th colspan="2"'.$classEditType($this->RevInfo2->val('type')).'>'.$title2.'</th>' | ||||
|                     .'</tr>'; | ||||
|                 // create formatter object | ||||
|                 $DiffFormatter = new TableDiffFormatter(); | ||||
|                 break; | ||||
|         } | ||||
|  | ||||
|         // output formatted difference | ||||
|         echo $this->insertSoftbreaks($DiffFormatter->format($Difference)); | ||||
|  | ||||
|         echo '</table>'; | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Print form to choose diff view type, and exact url reference to the view | ||||
|      */ | ||||
|     protected function showDiffViewSelector() | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         // no revisions selector for PageConflict or PageDraft | ||||
|         if ($this->RevInfo2->val('extra') == 'compareWith') return; | ||||
|  | ||||
|         // use timestamp for current revision, date may be false when revisions < 2 | ||||
|         [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')]; | ||||
|  | ||||
|         echo '<div class="diffoptions group">'; | ||||
|  | ||||
|         // create the form to select difftype | ||||
|         $form = new Form(['action' => wl()]); | ||||
|         $form->setHiddenField('id', $this->id); | ||||
|         $form->setHiddenField('rev2[0]', $rev1); | ||||
|         $form->setHiddenField('rev2[1]', $rev2); | ||||
|         $form->setHiddenField('do', 'diff'); | ||||
|         $options = array( | ||||
|                      'sidebyside' => $lang['diff_side'], | ||||
|                      'inline' => $lang['diff_inline'], | ||||
|         ); | ||||
|         $input = $form->addDropdown('difftype', $options, $lang['diff_type']) | ||||
|             ->val($this->preference['difftype']) | ||||
|             ->addClass('quickselect'); | ||||
|         $input->useInput(false); // inhibit prefillInput() during toHTML() process | ||||
|         $form->addButton('do[diff]', 'Go')->attr('type','submit'); | ||||
|         echo $form->toHTML(); | ||||
|  | ||||
|         // show exact url reference to the view when it is meaningful | ||||
|         echo '<p>'; | ||||
|         if ($rev1 && $rev2) { | ||||
|             // link to exactly this view FS#2835 | ||||
|             $viewUrl = $this->diffViewlink('difflink', $rev1, $rev2); | ||||
|         } | ||||
|         echo $viewUrl ?? '<br />'; | ||||
|         echo '</p>'; | ||||
|  | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create html for revision navigation | ||||
|      * | ||||
|      * The navigation consists of older and newer revisions selectors, each | ||||
|      * state mutually depends on the selected revision of opposite side. | ||||
|      * | ||||
|      * @return string[] html of navigation for both older and newer sides | ||||
|      */ | ||||
|     protected function buildRevisionsNavigation() | ||||
|     { | ||||
|         $changelog =& $this->changelog; | ||||
|  | ||||
|         if ($this->RevInfo2->val('extra') == 'compareWith') { | ||||
|             // no revisions selector for PageConflict or PageDraft | ||||
|             return array('', ''); | ||||
|         } | ||||
|  | ||||
|         // use timestamp for current revision, date may be false when revisions < 2 | ||||
|         [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')]; | ||||
|  | ||||
|         // retrieve revisions used in dropdown selectors, even when rev1 or rev2 is false | ||||
|         [$revs1, $revs2] = $changelog->getRevisionsAround( | ||||
|             ($rev1 ?: $changelog->currentRevision()), | ||||
|             ($rev2 ?: $changelog->currentRevision()) | ||||
|         ); | ||||
|  | ||||
|         // build options for dropdown selector | ||||
|         $rev1Options = $this->buildRevisionOptions('older', $revs1); | ||||
|         $rev2Options = $this->buildRevisionOptions('newer', $revs2); | ||||
|  | ||||
|         // determine previous/next revisions (older/left side) | ||||
|         $rev1Prev = $rev1Next = false; | ||||
|         if (($index = array_search($rev1, $revs1)) !== false) { | ||||
|             $rev1Prev = ($index +1 < count($revs1)) ? $revs1[$index +1] : false; | ||||
|             $rev1Next = ($index > 0)                ? $revs1[$index -1] : false; | ||||
|         } | ||||
|         // determine previous/next revisions (newer/right side) | ||||
|         $rev2Prev = $rev2Next = false; | ||||
|         if (($index = array_search($rev2, $revs2)) !== false) { | ||||
|             $rev2Prev = ($index +1 < count($revs2)) ? $revs2[$index +1] : false; | ||||
|             $rev2Next = ($index > 0)                ? $revs2[$index -1] : false; | ||||
|         } | ||||
|  | ||||
|         /* | ||||
|          * navigation UI for older revisions / Left side: | ||||
|          */ | ||||
|         $rev1Navi = ''; | ||||
|         // move backward both side: ◀◀ | ||||
|         if ($rev1Prev && $rev2Prev) | ||||
|             $rev1Navi .= $this->diffViewlink('diffbothprevrev', $rev1Prev, $rev2Prev); | ||||
|         // move backward left side: ◀ | ||||
|         if ($rev1Prev) | ||||
|             $rev1Navi .= $this->diffViewlink('diffprevrev', $rev1Prev, $rev2); | ||||
|         // dropdown | ||||
|         $rev1Navi .= $this->buildDropdownSelector('older', $rev1Options); | ||||
|         // move forward left side: ▶ | ||||
|         if ($rev1Next && ($rev1Next < $rev2)) | ||||
|             $rev1Navi .= $this->diffViewlink('diffnextrev', $rev1Next, $rev2); | ||||
|  | ||||
|         /* | ||||
|          * navigation UI for newer revisions / Right side: | ||||
|          */ | ||||
|         $rev2Navi = ''; | ||||
|         // move backward right side: ◀ | ||||
|         if ($rev2Prev && ($rev1 < $rev2Prev)) | ||||
|             $rev2Navi .= $this->diffViewlink('diffprevrev', $rev1, $rev2Prev); | ||||
|         // dropdown | ||||
|         $rev2Navi .= $this->buildDropdownSelector('newer', $rev2Options); | ||||
|         // move forward right side: ▶ | ||||
|         if ($rev2Next) { | ||||
|             if ($changelog->isCurrentRevision($rev2Next)) { | ||||
|                 $rev2Navi .= $this->diffViewlink('difflastrev', $rev1, $rev2Next); | ||||
|             } else { | ||||
|                 $rev2Navi .= $this->diffViewlink('diffnextrev', $rev1, $rev2Next); | ||||
|             } | ||||
|         } | ||||
|         // move forward both side: ▶▶ | ||||
|         if ($rev1Next && $rev2Next) | ||||
|             $rev2Navi .= $this->diffViewlink('diffbothnextrev', $rev1Next, $rev2Next); | ||||
|  | ||||
|         return array($rev1Navi, $rev2Navi); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * prepare options for dropdwon selector | ||||
|      * | ||||
|      * @params string $side  "older" or "newer" | ||||
|      * @params array $revs  list of revsion | ||||
|      * @return array | ||||
|      */ | ||||
|     protected function buildRevisionOptions($side, $revs) | ||||
|     { | ||||
|         // use timestamp for current revision, date may be false when revisions < 2 | ||||
|         [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')]; | ||||
|  | ||||
|         $changelog =& $this->changelog; | ||||
|         $options = []; | ||||
|  | ||||
|         foreach ($revs as $rev) { | ||||
|             $info = $changelog->getRevisionInfo($rev); | ||||
|             // revision info may have timestamp key when external edits occurred | ||||
|             $info['timestamp'] = $info['timestamp'] ?? true; | ||||
|             $date = dformat($info['date']); | ||||
|             if ($info['timestamp'] === false) { | ||||
|                 // exteranlly deleted or older file restored | ||||
|                 $date = preg_replace('/[0-9a-zA-Z]/','_', $date); | ||||
|             } | ||||
|             $options[$rev] = array( | ||||
|                 'label' => implode(' ', [ | ||||
|                             $date, | ||||
|                             editorinfo($info['user'], true), | ||||
|                             $info['sum'], | ||||
|                            ]), | ||||
|                 'attrs' => ['title' => $rev], | ||||
|             ); | ||||
|             if (($side == 'older' && ($rev2 && $rev >= $rev2)) | ||||
|               ||($side == 'newer' && ($rev <= $rev1)) | ||||
|             ) { | ||||
|                 $options[$rev]['attrs']['disabled'] = 'disabled'; | ||||
|             } | ||||
|         } | ||||
|         return $options; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * build Dropdown form for revisions navigation | ||||
|      * | ||||
|      * @params string $side  "older" or "newer" | ||||
|      * @params array $options  dropdown options | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function buildDropdownSelector($side, $options) | ||||
|     { | ||||
|         // use timestamp for current revision, date may be false when revisions < 2 | ||||
|         [$rev1, $rev2] = [(int)$this->RevInfo1->val('date'), (int)$this->RevInfo2->val('date')]; | ||||
|  | ||||
|         $form = new Form(['action' => wl($this->id)]); | ||||
|         $form->setHiddenField('id', $this->id); | ||||
|         $form->setHiddenField('do', 'diff'); | ||||
|         $form->setHiddenField('difftype', $this->preference['difftype']); | ||||
|  | ||||
|         switch ($side) { | ||||
|             case 'older': // left side | ||||
|                 $form->setHiddenField('rev2[1]', $rev2); | ||||
|                 $input = $form->addDropdown('rev2[0]', $options) | ||||
|                     ->val($rev1)->addClass('quickselect'); | ||||
|                 $input->useInput(false); // inhibit prefillInput() during toHTML() process | ||||
|                 break; | ||||
|             case 'newer': // right side | ||||
|                 $form->setHiddenField('rev2[0]', $rev1); | ||||
|                 $input = $form->addDropdown('rev2[1]', $options) | ||||
|                     ->val($rev2)->addClass('quickselect'); | ||||
|                 $input->useInput(false); // inhibit prefillInput() during toHTML() process | ||||
|                 break; | ||||
|         } | ||||
|         $form->addButton('do[diff]', 'Go')->attr('type','submit'); | ||||
|         return $form->toHTML(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create html link to a diff view defined by two revisions | ||||
|      * | ||||
|      * @param string $linktype | ||||
|      * @param int $rev1 older revision | ||||
|      * @param int $rev2 newer revision or null for diff with current revision | ||||
|      * @return string html of link to a diff view | ||||
|      */ | ||||
|     protected function diffViewlink($linktype, $rev1, $rev2 = null) | ||||
|     { | ||||
|         global $lang; | ||||
|         if ($rev1 === false) return ''; | ||||
|  | ||||
|         if ($rev2 === null) { | ||||
|             $urlparam = array( | ||||
|                 'do' => 'diff', | ||||
|                 'rev' => $rev1, | ||||
|                 'difftype' => $this->preference['difftype'], | ||||
|             ); | ||||
|         } else { | ||||
|             $urlparam = array( | ||||
|                 'do' => 'diff', | ||||
|                 'rev2[0]' => $rev1, | ||||
|                 'rev2[1]' => $rev2, | ||||
|                 'difftype' => $this->preference['difftype'], | ||||
|             ); | ||||
|         } | ||||
|         $attr = array( | ||||
|             'class' => $linktype, | ||||
|             'href'  => wl($this->id, $urlparam, true, '&'), | ||||
|             'title' => $lang[$linktype], | ||||
|         ); | ||||
|         return '<a '. buildAttributes($attr) .'><span>'. $lang[$linktype] .'</span></a>'; | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Insert soft breaks in diff html | ||||
|      * | ||||
|      * @param string $diffhtml | ||||
|      * @return string | ||||
|      */ | ||||
|     public function insertSoftbreaks($diffhtml) | ||||
|     { | ||||
|         // search the diff html string for both: | ||||
|         // - html tags, so these can be ignored | ||||
|         // - long strings of characters without breaking characters | ||||
|         return preg_replace_callback('/<[^>]*>|[^<> ]{12,}/', function ($match) { | ||||
|             // if match is an html tag, return it intact | ||||
|             if ($match[0][0] == '<') return $match[0]; | ||||
|             // its a long string without a breaking character, | ||||
|             // make certain characters into breaking characters by inserting a | ||||
|             // word break opportunity (<wbr> tag) in front of them. | ||||
|             $regex = <<< REGEX | ||||
| (?(?=              # start a conditional expression with a positive look ahead ... | ||||
| &\#?\\w{1,6};)     # ... for html entities - we don't want to split them (ok to catch some invalid combinations) | ||||
| &\#?\\w{1,6};      # yes pattern - a quicker match for the html entity, since we know we have one | ||||
| | | ||||
| [?/,&\#;:]         # no pattern - any other group of 'special' characters to insert a breaking character after | ||||
| )+                 # end conditional expression | ||||
| REGEX; | ||||
|             return preg_replace('<'.$regex.'>xu', '\0<wbr>', $match[0]); | ||||
|         }, $diffhtml); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										55
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageDraft.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageDraft.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Draft; | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Page Draft Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class PageDraft extends Ui | ||||
| { | ||||
|     /** | ||||
|      * Display the Page Draft Form | ||||
|      * ask the user about how to handle an exisiting draft | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $INFO; | ||||
|         global $lang; | ||||
|  | ||||
|         $draft = new Draft($INFO['id'], $INFO['client']); | ||||
|         $text  = $draft->getDraftText(); | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('draft'); | ||||
|  | ||||
|         // print difference | ||||
|         (new PageDiff($INFO['id']))->compareWith($text)->preference('showIntro', false)->show(); | ||||
|  | ||||
|         // create the draft form | ||||
|         $form = new Form(['id' => 'dw__editform']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->setHiddenField('id', $INFO['id']); | ||||
|         $form->setHiddenField('date', $draft->getDraftDate()); | ||||
|         $form->setHiddenField('wikitext', $text); | ||||
|  | ||||
|         $form->addTagOpen('div')->id('draft__status'); | ||||
|         $form->addHTML($draft->getDraftMessage()); | ||||
|         $form->addTagClose('div'); | ||||
|         $form->addButton('do[recover]',  $lang['btn_recover'] )->attrs(['type' => 'submit', 'tabindex' => '1']); | ||||
|         $form->addButton('do[draftdel]', $lang['btn_draftdel'])->attrs(['type' => 'submit', 'tabindex' => '2']); | ||||
|         $form->addButton('do[show]',     $lang['btn_cancel']  )->attrs(['type' => 'submit', 'tabindex' => '3']); | ||||
|         $form->addTagClose('div'); | ||||
|  | ||||
|         print $form->toHTML('Draft'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										118
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageRevisions.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageRevisions.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\ChangeLog\PageChangeLog; | ||||
| use dokuwiki\ChangeLog\RevisionInfo; | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki PageRevisions Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class PageRevisions extends Revisions | ||||
| { | ||||
|     /* @var PageChangeLog */ | ||||
|     protected $changelog; | ||||
|  | ||||
|     /** | ||||
|      * PageRevisions Ui constructor | ||||
|      * | ||||
|      * @param string $id  id of page | ||||
|      */ | ||||
|     public function __construct($id = null) | ||||
|     { | ||||
|         global $INFO; | ||||
|         if (!isset($id)) $id = $INFO['id']; | ||||
|         parent::__construct($id); | ||||
|     } | ||||
|  | ||||
|     /** @inheritdoc */ | ||||
|     protected function setChangeLog() | ||||
|     { | ||||
|         $this->changelog = new PageChangeLog($this->id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display list of old revisions of the page | ||||
|      * | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * @author Ben Coburn <btcoburn@silicodon.net> | ||||
|      * @author Kate Arzamastseva <pshns@ukr.net> | ||||
|      * @author Satoshi Sahara <sahara.satoshi@gmail.com> | ||||
|      * | ||||
|      * @param int $first  skip the first n changelog lines | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show($first = -1) | ||||
|     { | ||||
|         global $lang, $REV; | ||||
|         $changelog =& $this->changelog; | ||||
|  | ||||
|         // get revisions, and set correct pagination parameters (first, hasNext) | ||||
|         if ($first === null) $first = -1; | ||||
|         $hasNext = false; | ||||
|         $revisions = $this->getRevisions($first, $hasNext); | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('revisions'); | ||||
|  | ||||
|         // create the form | ||||
|         $form = new Form([ | ||||
|                 'id' => 'page__revisions', | ||||
|                 'class' => 'changes', | ||||
|         ]); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|  | ||||
|         // start listing | ||||
|         $form->addTagOpen('ul'); | ||||
|         foreach ($revisions as $info) { | ||||
|             $rev = $info['date']; | ||||
|             $info['media'] = false; | ||||
|             $RevInfo = new RevisionInfo($info); | ||||
|             $RevInfo->isCurrent($changelog->isCurrentRevision($rev)); | ||||
|  | ||||
|             $class = ($RevInfo->val('type') === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor' : ''; | ||||
|             $form->addTagOpen('li')->addClass($class); | ||||
|             $form->addTagOpen('div')->addClass('li'); | ||||
|  | ||||
|             if ($RevInfo->isCurrent()) { | ||||
|                 $form->addCheckbox('rev2[]')->val($rev); | ||||
|             } elseif ($rev == $REV) { | ||||
|                 $form->addCheckbox('rev2[]')->val($rev)->attr('checked','checked'); | ||||
|             } elseif (page_exists($this->id, $rev)) { | ||||
|                 $form->addCheckbox('rev2[]')->val($rev); | ||||
|             } else { | ||||
|                 $form->addCheckbox('')->val($rev)->attr('disabled','disabled'); | ||||
|             } | ||||
|             $form->addHTML(' '); | ||||
|  | ||||
|             $html = implode(' ', [ | ||||
|                 $RevInfo->showEditDate(true),      // edit date and time | ||||
|                 $RevInfo->showIconCompareWithCurrent(),  // link to diff view icon | ||||
|                 $RevInfo->showFileName(),          // name of page or media | ||||
|                 $RevInfo->showEditSummary(),       // edit summary | ||||
|                 $RevInfo->showEditor(),            // editor info | ||||
|                 $RevInfo->showSizechange(),        // size change indicator | ||||
|                 $RevInfo->showCurrentIndicator(),  // current indicator (only when k=1) | ||||
|             ]); | ||||
|             $form->addHTML($html); | ||||
|             $form->addTagClose('div'); | ||||
|             $form->addTagClose('li'); | ||||
|         } | ||||
|         $form->addTagClose('ul');  // end of revision list | ||||
|  | ||||
|         // show button for diff view | ||||
|         $form->addButton('do[diff]', $lang['diff2'])->attr('type', 'submit'); | ||||
|  | ||||
|         $form->addTagClose('div'); // close div class=no | ||||
|  | ||||
|         print $form->toHTML('Revisions'); | ||||
|  | ||||
|         // provide navigation for paginated revision list (of pages and/or media files) | ||||
|         print $this->navigation($first, $hasNext, function ($n) { | ||||
|             return array('do' => 'revisions', 'first' => $n); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										87
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageView.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/PageView.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Extension\Event; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki PageView Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class PageView extends Ui | ||||
| { | ||||
|     protected $text; | ||||
|  | ||||
|     /**  | ||||
|      * PageView Ui constructor | ||||
|      * | ||||
|      * @param null|string $text  wiki text or null for showing $ID | ||||
|      */ | ||||
|     public function __construct($text = null) | ||||
|     { | ||||
|         $this->text = $text; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show a wiki page | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @triggers HTML_SHOWREV_OUTPUT | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $ID; | ||||
|         global $REV; | ||||
|         global $HIGH; | ||||
|         global $INFO; | ||||
|         global $DATE_AT; | ||||
|  | ||||
|         //disable section editing for old revisions or in preview | ||||
|         if ($this->text !== null || $REV) { | ||||
|             $secedit = false; | ||||
|         } else { | ||||
|             $secedit = true; | ||||
|         } | ||||
|  | ||||
|         if ($this->text !== null) { | ||||
|             //PreviewHeader | ||||
|             echo '<br id="scroll__here" />'; | ||||
|  | ||||
|             // print intro for preview | ||||
|             echo p_locale_xhtml('preview'); | ||||
|             echo '<div class="preview"><div class="pad">'; | ||||
|             $html = html_secedit(p_render('xhtml', p_get_instructions($this->text), $info), $secedit); | ||||
|             if ($INFO['prependTOC']) $html = tpl_toc(true) . $html; | ||||
|             echo $html; | ||||
|             echo '<div class="clearer"></div>'; | ||||
|             echo '</div></div>'; | ||||
|  | ||||
|         } else { | ||||
|             if ($REV || $DATE_AT) { | ||||
|                 // print intro for old revisions | ||||
|                 $data = array('rev' => &$REV, 'date_at' => &$DATE_AT); | ||||
|                 Event::createAndTrigger('HTML_SHOWREV_OUTPUT', $data, [$this, 'showrev']); | ||||
|             } | ||||
|             $html = p_wiki_xhtml($ID, $REV, true, $DATE_AT); | ||||
|             $html = html_secedit($html, $secedit); | ||||
|             if ($INFO['prependTOC']) $html = tpl_toc(true) . $html; | ||||
|             $html = html_hilight($html, $HIGH); | ||||
|             echo $html; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Show a revision warning | ||||
|      * | ||||
|      * @author Szymon Olewniczak <dokuwiki@imz.re> | ||||
|      */ | ||||
|     public function showrev() | ||||
|     { | ||||
|         print p_locale_xhtml('showrev'); | ||||
|     } | ||||
|  | ||||
|  | ||||
| } | ||||
							
								
								
									
										231
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Recent.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Recent.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,231 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\ChangeLog\PageChangeLog; | ||||
| use dokuwiki\ChangeLog\MediaChangeLog; | ||||
| use dokuwiki\ChangeLog\RevisionInfo; | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Recent Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class Recent extends Ui | ||||
| { | ||||
|     protected $first; | ||||
|     protected $show_changes; | ||||
|  | ||||
|     /** | ||||
|      * Recent Ui constructor | ||||
|      * | ||||
|      * @param int $first  skip the first n changelog lines | ||||
|      * @param string $show_changes  type of changes to show; 'pages', 'mediafiles', or 'both' | ||||
|      */ | ||||
|     public function __construct($first = 0, $show_changes = 'both') | ||||
|     { | ||||
|         $this->first        = $first; | ||||
|         $this->show_changes = $show_changes; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Display recent changes | ||||
|      * | ||||
|      * @author Andreas Gohr <andi@splitbrain.org> | ||||
|      * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> | ||||
|      * @author Ben Coburn <btcoburn@silicodon.net> | ||||
|      * @author Kate Arzamastseva <pshns@ukr.net> | ||||
|      * @author Satoshi Sahara <sahara.satoshi@gmail.com> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $conf, $lang; | ||||
|         global $ID; | ||||
|  | ||||
|         // get recent items, and set correct pagination parameters (first, hasNext) | ||||
|         $first = $this->first; | ||||
|         $hasNext = false; | ||||
|         $recents = $this->getRecents($first, $hasNext); | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('recent'); | ||||
|  | ||||
|         if (getNS($ID) != '') { | ||||
|             print '<div class="level1"><p>' | ||||
|                 . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent')) | ||||
|                 .'</p></div>'; | ||||
|         } | ||||
|  | ||||
|         // create the form | ||||
|         $form = new Form(['id'=>'dw__recent', 'method'=>'GET', 'action'=> wl($ID), 'class'=>'changes']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->setHiddenField('sectok', null); | ||||
|         $form->setHiddenField('do', 'recent'); | ||||
|         $form->setHiddenField('id', $ID); | ||||
|  | ||||
|         // show dropdown selector, whether include not only recent pages but also recent media files? | ||||
|         if ($conf['mediarevisions']) { | ||||
|             $this->addRecentItemSelector($form); | ||||
|         } | ||||
|  | ||||
|         // start listing of recent items | ||||
|         $form->addTagOpen('ul'); | ||||
|         foreach ($recents as $recent) { | ||||
|             // check possible external edition for current page or media | ||||
|             $this->checkCurrentRevision($recent); | ||||
|  | ||||
|             $RevInfo = new RevisionInfo($recent); | ||||
|             $RevInfo->isCurrent(true); | ||||
|             $class = ($RevInfo->val('type') === DOKU_CHANGE_TYPE_MINOR_EDIT) ? 'minor': ''; | ||||
|             $form->addTagOpen('li')->addClass($class); | ||||
|             $form->addTagOpen('div')->addClass('li'); | ||||
|             $html = implode(' ', [ | ||||
|                 $RevInfo->showFileIcon(),          // filetype icon | ||||
|                 $RevInfo->showEditDate(),          // edit date and time | ||||
|                 $RevInfo->showIconCompareWithPrevious(),    // link to diff view icon | ||||
|                 $RevInfo->showIconRevisions(),     // link to revisions icon | ||||
|                 $RevInfo->showFileName(),          // name of page or media | ||||
|                 $RevInfo->showEditSummary(),       // edit summary | ||||
|                 $RevInfo->showEditor(),            // editor info | ||||
|                 $RevInfo->showSizechange(),        // size change indicator | ||||
|             ]); | ||||
|             $form->addHTML($html); | ||||
|             $form->addTagClose('div'); | ||||
|             $form->addTagClose('li'); | ||||
|         } | ||||
|         $form->addTagClose('ul'); | ||||
|  | ||||
|         $form->addTagClose('div'); // close div class=no | ||||
|  | ||||
|         // provide navigation for paginated recent list (of pages and/or media files) | ||||
|         $form->addHTML($this->htmlNavigation($first, $hasNext)); | ||||
|  | ||||
|         print $form->toHTML('Recent'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get recent items, and set correct pagination parameters (first, hasNext) | ||||
|      * | ||||
|      * @param int  $first | ||||
|      * @param bool $hasNext | ||||
|      * @return array  recent items to be shown in a paginated list | ||||
|      * | ||||
|      * @see also dokuwiki\Changelog::getRevisionInfo() | ||||
|      */ | ||||
|     protected function getRecents(&$first, &$hasNext) | ||||
|     { | ||||
|         global $ID, $conf; | ||||
|  | ||||
|         $flags = 0; | ||||
|         if ($this->show_changes == 'mediafiles' && $conf['mediarevisions']) { | ||||
|             $flags = RECENTS_MEDIA_CHANGES; | ||||
|         } elseif ($this->show_changes == 'pages') { | ||||
|             $flags = 0; | ||||
|         } elseif ($conf['mediarevisions']) { | ||||
|             $flags = RECENTS_MEDIA_PAGES_MIXED; | ||||
|         } | ||||
|  | ||||
|         /* we need to get one additionally log entry to be able to | ||||
|          * decide if this is the last page or is there another one. | ||||
|          * This is the cheapest solution to get this information. | ||||
|          */ | ||||
|         $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags); | ||||
|         if (count($recents) == 0 && $first != 0) { | ||||
|             $first = 0; | ||||
|             $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags); | ||||
|         } | ||||
|  | ||||
|         $hasNext = false; | ||||
|         if (count($recents) > $conf['recent']) { | ||||
|             $hasNext = true; | ||||
|             array_pop($recents); // remove extra log entry | ||||
|         } | ||||
|         return $recents; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check possible external deletion for current page or media | ||||
|      * | ||||
|      * To keep sort order in the recent list, we ignore externally modification. | ||||
|      * It is not possible to know when external deletion had happened, | ||||
|      * $info['date'] is to be incremented 1 second when such deletion detected. | ||||
|      */ | ||||
|     protected function checkCurrentRevision(array &$info) | ||||
|     { | ||||
|         $itemType = $info['media'] ? 'media' : 'page'; | ||||
|         if ($itemType == 'page') { | ||||
|             $changelog = new PageChangelog($info['id']); | ||||
|         } else { | ||||
|             $changelog = new MediaChangelog($info['id']); | ||||
|         } | ||||
|         if (!$changelog->isCurrentRevision($info['date'])) { | ||||
|             $currentRevInfo = $changelog->getCurrentRevisionInfo(); | ||||
|             if ($currentRevInfo['type'] == DOKU_CHANGE_TYPE_DELETE) { | ||||
|                 // the page or media file was externally deleted, updated info because the link is already red | ||||
|                 // externally created and edited not updated because sorting by date is not worth so much changes | ||||
|                 $info = array_merge($info, $currentRevInfo); | ||||
|             } | ||||
|         } | ||||
|         unset($changelog); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Navigation buttons for Pagination (prev/next) | ||||
|      * | ||||
|      * @param int  $first | ||||
|      * @param bool $hasNext | ||||
|      * @return string html | ||||
|      */ | ||||
|     protected function htmlNavigation($first, $hasNext) | ||||
|     { | ||||
|         global $conf, $lang; | ||||
|  | ||||
|         $last = $first + $conf['recent']; | ||||
|         $html = '<div class="pagenav">'; | ||||
|         if ($first > 0) { | ||||
|             $first = max($first - $conf['recent'], 0); | ||||
|             $html.= '<div class="pagenav-prev">'; | ||||
|             $html.= '<button type="submit" name="first['.$first.']" accesskey="n"' | ||||
|                   . ' title="'.$lang['btn_newer'].' [N]" class="button show">' | ||||
|                   . $lang['btn_newer'] | ||||
|                   . '</button>'; | ||||
|             $html.= '</div>'; | ||||
|         } | ||||
|         if ($hasNext) { | ||||
|             $html.= '<div class="pagenav-next">'; | ||||
|             $html.= '<button type="submit" name="first['.$last.']" accesskey="p"' | ||||
|                   . ' title="'.$lang['btn_older'].' [P]" class="button show">' | ||||
|                   . $lang['btn_older'] | ||||
|                   . '</button>'; | ||||
|             $html.= '</div>'; | ||||
|         } | ||||
|         $html.= '</div>'; | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add dropdown selector of item types to the form instance | ||||
|      * | ||||
|      * @param Form $form | ||||
|      * @return void | ||||
|      */ | ||||
|     protected function addRecentItemSelector(Form $form) | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         $form->addTagOpen('div')->addClass('changeType'); | ||||
|         $options = array( | ||||
|                     'pages'      => $lang['pages_changes'], | ||||
|                     'mediafiles' => $lang['media_changes'], | ||||
|                     'both'       => $lang['both_changes'], | ||||
|         ); | ||||
|         $form->addDropdown('show_changes', $options, $lang['changes_type']) | ||||
|                 ->val($this->show_changes)->addClass('quickselect'); | ||||
|         $form->addButton('do[recent]', $lang['btn_apply'])->attr('type','submit'); | ||||
|         $form->addTagClose('div'); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										114
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Revisions.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Revisions.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,114 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\ChangeLog\ChangeLog; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Revisions Interface | ||||
|  * parent class of PageRevisions and MediaRevisions | ||||
|  * | ||||
|  * Note: navigation starts from -1, not 0. This is because our Revision management starts old revisions at 0 and | ||||
|  * will return the current revision only if the revisions starting at -1 are requested. | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| abstract class Revisions extends Ui | ||||
| { | ||||
|     /* @var string */ | ||||
|     protected $id;   // page id or media id | ||||
|  | ||||
|     /* @var ChangeLog */ | ||||
|     protected $changelog; // PageChangeLog or MediaChangeLog object | ||||
|  | ||||
|     /** | ||||
|      * Revisions Ui constructor | ||||
|      * | ||||
|      * @param string $id page id or media id | ||||
|      */ | ||||
|     public function __construct($id) | ||||
|     { | ||||
|         $this->id = $id; | ||||
|         $this->setChangeLog(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * set class property changelog | ||||
|      */ | ||||
|     abstract protected function setChangeLog(); | ||||
|  | ||||
|     /** | ||||
|      * Get revisions, and set correct pagination parameters (first, hasNext) | ||||
|      * | ||||
|      * @param int $first | ||||
|      * @param bool $hasNext | ||||
|      * @return array  revisions to be shown in a paginated list | ||||
|      * @see also https://www.dokuwiki.org/devel:changelog | ||||
|      */ | ||||
|     protected function getRevisions(&$first, &$hasNext) | ||||
|     { | ||||
|         global $conf; | ||||
|  | ||||
|         $changelog =& $this->changelog; | ||||
|         $revisions = []; | ||||
|  | ||||
|         $currentRevInfo = $changelog->getCurrentRevisionInfo(); | ||||
|         if (!$currentRevInfo) return $revisions; | ||||
|  | ||||
|         $num = $conf['recent']; | ||||
|  | ||||
|         /* we need to get one additional log entry to be able to | ||||
|          * decide if this is the last page or is there another one. | ||||
|          * see also Ui\Recent::getRecents() | ||||
|          */ | ||||
|         $revlist = $changelog->getRevisions($first, $num + 1); | ||||
|         if (count($revlist) == 0 && $first > -1) { | ||||
|             // resets to zero if $first requested a too high number | ||||
|             $first = -1; | ||||
|             return $this->getRevisions($first, $hasNext); | ||||
|         } | ||||
|  | ||||
|         // decide if this is the last page or is there another one | ||||
|         $hasNext = false; | ||||
|         if (count($revlist) > $num) { | ||||
|             $hasNext = true; | ||||
|             array_pop($revlist); // remove one additional log entry | ||||
|         } | ||||
|  | ||||
|         // append each revision info array to the revisions | ||||
|         foreach ($revlist as $rev) { | ||||
|             $revisions[] = $changelog->getRevisionInfo($rev); | ||||
|         } | ||||
|         return $revisions; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Navigation buttons for Pagination (prev/next) | ||||
|      * | ||||
|      * @param int $first | ||||
|      * @param bool $hasNext | ||||
|      * @param callable $callback returns array of hidden fields for the form button | ||||
|      * @return string html | ||||
|      */ | ||||
|     protected function navigation($first, $hasNext, $callback) | ||||
|     { | ||||
|         global $conf; | ||||
|  | ||||
|         $html = '<div class="pagenav">'; | ||||
|         $last = $first + $conf['recent']; | ||||
|         if ($first > -1) { | ||||
|             $first = max($first - $conf['recent'], -1); | ||||
|             $html .= '<div class="pagenav-prev">'; | ||||
|             $html .= html_btn('newer', $this->id, "p", $callback($first)); | ||||
|             $html .= '</div>'; | ||||
|         } | ||||
|         if ($hasNext) { | ||||
|             $html .= '<div class="pagenav-next">'; | ||||
|             $html .= html_btn('older', $this->id, "n", $callback($last)); | ||||
|             $html .= '</div>'; | ||||
|         } | ||||
|         $html .= '</div>'; | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										643
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Search.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										643
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Search.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,643 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Extension\Event; | ||||
| use dokuwiki\Form\Form; | ||||
| use dokuwiki\Utf8\PhpString; | ||||
| use dokuwiki\Utf8\Sort; | ||||
|  | ||||
| class Search extends Ui | ||||
| { | ||||
|     protected $query; | ||||
|     protected $parsedQuery; | ||||
|     protected $searchState; | ||||
|     protected $pageLookupResults = array(); | ||||
|     protected $fullTextResults = array(); | ||||
|     protected $highlight = array(); | ||||
|  | ||||
|     /** | ||||
|      * Search constructor. | ||||
|      * | ||||
|      * @param array $pageLookupResults pagename lookup results in the form [pagename => pagetitle] | ||||
|      * @param array $fullTextResults fulltext search results in the form [pagename => #hits] | ||||
|      * @param array $highlight  array of strings to be highlighted | ||||
|      */ | ||||
|     public function __construct(array $pageLookupResults, array $fullTextResults, $highlight) | ||||
|     { | ||||
|         global $QUERY; | ||||
|         $Indexer = idx_get_indexer(); | ||||
|  | ||||
|         $this->query = $QUERY; | ||||
|         $this->parsedQuery = ft_queryParser($Indexer, $QUERY); | ||||
|         $this->searchState = new SearchState($this->parsedQuery); | ||||
|  | ||||
|         $this->pageLookupResults = $pageLookupResults; | ||||
|         $this->fullTextResults = $fullTextResults; | ||||
|         $this->highlight = $highlight; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * display the search result | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         $searchHTML = $this->getSearchIntroHTML($this->query); | ||||
|  | ||||
|         $searchHTML .= $this->getSearchFormHTML($this->query); | ||||
|  | ||||
|         $searchHTML .= $this->getPageLookupHTML($this->pageLookupResults); | ||||
|  | ||||
|         $searchHTML .= $this->getFulltextResultsHTML($this->fullTextResults, $this->highlight); | ||||
|  | ||||
|         echo $searchHTML; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a form which can be used to adjust/refine the search | ||||
|      * | ||||
|      * @param string $query | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function getSearchFormHTML($query) | ||||
|     { | ||||
|         global $lang, $ID, $INPUT; | ||||
|  | ||||
|         $searchForm = (new Form(['method' => 'get'], true))->addClass('search-results-form'); | ||||
|         $searchForm->setHiddenField('do', 'search'); | ||||
|         $searchForm->setHiddenField('id', $ID); | ||||
|         $searchForm->setHiddenField('sf', '1'); | ||||
|         if ($INPUT->has('min')) { | ||||
|             $searchForm->setHiddenField('min', $INPUT->str('min')); | ||||
|         } | ||||
|         if ($INPUT->has('max')) { | ||||
|             $searchForm->setHiddenField('max', $INPUT->str('max')); | ||||
|         } | ||||
|         if ($INPUT->has('srt')) { | ||||
|             $searchForm->setHiddenField('srt', $INPUT->str('srt')); | ||||
|         } | ||||
|         $searchForm->addFieldsetOpen()->addClass('search-form'); | ||||
|         $searchForm->addTextInput('q')->val($query)->useInput(false); | ||||
|         $searchForm->addButton('', $lang['btn_search'])->attr('type', 'submit'); | ||||
|  | ||||
|         $this->addSearchAssistanceElements($searchForm); | ||||
|  | ||||
|         $searchForm->addFieldsetClose(); | ||||
|  | ||||
|         return $searchForm->toHTML('Search'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add elements to adjust how the results are sorted | ||||
|      * | ||||
|      * @param Form $searchForm | ||||
|      */ | ||||
|     protected function addSortTool(Form $searchForm) | ||||
|     { | ||||
|         global $INPUT, $lang; | ||||
|  | ||||
|         $options = [ | ||||
|             'hits' => [ | ||||
|                 'label' => $lang['search_sort_by_hits'], | ||||
|                 'sort' => '', | ||||
|             ], | ||||
|             'mtime' => [ | ||||
|                 'label' => $lang['search_sort_by_mtime'], | ||||
|                 'sort' => 'mtime', | ||||
|             ], | ||||
|         ]; | ||||
|         $activeOption = 'hits'; | ||||
|  | ||||
|         if ($INPUT->str('srt') === 'mtime') { | ||||
|             $activeOption = 'mtime'; | ||||
|         } | ||||
|  | ||||
|         $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true'); | ||||
|         // render current | ||||
|         $currentWrapper = $searchForm->addTagOpen('div')->addClass('current'); | ||||
|         if ($activeOption !== 'hits') { | ||||
|             $currentWrapper->addClass('changed'); | ||||
|         } | ||||
|         $searchForm->addHTML($options[$activeOption]['label']); | ||||
|         $searchForm->addTagClose('div'); | ||||
|  | ||||
|         // render options list | ||||
|         $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false'); | ||||
|  | ||||
|         foreach ($options as $key => $option) { | ||||
|             $listItem = $searchForm->addTagOpen('li'); | ||||
|  | ||||
|             if ($key === $activeOption) { | ||||
|                 $listItem->addClass('active'); | ||||
|                 $searchForm->addHTML($option['label']); | ||||
|             } else { | ||||
|                 $link = $this->searchState->withSorting($option['sort'])->getSearchLink($option['label']); | ||||
|                 $searchForm->addHTML($link); | ||||
|             } | ||||
|             $searchForm->addTagClose('li'); | ||||
|         } | ||||
|         $searchForm->addTagClose('ul'); | ||||
|  | ||||
|         $searchForm->addTagClose('div'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if the query is simple enough to modify its namespace limitations without breaking the rest of the query | ||||
|      * | ||||
|      * @param array $parsedQuery | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function isNamespaceAssistanceAvailable(array $parsedQuery) { | ||||
|         if (preg_match('/[\(\)\|]/', $parsedQuery['query']) === 1) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Check if the query is simple enough to modify the fragment search behavior without breaking the rest of the query | ||||
|      * | ||||
|      * @param array $parsedQuery | ||||
|      * | ||||
|      * @return bool | ||||
|      */ | ||||
|     protected function isFragmentAssistanceAvailable(array $parsedQuery) { | ||||
|         if (preg_match('/[\(\)\|]/', $parsedQuery['query']) === 1) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (!empty($parsedQuery['phrases'])) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the elements to be used for search assistance | ||||
|      * | ||||
|      * @param Form $searchForm | ||||
|      */ | ||||
|     protected function addSearchAssistanceElements(Form $searchForm) | ||||
|     { | ||||
|         $searchForm->addTagOpen('div') | ||||
|             ->addClass('advancedOptions') | ||||
|             ->attr('style', 'display: none;') | ||||
|             ->attr('aria-hidden', 'true'); | ||||
|  | ||||
|         $this->addFragmentBehaviorLinks($searchForm); | ||||
|         $this->addNamespaceSelector($searchForm); | ||||
|         $this->addDateSelector($searchForm); | ||||
|         $this->addSortTool($searchForm); | ||||
|  | ||||
|         $searchForm->addTagClose('div'); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      *  Add the elements to adjust the fragment search behavior | ||||
|      * | ||||
|      * @param Form $searchForm | ||||
|      */ | ||||
|     protected function addFragmentBehaviorLinks(Form $searchForm) | ||||
|     { | ||||
|         if (!$this->isFragmentAssistanceAvailable($this->parsedQuery)) { | ||||
|             return; | ||||
|         } | ||||
|         global $lang; | ||||
|  | ||||
|         $options = [ | ||||
|             'exact' => [ | ||||
|                 'label' => $lang['search_exact_match'], | ||||
|                 'and' => array_map(function ($term) { | ||||
|                     return trim($term, '*'); | ||||
|                 }, $this->parsedQuery['and']), | ||||
|                 'not' => array_map(function ($term) { | ||||
|                     return trim($term, '*'); | ||||
|                 }, $this->parsedQuery['not']), | ||||
|             ], | ||||
|             'starts' => [ | ||||
|                 'label' => $lang['search_starts_with'], | ||||
|                 'and' => array_map(function ($term) { | ||||
|                     return trim($term, '*') . '*'; | ||||
|                 }, $this->parsedQuery['and']), | ||||
|                 'not' => array_map(function ($term) { | ||||
|                     return trim($term, '*') . '*'; | ||||
|                 }, $this->parsedQuery['not']), | ||||
|             ], | ||||
|             'ends' => [ | ||||
|                 'label' => $lang['search_ends_with'], | ||||
|                 'and' => array_map(function ($term) { | ||||
|                     return '*' . trim($term, '*'); | ||||
|                 }, $this->parsedQuery['and']), | ||||
|                 'not' => array_map(function ($term) { | ||||
|                     return '*' . trim($term, '*'); | ||||
|                 }, $this->parsedQuery['not']), | ||||
|             ], | ||||
|             'contains' => [ | ||||
|                 'label' => $lang['search_contains'], | ||||
|                 'and' => array_map(function ($term) { | ||||
|                     return '*' . trim($term, '*') . '*'; | ||||
|                 }, $this->parsedQuery['and']), | ||||
|                 'not' => array_map(function ($term) { | ||||
|                     return '*' . trim($term, '*') . '*'; | ||||
|                 }, $this->parsedQuery['not']), | ||||
|             ] | ||||
|         ]; | ||||
|  | ||||
|         // detect current | ||||
|         $activeOption = 'custom'; | ||||
|         foreach ($options as $key => $option) { | ||||
|             if ($this->parsedQuery['and'] === $option['and']) { | ||||
|                 $activeOption = $key; | ||||
|             } | ||||
|         } | ||||
|         if ($activeOption === 'custom') { | ||||
|             $options = array_merge(['custom' => [ | ||||
|                 'label' => $lang['search_custom_match'], | ||||
|             ]], $options); | ||||
|         } | ||||
|  | ||||
|         $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true'); | ||||
|         // render current | ||||
|         $currentWrapper = $searchForm->addTagOpen('div')->addClass('current'); | ||||
|         if ($activeOption !== 'exact') { | ||||
|             $currentWrapper->addClass('changed'); | ||||
|         } | ||||
|         $searchForm->addHTML($options[$activeOption]['label']); | ||||
|         $searchForm->addTagClose('div'); | ||||
|  | ||||
|         // render options list | ||||
|         $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false'); | ||||
|  | ||||
|         foreach ($options as $key => $option) { | ||||
|             $listItem = $searchForm->addTagOpen('li'); | ||||
|  | ||||
|             if ($key === $activeOption) { | ||||
|                 $listItem->addClass('active'); | ||||
|                 $searchForm->addHTML($option['label']); | ||||
|             } else { | ||||
|                 $link = $this->searchState | ||||
|                     ->withFragments($option['and'], $option['not']) | ||||
|                     ->getSearchLink($option['label']) | ||||
|                 ; | ||||
|                 $searchForm->addHTML($link); | ||||
|             } | ||||
|             $searchForm->addTagClose('li'); | ||||
|         } | ||||
|         $searchForm->addTagClose('ul'); | ||||
|  | ||||
|         $searchForm->addTagClose('div'); | ||||
|  | ||||
|         // render options list | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Add the elements for the namespace selector | ||||
|      * | ||||
|      * @param Form $searchForm | ||||
|      */ | ||||
|     protected function addNamespaceSelector(Form $searchForm) | ||||
|     { | ||||
|         if (!$this->isNamespaceAssistanceAvailable($this->parsedQuery)) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         global $lang; | ||||
|  | ||||
|         $baseNS = empty($this->parsedQuery['ns']) ? '' : $this->parsedQuery['ns'][0]; | ||||
|         $extraNS = $this->getAdditionalNamespacesFromResults($baseNS); | ||||
|  | ||||
|         $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true'); | ||||
|         // render current | ||||
|         $currentWrapper = $searchForm->addTagOpen('div')->addClass('current'); | ||||
|         if ($baseNS) { | ||||
|             $currentWrapper->addClass('changed'); | ||||
|             $searchForm->addHTML('@' . $baseNS); | ||||
|         } else { | ||||
|             $searchForm->addHTML($lang['search_any_ns']); | ||||
|         } | ||||
|         $searchForm->addTagClose('div'); | ||||
|  | ||||
|         // render options list | ||||
|         $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false'); | ||||
|  | ||||
|         $listItem = $searchForm->addTagOpen('li'); | ||||
|         if ($baseNS) { | ||||
|             $listItem->addClass('active'); | ||||
|             $link = $this->searchState->withNamespace('')->getSearchLink($lang['search_any_ns']); | ||||
|             $searchForm->addHTML($link); | ||||
|         } else { | ||||
|             $searchForm->addHTML($lang['search_any_ns']); | ||||
|         } | ||||
|         $searchForm->addTagClose('li'); | ||||
|  | ||||
|         foreach ($extraNS as $ns => $count) { | ||||
|             $listItem = $searchForm->addTagOpen('li'); | ||||
|             $label = $ns . ($count ? " <bdi>($count)</bdi>" : ''); | ||||
|  | ||||
|             if ($ns === $baseNS) { | ||||
|                 $listItem->addClass('active'); | ||||
|                 $searchForm->addHTML($label); | ||||
|             } else { | ||||
|                 $link = $this->searchState->withNamespace($ns)->getSearchLink($label); | ||||
|                 $searchForm->addHTML($link); | ||||
|             } | ||||
|             $searchForm->addTagClose('li'); | ||||
|         } | ||||
|         $searchForm->addTagClose('ul'); | ||||
|  | ||||
|         $searchForm->addTagClose('div'); | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Parse the full text results for their top namespaces below the given base namespace | ||||
|      * | ||||
|      * @param string $baseNS the namespace within which was searched, empty string for root namespace | ||||
|      * | ||||
|      * @return array an associative array with namespace => #number of found pages, sorted descending | ||||
|      */ | ||||
|     protected function getAdditionalNamespacesFromResults($baseNS) | ||||
|     { | ||||
|         $namespaces = []; | ||||
|         $baseNSLength = strlen($baseNS); | ||||
|         foreach ($this->fullTextResults as $page => $numberOfHits) { | ||||
|             $namespace = getNS($page); | ||||
|             if (!$namespace) { | ||||
|                 continue; | ||||
|             } | ||||
|             if ($namespace === $baseNS) { | ||||
|                 continue; | ||||
|             } | ||||
|             $firstColon = strpos((string)$namespace, ':', $baseNSLength + 1) ?: strlen($namespace); | ||||
|             $subtopNS = substr($namespace, 0, $firstColon); | ||||
|             if (empty($namespaces[$subtopNS])) { | ||||
|                 $namespaces[$subtopNS] = 0; | ||||
|             } | ||||
|             $namespaces[$subtopNS] += 1; | ||||
|         } | ||||
|         Sort::ksort($namespaces); | ||||
|         arsort($namespaces); | ||||
|         return $namespaces; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @ToDo: custom date input | ||||
|      * | ||||
|      * @param Form $searchForm | ||||
|      */ | ||||
|     protected function addDateSelector(Form $searchForm) | ||||
|     { | ||||
|         global $INPUT, $lang; | ||||
|  | ||||
|         $options = [ | ||||
|             'any' => [ | ||||
|                 'before' => false, | ||||
|                 'after' => false, | ||||
|                 'label' => $lang['search_any_time'], | ||||
|             ], | ||||
|             'week' => [ | ||||
|                 'before' => false, | ||||
|                 'after' => '1 week ago', | ||||
|                 'label' => $lang['search_past_7_days'], | ||||
|             ], | ||||
|             'month' => [ | ||||
|                 'before' => false, | ||||
|                 'after' => '1 month ago', | ||||
|                 'label' => $lang['search_past_month'], | ||||
|             ], | ||||
|             'year' => [ | ||||
|                 'before' => false, | ||||
|                 'after' => '1 year ago', | ||||
|                 'label' => $lang['search_past_year'], | ||||
|             ], | ||||
|         ]; | ||||
|         $activeOption = 'any'; | ||||
|         foreach ($options as $key => $option) { | ||||
|             if ($INPUT->str('min') === $option['after']) { | ||||
|                 $activeOption = $key; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true'); | ||||
|         // render current | ||||
|         $currentWrapper = $searchForm->addTagOpen('div')->addClass('current'); | ||||
|         if ($INPUT->has('max') || $INPUT->has('min')) { | ||||
|             $currentWrapper->addClass('changed'); | ||||
|         } | ||||
|         $searchForm->addHTML($options[$activeOption]['label']); | ||||
|         $searchForm->addTagClose('div'); | ||||
|  | ||||
|         // render options list | ||||
|         $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false'); | ||||
|  | ||||
|         foreach ($options as $key => $option) { | ||||
|             $listItem = $searchForm->addTagOpen('li'); | ||||
|  | ||||
|             if ($key === $activeOption) { | ||||
|                 $listItem->addClass('active'); | ||||
|                 $searchForm->addHTML($option['label']); | ||||
|             } else { | ||||
|                 $link = $this->searchState | ||||
|                     ->withTimeLimitations($option['after'], $option['before']) | ||||
|                     ->getSearchLink($option['label']) | ||||
|                 ; | ||||
|                 $searchForm->addHTML($link); | ||||
|             } | ||||
|             $searchForm->addTagClose('li'); | ||||
|         } | ||||
|         $searchForm->addTagClose('ul'); | ||||
|  | ||||
|         $searchForm->addTagClose('div'); | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Build the intro text for the search page | ||||
|      * | ||||
|      * @param string $query the search query | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function getSearchIntroHTML($query) | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         $intro = p_locale_xhtml('searchpage'); | ||||
|  | ||||
|         $queryPagename = $this->createPagenameFromQuery($this->parsedQuery); | ||||
|         $createQueryPageLink = html_wikilink($queryPagename . '?do=edit', $queryPagename); | ||||
|  | ||||
|         $pagecreateinfo = ''; | ||||
|         if (auth_quickaclcheck($queryPagename) >= AUTH_CREATE) { | ||||
|             $pagecreateinfo = sprintf($lang['searchcreatepage'], $createQueryPageLink); | ||||
|         } | ||||
|         return str_replace( | ||||
|             array('@QUERY@', '@SEARCH@', '@CREATEPAGEINFO@'), | ||||
|             array(hsc(rawurlencode($query)), hsc($query), $pagecreateinfo), | ||||
|             $intro | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a pagename based the parsed search query | ||||
|      * | ||||
|      * @param array $parsedQuery | ||||
|      * | ||||
|      * @return string pagename constructed from the parsed query | ||||
|      */ | ||||
|     public function createPagenameFromQuery($parsedQuery) | ||||
|     { | ||||
|         $cleanedQuery = cleanID($parsedQuery['query']); // already strtolowered | ||||
|         if ($cleanedQuery === PhpString::strtolower($parsedQuery['query'])) { | ||||
|             return ':' . $cleanedQuery; | ||||
|         } | ||||
|         $pagename = ''; | ||||
|         if (!empty($parsedQuery['ns'])) { | ||||
|             $pagename .= ':' . cleanID($parsedQuery['ns'][0]); | ||||
|         } | ||||
|         $pagename .= ':' . cleanID(implode(' ' , $parsedQuery['highlight'])); | ||||
|         return $pagename; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Build HTML for a list of pages with matching pagenames | ||||
|      * | ||||
|      * @param array $data search results | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function getPageLookupHTML($data) | ||||
|     { | ||||
|         if (empty($data)) { | ||||
|             return ''; | ||||
|         } | ||||
|  | ||||
|         global $lang; | ||||
|  | ||||
|         $html = '<div class="search_quickresult">'; | ||||
|         $html .= '<h2>' . $lang['quickhits'] . ':</h2>'; | ||||
|         $html .= '<ul class="search_quickhits">'; | ||||
|         foreach ($data as $id => $title) { | ||||
|             $name = null; | ||||
|             if (!useHeading('navigation') && $ns = getNS($id)) { | ||||
|                 $name = shorten(noNS($id), ' (' . $ns . ')', 30); | ||||
|             } | ||||
|             $link = html_wikilink(':' . $id, $name); | ||||
|             $eventData = [ | ||||
|                 'listItemContent' => [$link], | ||||
|                 'page' => $id, | ||||
|             ]; | ||||
|             Event::createAndTrigger('SEARCH_RESULT_PAGELOOKUP', $eventData); | ||||
|             $html .= '<li>' . implode('', $eventData['listItemContent']) . '</li>'; | ||||
|         } | ||||
|         $html .= '</ul> '; | ||||
|         //clear float (see http://www.complexspiral.com/publications/containing-floats/) | ||||
|         $html .= '<div class="clearer"></div>'; | ||||
|         $html .= '</div>'; | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Build HTML for fulltext search results or "no results" message | ||||
|      * | ||||
|      * @param array $data      the results of the fulltext search | ||||
|      * @param array $highlight the terms to be highlighted in the results | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     protected function getFulltextResultsHTML($data, $highlight) | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         if (empty($data)) { | ||||
|             return '<div class="nothing">' . $lang['nothingfound'] . '</div>'; | ||||
|         } | ||||
|  | ||||
|         $html = '<div class="search_fulltextresult">'; | ||||
|         $html .= '<h2>' . $lang['search_fullresults'] . ':</h2>'; | ||||
|  | ||||
|         $html .= '<dl class="search_results">'; | ||||
|         $num = 0; | ||||
|         $position = 0; | ||||
|  | ||||
|         foreach ($data as $id => $cnt) { | ||||
|             $position += 1; | ||||
|             $resultLink = html_wikilink(':' . $id, null, $highlight); | ||||
|  | ||||
|             $resultHeader = [$resultLink]; | ||||
|  | ||||
|  | ||||
|             $restrictQueryToNSLink = $this->restrictQueryToNSLink(getNS($id)); | ||||
|             if ($restrictQueryToNSLink) { | ||||
|                 $resultHeader[] = $restrictQueryToNSLink; | ||||
|             } | ||||
|  | ||||
|             $resultBody = []; | ||||
|             $mtime = filemtime(wikiFN($id)); | ||||
|             $lastMod = '<span class="lastmod">' . $lang['lastmod'] . '</span> '; | ||||
|             $lastMod .= '<time datetime="' . date_iso8601($mtime) . '" title="' . dformat($mtime) . '">' . | ||||
|                 dformat($mtime, '%f') . | ||||
|                 '</time>'; | ||||
|             $resultBody['meta'] = $lastMod; | ||||
|             if ($cnt !== 0) { | ||||
|                 $num++; | ||||
|                 $hits = '<span class="hits">' . $cnt . ' ' . $lang['hits'] . '</span>, '; | ||||
|                 $resultBody['meta'] = $hits . $resultBody['meta']; | ||||
|                 if ($num <= FT_SNIPPET_NUMBER) { // create snippets for the first number of matches only | ||||
|                     $resultBody['snippet'] = ft_snippet($id, $highlight); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             $eventData = [ | ||||
|                 'resultHeader' => $resultHeader, | ||||
|                 'resultBody' => $resultBody, | ||||
|                 'page' => $id, | ||||
|                 'position' => $position, | ||||
|             ]; | ||||
|             Event::createAndTrigger('SEARCH_RESULT_FULLPAGE', $eventData); | ||||
|             $html .= '<div class="search_fullpage_result">'; | ||||
|             $html .= '<dt>' . implode(' ', $eventData['resultHeader']) . '</dt>'; | ||||
|             foreach ($eventData['resultBody'] as $class => $htmlContent) { | ||||
|                 $html .= "<dd class=\"$class\">$htmlContent</dd>"; | ||||
|             } | ||||
|             $html .= '</div>'; | ||||
|         } | ||||
|         $html .= '</dl>'; | ||||
|  | ||||
|         $html .= '</div>'; | ||||
|  | ||||
|         return $html; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * create a link to restrict the current query to a namespace | ||||
|      * | ||||
|      * @param false|string $ns the namespace to which to restrict the query | ||||
|      * | ||||
|      * @return false|string | ||||
|      */ | ||||
|     protected function restrictQueryToNSLink($ns) | ||||
|     { | ||||
|         if (!$ns) { | ||||
|             return false; | ||||
|         } | ||||
|         if (!$this->isNamespaceAssistanceAvailable($this->parsedQuery)) { | ||||
|             return false; | ||||
|         } | ||||
|         if (!empty($this->parsedQuery['ns']) && $this->parsedQuery['ns'][0] === $ns) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         $name = '@' . $ns; | ||||
|         return $this->searchState->withNamespace($ns)->getSearchLink($name); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										141
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/SearchState.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/SearchState.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,141 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| class SearchState | ||||
| { | ||||
|     /** | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $parsedQuery = []; | ||||
|  | ||||
|     /** | ||||
|      * SearchState constructor. | ||||
|      * | ||||
|      * @param array $parsedQuery | ||||
|      */ | ||||
|     public function __construct(array $parsedQuery) | ||||
|     { | ||||
|         global $INPUT; | ||||
|  | ||||
|         $this->parsedQuery = $parsedQuery; | ||||
|         if (!isset($parsedQuery['after'])) { | ||||
|             $this->parsedQuery['after'] = $INPUT->str('min'); | ||||
|         } | ||||
|         if (!isset($parsedQuery['before'])) { | ||||
|             $this->parsedQuery['before'] = $INPUT->str('max'); | ||||
|         } | ||||
|         if (!isset($parsedQuery['sort'])) { | ||||
|             $this->parsedQuery['sort'] = $INPUT->str('srt'); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a search state for the current search limited to a new namespace | ||||
|      * | ||||
|      * @param string $ns the namespace to which to limit the search, falsy to remove the limitation | ||||
|      * @param array  $notns | ||||
|      * | ||||
|      * @return SearchState | ||||
|      */ | ||||
|     public function withNamespace($ns, array $notns = []) | ||||
|     { | ||||
|         $parsedQuery = $this->parsedQuery; | ||||
|         $parsedQuery['ns'] = $ns ? [$ns] : []; | ||||
|         $parsedQuery['notns'] = $notns; | ||||
|  | ||||
|         return new SearchState($parsedQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a search state for the current search with new search fragments and optionally phrases | ||||
|      * | ||||
|      * @param array $and | ||||
|      * @param array $not | ||||
|      * @param array $phrases | ||||
|      * | ||||
|      * @return SearchState | ||||
|      */ | ||||
|     public function withFragments(array $and, array $not, array $phrases = []) | ||||
|     { | ||||
|         $parsedQuery = $this->parsedQuery; | ||||
|         $parsedQuery['and'] = $and; | ||||
|         $parsedQuery['not'] = $not; | ||||
|         $parsedQuery['phrases'] = $phrases; | ||||
|  | ||||
|         return new SearchState($parsedQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a search state for the current search with with adjusted time limitations | ||||
|      * | ||||
|      * @param $after | ||||
|      * @param $before | ||||
|      * | ||||
|      * @return SearchState | ||||
|      */ | ||||
|     public function withTimeLimitations($after, $before) | ||||
|     { | ||||
|         $parsedQuery = $this->parsedQuery; | ||||
|         $parsedQuery['after'] = $after; | ||||
|         $parsedQuery['before'] = $before; | ||||
|  | ||||
|         return new SearchState($parsedQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a search state for the current search with adjusted sort preference | ||||
|      * | ||||
|      * @param $sort | ||||
|      * | ||||
|      * @return SearchState | ||||
|      */ | ||||
|     public function withSorting($sort) | ||||
|     { | ||||
|         $parsedQuery = $this->parsedQuery; | ||||
|         $parsedQuery['sort'] = $sort; | ||||
|  | ||||
|         return new SearchState($parsedQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a link that represents the current search state | ||||
|      * | ||||
|      * Note that this represents only a simplified version of the search state. | ||||
|      * Grouping with braces and "OR" conditions are not supported. | ||||
|      * | ||||
|      * @param $label | ||||
|      * | ||||
|      * @return string | ||||
|      */ | ||||
|     public function getSearchLink($label) | ||||
|     { | ||||
|         global $ID, $conf; | ||||
|         $parsedQuery = $this->parsedQuery; | ||||
|  | ||||
|         $tagAttributes = [ | ||||
|             'target' => $conf['target']['wiki'], | ||||
|         ]; | ||||
|  | ||||
|         $newQuery = ft_queryUnparser_simple( | ||||
|             $parsedQuery['and'], | ||||
|             $parsedQuery['not'], | ||||
|             $parsedQuery['phrases'], | ||||
|             $parsedQuery['ns'], | ||||
|             $parsedQuery['notns'] | ||||
|         ); | ||||
|         $hrefAttributes = ['do' => 'search', 'sf' => '1', 'q' => $newQuery]; | ||||
|         if ($parsedQuery['after']) { | ||||
|             $hrefAttributes['min'] = $parsedQuery['after']; | ||||
|         } | ||||
|         if ($parsedQuery['before']) { | ||||
|             $hrefAttributes['max'] = $parsedQuery['before']; | ||||
|         } | ||||
|         if ($parsedQuery['sort']) { | ||||
|             $hrefAttributes['srt'] = $parsedQuery['sort']; | ||||
|         } | ||||
|  | ||||
|         $href = wl($ID, $hrefAttributes, false, '&'); | ||||
|         return "<a href='$href' " . buildAttributes($tagAttributes, true) . ">$label</a>"; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										115
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Subscribe.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Subscribe.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Subscribe Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class Subscribe extends Ui | ||||
| { | ||||
|     /** | ||||
|      * Display the subscribe form | ||||
|      * | ||||
|      * @author Adrian Lang <lang@cosmocode.de> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $INPUT; | ||||
|         global $INFO; | ||||
|         global $ID; | ||||
|         global $lang; | ||||
|         global $conf; | ||||
|         $stime_days = $conf['subscribe_time'] / 60 / 60 / 24; | ||||
|  | ||||
|         // print intro | ||||
|         echo p_locale_xhtml('subscr_form'); | ||||
|  | ||||
|         // list up current subscriptions | ||||
|         echo '<h2>'.$lang['subscr_m_current_header'].'</h2>'; | ||||
|         echo '<div class="level2">'; | ||||
|         if ($INFO['subscribed'] === false) { | ||||
|             echo '<p>'.$lang['subscr_m_not_subscribed'].'</p>'; | ||||
|         } else { | ||||
|             echo '<ul>'; | ||||
|             foreach ($INFO['subscribed'] as $sub) { | ||||
|                 echo '<li><div class="li">'; | ||||
|                 if ($sub['target'] !== $ID) { | ||||
|                     echo '<code class="ns">'.hsc(prettyprint_id($sub['target'])).'</code>'; | ||||
|                 } else { | ||||
|                     echo '<code class="page">'.hsc(prettyprint_id($sub['target'])).'</code>'; | ||||
|                 } | ||||
|                 $sstl = sprintf($lang['subscr_style_'.$sub['style']], $stime_days); | ||||
|                 if (!$sstl) $sstl = hsc($sub['style']); | ||||
|                 echo ' ('.$sstl.') '; | ||||
|  | ||||
|                 echo '<a href="'.wl( | ||||
|                     $ID, | ||||
|                     array( | ||||
|                          'do'        => 'subscribe', | ||||
|                          'sub_target'=> $sub['target'], | ||||
|                          'sub_style' => $sub['style'], | ||||
|                          'sub_action'=> 'unsubscribe', | ||||
|                          'sectok'    => getSecurityToken() | ||||
|                     ) | ||||
|                 ). | ||||
|                     '" class="unsubscribe">'.$lang['subscr_m_unsubscribe']. | ||||
|                     '</a></div></li>'; | ||||
|             } | ||||
|             echo '</ul>'; | ||||
|         } | ||||
|         echo '</div>'; | ||||
|  | ||||
|         // Add new subscription form | ||||
|         echo '<h2>'.$lang['subscr_m_new_header'].'</h2>'; | ||||
|         echo '<div class="level2">'; | ||||
|         $ns      = getNS($ID).':'; | ||||
|         $targets = [ | ||||
|             $ID => '<code class="page">'.prettyprint_id($ID).'</code>', | ||||
|             $ns => '<code class="ns">'.prettyprint_id($ns).'</code>', | ||||
|         ]; | ||||
|         $styles = [ | ||||
|             'every'  => $lang['subscr_style_every'], | ||||
|             'digest' => sprintf($lang['subscr_style_digest'], $stime_days), | ||||
|             'list'   => sprintf($lang['subscr_style_list'], $stime_days), | ||||
|         ]; | ||||
|  | ||||
|         // create the form | ||||
|         $form = new Form(['id' => 'subscribe__form']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->setHiddenField('id', $ID); | ||||
|         $form->setHiddenField('do', 'subscribe'); | ||||
|         $form->setHiddenField('sub_action', 'subscribe'); | ||||
|  | ||||
|         $form->addFieldsetOpen($lang['subscr_m_subscribe']); | ||||
|         $value = (array_key_exists($INPUT->post->str('sub_target'), $targets)) ? | ||||
|                  $INPUT->str('sub_target') : key($targets); | ||||
|         foreach ($targets as $val => $label) { | ||||
|             $data = ($value === $val) ? ['checked' => 'checked'] : []; | ||||
|             $form->addRadioButton('sub_target', $label)->val($val)->attrs($data); | ||||
|         } | ||||
|         $form->addFieldsetClose(); | ||||
|  | ||||
|         $form->addFieldsetOpen($lang['subscr_m_receive']); | ||||
|         $value = (array_key_exists($INPUT->post->str('sub_style'), $styles)) ? | ||||
|                  $INPUT->str('sub_style') : key($styles); | ||||
|         foreach ($styles as $val => $label) { | ||||
|             $data = ($value === $val) ? ['checked' => 'checked'] : []; | ||||
|             $form->addRadioButton('sub_style', $label)->val($val)->attrs($data); | ||||
|         } | ||||
|         $form->addFieldsetClose(); | ||||
|  | ||||
|         $form->addButton('do[subscribe]', $lang['subscr_m_subscribe'])->attr('type', 'submit'); | ||||
|         $form->addTagClose('div'); | ||||
|  | ||||
|         print $form->toHTML('Subscribe'); | ||||
|  | ||||
|         echo '</div>'; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										21
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Ui.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/Ui.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| /** | ||||
|  * Class Ui | ||||
|  * | ||||
|  * Abstract base class for all DokuWiki screens | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| abstract class Ui | ||||
| { | ||||
|     /** | ||||
|      * Display the UI element | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     abstract public function show(); | ||||
|  | ||||
| } | ||||
							
								
								
									
										126
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/UserProfile.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/UserProfile.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Extension\AuthPlugin; | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki User Profile Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class UserProfile extends Ui | ||||
| { | ||||
|     /** | ||||
|      * Display the User Profile Form Panel | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $lang; | ||||
|         global $conf; | ||||
|         global $INPUT; | ||||
|         global $INFO; | ||||
|         /** @var AuthPlugin $auth */ | ||||
|         global $auth; | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('updateprofile'); | ||||
|         print '<div class="centeralign">'; | ||||
|  | ||||
|         $fullname = $INPUT->post->str('fullname', $INFO['userinfo']['name'], true); | ||||
|         $email = $INPUT->post->str('email', $INFO['userinfo']['mail'], true); | ||||
|  | ||||
|         // create the updateprofile form | ||||
|         $form = new Form(['id' => 'dw__register']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->addFieldsetOpen($lang['profile']); | ||||
|         $form->setHiddenField('do', 'profile'); | ||||
|         $form->setHiddenField('save', '1'); | ||||
|  | ||||
|         $attr = array('size' => '50', 'disabled' => 'disabled'); | ||||
|         $input = $form->addTextInput('login', $lang['user'])->attrs($attr)->addClass('edit') | ||||
|             ->val($INPUT->server->str('REMOTE_USER')); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         $attr = array('size' => '50'); | ||||
|         if (!$auth->canDo('modName')) $attr['disabled'] = 'disabled'; | ||||
|         $input = $form->addTextInput('fullname', $lang['fullname'])->attrs($attr)->addClass('edit') | ||||
|             ->val($fullname); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         $attr = array('type' => 'email', 'size' =>  '50'); | ||||
|         if (!$auth->canDo('modMail')) $attr['disabled'] = 'disabled'; | ||||
|         $input = $form->addTextInput('email', $lang['email'])->attrs($attr)->addClass('edit') | ||||
|             ->val($email); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         if ($auth->canDo('modPass')) { | ||||
|             $attr = array('size'=>'50'); | ||||
|             $input = $form->addPasswordInput('newpass', $lang['newpass'])->attrs($attr)->addClass('edit'); | ||||
|             $input->getLabel()->attr('class', 'block'); | ||||
|             $form->addHTML("<br>\n"); | ||||
|  | ||||
|             $input = $form->addPasswordInput('passchk', $lang['passchk'])->attrs($attr)->addClass('edit'); | ||||
|             $input->getLabel()->attr('class', 'block'); | ||||
|             $form->addHTML("<br>\n"); | ||||
|         } | ||||
|  | ||||
|         if ($conf['profileconfirm']) { | ||||
|             $form->addHTML("<br>\n"); | ||||
|             $attr = array('size' => '50', 'required' => 'required'); | ||||
|             $input = $form->addPasswordInput('oldpass', $lang['oldpass'])->attrs($attr)->addClass('edit'); | ||||
|             $input->getLabel()->attr('class', 'block'); | ||||
|             $form->addHTML("<br>\n"); | ||||
|         } | ||||
|  | ||||
|         $form->addButton('', $lang['btn_save'])->attr('type', 'submit'); | ||||
|         $form->addButton('', $lang['btn_reset'])->attr('type', 'reset'); | ||||
|  | ||||
|         $form->addFieldsetClose(); | ||||
|         $form->addTagClose('div'); | ||||
|  | ||||
|         print $form->toHTML('UpdateProfile'); | ||||
|  | ||||
|  | ||||
|         if ($auth->canDo('delUser') && actionOK('profile_delete')) { | ||||
|  | ||||
|             // create the profiledelete form | ||||
|             $form = new Form(['id' => 'dw__profiledelete']); | ||||
|             $form->addTagOpen('div')->addClass('no'); | ||||
|             $form->addFieldsetOpen($lang['profdeleteuser']); | ||||
|             $form->setHiddenField('do', 'profile_delete'); | ||||
|             $form->setHiddenField('delete', '1'); | ||||
|  | ||||
|             $form->addCheckbox('confirm_delete', $lang['profconfdelete']) | ||||
|                 ->attrs(['required' => 'required']) | ||||
|                 ->id('dw__confirmdelete') | ||||
|                 ->val('1'); | ||||
|  | ||||
|             if ($conf['profileconfirm']) { | ||||
|                 $form->addHTML("<br>\n"); | ||||
|                 $attr = array('size' => '50', 'required' => 'required'); | ||||
|                 $input = $form->addPasswordInput('oldpass', $lang['oldpass'])->attrs($attr) | ||||
|                     ->addClass('edit'); | ||||
|                 $input->getLabel()->attr('class', 'block'); | ||||
|                 $form->addHTML("<br>\n"); | ||||
|             } | ||||
|  | ||||
|             $form->addButton('', $lang['btn_deleteuser'])->attr('type', 'submit'); | ||||
|             $form->addFieldsetClose(); | ||||
|             $form->addTagClose('div'); | ||||
|  | ||||
|             print $form->toHTML('ProfileDelete'); | ||||
|         } | ||||
|  | ||||
|         print '</div>'; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										74
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/UserRegister.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/UserRegister.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki User Registration Interface (Register Form) | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class UserRegister extends Ui | ||||
| { | ||||
|     /** | ||||
|      * Display the User Registration Form Panel | ||||
|      * | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $lang; | ||||
|         global $conf; | ||||
|         global $INPUT; | ||||
|  | ||||
|         $base_attrs = array('size' => '50', 'required' => 'required'); | ||||
|         $email_attrs = $base_attrs + array('type' => 'email'); | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('register'); | ||||
|         print '<div class="centeralign">'; | ||||
|  | ||||
|         // create the login form | ||||
|         $form = new Form(['id' => 'dw__register']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->addFieldsetOpen($lang['btn_register']); | ||||
|         $form->setHiddenField('do', 'register'); | ||||
|         $form->setHiddenField('save', '1'); | ||||
|  | ||||
|         $input = $form->addTextInput('login', $lang['user'])->attrs($base_attrs)->addClass('edit') | ||||
|             ->val($INPUT->post->str('login')); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         if (!$conf['autopasswd']) { | ||||
|             $input = $form->addPasswordInput('pass', $lang['pass'])->attrs($base_attrs)->addClass('edit'); | ||||
|             $input->getLabel()->attr('class', 'block'); | ||||
|             $form->addHTML("<br>\n"); | ||||
|             $input = $form->addPasswordInput('passchk', $lang['passchk'])->attrs($base_attrs)->addClass('edit'); | ||||
|             $input->getLabel()->attr('class', 'block'); | ||||
|             $form->addHTML("<br>\n"); | ||||
|         } | ||||
|  | ||||
|         $input = $form->addTextInput('fullname', $lang['fullname'])->attrs($base_attrs)->addClass('edit') | ||||
|             ->val($INPUT->post->str('fullname')); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         $input = $form->addTextInput('email', $lang['email'])->attrs($email_attrs)->addClass('edit') | ||||
|             ->val($INPUT->post->str('email')); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|  | ||||
|         $form->addButton('', $lang['btn_register'])->attr('type', 'submit'); | ||||
|         $form->addFieldsetClose(); | ||||
|         $form->addTagClose('div'); | ||||
|  | ||||
|         print $form->toHTML('Register'); | ||||
|  | ||||
|         print '</div>'; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										98
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/UserResendPwd.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								snippets/dokuwiki-2023-04-04/inc/Ui/UserResendPwd.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,98 @@ | ||||
| <?php | ||||
|  | ||||
| namespace dokuwiki\Ui; | ||||
|  | ||||
| use dokuwiki\Form\Form; | ||||
|  | ||||
| /** | ||||
|  * DokuWiki Resend Password Request Interface | ||||
|  * | ||||
|  * @package dokuwiki\Ui | ||||
|  */ | ||||
| class UserResendPwd extends Ui | ||||
| { | ||||
|     /** | ||||
|      * Display the form to request a new password for an existing account | ||||
|      * | ||||
|      * @author   Benoit Chesneau <benoit@bchesneau.info> | ||||
|      * @author   Andreas Gohr <andi@splitbrain.org> | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function show() | ||||
|     { | ||||
|         global $conf; | ||||
|         global $INPUT; | ||||
|  | ||||
|         $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth')); | ||||
|  | ||||
|         // print intro | ||||
|         print p_locale_xhtml('resetpwd'); | ||||
|         print '<div class="centeralign">'; | ||||
|  | ||||
|         if (!$conf['autopasswd'] && $token) { | ||||
|             $form = $this->formSetNewPassword($token); | ||||
|         } else { | ||||
|             $form = $this->formResendPassword(); | ||||
|         } | ||||
|  | ||||
|         print $form->toHTML('ResendPwd'); | ||||
|  | ||||
|         print '</div>'; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * create a form ui to set new password | ||||
|      * | ||||
|      * @params string $token  cleaned pwauth request variable | ||||
|      * @return Form | ||||
|      */ | ||||
|     protected function formSetNewPassword($token) | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         // create the form | ||||
|         $form = new Form(['id' => 'dw__resendpwd']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->addFieldsetOpen($lang['btn_resendpwd']); | ||||
|         $form->setHiddenField('token', $token); | ||||
|         $form->setHiddenField('do', 'resendpwd'); | ||||
|         $input = $form->addPasswordInput('pass', $lang['pass'])->attr('size', '50')->addClass('edit'); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|         $input = $form->addPasswordInput('passchk', $lang['passchk'])->attr('size', '50')->addClass('edit'); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|         $form->addButton('', $lang['btn_resendpwd'])->attr('type', 'submit'); | ||||
|         $form->addFieldsetClose(); | ||||
|         $form->addTagClose('div'); | ||||
|         return $form; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * create a form ui to request new password | ||||
|      * | ||||
|      * @return Form | ||||
|      */ | ||||
|     protected function formResendPassword() | ||||
|     { | ||||
|         global $lang; | ||||
|  | ||||
|         // create the form | ||||
|         $form = new Form(['id' => 'dw__resendpwd']); | ||||
|         $form->addTagOpen('div')->addClass('no'); | ||||
|         $form->addFieldsetOpen($lang['btn_resendpwd']); | ||||
|         $form->setHiddenField('do', 'resendpwd'); | ||||
|         $form->setHiddenField('save', '1'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|         $input = $form->addTextInput('login', $lang['user'])->addClass('edit'); | ||||
|         $input->getLabel()->attr('class', 'block'); | ||||
|         $form->addHTML("<br>\n"); | ||||
|         $form->addHTML("<br>\n"); | ||||
|         $form->addButton('', $lang['btn_resendpwd'])->attr('type', 'submit'); | ||||
|         $form->addFieldsetClose(); | ||||
|         $form->addTagClose('div'); | ||||
|         return $form; | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user