/** * Autocompletion support for pages * * @return array */ public function handleAjax() { global $INPUT; // check minimum length $lookup = trim($INPUT->str('search')); if (utf8_strlen($lookup) < $this->config['autocomplete']['mininput']) { return array(); } // results wanted? $max = $this->config['autocomplete']['maxresult']; if ($max <= 0) { return array(); } // lookup with namespace and postfix applied $namespace = $this->config['autocomplete']['namespace']; if ($namespace) { // namespace may be relative, resolve in current context $namespace .= ':foo'; // resolve expects pageID resolve_pageid($INPUT->str('ns'), $namespace, $exists); $namespace = getNS($namespace); } $postfix = $this->config['autocomplete']['postfix']; if ($namespace) { $lookup .= ' @' . $namespace; } $data = ft_pageLookup($lookup, true, $this->config['usetitles']); if (!count($data)) { return array(); } // this basically duplicates what we do in ajax_qsearch() $result = array(); $counter = 0; foreach ($data as $id => $title) { if ($this->config['usetitles']) { $name = $title . ' (' . $id . ')'; } else { $ns = getNS($id); if ($ns) { $name = noNS($id) . ' (' . $ns . ')'; } else { $name = $id; } } // check suffix if ($postfix && substr($id, -1 * strlen($postfix)) != $postfix) { continue; // page does not end in postfix, don't suggest it } $result[] = array('label' => $name, 'value' => $id); $counter++; if ($counter > $max) { break; } } return $result; }
/** * Run a search and display the result * * @author Andreas Gohr <*****@*****.**> */ function html_search() { global $conf; global $QUERY; global $ID; global $lang; $intro = p_locale_xhtml('searchpage'); // allow use of placeholder in search intro $intro = str_replace(array('@QUERY@', '@SEARCH@'), array(hsc(rawurlencode($QUERY)), hsc($QUERY)), $intro); echo $intro; flush(); //show progressbar print '<div class="centeralign" id="dw__loading">' . NL; print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL; print 'showLoadBar();' . NL; print '//--><!]]></script>' . NL; print '<br /></div>' . NL; flush(); //do quick pagesearch $data = array(); $data = ft_pageLookup($QUERY, true, useHeading('navigation')); if (count($data)) { print '<div class="search_quickresult">'; print '<h3>' . $lang['quickhits'] . ':</h3>'; print '<ul class="search_quickhits">'; foreach ($data as $id => $title) { print '<li> '; if (useHeading('navigation')) { $name = $title; } else { $ns = getNS($id); if ($ns) { $name = shorten(noNS($id), ' (' . $ns . ')', 30); } else { $name = $id; } } print html_wikilink(':' . $id, $name); print '</li> '; } print '</ul> '; //clear float (see http://www.complexspiral.com/publications/containing-floats/) print '<div class="clearer"></div>'; print '</div>'; } flush(); //do fulltext search $data = ft_pageSearch($QUERY, $regex); if (count($data)) { $num = 1; foreach ($data as $id => $cnt) { print '<div class="search_result">'; print html_wikilink(':' . $id, useHeading('navigation') ? null : $id, $regex); if ($cnt !== 0) { print ': <span class="search_cnt">' . $cnt . ' ' . $lang['hits'] . '</span><br />'; if ($num < FT_SNIPPET_NUMBER) { // create snippets for the first number of matches only print '<div class="search_snippet">' . ft_snippet($id, $regex) . '</div>'; } $num++; } print '</div>'; flush(); } } else { print '<div class="nothing">' . $lang['nothingfound'] . '</div>'; } //hide progressbar print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL; print 'hideLoadBar("dw__loading");' . NL; print '//--><!]]></script>' . NL; flush(); }
/** * List matching namespaces and pages for the link wizard * * @author Andreas Gohr <*****@*****.**> */ function ajax_linkwiz() { global $conf; global $lang; $q = ltrim($_POST['q'], ':'); $id = noNS($q); $ns = getNS($q); $ns = cleanID($ns); $id = cleanID($id); $nsd = utf8_encodeFN(str_replace(':', '/', $ns)); $idd = utf8_encodeFN(str_replace(':', '/', $id)); $data = array(); if ($q && !$ns) { // use index to lookup matching pages $pages = array(); $pages = ft_pageLookup($id, true); // result contains matches in pages and namespaces // we now extract the matching namespaces to show // them seperately $dirs = array(); foreach ($pages as $pid => $title) { if (strpos(noNS($pid), $id) === false) { // match was in the namespace $dirs[getNS($pid)] = 1; // assoc array avoids dupes } else { // it is a matching page, add it to the result $data[] = array('id' => $pid, 'title' => $title, 'type' => 'f'); } unset($pages[$pid]); } foreach ($dirs as $dir => $junk) { $data[] = array('id' => $dir, 'type' => 'd'); } } else { $opts = array('depth' => 1, 'listfiles' => true, 'listdirs' => true, 'pagesonly' => true, 'firsthead' => true, 'sneakyacl' => $conf['sneaky_index']); if ($id) { $opts['filematch'] = '^.*\\/' . $id; } if ($id) { $opts['dirmatch'] = '^.*\\/' . $id; } search($data, $conf['datadir'], 'search_universal', $opts, $nsd); // add back to upper if ($ns) { array_unshift($data, array('id' => getNS($ns), 'type' => 'u')); } } // fixme sort results in a useful way ? if (!count($data)) { echo $lang['nothingfound']; exit; } // output the found data $even = 1; foreach ($data as $item) { $even *= -1; //zebra if (($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) { $item['id'] .= ':'; } $link = wl($item['id']); echo '<div class="' . ($even > 0 ? 'even' : 'odd') . ' type_' . $item['type'] . '">'; if ($item['type'] == 'u') { $name = $lang['upperns']; } else { $name = htmlspecialchars($item['id']); } echo '<a href="' . $link . '" title="' . htmlspecialchars($item['id']) . '" class="wikilink1">' . $name . '</a>'; if ($item['title']) { echo '<span>' . htmlspecialchars($item['title']) . '</span>'; } echo '</div>'; } }
/** * Run a search and display the result * * @author Andreas Gohr <*****@*****.**> */ function html_search() { require_once DOKU_INC . 'inc/search.php'; require_once DOKU_INC . 'inc/fulltext.php'; global $conf; global $QUERY; global $ID; global $lang; print p_locale_xhtml('searchpage'); flush(); //check if search is restricted to namespace if (preg_match('/([^@]*)@([^@]*)/', $QUERY, $match)) { $id = cleanID($match[1]); if (empty($id)) { print '<div class="nothing">' . $lang['nothingfound'] . '</div>'; flush(); return; } } else { $id = cleanID($QUERY); } //show progressbar print '<div class="centeralign" id="dw__loading">' . NL; print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL; print 'showLoadBar();' . NL; print '//--><!]]></script>' . NL; print '<br /></div>' . NL; flush(); //do quick pagesearch $data = array(); $data = ft_pageLookup($id); if (count($data)) { print '<div class="search_quickresult">'; print '<h3>' . $lang['quickhits'] . ':</h3>'; print '<ul class="search_quickhits">'; foreach ($data as $id) { print '<li> '; $ns = getNS($id); if ($ns) { $name = shorten(noNS($id), ' (' . $ns . ')', 30); } else { $name = $id; } print html_wikilink(':' . $id, $name); print '</li> '; } print '</ul> '; //clear float (see http://www.complexspiral.com/publications/containing-floats/) print '<div class="clearer"> </div>'; print '</div>'; } flush(); //do fulltext search $data = ft_pageSearch($QUERY, $regex); if (count($data)) { $num = 1; foreach ($data as $id => $cnt) { print '<div class="search_result">'; print html_wikilink(':' . $id, useHeading('navigation') ? NULL : $id, $regex); print ': <span class="search_cnt">' . $cnt . ' ' . $lang['hits'] . '</span><br />'; if ($num < 15) { // create snippets for the first number of matches only #FIXME add to conf ? print '<div class="search_snippet">' . ft_snippet($id, $regex) . '</div>'; } print '</div>'; flush(); $num++; } } else { print '<div class="nothing">' . $lang['nothingfound'] . '</div>'; } //hide progressbar print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL; print 'hideLoadBar("dw__loading");' . NL; print '//--><!]]></script>' . NL; flush(); }
/** * Support OpenSearch suggestions * * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0 * @author Mike Frysinger <*****@*****.**> */ function ajax_suggestions() { global $conf; global $lang; $query = cleanID($_POST['q']); if (empty($query)) { $query = cleanID($_GET['q']); } if (empty($query)) { return; } require_once DOKU_INC . 'inc/html.php'; require_once DOKU_INC . 'inc/fulltext.php'; require_once DOKU_INC . 'inc/JSON.php'; $data = array(); $data = ft_pageLookup($query); if (!count($data)) { return; } // limit results to 15 hits $data = array_slice($data, 0, 15); $data = array_map('trim', $data); $data = array_map('noNS', $data); $data = array_unique($data); sort($data); /* now construct a json */ $suggestions = array($query, $data, array(), array()); $json = new JSON(); header('Content-Type: application/x-suggestions+json'); print $json->encode($suggestions); }
function _handle_ajax($event) { if (strpos($event->data, 'data_page_') !== 0) { return; } $event->preventDefault(); $type = substr($event->data, 10); $aliases = $this->dthlp->_aliases(); if (!isset($aliases[$type])) { echo 'Unknown type'; return; } if ($aliases[$type]['type'] !== 'page') { echo 'AutoCompletion is only supported for page types'; return; } if (substr($aliases[$type]['postfix'], -1, 1) === ':') { // Resolve namespace start page ID global $conf; $aliases[$type]['postfix'] .= $conf['start']; } require_once DOKU_INC . 'inc/fulltext.php'; $search = cleanID($_POST['search']); $pages = ft_pageLookup($search, false); $result = array(); foreach ($pages as $page) { if ($aliases[$type]['prefix'] !== '' && stripos($page, $aliases[$type]['prefix']) !== 0 || $aliases[$type]['postfix'] !== '' && strripos($page, $aliases[$type]['postfix']) !== strlen($page) - strlen($aliases[$type]['postfix'])) { continue; } $rtrim = -strlen($aliases[$type]['postfix']); if ($rtrim === 0) { // trimming with -0 gives the empty string, not the untrimmed // string $id = substr($page, strlen($aliases[$type]['prefix'])); } else { $id = substr($page, strlen($aliases[$type]['prefix']), $rtrim); } if (useHeading('content')) { $heading = p_get_first_heading($page, true); } if (!isset($heading) || $heading === '') { $heading = $id; } if ($search !== '' && (stripos($id, $search) === false && stripos($heading, $search) === false) || strpos($id, ':') !== false) { continue; } $result[hsc($id)] = hsc($heading); } require_once DOKU_INC . 'inc/JSON.php'; $json = new JSON(); echo '(' . $json->encode($result) . ')'; }
/** * @param Doku_Event $event */ function _handle_ajax(Doku_Event $event) { if ($event->data !== 'data_page') { return; } $event->stopPropagation(); $event->preventDefault(); $type = substr($_REQUEST['aliastype'], 10); $aliases = $this->dthlp->_aliases(); if (!isset($aliases[$type])) { echo 'Unknown type'; return; } if ($aliases[$type]['type'] !== 'page') { echo 'AutoCompletion is only supported for page types'; return; } if (substr($aliases[$type]['postfix'], -1, 1) === ':') { // Resolve namespace start page ID global $conf; $aliases[$type]['postfix'] .= $conf['start']; } $search = $_REQUEST['search']; $c_search = $search; $in_ns = false; if (!$search) { // No search given, so we just want all pages in the prefix $c_search = $aliases[$type]['prefix']; $in_ns = true; } $pages = ft_pageLookup($c_search, $in_ns, false); $regexp = '/^'; if ($aliases[$type]['prefix'] !== '') { $regexp .= preg_quote($aliases[$type]['prefix'], '/'); } $regexp .= '([^:]+)'; if ($aliases[$type]['postfix'] !== '') { $regexp .= preg_quote($aliases[$type]['postfix'], '/'); } $regexp .= '$/'; $result = array(); foreach ($pages as $page => $title) { $id = array(); if (!preg_match($regexp, $page, $id)) { // Does not satisfy the postfix and prefix criteria continue; } $id = $id[1]; if ($search !== '' && stripos($id, cleanID($search)) === false && stripos($title, $search) === false) { // Search string is not in id part or title continue; } if ($title === '') { $title = utf8_ucwords(str_replace('_', ' ', $id)); } $result[hsc($id)] = hsc($title); } $json = new JSON(); header('Content-Type: application/json'); echo $json->encode($result); }
/** * Search for the page. */ function _quick_pagesearch($id) { $data = array(); if ($id) { $data = ft_pageLookup($id); } if (count($data)) { foreach ($data as $id) { } } }
function _handle_ajax($event) { if (strpos($event->data, 'data_page_') !== 0) { return; } $event->preventDefault(); $type = substr($event->data, 10); $aliases = $this->dthlp->_aliases(); if (!isset($aliases[$type])) { echo 'Unknown type'; return; } if ($aliases[$type]['type'] !== 'page') { echo 'AutoCompletion is only supported for page types'; return; } if (substr($aliases[$type]['postfix'], -1, 1) === ':') { // Resolve namespace start page ID global $conf; $aliases[$type]['postfix'] .= $conf['start']; } $search = $_POST['search']; $pages = ft_pageLookup($search, false, false); $regexp = '/^'; if ($aliases[$type]['prefix'] !== '') { $regexp .= preg_quote($aliases[$type]['prefix'], '/'); } $regexp .= '([^:]+)'; if ($aliases[$type]['postfix'] !== '') { $regexp .= preg_quote($aliases[$type]['postfix'], '/'); } $regexp .= '$/'; $result = array(); foreach ($pages as $page => $title) { $id = array(); if (!preg_match($regexp, $page, $id)) { // Does not satisfy the postfix and prefix criteria continue; } $id = $id[1]; if ($search !== '' && stripos($id, cleanID($search)) === false && stripos($title, $search) === false) { // Search string is not in id part or title continue; } if ($title === '') { $title = utf8_ucwords(str_replace('_', ' ', $id)); } $result[hsc($id)] = hsc($title); } $json = new JSON(); echo '(' . $json->encode($result) . ')'; }
/** * getBestNamespace * Return a list with 'BestNamespaceId Score' */ function getBestNamespace($Vl_ID) { global $conf; $Vl_ListNamespaceId = array(); $Vl_ListNamespaceId = ft_pageLookup($conf['start']); $Vl_BestNbWordFound = 0; $Vl_BestNamespaceId = ''; $Vl_IdToExplode = str_replace('_', ':', $Vl_ID); $Vl_WordsInId = explode(':', $Vl_IdToExplode); foreach ($Vl_ListNamespaceId as $Vl_NamespaceId) { $Vl_NbWordFound = 0; foreach ($Vl_WordsInId as $Vl_Word) { if (strlen($Vl_Word) > 2) { $Vl_NbWordFound = $Vl_NbWordFound + substr_count($Vl_NamespaceId, $Vl_Word); } } if ($Vl_NbWordFound > $Vl_BestNbWordFound) { //Take only the smallest namespace if (strlen($Vl_NamespaceId) < strlen($Vl_BestNamespaceId) or $Vl_NbWordFound > $Vl_BestNbWordFound) { $Vl_BestNbWordFound = $Vl_NbWordFound; $Vl_BestNamespaceId = $Vl_NamespaceId; } } } $Vl_WfForStartPage = $this->getConf('WeightFactorForStartPage'); $Vl_WfForSameNamespace = $this->getConf('WeightFactorForSameNamespace'); if ($Vl_BestNbWordFound > 0) { $Vl_Score = $Vl_BestNbWordFound * $Vl_WfForSameNamespace + $Vl_WfForStartPage; } else { $Vl_Score = 0; } return $Vl_BestNamespaceId . " " . $Vl_Score; }
/** * Run a search and display the result * * @author Andreas Gohr <*****@*****.**> */ function html_search() { global $conf; global $QUERY; global $ID; global $lang; print '<div class="toc"> <div class="tocheader toctoggle" id="toc__header">Table of Contents</div> <div id="toc__inside"> <ul class="toc"> <li class="level1"><div class="li"><span class="li"><a href="#pages" class="toc">Pagenames</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#authors" class="toc">Authors</a></span></div> <li class="level1"><div class="li"><span class="li"><a href="#tools" class="toc">Tools</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#articles" class="toc">Articles</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#conferences" class="toc">Conferences</a></span></div></li> <li class="level1"><div class="li"><span class="li"><a href="#other" class="toc">Other pages</a></span></div> </ul> </div> </div>'; $intro = p_locale_xhtml('searchpage'); // allow use of placeholder in search intro $intro = str_replace(array('@QUERY@', '@SEARCH@'), array(hsc(rawurlencode($QUERY)), hsc($QUERY)), $intro); //echo $intro; print '<h1>Search: ' . $QUERY . '</h1>'; flush(); //show progressbar print '<div class="centeralign" id="dw__loading">' . NL; print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL; print 'showLoadBar();' . NL; print '//--><!]]></script>' . NL; print '<br /></div>' . NL; flush(); $articles = '/^(clip|kindle|notes)\\:/'; $avoid = '/((^(ref|kbib|abib|jbib|bib|t|clip|kindle|notes|skimg|conf)\\:)|^start$)/'; // add more conference namespaces at the end of $avoid and in $conferences, if you use first level namespaces // for this, for example I have aera11: cscl11: etc. $conferences = '/^(conf)\\:/'; $tool = '/^t\\:/'; $author = '/^a\\:/'; //do quick pagesearch $data = array(); $data = ft_pageLookup($QUERY, true, useHeading('navigation')); $out = ''; foreach ($data as $id => $title) { if (!preg_match($avoid, $id) || preg_match('/^abib:/', $id)) { $out = $out . '<li> '; if (useHeading('navigation')) { $name = $title; } else { $ns = getNS($id); if ($ns) { $name = shorten(noNS($id), ' (' . $ns . ')', 30); } else { $name = $id; } } $out = $out . html_wikilink(':' . $id, $name); $out = $out . '</li> '; } } if ($out != '') { print '<h2 name=pages id=pages>Page titles</h2>'; print '<ul class="search_quickhits">'; print $out; print "</ul>"; print '<div class="clearer"></div>'; flush(); } $data = ft_pageSearch($QUERY, $regexp); /////////////////////////////////////////////////////////////////////////// // authors $out = ''; foreach ($data as $id => $cnt) { if (preg_match($author, $id)) { $out = $out . '<li>' . html_wikilink(':' . $id, useHeading('navigation') ? null : $id, $regexp) . '</li>'; } } if ($out != '') { print '<br><h2 name=authors id=authors>Authors</h2>'; print '<ul class="search_quickhits">'; print $out; print "</ul>"; print '<div class="clearer"></div>'; } /////////////////////////////////////////////////////////////////////////// // tools $out = ''; foreach ($data as $id => $cnt) { if (preg_match($tool, $id)) { $out = $out . '<li>' . html_wikilink(':' . $id, useHeading('navigation') ? null : $id, $regexp) . '</li>'; } } if ($out != '') { print '<br><h2 name=tools id=tools>Tool results</h2>'; print '<ul class="search_quickhits">'; print $out; print "</ul>"; print '<div class="clearer"></div>'; flush(); } /////////////////////////////////////////////////////////////////////////// // articles $out = ''; $out2 = ''; $pattern = '/^(clip:|skimg:|kindle:|notes:|ref:)(.*)$/'; $already = array(); // $json =file_get_contents(dirname ( __FILE__ )."/../lib/plugins/dokuresearchr/json.tmp"); // $jbib = json_decode($json,true); foreach ($data as $id => $cnt) { if (preg_match('/^notes\\:/', $id)) { if (preg_match($pattern, $id, $matches)) { $idshow = $matches[2]; } else { $idshow = $id; } if (!in_array($idshow, $already)) { $cnttxt = ''; if ($cnt !== 0) { $cnttxt = ': <span class="search_cnt">' . $cnt . ' ' . $lang['hits'] . '</span><br />'; } $already[] = $idshow; $pub = '<div class="search_result">'; // $entry = $jbib[$idshow]; //print var_dump($entry); //$pub = $pub . html_wikilink('ref:'.$idshow,$entry[2],$regexp); $pub = $pub . html_wikilink('ref:' . $idshow, useHeading('navigation') ? null : $id, $regexp); // $citekey = substr($match,2,-1); // $json =file_get_contents(dirname ( __FILE__ )."/json.tmp"); // $t = json_decode($json,true); // $entry = $t[$citekey]; // $cit = $entry[0]; // $year = $entry[1]; // return array($citekey,$cit,$year,$entry[2]); // break; $pub = $pub . $cnttxt; $out = $out . $pub . '</div>'; } } } foreach ($data as $id => $cnt) { if (preg_match($articles, $id)) { if (preg_match($pattern, $id, $matches)) { $idshow = 'ref:' . $matches[2]; } else { $idshow = $id; } if (!in_array($idshow, $already)) { $cnttxt = ''; if ($cnt !== 0) { $cnttxt = ': <span class="search_cnt">' . $cnt . ' ' . $lang['hits'] . '</span><br />'; } $already[] = $idshow; $pub = '<div class="search_result">'; $pub = $pub . html_wikilink(':' . $idshow, useHeading('navigation') ? null : $id, $regexp); $pub = $pub . $cnttxt . '</div>'; $out2 = $out2 . $pub; } } } if ($out != '') { print '<br><h2 name=articles id=articles>Article results (notes)</h2>'; print $out; flush(); } if ($out != '') { print '<br><h2 name=articles id=articles>Article results (clippings)</h2>'; print $out2; flush(); } /////////////////////////////////////////////////////////////////////////// //conferences $out = ''; foreach ($data as $id => $cnt) { if (preg_match($conferences, $id)) { if ($cnt !== 0) { $cnttxt = ': <span class="search_cnt">' . $cnt . ' ' . $lang['hits'] . '</span><br />'; } $out = $out . '<div class="search_result">' . html_wikilink(':' . $id, useHeading('navigation') ? null : $id, $regexp); $out = $out . $cnttxt . '</span></div>'; } } if ($out != '') { print '<br><h2 name=conferences id=conferences>Conference results</h2>'; print $out; flush(); } /////////////////////////////////////////////////////////////////////////// //other $out = ''; foreach ($data as $id => $cnt) { if (!preg_match($avoid, $id)) { if ($cnt !== 0) { $cnttxt = ': <span class="search_cnt">' . $cnt . ' ' . $lang['hits'] . '</span><br />'; } $out = $out . '<div class="search_result">' . html_wikilink(':' . $id, useHeading('navigation') ? null : $id, $regexp); $out = $out . $cnttxt . '</span></div>'; } } if ($out != '') { print '<br><h2 name=other id=other>All other pages results</h2>'; print $out; flush(); } //hide progressbar print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL; print 'hideLoadBar("dw__loading");' . NL; print '//--><!]]></script>' . NL; flush(); }