?> <?php // The main area switch ($serendipity["GET"]["action"]) { // User wants to read the diary case "read": if (isset($serendipity['GET']['id'])) { serendipity_printEntries(array(serendipity_fetchEntry("id", $serendipity['GET']['id'])), 1); } else { serendipity_printEntries(serendipity_fetchEntries($serendipity['range'], true, $serendipity['fetchLimit'])); } break; // User searches // User searches case "search": $r = serendipity_searchEntries($serendipity["GET"]["searchTerm"]); if (strlen($serendipity["GET"]["searchTerm"]) <= 3) { echo SEARCH_TOO_SHORT; break; } if ($r === true) { echo sprintf(NO_ENTRIES_BLAHBLAH, $serendipity['GET']['searchTerm']); break; } echo sprintf(YOUR_SEARCH_RETURNED_BLAHBLAH, $serendipity["GET"]["searchTerm"], count($r)); serendipity_printEntries($r); break; // Show the archive // Show the archive case "archives": serendipity_printArchives();
$serendipity['head_subtitle'] = ''; $serendipity['smarty']->assign('head_title', $serendipity['head_title']); $serendipity['smarty']->assign('head_subtitle', $serendipity['head_subtitle']); $serendipity['view'] = '404'; serendipity_header('HTTP/1.0 404 Not found'); serendipity_header('Status: 404 Not found'); } serendipity_printEntries($entry, 1); } else { serendipity_printEntries(serendipity_fetchEntries($serendipity['range'], true, $serendipity['fetchLimit'])); } break; // User searches // User searches case 'search': $r = serendipity_searchEntries($serendipity['GET']['searchTerm']); if (strlen($serendipity['GET']['searchTerm']) <= 3) { $serendipity['smarty']->assign(array('content_message' => SEARCH_TOO_SHORT, 'searchresult_tooShort' => true)); break; } if (is_string($r) && $r !== true) { $serendipity['smarty']->assign(array('content_message' => sprintf(SEARCH_ERROR, $serendipity['dbPrefix'], $r), 'searchresult_error' => true)); break; } elseif ($r === true) { $serendipity['smarty']->assign(array('content_message' => sprintf(NO_ENTRIES_BLAHBLAH, '<span class="searchterm">' . $serendipity['GET']['searchTerm'] . '</span>'), 'searchresult_noEntries' => true)); break; } $serendipity['smarty']->assign(array('content_message' => sprintf(YOUR_SEARCH_RETURNED_BLAHBLAH, '<span class="searchterm">' . $serendipity['GET']['searchTerm'] . '</span>', '<span class="searchresults">' . serendipity_getTotalEntries() . '</span>'), 'searchresult_results' => true, 'searchresult_fullentry' => $serendipity['GET']['fullentry'])); serendipity_printEntries($r); break; // Show the comments
/** * Searches the list of entries by a specific term * * @todo: Allow to show results of staticpage plugins or others * @access public * @param string The searchterm (may contain wildcards) * @param int Restrict the number of results [also uses $serendipity['GET']['page'] for pagination] * @param array Add search Results at the top * @return array Returns the superarray of entries found */ function &serendipity_searchEntries($term, $limit = '', $searchresults = '') { global $serendipity; static $log_queries = false; if ($log_queries) { $fp = fopen($serendipity['serendipityPath'] . '/archives/queries.csv', 'a'); fwrite($fp, date('Y-m-d H:i') . ';' . $_SERVER['REMOTE_ADDR'] . ';' . $term . "\n"); fclose($fp); } $orig_limit = $limit; if ($limit == '') { $limit = $serendipity['fetchLimit']; } if (isset($serendipity['GET']['page']) && $serendipity['GET']['page'] > 1 && !strstr($limit, ',')) { $limit = serendipity_db_limit(($serendipity['GET']['page'] - 1) * $limit, $limit); } $limit = serendipity_db_limit_sql($limit); $term = serendipity_db_escape_string($term); $cond = array(); $relevance_enabled = false; if ($serendipity['dbType'] == 'postgres' || $serendipity['dbType'] == 'pdo-postgres') { $cond['group'] = ''; $cond['distinct'] = 'DISTINCT'; $r = serendipity_db_query("SELECT count(routine_name) AS counter\n FROM information_schema.routines\n WHERE routine_name LIKE 'to_tsvector'\n AND specific_catalog = '" . $serendipity['dbName'] . "'"); if (is_array($r) && $r[0]['counter'] > 0) { $term = str_replace('&', '&', $term); $cond['find_part'] = "(\n to_tsvector('english', title) @@to_tsquery('{$term}') OR\n to_tsvector('english', body) @@to_tsquery('{$term}') OR\n to_tsvector('english', extended) @@to_tsquery('{$term}')\n )"; } else { $cond['find_part'] = "(title ILIKE '%{$term}%' OR body ILIKE '%{$term}%' OR extended ILIKE '%{$term}%')"; } } elseif ($serendipity['dbType'] == 'sqlite' || $serendipity['dbType'] == 'sqlite3') { // Very extensive SQLite search. There currently seems no other way to perform fulltext search in SQLite // But it's better than no search at all :-D $cond['group'] = 'GROUP BY e.id'; $cond['distinct'] = ''; $term = serendipity_mb('strtolower', $term); $cond['find_part'] = "(lower(title) LIKE '%{$term}%' OR lower(body) LIKE '%{$term}%' OR lower(extended) LIKE '%{$term}%')"; } else { $cond['group'] = 'GROUP BY e.id'; $cond['distinct'] = ''; $term = str_replace('"', '"', $term); $relevance_enabled = true; if (preg_match('@["\\+\\-\\*~<>\\(\\)]+@', $term)) { $cond['find_part'] = "MATCH(title,body,extended) AGAINST('{$term}' IN BOOLEAN MODE)"; } else { $cond['find_part'] = "MATCH(title,body,extended) AGAINST('{$term}')"; } } switch ($serendipity['searchsort']) { case 'relevance': if ($relevance_enabled) { $cond['searchorderby'] = $cond['find_part'] . " DESC"; } else { $cond['searchorderby'] = "timestamp DESC"; } break; case 'timestamp': default: $cond['searchorderby'] = "timestamp DESC"; break; } $cond['and'] = " AND isdraft = 'false' " . (!serendipity_db_bool($serendipity['showFutureEntries']) ? " AND timestamp <= " . serendipity_db_time() : ''); serendipity_plugin_api::hook_event('frontend_fetchentries', $cond, array('source' => 'search', 'term' => $term)); serendipity_ACL_SQL($cond, 'limited'); $serendipity['fullCountQuery'] = "\n FROM\n {$serendipity['dbPrefix']}entries e\n LEFT JOIN {$serendipity['dbPrefix']}authors a\n ON e.authorid = a.authorid\n LEFT JOIN {$serendipity['dbPrefix']}entrycat ec\n ON e.id = ec.entryid\n {$cond['joins']}\n WHERE\n ({$cond['find_part']})\n {$cond['and']}"; $querystring = "SELECT {$cond['distinct']}\n {$cond['addkey']}\n e.id,\n e.authorid,\n a.realname AS author,\n e.allow_comments,\n e.moderate_comments,\n a.email,\n e.timestamp,\n e.comments,\n e.title,\n e.body,\n e.extended,\n e.trackbacks,\n e.exflag,\n e.isdraft,\n e.last_modified,\n a.username AS loginname\n {$serendipity['fullCountQuery']}\n {$cond['group']}\n {$cond['having']}\n ORDER BY {$cond['searchorderby']}\n {$limit}"; $search =& serendipity_db_query($querystring); //Add param searchresults at the top and remove duplicates. if (is_array($searchresults)) { $ids_current = array(); foreach ($searchresults as $idx => $data) { $ids_current[$data['id']] = true; } foreach ($search as $idx => $data) { if (isset($ids_current[$data['id']])) { unset($search[$idx]); } } $search = array_merge($searchresults, $search); } //if * wasn't already appended and if there are none or not enough //results, search again for entries containing the searchterm as a part if (strpos($term, '*') === false) { if (!is_array($search)) { return serendipity_searchEntries($term . '*', $orig_limit); } else { if (count($search) < 4) { return serendipity_searchEntries($term . '*', $orig_limit, $search); } } } if (is_array($search)) { serendipity_fetchEntryData($search); } return $search; }
function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks =& $bag->get('event_hooks'); if (isset($hooks[$event])) { switch ($event) { case 'css': if (strpos($eventData, '.serendipity_livesearch_row')) { // class exists in CSS, so a user has customized it and we don't need default return true; } ?> #LSResult { position: absolute; margin-left: 4px; margin-top: 4px; background-color: #fff7e8; } #LSShadow { position: relative; bottom: 1px; right: 1px; color: inherit; border-right: 2px solid #ccc; border-bottom: 2px solid #ccc; } #LSHighlight { background-color: #bdd2ec; color: black; } .serendipity_livesearch_row { margin: 0px; padding-top: 0.5em; padding-bottom: 0.5em; padding-left: 1.5em; padding-right: 1.5em; text-indent: -1em; line-height: 1.4em; } .serendipity_livesearch_result { position: relative; bottom: 2px; border: 1px solid black; right: 2px; padding: 2px; } <?php break; case 'frontend_header': if (!$serendipity['embed'] || $serendipity['embed'] === 'false' || $serendipity['embed'] === false) { echo '<script type="text/javascript" src="' . $serendipity['baseURL'] . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] . '?/' : '') . 'plugin/ls-js"></script>'; } break; case 'quicksearch_plugin': echo '<script type="text/javascript"> lsbase = "' . $serendipity['baseURL'] . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] . '?/' : '') . 'plugin/ls' . ($serendipity['rewrite'] == 'none' ? '_&' : '?') . '"; waittext = "' . PLUGIN_EVENT_LIVESEARCH_WAIT . '"; notfoundtext = "' . PLUGIN_EVENT_LIVESEARCH_NOTFOUND . '"; addLoadEvent(liveSearchInit); </script>'; break; case 'external_plugin': $uri_parts = explode('?', str_replace('&', '&', $eventData)); // Try to get request parameters from eventData name if (!empty($uri_parts[1])) { $reqs = explode('&', $uri_parts[1]); foreach ($reqs as $id => $req) { $val = explode('=', $req); if (empty($_REQUEST[$val[0]])) { $_REQUEST[$val[0]] = $val[1]; } } } $parts = explode('_', $uri_parts[0]); switch ($parts[0]) { case 'ls-js': header('Content-Type: text/javascript'); echo file_get_contents(dirname(__FILE__) . '/serendipity_event_livesearch.js'); break; case 'ls': // header('X-Search: ' . htmlspecialchars($eventData) . ' leads to ' . preg_replace('@[^a-z0-9 \.\-_]@i', '', $_REQUEST['s'])); $res = serendipity_searchEntries($_REQUEST['s']); echo '<?xml version="1.0" encoding="utf-8" ?>'; echo '<div class="serendipity_livesearch_result">'; if (is_array($res) && count($res) > 0) { foreach ($res as $id => $entry) { echo '<div class="serendipity_livesearch_row"><a href="' . serendipity_archiveURL($entry['id'], $entry['title'], 'baseURL', true, array('timestamp' => $entry['timestamp'])) . '">' . htmlspecialchars($entry['title']) . '</a></div>'; } } else { echo '<div class="serendipity_livesearch_row">' . print_r($res, true) . '</div>'; } echo '</div>'; break; } return true; break; default: return false; break; } } else { return false; } }