1<?php 2 3 4use ComboStrap\Bootstrap; 5use ComboStrap\Page; 6use ComboStrap\PluginUtility; 7 8 9class syntax_plugin_combo_search extends DokuWiki_Syntax_Plugin 10{ 11 12 const SNIPPET_ID = "search"; 13 14 function getType() 15 { 16 return 'substition'; 17 } 18 19 function getPType() 20 { 21 return 'normal'; 22 } 23 24 function getAllowedTypes() 25 { 26 return array(); 27 } 28 29 function getSort(): int 30 { 31 return 201; 32 } 33 34 35 function connectTo($mode) 36 { 37 38 $this->Lexer->addSpecialPattern('<' . self::getTag() . '[^>]*>', $mode, 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent()); 39 40 } 41 42 function handle($match, $state, $pos, Doku_Handler $handler): array 43 { 44 45 switch ($state) { 46 47 case DOKU_LEXER_SPECIAL : 48 $init = array( 49 'ajax' => true, 50 'autocomplete' => false 51 ); 52 $match = substr($match, strlen($this->getPluginComponent()) + 1, -1); 53 $parameters = array_merge($init, PluginUtility::parseAttributes($match)); 54 return array( 55 PluginUtility::STATE => $state, 56 PluginUtility::ATTRIBUTES => $parameters 57 ); 58 59 } 60 return array(); 61 62 } 63 64 /** 65 * Render the output 66 * @param string $format 67 * @param Doku_Renderer $renderer 68 * @param array $data - what the function handle() return'ed 69 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 70 * @see DokuWiki_Syntax_Plugin::render() 71 * 72 * 73 */ 74 function render($format, Doku_Renderer $renderer, $data) 75 { 76 77 if ($format == 'xhtml') { 78 79 /** @var Doku_Renderer_xhtml $renderer */ 80 $state = $data[PluginUtility::STATE]; 81 switch ($state) { 82 case DOKU_LEXER_SPECIAL : 83 84 global $lang; 85 global $ACT; 86 global $QUERY; // $QUERY = $INPUT->str('q') 87 88 // don't print the search form if search action has been disabled 89 if (!actionOK('search')) return false; 90 91 PluginUtility::getSnippetManager()->attachInternalJavascriptForSlot("debounce"); 92 PluginUtility::getSnippetManager()->attachInternalJavascriptForSlot(self::SNIPPET_ID); 93 94 $parameters = $data[PluginUtility::ATTRIBUTES]; 95 $extraClass = ""; 96 if (array_key_exists("class", $parameters)) { 97 $extraClass = $parameters["class"]; 98 } 99 100 $id = Page::createPageFromRequestedPage()->getDokuwikiId(); 101 $inputSearchId = 'internal-search-box'; 102 103 // https://getbootstrap.com/docs/5.0/getting-started/accessibility/#visually-hidden-content 104 // 105 $visuallyHidden = "sr-only"; 106 $bootStrapVersion = Bootstrap::getBootStrapMajorVersion(); 107 if ($bootStrapVersion === Bootstrap::BootStrapFiveMajorVersion) { 108 $visuallyHidden = "visually-hidden"; 109 } 110 $valueKeyProp = ""; 111 if ($ACT == 'search') $valueKeyProp = ' value="' . htmlspecialchars($QUERY) . '" '; 112 $browserAutoComplete = 'on'; 113 if (!$parameters['autocomplete']) $browserAutoComplete = 'off'; 114 $ajaxAutoComplete = ""; 115 if ($parameters['ajax']) { 116 $ajaxAutoComplete = "<ul class=\"dropdown-menu\"></ul>"; 117 } 118 $action = wl(); 119 $renderer->doc .= <<<EOF 120<form 121 id="dw__search" 122 action="$action" 123 accept-charset="utf-8" 124 method="get" 125 role="search" 126 class="search form-inline $extraClass" 127 > 128<input type="hidden" name="do" value="search" /> 129<input type="hidden" name="id" value="$id" /> 130<label class="$visuallyHidden" for="$inputSearchId">Search Term</label> 131<input 132 id="$inputSearchId" 133 name="q" 134 type="text" 135 tabindex="1" 136 $valueKeyProp 137 placeholder="{$lang['btn_search']}..." 138 autocomplete="$browserAutoComplete" 139 accesskey="f" 140 class="edit form-control" 141 title="[F]"/> 142$ajaxAutoComplete 143</form> 144EOF; 145 break; 146 } 147 return true; 148 } 149 150 // unsupported $mode 151 return false; 152 } 153 154 public static function getTag() 155 { 156 list(/* $t */, /* $p */, /* $n */, $c) = explode('_', get_called_class(), 4); 157 return (isset($c) ? $c : ''); 158 } 159 160} 161 162