function generate_content(&$title) { global $serendipity; $title = $this->get_config('title', $this->title); $max_entries = $this->get_config('max_entries'); $max_chars = $this->get_config('max_chars'); $wordwrap = $this->get_config('wordwrap'); $dateformat = $this->get_config('dateformat'); if (!$max_entries || !is_numeric($max_entries) || $max_entries < 1) { $max_entries = 15; } if (!$max_chars || !is_numeric($max_chars) || $max_chars < 1) { $max_chars = 120; } if (!$wordwrap || !is_numeric($wordwrap) || $wordwrap < 1) { $wordwrap = 30; } if (!$dateformat || strlen($dateformat) < 1) { $dateformat = '%a, %d.%m.%Y %H:%M'; } $viewtype = ''; if ($this->get_config('viewmode') == 'comments') { $viewtype .= ' AND co.type = \'NORMAL\''; } elseif ($this->get_config('viewmode') == 'trackbacks') { $viewtype .= ' AND (co.type = \'TRACKBACK\' OR co.type = \'PINGBACK\')'; } $cond = array(); $cond['and'] = ' AND e.isdraft = \'false\' '; if ($this->get_config('authorid') == 'login') { serendipity_ACL_SQL($cond, true); serendipity_plugin_api::hook_event('frontend_fetchentries', $cond, array('source' => 'entries')); } $q = 'SELECT co.body AS comment, co.timestamp AS stamp, co.author AS user, e.title AS subject, e.timestamp AS entrystamp, e.id AS entry_id, co.id AS comment_id, co.type AS comment_type, co.url AS comment_url, co.title AS comment_title, co.email AS comment_email FROM ' . $serendipity['dbPrefix'] . 'comments AS co, ' . $serendipity['dbPrefix'] . 'entries AS e ' . $cond['joins'] . ' WHERE e.id = co.entry_id AND NOT (co.type = \'TRACKBACK\' AND co.author = \'' . serendipity_db_escape_string($serendipity['blogTitle']) . '\' AND co.title != \'\') AND co.status = \'approved\' ' . $viewtype . ' ' . $cond['and'] . ' ORDER BY co.timestamp DESC LIMIT ' . $max_entries; $sql = serendipity_db_query($q); // echo $q; if ($sql && is_array($sql)) { foreach ($sql as $key => $row) { if (function_exists('mb_strimwidth')) { $comment = mb_strimwidth(strip_tags($row['comment']), 0, $max_chars, " [...]", LANG_CHARSET); } else { $comments = wordwrap(strip_tags($row['comment']), $max_chars, '@@@', 1); $aComment = explode('@@@', $comments); $comment = $aComment[0]; if (count($aComment) > 1) { $comment .= ' [...]'; } } $showurls = $this->get_config('showurls', 'trackbacks'); $isTrackBack = $row['comment_type'] == 'TRACKBACK' || $row['comment_type'] == 'PINGBACK'; if ($row['comment_url'] != '' && ($isTrackBack && ($showurls == 'trackbacks' || $showurls == 'all') || !$isTrackBack && ($showurls == 'comments' || $showurls == 'all'))) { /* Fix invalid cases in protocoll part */ $row['comment_url'] = preg_replace('@^http://@i', 'http://', $row['comment_url']); $row['comment_url'] = preg_replace('@^https://@i', 'https://', $row['comment_url']); if (substr($row['comment_url'], 0, 7) != 'http://' && substr($row['comment_url'], 0, 8) != 'https://') { $row['comment_url'] = 'http://' . $row['comment_url']; } $user = '******' . htmlspecialchars(strip_tags($row['comment_url'])) . '" title="' . htmlspecialchars(strip_tags($row['comment_title'])) . '">' . htmlspecialchars(strip_tags($row['user'])) . '</a>'; } else { $user = htmlspecialchars(strip_tags($row['user'])); } $user = trim($user); if (empty($user)) { $user = PLUGIN_COMMENTS_ANONYMOUS; } if (function_exists('mb_strimwidth')) { $pos = 0; $parts = array(); $enc = LANG_CHARSET; $comment_len = mb_strlen($comment, $enc); while ($pos < $comment_len) { $part = mb_strimwidth($comment, $pos, $wordwrap, '', $enc); $pos += mb_strlen($part, $enc); $parts[] = $part; } $comment = implode("\n", $parts); } else { $comment = wordwrap($comment, $wordwrap, "\n", 1); } $entry = array('comment' => $comment, 'email' => $row['comment_email'], 'url' => $row['comment_url'], 'author' => $row['user']); // Let's help the BBCOde plugin a bit: if (class_exists('serendipity_event_bbcode')) { $entry['comment'] = preg_replace('@((\\[.*)[\\n\\r]+(.*\\]))+@imsU', '\\2\\3', $entry['comment']); $entry['comment'] = preg_replace('@((\\[.+\\].*)[\\r\\n]+(.*\\[/.+\\]))+@imsU', '\\2\\3', $entry['comment']); } $addData = array('from' => 'serendipity_plugin_comments:generate_content'); serendipity_plugin_api::hook_event('frontend_display', $entry, $addData); printf('<div class="plugin_comment_wrap">' . PLUGIN_COMMENTS_ABOUT . '</div>', '<div class="plugin_comment_subject"><span class="plugin_comment_author">' . $user . '</span>', ' <a class="highlight" href="' . serendipity_archiveURL($row['entry_id'], $row['subject'], 'baseURL', true, array('timestamp' => $row['entrystamp'])) . '#c' . $row['comment_id'] . '" title="' . htmlspecialchars($row['subject']) . '">' . htmlspecialchars($row['subject']) . '</a></div>' . "\n" . '<div class="plugin_comment_date">' . htmlspecialchars(serendipity_strftime($dateformat, $row['stamp'])) . '</div>' . "\n" . '<div class="plugin_comment_body">' . strip_tags($entry['comment'], '<br /><img><a>') . '</div>' . "\n\n"); } } }
/** * Check all existing thumbnails if they are the right size, insert missing thumbnails * * LONG * * @access public * @return int Number of updated thumbnails */ function serendipity_syncThumbs($deleteThumbs = false) { global $serendipity; $i = 0; $files = serendipity_fetchImages(); $fcount = count($files); for ($x = 0; $x < $fcount; $x++) { $update = array(); $f = serendipity_parseFileName($files[$x]); if (empty($f[1]) || $f[1] == $files[$x]) { // No extension means bad file most probably. Skip it. printf(SKIPPING_FILE_EXTENSION . '<br />', $files[$x]); continue; } $ffull = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $files[$x]; $fthumb = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $f[0] . '.' . $serendipity['thumbSuffix'] . '.' . $f[1]; $sThumb = $f[0] . '.' . $serendipity['thumbSuffix'] . '.' . $f[1]; $fbase = basename($f[0]); $fdir = dirname($f[0]) . '/'; if ($fdir == './') { $fdir = ''; } if (!is_readable($ffull) || filesize($ffull) == 0) { printf(SKIPPING_FILE_UNREADABLE . '<br />', $files[$x]); continue; } $ft_mime = serendipity_guessMime($f[1]); $fdim = serendipity_getimagesize($ffull, $ft_mime); // If we're supposed to delete thumbs, this is the easiest place. if (is_readable($fthumb)) { if ($deleteThumbs === true) { if (@unlink($fthumb)) { printf(DELETE_THUMBNAIL . "<br />\n", $sThumb); $i++; } } else { if ($deleteThumbs == 'checksize') { // Find existing thumbnail dimensions $tdim = serendipity_getimagesize($fthumb); if ($tdim['noimage']) { // Delete it so it can be regenerated if (@unlink($fthumb)) { printf(DELETE_THUMBNAIL . "<br />\n", $sthumb); $i++; } } else { // Calculate correct thumbnail size from original image $expect = serendipity_calculate_aspect_size($fdim[0], $fdim[1], $serendipity['thumbSize'], $serendipity['thumbConstraint']); // Check actual thumbnail size if ($tdim[0] != $expect[0] || $tdim[1] != $expect[1]) { // This thumbnail is incorrect; delete it so // it can be regenerated if (@unlink($fthumb)) { printf(DELETE_THUMBNAIL . "<br />\n", $sthumb); $i++; } } } } } // else the option is to keep all existing thumbs; do nothing. } // end if thumb exists $cond = array('and' => "WHERE name = '" . serendipity_db_escape_string($fbase) . "'\n " . ($fdir != '' ? "AND path = '" . serendipity_db_escape_string($fdir) . "'" : '') . "\n AND mime = '" . serendipity_db_escape_string($fdim['mime']) . "'"); serendipity_ACL_SQL($cond, false, 'directory'); $rs = serendipity_db_query("SELECT *\n FROM {$serendipity['dbPrefix']}images AS i\n {$cond['joins']}\n\n {$cond['and']}", true, 'assoc'); if (is_array($rs)) { // This image is in the database. Check our calculated data against the database data. $update = array(); // Is the width correct? if (isset($fdim[0]) && $rs['dimensions_width'] != $fdim[0]) { $update['dimensions_width'] = $fdim[0]; } // Is the height correct? if (isset($fdim[1]) && $rs['dimensions_height'] != $fdim[1]) { $update['dimensions_height'] = $fdim[1]; } // Is the image size correct? if ($rs['size'] != filesize($ffull)) { $update['size'] = filesize($ffull); } // Has the thumbnail suffix changed? $checkfile = $serendipity['serendipityPath'] . $serendipity['uploadPath'] . $rs['path'] . $rs['name'] . '.' . $rs['thumbnail_name'] . '.' . $rs['extension']; if (!file_exists($checkfile) && file_exists($fthumb)) { $update['thumbnail_name'] = $serendipity['thumbSuffix']; } /* Do the database update, if needed */ if (sizeof($update) != 0) { printf(FOUND_FILE . '<br />', $files[$x]); serendipity_updateImageInDatabase($update, $rs['id']); $i++; } } else { printf(FOUND_FILE . '<br />', $files[$x]); serendipity_insertImageInDatabase($fbase . '.' . $f[1], $fdir, 0, filemtime($ffull)); $i++; } } return $i; }
function generate_content(&$title) { global $serendipity; $number = $this->get_config('number'); $dateformat = $this->get_config('dateformat'); $category = $this->get_config('category', 'none'); $show_where = $this->get_config('show_where', 'both'); if ($show_where == 'extended' && (!isset($serendipity['GET']['id']) || !is_numeric($serendipity['GET']['id']))) { return false; } else { if ($show_where == 'overview' && isset($serendipity['GET']['id']) && is_numeric($serendipity['GET']['id'])) { return false; } } if ($category == '_cur') { $category = $serendipity['GET']['category']; if (empty($category) && !empty($serendipity['GET']['id'])) { $entry = serendipity_fetchEntry('id', $serendipity['GET']['id']); $category = $entry['categories'][0]['categoryid']; } } $title = $this->get_config('title', $this->title); $number_from_sw = $this->get_config('number_from'); $randomize = $this->get_config('randomize') == "yes" ? true : false; $sql_condition = array(); $sql_condition['joins'] = ''; $sql_condition['and'] = ''; if ($category != 'none' && !empty($category)) { $sql_categories = array(); if (is_numeric($category)) { $sql_categories[] = $category; } else { $sql_categories = explode('^', $category); } $category_parts = array(); foreach ($sql_categories as $sql_category) { $category_parts[] = "\n" . implode(' AND ', serendipity_fetchCategoryRange($sql_category)); } $sql_condition['and'] .= ' AND (c.category_left BETWEEN ' . implode(' OR c.category_left BETWEEN ', $category_parts) . ')'; } if (!$number || !is_numeric($number) || $number < 1) { $number = 10; } $sql_number = serendipity_db_limit_sql($number); $db = $serendipity['dbType']; switch ($number_from_sw) { case 'skip': $sql_number = serendipity_db_limit_sql(serendipity_db_limit($serendipity['fetchLimit'], $number)); break; } if (!$dateformat || strlen($dateformat) < 1) { $dateformat = '%A, %B %e %Y'; } if ($randomize) { if ($db == 'mysql' || $db == 'mysqli') { $sql_order = "ORDER BY RAND()"; } else { // SQLite and PostgreSQL support this, hooray. $sql_order = "ORDER BY RANDOM()"; } } else { $sql_order = "ORDER BY timestamp DESC "; } $sql_condition['and'] .= "AND timestamp <= " . time(); serendipity_ACL_SQL($sql_condition, $category == 'none'); if (!stristr($sql_condition['joins'], $serendipity['dbPrefix'] . 'category')) { $sql_condition['joins'] = ' LEFT OUTER JOIN ' . $serendipity['dbPrefix'] . 'category AS c ON ec.categoryid = c.categoryid ' . $sql_condition['joins']; } if (!stristr($sql_condition['joins'], $serendipity['dbPrefix'] . 'entrycat')) { $sql_condition['joins'] = ' LEFT OUTER JOIN ' . $serendipity['dbPrefix'] . 'entrycat AS ec ON id = ec.entryid ' . $sql_condition['joins']; } $entries_query = "SELECT DISTINCT id,\n title,\n timestamp,\n epm.value AS multilingual_title\n FROM {$serendipity['dbPrefix']}entries AS e\n {$sql_condition['joins']}\n\n LEFT OUTER JOIN {$serendipity['dbPrefix']}entryproperties AS epm\n ON (epm.entryid = e.id AND epm.property = 'multilingual_title_" . $serendipity['lang'] . "')\n\n WHERE isdraft = 'false' {$sql_condition['and']}\n {$sql_order}\n {$sql_number}"; $entries = serendipity_db_query($entries_query); if (is_string($entries)) { echo $entries . "<br />\n"; echo $entries_query . "<br />\n"; } if (isset($entries) && is_array($entries)) { echo '<dl>' . "\n"; foreach ($entries as $k => $entry) { if (!empty($entry['multilingual_title'])) { $entry['title'] = $entry['multilingual_title']; } $entryLink = serendipity_archiveURL($entry['id'], $entry['title'], 'serendipityHTTPPath', true, array('timestamp' => $entry['timestamp'])); if (empty($entry['title'])) { $entry['title'] = '#' . $entry['id']; } echo '<dt class="serendipity_recententries_entrylink"><a href="' . $entryLink . '" title="' . serendipity_specialchars($entry['title']) . '">' . serendipity_specialchars($entry['title']) . '</a></dt>' . "\n" . '<dd class="serendipity_recententries_entrydate serendipitySideBarDate">' . serendipity_specialchars(serendipity_strftime($dateformat, $entry['timestamp'])) . '</dd>' . "\n"; } echo '</dl>' . "\n\n"; } }
/** * 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; }