function plugin_search_action() { global $post, $vars; global $_search_msg, $_LANG; /* if (isset($vars['update_index'])){ PukiWiki\SearchLucene::updateIndex(); return array('msg'=>'done.'); } */ if (PLUGIN_SEARCH_DISABLE_GET_ACCESS) { $s_word = isset($post['word']) ? htmlsc($post['word']) : ''; } else { $s_word = isset($vars['word']) ? htmlsc($vars['word']) : ''; } if (strlen($s_word) > PLUGIN_SEARCH_MAX_LENGTH) { unset($vars['word']); // Stop using $_msg_word at lib/html.php die_message('Search words too long'); } $type = isset($vars['type']) ? $vars['type'] : ''; $base = isset($vars['base']) ? $vars['base'] : ''; $format = isset($vars['format']) ? $vars['format'] : 'html'; switch ($format) { case 'xml': // OpenSearch // http://www.opensearch.org/ global $site_name, $notify_from, $shortcut_icon; $ret = array('<?xml version="1.0" encoding="UTF-8"?>', '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:moz="http://www.mozilla.org/2006/browser/search/">', '<ShortName>' . $_search_msg['title_search'] . ' - ' . $site_name . '</ShortName>', '<Description>' . $_search_msg['title_search'] . ' - ' . $site_name . '</Description>', '<Contact>' . $notify_from . '</Contact>', '<Image height="16" width="16" type="image/x-icon">data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2F%2F%2F%2FBP%2F8%2BjT%2F7%2BdK%2F%2F38M%2F%2F%2F%2Fw0AAAAAAAAAAAAAAAAAAAAA%2F%2F%2F%2FC%2F%2F%2B%2FTH%2F7%2BdK%2F%2Fv4N%2F%2F%2F%2FwUAAAAA%2F%2F%2F%2FBf%2Ft5IH%2F5djE%2F%2FLsn%2F7u5pT63tKe%2BNzLkOjFmnnq27p%2B%2BOfXk%2Fnl06z%2B7eOV%2F%2FLsn%2F%2Fm2cD%2F6%2BGM%2F%2F%2F%2FBv%2F072P%2F5til%2F%2F%2F%2FGfz4%2BB%2FrqJOE9qBr7vukUv3%2FzoL%2F%2F%2Bao%2F%2Fznsv7337j4662LwPXWyyX%2F%2F%2F8Y%2F%2Bfbmv%2Fz7XD%2F7uaJ%2F%2FDohf%2F%2F%2FwH729Ib9loZzv97Jv7%2Fo0v%2F%2F%2BOt%2F%2F%2Fmrf%2F%2F0oD%2F%2F9KC%2F%2Fm3bu3vsZopAAAAAP%2Fw6H7%2F7uaQ%2FvHpgP%2Fy7JL%2F9vQW%2F1kvvf9UEef%2Fhj7v%2F%2FPP9%2F%2F95Pv%2F9df7%2F7FQ%2Bf%2BxUPT%2F0IPq%2F8V3xf%2F69RT%2F8uyR%2FvHphv%2F28Vr%2F9vGB%2F6qWsf9jK%2Bb%2FhEjm%2F7iF5v%2F16Ob%2F59Ln%2F9iw5%2F%2BZL%2Bf%2Fnzvm%2F%2Bq15v%2B1Zeb%2Bxp6x%2F%2Fbygf%2F07mf%2F%2F%2F8R%2FvHqkP68p9f%2FoW7o%2F4BL5v%2BCROb%2FfCrm%2F4Al5v%2BRPOb%2FvIXm%2F9Sp5v%2Fuxeb%2FsnHn%2F8Ci3f7x6o7%2F%2F%2F8XAAAAAP%2F38lz9o4Tu%2F9K28%2F%2FUs%2Bb%2FYxrm%2F3os5v%2BWSeb%2F1LPm%2F%2F%2F%2F5v%2F%2F%2Feb%2F9Nfm%2F9Wy8v%2BceO7%2F9fBoAAAAAAAAAAD%2F%2BfZD%2Brig8%2F%2FRtvH%2F8OLv%2F5dg5v%2BOSub%2FnFjm%2F8KW5v%2F%2F%2F%2Bb%2F%2F%2F7m%2F%2FPg7v%2FMqfH%2FsZnz%2F%2FfzTQAAAAD%2F%2F%2F8J%2F%2FDpku2EZcL8up71%2F%2BfW8v%2FUu%2B7%2Fp3Dm%2F6hw5v%2FKo%2Bb%2F4s7m%2F8ip7f%2FkzvP%2FzbD1%2FXxazP%2Fw6ZH%2F%2F%2F8O%2F%2Fn1SP%2F18ILtooy19Zt16v%2FUvfL%2Fz7Xy%2F9G07%2F%2FDmub%2F1bnm%2F%2FDn7v%2Fw4%2FL%2F38jy%2FYhb6%2FeTfbn%2F9fCB%2F%2FfyVf%2Fy63v%2F9O6N%2FPX1Hed%2BW7z%2BuZjq%2F%2Bja9P%2Fo2PH%2F4c3y%2F9i%2F8v%2Ft3%2FL%2F4s%2F0%2FKV%2B6%2BlUL8f77%2B0c%2F%2FTujf%2Fy64H%2F7OKA%2F%2FTvhv%2F%2F%2FwL35OAa9rmgwP%2F58On%2B7eL2%2F%2Bre%2BP7j1Pj%2B4M72%2BrCN6uNeOcb22dQi%2F%2F%2F%2FAf%2F074H%2F7OKG%2F%2FLsbf%2Fs4qj%2F%2F%2F8J%2F%2F%2F%2FDv3y8EX84tbL%2Fenh2v7m2vn93s%2F6%2BMq42%2FS6p8z77OhM%2F%2F%2F%2FD%2F%2F%2F%2Fwj%2F7eSc%2F%2FHqev%2F%2F%2Fwn%2F6NyN%2F%2BjcvP%2Fw6KH%2F8ema%2F%2B%2Fmk%2F%2Fv54%2F%2F%2B%2Fk2%2F%2Fv6MP%2Fv54z%2F7%2BaU%2F%2FDpmf%2Fw6KH%2F6d65%2FubZmP%2F%2F%2FwwAAAAA%2F%2F%2F%2FBf%2F59UP%2B7eNl%2FvPtVv%2F%2F%2Fx7%2F%2F%2F8CAAAAAAAAAAD%2F%2F%2F8C%2F%2F%2F%2FG%2F%2F07lP%2B7eNl%2F%2Fj0R%2F%2F%2F%2FwcAAAAAg8GsQQAArEEAAKxBAASsQQAArEEAAKxBAACsQYABrEGAAaxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBgYGsQQ%3D%3D</Image>', '<Language>' . DEFAULT_LANG . '</Language>', '<InputEncoding>UTF-8</InputEncoding>', '<OutputEncoding>UTF-8</OutputEncoding>', '<Url type="text/html" method="' . (!PLUGIN_SEARCH_DISABLE_GET_ACCESS ? 'get' : 'post') . '" template="' . Router::get_script_uri() . '">', '<Param name="cmd" value="search" />', '<Param name="encode_hint" value="' . PKWK_ENCODING_HINT . '" />', '<Param name="type" value="AND" />', '<Param name="word" value="{searchTerms}" />', '</Url>', '<Url type="application/x-suggestions+json" template="' . Router::get_cmd_uri('list', null, null, array('type' => 'json')) . '&word={searchTerms}" />', '<moz:SearchForm>' . Router::get_cmd_uri('search') . '</moz:SearchForm>', '</OpenSearchDescription>'); header('Content-Type:application/opensearchdescription+xml'); echo join("\n", $ret); exit; break; default: if ($s_word !== '') { // Search $msg = str_replace('$1', $s_word, $_search_msg['title_result']); $body = Search::do_search($vars['word'], $type, FALSE, $base); } else { // Init unset($vars['word']); // Stop using $_msg_word at lib/html.php $msg = $_search_msg['title_search']; $body = '<p>' . $_search_msg['msg_searching'] . '</p>' . "\n"; } // Show search form $bases = $base == '' ? array() : array($base); $body .= plugin_search_search_form($s_word, $type, $bases); break; } return array('msg' => $msg, 'body' => $body); }
function do_search($word, $type = 'and', $non_format = FALSE, $base = '') { return Search::do_search($word, $type, $non_format, $base); }
/** * ワードをハイライト * @param string or array $target ハイライトさせたいワード * @param array $content 対象の文字列 * @return string */ private static function hilightWord($target, $content) { $contents = is_string($content) ? array($content) : $content; // ワードが配列で渡されてないときはスペースと+の部分で分割 $words = is_string($target) ? preg_split('/\\s+/', $target, -1, PREG_SPLIT_NO_EMPTY) : $target; $words = array_splice($words, 0, 10); // Max: 10 words $words = array_flip($words); $keys = array(); foreach ($words as $word => $id) { $keys[$word] = strlen($word); } $keys = Search::get_search_words(array_keys($keys), TRUE); $id = 0; foreach ($keys as $key => $pattern) { $s_key = Utility::htmlsc($key); $pattern = '/' . '<textarea[^>]*>.*?<\\/textarea>' . '|' . '<[^>]*>' . '|' . '&[^;]+;' . '|' . '(' . $pattern . ')' . '/sS'; // ハイライトさせる関数を生成 $decorate_Nth_word = function ($matches) use($id) { return isset($matches[1]) ? '<mark class="word' . $id . '">' . $matches[1] . '</mark>' : $matches[0]; }; // 書き換え foreach ($contents as $content) { $contents = preg_replace_callback($pattern, $decorate_Nth_word, $content); } ++$id; } return $contents; }
/** * ページの関連性データーベースを更新 * @global string $WikiName * @global boolean $autolink * @global type $nowikiname * @global array $search_non_list * @param string $page * @return void */ public function update($page = '') { $time = Factory::Wiki($page)->time(); $rel_old = self::getRel($this->page); $rel_exist = $rel_old === array(); $rel_auto = $rel_new = array(); $pages = self::getObjects($page); if (!empty($pages)) { foreach ($pages as $_obj) { if (!isset($_obj->type) || $_obj->type !== 'pagename' || $_obj->name === $page || empty($_obj->name)) { continue; } if ($_obj instanceof AutoLink) { // Not cool though $rel_auto[] = $_obj->name; } else { if ($_obj instanceof AutoAlias) { $_alias = AutoAlias::getAutoAliasDict($_obj->name); if (Factory::Wiki($_alias)->isValied()) { $rel_auto[] = $_alias; } } else { $rel_new[] = $_obj->name; } } } } // All pages "Referenced to" only by AutoLink $rel_auto = array_diff(array_unique($rel_auto), $rel_new); // All pages "Referenced to" $rel_new = array_merge(array_unique($rel_new), $rel_auto); // update Pages referred from the $page if ($time) { // Page exists self::setRel($this->page, $rel_new); } // .ref: Pages refer to the $page self::add($this->page, array_diff($rel_new, $rel_old), $rel_auto); self::remove($this->page, array_diff($rel_old, $rel_new)); global $autolink, $nowikiname, $search_non_list; // $page seems newly created, and matches with AutoLink if ($time && !$rel_exist && $autolink && (Utility::isWikiName($page) ? $nowikiname : strlen($page) >= $autolink)) { // Update all, because they __MAY__ refer the $page [HEAVY] $search_non_list = 1; $pages = Search::do_search($page, 'AND', TRUE); foreach ($pages as $_page) { if ($_page !== $page) { $this->update($_page); } } } // $pageが削除されたときに、 foreach (self::getRef($this->page) as $line) { list($ref_page, $ref_auto) = explode("\t", rtrim($line)); // $pageをAutoLinkでしか参照していないページを一斉更新する(おいおい) if ($ref_auto) { self::remove($ref_page, array($page)); } } }