function showSearch() { global $serendipity; $this->setupDB(); $term = serendipity_db_escape_string($serendipity['GET']['searchTerm']); if ($serendipity['dbType'] == 'postgres') { $group = ''; $distinct = 'DISTINCT'; $find_part = "(c.title ILIKE '%{$term}%' OR c.body ILIKE '%{$term}%')"; } elseif ($serendipity['dbType'] == 'sqlite') { $group = 'GROUP BY id'; $distinct = ''; $term = serendipity_mb('strtolower', $term); $find_part = "(lower(c.title) LIKE '%{$term}%' OR lower(c.body) LIKE '%{$term}%')"; } else { $group = 'GROUP BY id'; $distinct = ''; $term = str_replace('"', '"', $term); if (preg_match('@["\\+\\-\\*~<>\\(\\)]+@', $term)) { $find_part = "MATCH(c.title,c.body) AGAINST('{$term}' IN BOOLEAN MODE)"; } else { $find_part = "MATCH(c.title,c.body) AGAINST('{$term}')"; } } $querystring = "SELECT c.title AS ctitle, c.body, c.author, c.entry_id, c.timestamp AS ctimestamp, c.url, c.type,\n e.id, e.title, e.timestamp\n FROM {$serendipity['dbPrefix']}comments AS c\n LEFT OUTER JOIN {$serendipity['dbPrefix']}entries AS e\n ON e.id = c.entry_id\n WHERE c.status = 'approved'\n AND {$find_part}\n {$group}\n ORDER BY c.timestamp DESC"; $results = serendipity_db_query($querystring, false, 'assoc'); if (!is_array($results)) { if ($results !== 1 && $results !== true) { echo function_exists('serendipity_specialchars') ? serendipity_specialchars($results) : htmlspecialchars($results, ENT_COMPAT, LANG_CHARSET); } $results = array(); } $myAddData = array("from" => "serendipity_plugin_commentsearch:generate_content"); foreach ($results as $idx => $result) { $results[$idx]['permalink'] = serendipity_archiveURL($result['id'], $result['title'], 'baseURL', true, $result); $results[$idx]['comment'] = $result['body']; //(function_exists('serendipity_specialchars') ? serendipity_specialchars(strip_tags($result['body'])) : htmlspecialchars(strip_tags($result['body']), ENT_COMPAT, LANG_CHARSET)); serendipity_plugin_api::hook_event('frontend_display', $results[$idx], $myAddData); // let the template decide, if we want to have tags or not $results[$idx]['commenthtml'] = $results[$idx]['comment']; $results[$idx]['comment'] = strip_tags($results[$idx]['comment']); } $serendipity['smarty']->assign(array('comment_searchresults' => count($results), 'comment_results' => $results)); $filename = 'plugin_commentsearch_searchresults.tpl'; $tfile = serendipity_getTemplateFile($filename, 'serendipityPath'); if (!$tfile) { $tfile = dirname(__FILE__) . '/' . $filename; } $inclusion = $serendipity['smarty']->security_settings[INCLUDE_ANY]; $serendipity['smarty']->security_settings[INCLUDE_ANY] = true; $content = $serendipity['smarty']->fetch('file:' . $tfile); $serendipity['smarty']->security_settings[INCLUDE_ANY] = $inclusion; echo $content; }
/** * Create a HTML SELECT dropdown field which represents all hierarchical comments * * @access public * @param int The entry ID to show comments for * @param array The existing comments for this entry * @param int The ID of the comment that is being referred to (last selection) * @param int The parent ID of the last comment [for recursive usage] * @param int The current nesting/hierarchy level [for recursive usage] * @param string The HTML indention string that gets prepended to a comment [for recursive usage] * @return string The HTML SELECT code */ function serendipity_generateCommentList($id, $comments = NULL, $selected = 0, $parent = 0, $level = 0, $indent = '') { global $serendipity; if (!is_array($comments)) { if (empty($id)) { $comments = array(); } else { $comments = serendipity_fetchComments($id); } } $retval = $parent ? '' : '<select id="serendipity_replyTo" onchange="' . (!empty($serendipity['plugindata']['onchange']) ? $serendipity['plugindata']['onchange'] : '') . '" name="serendipity[replyTo]"><option value="0">[ ' . TOP_LEVEL . ' ]</option>'; $i = 0; foreach ($comments as $comment) { if ($comment['parent_id'] == $parent) { $i++; $retval .= '<option value="' . $comment['id'] . '"' . ($selected == $comment['id'] || isset($serendipity['POST']['replyTo']) && $comment['id'] == $serendipity['POST']['replyTo'] ? ' selected="selected"' : '') . '>' . str_repeat(' ', $level * 2) . '#' . $indent . $i . ': ' . (empty($comment['author']) ? ANONYMOUS : htmlspecialchars($comment['author'])) . ' ' . ON . ' ' . serendipity_mb('ucfirst', serendipity_strftime(DATE_FORMAT_SHORT, $comment['timestamp'])) . "</option>\n"; $retval .= serendipity_generateCommentList($id, $comments, $selected, $comment['id'], $level + 1, $indent . $i . '.'); } } $retval .= $parent ? '' : '</select>'; return $retval; }
function printComments($comments) { if (!is_array($comments) || count($comments) < 1) { return; } foreach ($comments as $i => $comment) { $comment['comment'] = function_exists('serendipity_specialchars') ? serendipity_specialchars(strip_tags($comment['body'])) : htmlspecialchars(strip_tags($comment['body']), ENT_COMPAT, LANG_CHARSET); if (!empty($comment['url']) && substr($comment['url'], 0, 7) != 'http://' && substr($comment['url'], 0, 8) != 'https://') { $comment['url'] = 'http://' . $comment['url']; } serendipity_plugin_api::hook_event('frontend_display', $comment); $name = empty($comment['username']) ? ANONYMOUS : $comment['username']; $body = $comment['comment']; $this->pdf->SetFont('Arial', '', 9); $html = $this->prep_out($body . "\n" . ' ' . $name . ' ' . ON . ' ' . serendipity_mb('ucfirst', $this->prep_out(serendipity_strftime('%b %e %Y, %H:%M', $comment['timestamp'])))) . "\n"; if (serendipity_db_bool($this->get_config('html2pdf'))) { $this->pdf->WriteHTML($html); } else { $this->pdf->Write(3, $html); } $this->pdf->Ln(); $this->pdf->Ln(); } }
// Can be set through serendipity_config_local.inc.php if (!isset($serendipity['dashboardCommentsLimit'])) { $serendipity['dashboardCommentsLimit'] = 5; } if (!isset($serendipity['dashboardLimit'])) { $serendipity['dashboardLimit'] = 5; } if (!isset($serendipity['dashboardDraftLimit'])) { $serendipity['dashboardDraftLimit'] = 5; } $comments = serendipity_db_query("SELECT c.*, e.title FROM {$serendipity['dbPrefix']}comments c\n LEFT JOIN {$serendipity['dbPrefix']}entries e ON (e.id = c.entry_id)\n ORDER BY c.id DESC LIMIT " . (int) $serendipity['dashboardCommentsLimit']); if (is_array($comments) && count($comments) > 0) { foreach ($comments as &$comment) { $comment['entrylink'] = serendipity_archiveURL($comment['entry_id'], 'comments', 'serendipityHTTPPath', true) . '#c' . $comment['id']; $comment['fullBody'] = $comment['body']; $comment['summary'] = serendipity_mb('substr', $comment['body'], 0, 100); if (strlen($comment['fullBody']) > strlen($comment['summary'])) { $comment['excerpt'] = true; // When summary is not the full body, strip HTML tags from summary, as it might break and leave unclosed HTML. $comment['fullBody'] = nl2br(serendipity_specialchars($comment['fullBody'])); $comment['summary'] = nl2br(strip_tags($comment['summary'])); } } } $data['comments'] = $comments; $entries = serendipity_fetchEntries(false, false, (int) $serendipity['dashboardLimit'], true, false, 'timestamp DESC', 'e.timestamp >= ' . serendipity_serverOffsetHour()); $entriesAmount = count($entries); if ($entriesAmount < (int) $serendipity['dashboardDraftLimit']) { // there is still space for drafts $drafts = serendipity_fetchEntries(false, false, (int) $serendipity['dashboardDraftLimit'] - $entriesAmount, true, false, 'timestamp DESC', "isdraft = 'true' AND e.timestamp <= " . serendipity_serverOffsetHour()); if (is_array($entries) && is_array($drafts)) {
function showElementCommentlist($where, $limit) { global $serendipity; $summaryLength = 200; $i = 0; if (version_compare(substr($serendipity['version'], 0, 3), '1.6') >= 0) { $comments = serendipity_fetchComments(null, $limit, 'co.id DESC', true, 'NORMAL', $where); } else { $comments = serendipity_db_query("SELECT c.*, e.title FROM {$serendipity['dbPrefix']}comments c\n LEFT JOIN {$serendipity['dbPrefix']}entries e ON (e.id = c.entry_id)\n WHERE 1 = 1 " . $where . (!serendipity_checkPermission('adminEntriesMaintainOthers') ? 'AND e.authorid = ' . (int) $serendipity['authorid'] : '') . "\n ORDER BY c.id DESC LIMIT {$limit}"); } if (!is_array($comments)) { return; } if (count($comments) == 0) { return; } echo '<table width="100%" cellpadding="3" border="0" cellspacing="0">'; foreach ($comments as $rs) { $i++; $comment = array('fullBody' => $rs['body'], 'summary' => serendipity_mb('substr', $rs['body'], 0, $summaryLength), 'status' => $rs['status'], 'type' => $rs['type'], 'id' => $rs['id'], 'title' => $rs['title'], 'timestamp' => $rs['timestamp'], 'referer' => $rs['referer'], 'url' => $rs['url'], 'ip' => $rs['ip'], 'entry_url' => serendipity_archiveURL($rs['entry_id'], $rs['title']), 'email' => $rs['email'], 'author' => empty($rs['author']) ? ANONYMOUS : $rs['author'], 'entry_id' => $rs['entry_id']); $entrylink = serendipity_archiveURL($comment['entry_id'], 'comments', 'serendipityHTTPPath', true) . '#c' . $comment['id']; if (strlen($comment['fullBody']) > strlen($comment['summary'])) { $comment['summary'] .= ' ...'; $comment['excerpt'] = true; // When summary is not the full body, strip HTML tags from summary, as it might break and leave unclosed HTML. $comment['fullBody'] = nl2br(function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['fullBody']) : htmlspecialchars($comment['fullBody'], ENT_COMPAT, LANG_CHARSET)); $comment['summary'] = nl2br(strip_tags($comment['summary'])); } else { $comment['excerpt'] = false; $comment['fullBody'] = $comment['summary'] = nl2br(function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['fullBody']) : htmlspecialchars($comment['fullBody'], ENT_COMPAT, LANG_CHARSET)); } #serendipity_plugin_api::hook_event('backend_view_comment', $comment, '&serendipity[page]='. $page . $searchString); $class = 'serendipity_admin_list_item_' . ($i % 2 == 0 ? 'even' : 'uneven'); if ($comment['status'] == 'pending' || $comment['status'] === 'confirm') { $class .= ' serendipity_admin_comment_pending'; } $header_class = $comment['status'] == 'pending' || $comment['status'] === 'confirm' ? 'serendipityAdminMsgNote serendipity_admin_comment_pending_header' : ''; ?> <tr> <td class="<?php echo $header_class; ?> "> <?php if ($header_class == 'serendipityAdminMsgNote serendipity_admin_comment_pending_header') { ?> <img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="<?php echo serendipity_getTemplateFile('admin/img/admin_msg_note.png'); ?> " alt="" /> <?php } ?> <a name="c<?php echo $comment['id']; ?> "></a> <?php echo ($comment['type'] == 'NORMAL' ? COMMENT : ($comment['type'] == 'TRACKBACK' ? TRACKBACK : PINGBACK)) . ' #' . $comment['id'] . ', ' . IN_REPLY_TO . ' <strong><a href="' . $comment['entry_url'] . '">' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['title']) : htmlspecialchars($comment['title'], ENT_COMPAT, LANG_CHARSET)) . '</a></strong>, ' . ON . ' ' . serendipity_formatTime('%b %e %Y, %H:%M', $comment['timestamp']); ?> </td> </tr> <tr> <td class="serendipity_admin_list_item <?php echo $class; ?> " id="comment_<?php echo $comment['id']; ?> "> <table width="100%" cellspacing="0" cellpadding="3" border="0"> <tr> <td width="40%"><strong><?php echo AUTHOR; ?> </strong>: <?php echo (function_exists('serendipity_specialchars') ? serendipity_specialchars(serendipity_truncateString($comment['author'], 30)) : htmlspecialchars(serendipity_truncateString($comment['author'], 30), ENT_COMPAT, LANG_CHARSET)) . $comment['action_author']; ?> </td> <td><strong><?php echo EMAIL; ?> </strong>: <?php if (empty($comment['email'])) { echo 'N/A'; } else { ?> <a href="mailto:<?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['email']) : htmlspecialchars($comment['email'], ENT_COMPAT, LANG_CHARSET); ?> " title="<?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['email']) : htmlspecialchars($comment['email'], ENT_COMPAT, LANG_CHARSET); ?> "><?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars(serendipity_truncateString($comment['email'], 30)) : htmlspecialchars(serendipity_truncateString($comment['email'], 30), ENT_COMPAT, LANG_CHARSET); ?> </a> <?php } ?> <?php echo $comment['action_email']; ?> </td> </tr> <tr> <td width="40%"><strong>IP</strong>: <?php if (empty($comment['ip'])) { echo '0.0.0.0'; } else { echo function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['ip']) : htmlspecialchars($comment['ip'], ENT_COMPAT, LANG_CHARSET); } ?> <?php echo $comment['action_ip']; ?> </td> <td><strong><?php echo URL; ?> </strong>: <?php if (empty($comment['url'])) { echo 'N/A'; } else { ?> <a href="<?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['url']) : htmlspecialchars($comment['url'], ENT_COMPAT, LANG_CHARSET); ?> " title="<?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['url']) : htmlspecialchars($comment['url'], ENT_COMPAT, LANG_CHARSET); ?> " target="_blank"><?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars(serendipity_truncateString($comment['url'], 30)) : htmlspecialchars(serendipity_truncateString($comment['url'], 30), ENT_COMPAT, LANG_CHARSET); ?> </a> <?php } ?> <?php echo $comment['action_url']; ?> </td> </tr> <tr> <td width="40%"> </td> <td><strong><?php echo REFERER; ?> </strong>: <?php if (empty($comment['referer'])) { echo 'N/A'; } else { ?> <a href="<?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['referer']) : htmlspecialchars($comment['referer'], ENT_COMPAT, LANG_CHARSET); ?> " title="<?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['referer']) : htmlspecialchars($comment['referer'], ENT_COMPAT, LANG_CHARSET); ?> " target="_blank"><?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars(serendipity_truncateString($comment['referer'], 30)) : htmlspecialchars(serendipity_truncateString($comment['referer'], 30), ENT_COMPAT, LANG_CHARSET); ?> </a> <?php } ?> <?php echo $comment['action_referer']; ?> </td> <tr> <td style="border-top: 1px solid #CCCCCC; border-bottom: 1px solid #CCCCCC" colspan="3"> <div id="<?php echo $comment['id']; ?> _summary"><?php echo $comment['summary']; ?> </div> <div id="<?php echo $comment['id']; ?> _full" style="display: none"><?php echo $comment['fullBody']; ?> </div> </td> </tr> </table> <?php if (($comment['status'] == 'pending' || $comment['status'] === 'confirm') && !serendipity_db_bool($this->get_config('read_only'))) { ?> <a href="?serendipity[action]=admin&serendipity[adminModule]=comments&serendipity[adminAction]=approve&serendipity[id]=<?php echo $comment['id']; ?> &<?php echo serendipity_setFormToken('url'); ?> " class="serendipityIconLink" title="<?php echo APPROVE; ?> "><img src="<?php echo serendipity_getTemplateFile('admin/img/accept.png'); ?> " alt="<?php echo APPROVE; ?> " /><?php echo APPROVE; ?> </a> <?php } ?> <?php if ($comment['status'] == 'approved' && !serendipity_db_bool($this->get_config('read_only'))) { ?> <a href="?serendipity[action]=admin&serendipity[adminModule]=comments&serendipity[adminAction]=pending&serendipity[id]=<?php echo $comment['id']; ?> &<?php echo serendipity_setFormToken('url'); ?> " class="serendipityIconLink" title="<?php echo SET_TO_MODERATED; ?> "><img src="<?php echo serendipity_getTemplateFile('admin/img/clock.png'); ?> " alt="<?php echo SET_TO_MODERATED; ?> " /><?php echo SET_TO_MODERATED; ?> </a> <?php } ?> <?php if ($comment['excerpt']) { ?> <a href="#c<?php echo $comment['id']; ?> " onclick="FT_toggle(<?php echo $comment['id']; ?> ); return false;" title="<?php echo VIEW; ?> " class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/zoom.png'); ?> " alt="<?php echo TOGGLE_ALL; ?> " /><span id="<?php echo $comment['id']; ?> _text"><?php echo TOGGLE_ALL; ?> </span></a> <?php } ?> <a target="_blank" href="<?php echo $entrylink; ?> " title="<?php echo VIEW; ?> " class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/zoom.png'); ?> " alt="<?php echo VIEW; ?> " /><?php echo VIEW; ?> </a> <a href="?serendipity[action]=admin&serendipity[adminModule]=comments&serendipity[adminAction]=edit&serendipity[id]=<?php echo $comment['id']; ?> &serendipity[entry_id]=<?php echo $comment['entry_id']; ?> &<?php echo serendipity_setFormToken('url'); ?> " title="<?php echo EDIT; ?> " class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/edit.png'); ?> " alt="<?php echo EDIT; ?> " /><?php echo EDIT; ?> </a> <?php if (!serendipity_db_bool($this->get_config('read_only'))) { ?> <a href="?serendipity[action]=admin&serendipity[adminModule]=comments&serendipity[adminAction]=delete&serendipity[id]=<?php echo $comment['id']; ?> &serendipity[entry_id]=<?php echo $comment['entry_id']; ?> &<?php echo serendipity_setFormToken('url'); ?> " onclick='return confirm("<?php echo sprintf(COMMENT_DELETE_CONFIRM, $comment['id'], function_exists('serendipity_specialchars') ? serendipity_specialchars($comment['author']) : htmlspecialchars($comment['author'], ENT_COMPAT, LANG_CHARSET)); ?> ")' title="<?php echo DELETE; ?> " class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/delete.png'); ?> " alt="<?php echo DELETE; ?> " /><?php echo DELETE; ?> </a> <?php } ?> <a target="_blank" onclick="cf = window.open(this.href, 'CommentForm', 'width=800,height=600,toolbar=no,scrollbars=1,scrollbars,resize=1,resizable=1'); cf.focus(); return false;" href="?serendipity[action]=admin&serendipity[adminModule]=comments&serendipity[adminAction]=reply&serendipity[id]=<?php echo $comment['id']; ?> &serendipity[entry_id]=<?php echo $comment['entry_id']; ?> &serendipity[noBanner]=true&serendipity[noSidebar]=true&<?php echo serendipity_setFormToken('url'); ?> " title="<?php echo REPLY; ?> " class="serendipityIconLink"><img src="<?php echo serendipity_getTemplateFile('admin/img/user_editor.png'); ?> " alt="<?php echo REPLY; ?> " /><?php echo REPLY; ?> </a> <?php echo $comment['action_more']; ?> </td> </tr> <?php } echo '</table>'; }
/** * 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; }
/** * Create an excerpt for a trackback to send * * @access public * @param string Input text * @return string Output text */ function serendipity_trackback_excerpt($text) { return serendipity_mb('substr', strip_tags($text), 0, 255); }
function showSearch() { global $serendipity; $term = serendipity_db_escape_string($serendipity['GET']['searchTerm']); if ($serendipity['dbType'] == 'postgres') { $group = ''; $distinct = 'DISTINCT'; $find_part = "(headline ILIKE '%{$term}%' OR content ILIKE '%{$term}%')"; } elseif ($serendipity['dbType'] == 'sqlite' || $serendipity['dbType'] == 'sqlite3' || $serendipity['dbType'] == 'pdo-sqlite') { $group = 'GROUP BY id'; $distinct = ''; $term = serendipity_mb('strtolower', $term); $find_part = "(lower(headline) LIKE '%{$term}%' OR lower(content) LIKE '%{$term}%')"; } else { $group = 'GROUP BY id'; $distinct = ''; $term = str_replace('"', '"', $term); if (preg_match('@["\\+\\-\\*~<>\\(\\)]+@', $term)) { $find_part = "MATCH(headline,content) AGAINST('{$term}' IN BOOLEAN MODE)"; } else { $find_part = "MATCH(headline,content) AGAINST('{$term}')"; } } $querystring = "SELECT {$distinct} s.*, a.realname\n FROM {$serendipity['dbPrefix']}staticpages AS s\n LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a\n ON a.authorid = s.authorid\n WHERE {$find_part}\n AND s.publishstatus = 1\n AND s.pass = ''\n {$group}\n ORDER BY timestamp DESC"; $results = serendipity_db_query($querystring); if (!is_array($results)) { if ($results !== 1 && $results !== true) { echo '<div style="margin: 1em 2em;">' . $results . '</div>'; //htmlspecialchars($results); // htmlspecialchars already done by serendipity_db_query() } $results = array(); } $serendipity['smarty']->assign(array('staticpage_searchresults' => count($results), 'staticpage_results' => $results)); $filename = 'plugin_staticpage_searchresults.tpl'; // use nativ API here - extends s9y version >= 1.3' $content = $this->parseTemplate($filename); echo $content; }
function generate_content(&$title) { global $serendipity; $title = $this->get_config('title', $this->title); $intro = $this->get_config('intro'); $outro = $this->get_config('outro'); $maxlength = $this->get_config('maxlength'); $max_entries = $this->get_config('max_entries'); $min_age = $this->get_config('min_age'); $max_age = $this->get_config('max_age'); $specialage = $this->get_config('specialage'); $displaydate = $this->get_config('displaydate', 'true'); $dateformat = $this->get_config('dateformat'); $full = serendipity_db_bool($this->get_config('full')); $displayauthor = serendipity_db_bool($this->get_config('displayauthor', false)); if (!is_numeric($min_age) || $min_age < 0 || $specialage == 'year') { $min_age = 365 + date('L', serendipity_serverOffsetHour()); } if (!is_numeric($max_age) || $max_age < 1 || $specialage == 'year') { $max_age = 365 + date('L', serendipity_serverOffsetHour()); } if (!is_numeric($max_entries) || $max_entries < 1) { $max_entries = 5; } if (!is_numeric($maxlength) || $maxlength < 0) { $maxlength = 30; } if (strlen($dateformat) < 1) { $dateformat = '%a, %d.%m.%Y %H:%M'; } $oldLim = $serendipity['fetchLimit']; $nowts = serendipity_serverOffsetHour(); $maxts = mktime(23, 59, 59, date('m', $nowts), date('d', $nowts), date('Y', $nowts)); $mints = mktime(0, 0, 0, date('m', $nowts), date('d', $nowts), date('Y', $nowts)); $e = serendipity_fetchEntries(array($mints - $max_age * 86400, $maxts - $min_age * 86400), $full, $max_entries); $serendipity['fetchLimit'] = $oldLim; echo empty($intro) ? '' : '<div class="serendipity_history_intro">' . $intro . '</div>' . "\n"; if (!is_array($e)) { return false; } if (($e_c = count($e)) == 0) { return false; } for ($x = 0; $x < $e_c; $x++) { $url = serendipity_archiveURL($e[$x]['id'], $e[$x]['title'], 'serendipityHTTPPath', true, array('timestamp' => $e[$x]['timestamp'])); $date = $displaydate == '0' ? '' : serendipity_strftime($dateformat, $e[$x]['timestamp']); $author = $displayauthor ? $e[$x]['author'] . ': ' : ''; echo '<div class="serendipity_history_info">'; if ($displayauthor) { echo '<span class="serendipity_history_author">' . $author . ' </span>'; } if ($displaydate) { echo '<span class="serendipity_history_date">' . $date . ' </span>'; } $t = $maxlength == 0 || strlen($e[$x]['title']) <= $maxlength ? $e[$x]['title'] : trim(serendipity_mb('substr', $e[$x]['title'], 0, $maxlength - 3)) . ' [...]'; echo '<a href="' . $url . '" title="' . str_replace("'", "`", serendipity_specialchars($e[$x]['title'])) . '">"' . serendipity_specialchars($t) . '"</a></div>'; if ($full) { echo '<div class="serendipity_history_body">' . strip_tags($e[$x]['body']) . '</div>'; } } echo empty($outro) ? '' : '<div class="serendipity_history_outro">' . $outro . '</div>'; }
/** * A wrapper function call for formatting Timestamps. * * Utilizes serendipity_strftime() and prepares the output timestamp with a few tweaks, and applies automatic uppercasing of the return. * * @see serendipity_strftime() * @param string Output format for the timestamp * @param int Timestamp to use for displaying * @param boolean Indicates, if timezone calculations shall be used. * @param boolean Whether to use strftime or simply date * @return string The formatted timestamp */ function serendipity_formatTime($format, $time, $useOffset = true, $useDate = false) { static $cache; if (!isset($cache)) { $cache = array(); } if (!isset($cache[$format])) { $cache[$format] = $format; if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $cache[$format] = str_replace('%e', '%d', $cache[$format]); } } return serendipity_mb('ucfirst', serendipity_strftime($cache[$format], (int) $time, $useOffset, $useDate)); }
function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks =& $bag->get('event_hooks'); if (isset($hooks[$event])) { switch ($event) { case 'backend_sidebar_entries': if ($serendipity['version'][0] < 2) { ?> <li class="serendipitySideBarMenuLink serendipitySideBarMenuEntryLinks"><a href="?serendipity[adminModule]=event_display&serendipity[adminAction]=adminnotes"><?php echo PLUGIN_ADMINNOTES_TITLE; ?> </a></li> <?php } // Serendipity 2.0 now uses the new backend_sidebar_admin hook break; case 'backend_sidebar_admin': if ($serendipity['version'][0] > 1) { ?> <li><a href="?serendipity[adminModule]=event_display&serendipity[adminAction]=adminnotes"><?php echo PLUGIN_ADMINNOTES_TITLE; ?> </a></li> <?php } break; case 'backend_sidebar_entries_event_display_adminnotes': $this->shownotes(); break; case 'js_backend': ?> /* serendipity_event_adminnotes (quicknotes) start */ function fulltext_toggle(id) { if ( document.getElementById(id + '_full').style.display == '' ) { document.getElementById(id + '_full').style.display='none'; document.getElementById(id + '_summary').style.display=''; document.getElementById(id + '_text').innerHTML = '<?php echo TOGGLE_ALL; ?> '; } else { document.getElementById(id + '_full').style.display=''; document.getElementById(id + '_summary').style.display='none'; document.getElementById(id + '_text').innerHTML = '<?php echo HIDE; ?> '; } return false; } /* serendipity_event_adminnotes (quicknotes) end */ <?php break; case 'backend_frontpage_display': if ($serendipity['version'][0] > 1) { break; } ?> <script type="text/javascript"> function fulltext_toggle(id) { if ( document.getElementById(id + '_full').style.display == '' ) { document.getElementById(id + '_full').style.display='none'; document.getElementById(id + '_summary').style.display=''; document.getElementById(id + '_text').innerHTML = '<?php echo TOGGLE_ALL; ?> '; } else { document.getElementById(id + '_full').style.display=''; document.getElementById(id + '_summary').style.display='none'; document.getElementById(id + '_text').innerHTML = '<?php echo HIDE; ?> '; } return false; } </script> <?php $cutoff = $this->get_config('cutoff'); $notes = $this->getMyNotes(); $zoom = serendipity_getTemplateFile('admin/img/zoom.png'); if (is_array($notes)) { foreach ($notes as $id => $note) { echo '<div class="serendipity_note note_' . $this->output($note['notetype']) . ' note_owner_' . $note['authorid'] . ($serendipity['COOKIE']['lastnote'] < $note['noteid'] ? ' note_new' : '') . '">' . "\n"; echo ' <div class="note_subject"><strong>' . $this->output($note['subject']) . '</strong> ' . POSTED_BY . ' ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($note['realname']) : htmlspecialchars($note['realname'], ENT_COMPAT, LANG_CHARSET)) . ' ' . ON . ' ' . serendipity_strftime(DATE_FORMAT_SHORT, $note['notetime']) . '</div>' . "\n"; if (strlen($note['body']) > $cutoff) { $output = $this->output($note['body']); echo ' <div id="' . $id . '_full" style="display: none" class="note_body">' . $output . '</div>' . "\n"; echo ' <div id="' . $id . '_summary" class="note_body">' . serendipity_mb('substr', $output, 0, $cutoff) . '...</div>' . "\n"; echo ' <div class="note_summarylink"><a href="#' . $id . '_full" onclick="fulltext_toggle(' . $id . '); return false;" title="' . VIEW . '" class="serendipityIconLink"><img src="' . $zoom . '" alt="' . TOGGLE_ALL . '" /><span id="' . $id . '_text">' . TOGGLE_ALL . '</span></a></div>'; } else { echo ' <div class="note_body">' . $this->output($note['body']) . '</div>' . "\n"; } echo "</div>\n"; } serendipity_JSsetCookie('lastnote', $notes[0]['noteid']); } break; case 'backend_dashboard': $cutoff = $this->get_config('cutoff'); $notes = $this->getMyNotes(); if (is_array($notes)) { ?> <section id="dashboard_quicknotes" class="equal_heights quick_list dashboard_widget"> <h3><?php echo PLUGIN_ADMINNOTES_TITLE; ?> </h3> <ol class="plainList"> <?php foreach ($notes as $id => $note) { ?> <li class="serendipity_note note_<?php echo $this->output($note['notetype']); ?> note_owner_<?php echo $note['authorid'] . ($serendipity['COOKIE']['lastnote'] < $note['noteid'] ? ' note_new' : ''); ?> "> <div class="note_subject"> <h3><?php echo $this->output($note['subject']); ?> </h3> <?php echo POSTED_BY . ' ' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($note['realname']) : htmlspecialchars($note['realname'], ENT_COMPAT, LANG_CHARSET)) . ' ' . ON . ' ' . serendipity_strftime(DATE_FORMAT_SHORT, $note['notetime']) . "\n"; ?> </div> <?php if (strlen($note['body']) > $cutoff) { $output = $this->output($note['body']); ?> <div id="<?php echo $id; ?> _full" style="display: none" class="note_body"> <?php echo $output . "\n"; ?> </div> <div id="<?php echo $id; ?> _summary" class="note_body"> <?php echo serendipity_mb('substr', $output, 0, $cutoff) . "…\n"; ?> </div> <div class="note_summarylink"> <button class="button_link toggle_comment_full" type="button" onclick="fulltext_toggle(<?php echo $id; ?> ); return false;" data-href="#qn<?php echo $id; ?> _full" title="<?php echo TOGGLE_ALL; ?> "><span class="icon-right-dir"></span><span class="visuallyhidden"> <?php echo TOGGLE_ALL; ?> </span></button> </div> <?php } else { ?> <div class="note_body"> <?php echo $this->output($note['body']) . "\n"; ?> </div> <?php } ?> </li> <?php } ?> </ol> </section> <?php serendipity_JSsetCookie('lastnote', $notes[0]['noteid']); } break; case 'css_backend': if (!strpos($eventData, '.note_')) { echo "\n/* plugin adminnotes start */\n"; // class exists in CSS, so a user has customized it and we don't need default if ($serendipity['version'][0] < 2) { echo file_get_contents(dirname(__FILE__) . '/notes.css'); } else { ?> .note_subject { margin: 0px 0px 1em; } .note_subject h3 { line height: 1.6; margin: 0; } .note_new { border: 2px solid rgb(0, 255, 0); margin: -0.2em; padding: 0.2em; } <?php } echo "/* plugin adminnotes end */\n\n"; } break; } } return true; }
$data['commentsPerPage'] = $commentsPerPage; $data['totalComments'] = $totalComments; $data['pages'] = $pages; $data['page'] = $page; $data['linkPrevious'] = $linkPrevious; $data['linkNext'] = $linkNext; $data['searchString'] = $searchString; $data['filter_vals'] = $filter_vals; $data['sql'] = $sql; $data['c_type'] = $c_type; $i = 0; $comments = array(); if (is_array($sql)) { foreach ($sql as $rs) { $i++; $comment = array('fullBody' => $rs['body'], 'summary' => serendipity_mb('substr', $rs['body'], 0, $summaryLength), 'status' => $rs['status'], 'type' => $rs['type'], 'id' => $rs['id'], 'title' => $rs['title'], 'timestamp' => $rs['timestamp'], 'pubdate' => date("c", (int) $rs['timestamp']), 'referer' => $rs['referer'], 'url' => $rs['url'], 'ip' => $rs['ip'], 'entry_url' => serendipity_archiveURL($rs['entry_id'], $rs['title']), 'email' => $rs['email'], 'author' => empty($rs['author']) ? ANONYMOUS : $rs['author'], 'entry_id' => $rs['entry_id'], 'subscribed' => $rs['subscribed']); $entrylink = serendipity_archiveURL($comment['entry_id'], 'comments', 'serendipityHTTPPath', true) . '#c' . $comment['id']; $comment['entrylink'] = $entrylink; if (strlen($comment['fullBody']) > strlen($comment['summary'])) { $comment['summary'] .= ' ...'; $comment['excerpt'] = true; // When summary is not the full body, strip HTML tags from summary, as it might break and leave unclosed HTML. $comment['fullBody'] = nl2br(serendipity_specialchars($comment['fullBody'])); $comment['summary'] = nl2br(strip_tags($comment['summary'])); } else { $comment['excerpt'] = false; $comment['fullBody'] = $comment['summary'] = nl2br(serendipity_specialchars($comment['fullBody'])); } serendipity_plugin_api::hook_event('backend_view_comment', $comment, '&serendipity[page]=' . $page . $searchString); $class = 'serendipity_admin_list_item_' . ($i % 2 == 0 ? 'even' : 'uneven'); if ($comment['status'] == 'pending') {
} } if (!empty($serendipity['GET']['filter']['body'])) { $term = serendipity_db_escape_string($serendipity['GET']['filter']['body']); if ($serendipity['dbType'] == 'postgres' || $serendipity['dbType'] == 'pdo-postgres') { $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); $filter[] = "( \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 { $filter[] = "(title ILIKE '%{$term}%' OR body ILIKE '%{$term}%' OR extended ILIKE '%{$term}%')"; } $full = true; } elseif ($serendipity['dbType'] == 'sqlite' || $serendipity['dbType'] == 'sqlite3' || $serendipity['dbType'] == 'pdo-sqlite' || $serendipity['dbType'] == 'sqlite3oo') { $term = str_replace('*', '%', $term); $term = serendipity_mb('strtolower', $term); $filter[] = "(lower(title) LIKE '%{$term}%' OR lower(body) LIKE '%{$term}%' OR lower(extended) LIKE '%{$term}%')"; $full = true; } else { if (preg_match('@["\\+\\-\\*~<>\\(\\)]+@', $term)) { $filter[] = "MATCH (title,body,extended) AGAINST ('" . $term . "' IN BOOLEAN MODE)"; } else { $filter[] = "MATCH (title,body,extended) AGAINST ('" . $term . "')"; } $full = true; } } $filter_sql = implode(' AND ', $filter); // Fetch the entries $entries = serendipity_fetchEntries(false, false, serendipity_db_limit($offSet, $perPage + 1), true, false, $orderby, $filter_sql); $users = serendipity_fetchUsers('', 'hidden', true);
function showSearch() { global $serendipity; $term = serendipity_db_escape_string($serendipity['GET']['searchTerm']); if ($serendipity['dbType'] == 'postgres') { $group = ''; $distinct = 'DISTINCT'; $find_part = "(question ILIKE '%{$term}%' OR answer ILIKE '%{$term}%')"; } elseif ($serendipity['dbType'] == 'sqlite') { $group = 'GROUP BY id'; $distinct = ''; $term = serendipity_mb('strtolower', $term); $find_part = "(lower(question) LIKE '%{$term}%' OR lower(answer) LIKE '%{$term}%')"; } else { $group = 'GROUP BY id'; $distinct = ''; $term = str_replace('"', '"', $term); if (preg_match('@["\\+\\-\\*~<>\\(\\)]+@', $term)) { $find_part = "MATCH(question,answer) AGAINST('{$term}' IN BOOLEAN MODE)"; } else { $find_part = "MATCH(question,answer) AGAINST('{$term}')"; } } $querystring = "SELECT {$distinct} f.*\n FROM {$serendipity['dbPrefix']}faqs AS f\n WHERE {$find_part}\n {$group}\n ORDER BY changedate DESC"; $results = serendipity_db_query($querystring); if (!is_array($results)) { if ($results !== 1 && $results !== true) { echo function_exists('serendipity_specialchars') ? serendipity_specialchars($results) : htmlspecialchars($results, ENT_COMPAT, LANG_CHARSET); } $results = array(); } if ($serendipity['rewrite'] == 'none') { $pluginpath = $serendipity['indexFile'] . '?/' . $serendipity['permalinkPluginPath'] . '/' . $this->get_config('faqurl', 'faqs'); } else { $pluginpath = $serendipity['permalinkPluginPath'] . '/' . $this->get_config('faqurl', 'faqs'); } $serendipity['smarty']->assign(array('faq_searchresults' => count($results), 'faq_results' => $results, 'faq_pluginpath' => $pluginpath)); $filename = 'plugin_faq_searchresults.tpl'; $tfile = serendipity_getTemplateFile($filename, 'serendipityPath'); if (!$tfile) { $tfile = dirname(__FILE__) . '/' . $filename; } $inclusion = $serendipity['smarty']->security_settings[INCLUDE_ANY]; $serendipity['smarty']->security_settings[INCLUDE_ANY] = true; $content = $serendipity['smarty']->fetch('file:' . $tfile); $serendipity['smarty']->security_settings[INCLUDE_ANY] = $inclusion; echo $content; }
<?php if (!empty($header_class)) { ?> <img style="width: 22px; height: 22px; border: 0px; padding-right: 4px; vertical-align: middle" src="<?php echo serendipity_getTemplateFile('admin/img/admin_msg_note.png'); ?> " alt="" /> <?php } ?> <a name="c<?php echo $comment['id']; ?> "></a> <?php echo ($comment['type'] == 'NORMAL' ? COMMENT : ($comment['type'] == 'TRACKBACK' ? TRACKBACK : PINGBACK)) . ' #' . $comment['id'] . ', ' . IN_REPLY_TO . ' <strong><a href="' . $comment['entry_url'] . '">' . htmlspecialchars($comment['title']) . '</a></strong>, ' . ON . ' ' . serendipity_mb('ucfirst', serendipity_strftime('%b %e %Y, %H:%M', $comment['timestamp'])); ?> </td> </tr> <tr> <td class="serendipity_admin_list_item <?php echo $class; ?> " id="comment_<?php echo $comment['id']; ?> "> <table width="100%" cellspacing="0" cellpadding="3" border="0"> <tr> <td rowspan="3" width="20" align="center"><input class="input_checkbox" type="checkbox" name="serendipity[delete][<?php echo $comment['id'];
function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks =& $bag->get('event_hooks'); if (isset($hooks[$event])) { switch ($event) { case 'backend_entry_updertEntry': if (isset($serendipity['POST']['no_save'])) { $eventData['error'] = true; } return true; break; case 'backend_entry_presave': if (!isset($serendipity['POST']['properties']) || !is_array($serendipity['POST']['properties']) || !isset($eventData['id']) || empty($serendipity['POST']['properties']['lang_selected'])) { return true; } // Restore native language version, ONLY if a different language is being submitted. $restore = serendipity_db_query("SELECT title, body, extended FROM {$serendipity['dbPrefix']}entries WHERE id = " . (int) $eventData['id']); if (is_array($restore)) { foreach ($restore as $row) { foreach ($this->switch_keys as $restorekey) { $eventData[$restorekey] = $row[$restorekey]; } } } break; case 'backend_publish': case 'backend_save': if (!isset($serendipity['POST']['properties']) || !is_array($serendipity['POST']['properties']) || !isset($eventData['id']) || empty($serendipity['POST']['properties']['lang_selected'])) { return true; } $ls =& $serendipity['POST']['properties']['lang_selected']; $this->supported_properties[] = 'multilingual_title_' . $ls; $serendipity['POST']['properties']['multilingual_title_' . $ls] = $serendipity['POST']['title']; $this->supported_properties[] = 'multilingual_body_' . $ls; $serendipity['POST']['properties']['multilingual_body_' . $ls] = $serendipity['POST']['body']; $this->supported_properties[] = 'multilingual_extended_' . $ls; $serendipity['POST']['properties']['multilingual_extended_' . $ls] = $serendipity['POST']['extended']; // Get existing data $property = serendipity_fetchEntryProperties($eventData['id']); foreach ($this->supported_properties as $prop_key) { $prop_val = isset($serendipity['POST']['properties'][$prop_key]) ? $serendipity['POST']['properties'][$prop_key] : null; if (!isset($property[$prop_key]) && !empty($prop_val)) { $q = "INSERT INTO {$serendipity['dbPrefix']}entryproperties (entryid, property, value) VALUES (" . (int) $eventData['id'] . ", '" . serendipity_db_escape_string($prop_key) . "', '" . serendipity_db_escape_string($prop_val) . "')"; } elseif ($property[$propkey] != $prop_val && !empty($prop_val)) { $q = "UPDATE {$serendipity['dbPrefix']}entryproperties SET value = '" . serendipity_db_escape_string($prop_val) . "' WHERE entryid = " . (int) $eventData['id'] . " AND property = '" . serendipity_db_escape_string($prop_key) . "'"; } else { $q = "DELETE FROM {$serendipity['dbPrefix']}entryproperties WHERE entryid = " . (int) $eventData['id'] . " AND property = '" . serendipity_db_escape_string($prop_key) . "'"; } serendipity_db_query($q); } return true; break; case 'genpage': if (!is_object($serendipity['smarty'])) { // never init in genpage without adding previously set $vars, which is $view etc! serendipity_smarty_init($serendipity['plugindata']['smartyvars']); } if (!defined('Smarty::SMARTY_VERSION')) { $this->tag_title(); // in Smarty 2 only // check this deeply! - since at least for the non-tag banner entry_title this seems to not work here with Smarty 3 - see workaround in frontent_display } if ($serendipity['version'][0] < 2) { $serendipity['smarty']->register_modifier('multilingual_lang', array($this, 'strip_langs')); } else { $serendipity['smarty']->registerPlugin('modifier', 'multilingual_lang', array($this, 'strip_langs')); } return true; break; case 'backend_entryform': if (!empty($this->showlang)) { // language is given (he wants a translation) $props = serendipity_fetchEntryProperties($eventData['id']); // this is a language change, not a save -- we want the DB values // unless the user chooses to retain previous language content if (isset($serendipity['POST']['no_save'])) { foreach ($this->switch_keys as $key) { if (!serendipity_db_bool($this->get_config('copytext', 'true')) || !empty($props['multilingual_' . $key . '_' . $this->showlang])) { $eventData[$key] = $props['multilingual_' . $key . '_' . $this->showlang]; } } } } elseif (!empty($eventData['id'])) { // language is NOT given (he wants the default language) $props = serendipity_fetchEntry('id', $eventData['id'], 1, 1); if (!is_array($props)) { return true; } // this is a language change, not a save -- we want the DB values if (isset($serendipity['POST']['no_save'])) { foreach ($this->switch_keys as $key) { $eventData[$key] = $props[$key]; } } } return true; break; case 'css': if (strpos($eventData, '.serendipity_multilingualInfo')) { // class exists in CSS, so a user has customized it and we don't need default return true; } ?> .serendipity_multilingualInfo { margin-left: auto; margin-right: 0px; text-align: right; font-size: 7pt; display: block; margin-top: 5px; margin-bottom: 0px; } .serendipity_multilingualInfo a { font-size: 7pt; text-decoration: none; } .serendipity_multilingualInfo a:hover { color: green; } <?php return true; break; case 'frontend_display': // cannot use tag_title() method here and use with Smarty3+ only // check for single entry multilingual context only, to set the correct themes banner title if (defined('Smarty::SMARTY_VERSION') && isset($eventData['properties']['multilingual_title_' . $this->showlang]) && serendipity_db_bool($this->get_config('tagged_title', 'true')) && $serendipity['view'] == 'entry') { $serendipity['smarty']->assign('head_title', $eventData['title']); } break; case 'entry_display': if (!is_array($eventData)) { return false; } $place = $this->get_config('placement', 'add_footer'); $msg = '<div class="serendipity_multilingualInfo">' . PLUGIN_EVENT_MULTILINGUAL_SWITCH . ': %s</div>'; if ($addData['extended'] || $addData['preview']) { if ($langs = $this->getLang($eventData[0]['id'], $eventData[0]['properties'])) { if (!empty($this->showlang)) { $props =& $eventData[0]['properties']; foreach ($this->switch_keys as $key) { if (!empty($props['multilingual_' . $key . '_' . $this->showlang])) { $eventData[0][$key] = $props['multilingual_' . $key . '_' . $this->showlang]; } } unset($eventData[0]['properties']['ep_cache_body']); unset($eventData[0]['properties']['ep_cache_extended']); } $eventData[0][$place] .= sprintf($msg, $langs); } } else { $elements = count($eventData); // Walk entry array and insert karma voting line. for ($i = 0; $i < $elements; $i++) { if (!isset($eventData[$i][$place])) { $eventData[$i][$place] = ''; } if (!empty($this->lang_display)) { $this->showlang = $this->lang_display; } if (!empty($this->showlang)) { // Not sure if it's the best way to get translations shown instead of the // original entries $props =& $eventData[$i]['properties']; foreach ($this->switch_keys as $key) { if (!empty($props['multilingual_' . $key . '_' . $this->showlang])) { $eventData[$i][$key] = $props['multilingual_' . $key . '_' . $this->showlang]; } } unset($eventData[$i]['properties']['ep_cache_body']); unset($eventData[$i]['properties']['ep_cache_extended']); } if ($langs = $this->getLang($eventData[$i]['id'], $eventData[$i]['properties'])) { $eventData[$i][$place] .= sprintf($msg, $langs); // this may throw two for the same, eg. when already linked as <en>, them set to POST cookie <en> too in the sidebar selection. // In this case the lang link and the default lang link are both named 'english' } } } // Tagged translation of Blog title and description $this->tag_title(); if (serendipity_db_bool($this->get_config('tagged_entries', 'true'))) { foreach ($eventData as $key => $entry) { if (isset($eventData[$key]['title'])) { $eventData[$key]['title'] = $this->strip_langs($eventData[$key]['title']); $eventData[$key]['body'] = $this->strip_langs($eventData[$key]['body']); if (is_array($eventData[$key]['categories'])) { foreach ($eventData[$key]['categories'] as $ec_key => $ec_val) { $eventData[$key]['categories'][$ec_key]['category_name'] = $this->strip_langs($ec_val['category_name']); } } } } } return true; break; case 'backend_display': if (isset($serendipity['POST']['properties']['lang_selected'])) { $lang_selected = $serendipity['POST']['properties']['lang_selected']; } else { $lang_selected = ''; } $use_lang = $serendipity['languages']; unset($use_lang[$serendipity['lang']]); // Unset 'default' language. Easier handling. $langs = ''; //asort($use_lang); //sorts by value ASC, but if so we should do it everywhere though foreach ($use_lang as $code => $desc) { $langs .= '<option value="' . $code . '" ' . ($lang_selected == $code ? 'selected="selected"' : '') . '>' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($desc) : htmlspecialchars($desc, ENT_COMPAT, LANG_CHARSET)) . '</option>' . "\n"; } if ($serendipity['version'][0] < 2) { ?> <fieldset style="margin: 5px"> <legend><?php echo PLUGIN_EVENT_MULTILINGUAL_TITLE; ?> </legend> <div class="form_field"> <?php } else { ?> <fieldset id="edit_entry_multilingual" class="entryproperties_multilingual" style="margin: 1em 0"> <span class="wrap_legend"><legend><?php echo PLUGIN_EVENT_MULTILINGUAL_TITLE; ?> </legend></span> <div class="form_field"> <?php } if (isset($eventData['id'])) { ?> <label for="serendipity[properties][lang_selected]"><?php echo PLUGIN_EVENT_MULTILINGUAL_CURRENT; ?> </label><br /> <select name="serendipity[properties][lang_selected]" id="properties_lang_selected" /> <option value=""><?php echo USE_DEFAULT; ?> </option> <?php echo $langs; ?> </select> <input class="serendipityPrettyButton input_button" type="submit" name="serendipity[no_save]" value="<?php echo PLUGIN_EVENT_MULTILINGUAL_SWITCH; ?> " /> <?php } else { echo '<span class="msg_notice"><span class="icon-info-circled"></span> ' . PLUGIN_EVENT_MULTILINGUAL_NEEDTOSAVE . "</span>\n"; } ?> </div> </fieldset> <?php return true; break; case 'frontend_entryproperties': if (class_exists('serendipity_event_entryproperties')) { // Fetching of properties is already done there, so this is just for poor users who don't have the entryproperties plugin enabled return true; } $q = "SELECT entryid, property, value FROM {$serendipity['dbPrefix']}entryproperties WHERE entryid IN (" . implode(', ', array_keys($addData)) . ") AND property LIKE '%multilingual_%'"; $properties = serendipity_db_query($q); if (!is_array($properties)) { return true; } foreach ($properties as $idx => $row) { $eventData[$addData[$row['entryid']]]['properties'][$row['property']] = $row['value']; } return true; break; case 'frontend_entries_rss': if (is_array($eventData)) { foreach ($eventData as $i => $entry) { if (!empty($this->lang_display)) { $this->showlang = $this->lang_display; } if (!empty($this->showlang)) { // Not sure if it's the best way to get translations shown instead of the // original entries $props =& $eventData[$i]['properties']; foreach ($this->switch_keys as $key) { if (!empty($props['multilingual_' . $key . '_' . $this->showlang])) { $eventData[$i][$key] = $props['multilingual_' . $key . '_' . $this->showlang]; } } unset($eventData[$i]['properties']['ep_cache_body']); unset($eventData[$i]['properties']['ep_cache_extended']); } } } if (serendipity_db_bool($this->get_config('tagged_entries', 'true'))) { foreach ($eventData as $key => $entry) { $eventData[$key]['title'] = $this->strip_langs($eventData[$key]['title']); $eventData[$key]['body'] = $this->strip_langs($eventData[$key]['body']); } } break; case 'frontend_fetchentries': case 'frontend_fetchentry': if (!empty($this->lang_display)) { $this->showlang = $this->lang_display; } if ($addData['source'] == 'search' && empty($this->showlang) && !empty($_SESSION['last_lang'])) { header('X-SearchLangOverride: ' . $_SESSION['last_lang']); $this->showlang = $_SESSION['last_lang']; } if (empty($this->showlang)) { return; } $cond = "multilingual_body.value AS multilingual_body,\n"; $cond .= "multilingual_extended.value AS multilingual_extended,\n"; $cond .= "multilingual_title.value AS multilingual_title,\n"; if (empty($eventData['addkey'])) { $eventData['addkey'] = $cond; } else { $eventData['addkey'] .= $cond; } $cond = "\nLEFT OUTER JOIN {$serendipity['dbPrefix']}entryproperties multilingual_body\n ON (e.id = multilingual_body.entryid AND multilingual_body.property = 'multilingual_body_" . $this->showlang . "')"; $cond .= "\nLEFT OUTER JOIN {$serendipity['dbPrefix']}entryproperties multilingual_extended\n ON (e.id = multilingual_extended.entryid AND multilingual_extended.property = 'multilingual_extended_" . $this->showlang . "')"; $cond .= "\nLEFT OUTER JOIN {$serendipity['dbPrefix']}entryproperties multilingual_title\n ON (e.id = multilingual_title.entryid AND multilingual_title.property = 'multilingual_title_" . $this->showlang . "')"; if (!empty($this->lang_display)) { // If lang_display is set - we want ONLY the entries which have translation $eventData['and'] .= " AND multilingual_body.value IS NOT NULL"; } if (empty($eventData['joins'])) { $eventData['joins'] = $cond; } else { $eventData['joins'] .= $cond; } if ($addData['source'] == 'search' && isset($eventData['find_part'])) { $term =& $addData['term']; $cond =& $eventData; if ($serendipity['dbType'] == 'postgres') { $cond['find_part'] .= " OR (multilingual_body.value ILIKE '%{$term}%' OR multilingual_extended.value ILIKE '%{$term}%' OR multilingual_title.value ILIKE '%{$term}%')"; } elseif ($serendipity['dbType'] == 'sqlite') { $term = serendipity_mb('strtolower', $term); $cond['find_part'] .= " OR (lower(multilingual_body.value) LIKE '%{$term}%' OR lower(multilingual_extended.value) LIKE '%{$term}%' OR lower(multilingual_title.value) LIKE '%{$term}%')"; } else { if (preg_match('@["\\+\\-\\*~<>\\(\\)]+@', $term)) { $bool = ' IN BOOLEAN MODE'; } else { $bool = ''; } $cond['find_part'] .= " OR (\n MATCH(multilingual_body.value) AGAINST('{$term}' {$bool})\n OR MATCH(multilingual_extended.value) AGAINST('{$term}' {$bool})\n OR MATCH(multilingual_title.value) AGAINST('{$term}' {$bool})\n )"; } } return true; break; case 'frontend_comment': if (serendipity_db_bool($this->get_config('tagged_entries', 'true'))) { $serendipity['smarty']->assign('head_title', $this->strip_langs($serendipity['head_title'])); } if (serendipity_db_bool($this->get_config('tagged_title', 'true'))) { $serendipity['smarty']->assign('head_subtitle', $this->strip_langs($serendipity['head_subtitle'])); } return true; break; case 'frontend_sidebar_plugins': if (serendipity_db_bool($this->get_config('tagged_sidebar', 'true'))) { foreach ($eventData as $key => $entry) { $eventData[$key]['title'] = $this->strip_langs($eventData[$key]['title']); $eventData[$key]['content'] = $this->strip_langs($eventData[$key]['content']); } } return true; break; default: return false; break; } } else { return false; } }