/** * Fetch a list of trackbacks for an entry * * @access public * @param int The ID of the entry * @param string How many trackbacks to show * @param boolean If true, also non-approved trackbacks will be shown * @return */ function &serendipity_fetchTrackbacks($id, $limit = null, $showAll = false) { global $serendipity; if (!$showAll) { $and = "AND status = 'approved'"; } $query = "SELECT * FROM {$serendipity['dbPrefix']}comments WHERE entry_id = '" . (int) $id . "' AND (type = 'TRACKBACK' OR type = 'PINGBACK') {$and} ORDER BY id"; if (isset($limit)) { $limit = serendipity_db_limit_sql($limit); $query .= " {$limit}"; } $comments = serendipity_db_query($query); if (!is_array($comments)) { return array(); } return $comments; }
/** * Fetch an array of comments to a specific entry id * * @access public * @param int The Entry ID to fetch comments for * @param int How many comments to fetch (empty: all) * @param string How shall comments be ordered (ASC|DESC) * @param boolean Shall non-approved comments be displayed? * @param string Comment type to fetch * @return array The SQL result of comments */ function serendipity_fetchComments($id, $limit = null, $order = '', $showAll = false, $type = 'NORMAL', $where = '') { global $serendipity; $and = ''; if (!empty($limit)) { $limit = serendipity_db_limit_sql($limit); } else { $limit = ''; } if ($type == 'comments' || empty($type)) { $type = 'NORMAL'; } elseif ($type == 'trackbacks') { $type = 'TRACKBACK'; } elseif ($type == 'pingbacks') { $type = 'PINGBACK'; } elseif ($type == 'comments_and_trackbacks') { $type = '%'; } if (!empty($id)) { $and .= " AND co.entry_id = '" . (int) $id . "'"; } if (!$showAll) { $and .= ' AND co.status = \'approved\''; } $and .= $where; if ($serendipity['dbType'] == 'postgres' || $serendipity['dbType'] == 'pdo-postgres') { $group = ''; $distinct = 'DISTINCT'; } else { $group = 'GROUP BY co.id'; $distinct = ''; } $query = "SELECT {$distinct}\n co.id,\n co.entry_id, co.timestamp, co.title AS ctitle, co.email, co.url, co.ip, co.body, co.type, co.subscribed,\n co.author,\n e.title,\n e.timestamp AS entrytimestamp,\n e.id AS entryid,\n e.authorid,\n co.id AS commentid,\n co.parent_id AS parent_id\n FROM\n {$serendipity['dbPrefix']}comments AS co\n LEFT JOIN {$serendipity['dbPrefix']}entries AS e ON (co.entry_id = e.id)\n WHERE co.type LIKE '" . $type . "' AND co.entry_id > 0 {$and}\n {$group}\n ORDER BY\n " . ($where != '' ? '' : 'co.id') . " " . ($order != '' ? $order : '') . "\n {$limit}"; $comments = serendipity_db_query($query, false, 'assoc'); if (!is_array($comments)) { $comments = array(); } $addData = array('id' => $id, 'limit' => $limit, 'order' => $order, 'showAll' => $showAll, 'type' => $type, 'where' => $where); serendipity_plugin_api::hook_event('fetchcomments', $comments, $addData); return $comments; }
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"; } }
/** * Gets a list of media items from our media database * * LONG * * @access public * @param int The offset to start fetching media files * @param int How many items to fetch * @param int The number (referenced varaible) of fetched items * @param string The "ORDER BY" sql part when fetching items * @param string Order by DESC or ASC * @param string Only fetch files from a specific directory * @param string Only fetch specific filenames * @param string Only fetch media with specific keyword * @param array An array of restricting filter sets * @param boolean Apply strict directory checks, or include subdirectories? * @return array Resultset of images */ function serendipity_fetchImagesFromDatabase($start = 0, $limit = 0, &$total, $order = false, $ordermode = false, $directory = '', $filename = '', $keywords = '', $filter = array(), $strict_directory = false) { global $serendipity; $cond = array('joinparts' => array(), 'parts' => array()); $orderfields = serendipity_getImageFields(); if (empty($order) || !isset($orderfields[$order])) { $order = 'i.date'; } if (!is_array($filter)) { $filter = array(); } if (empty($ordermode) || $ordermode != 'DESC' && $ordermode != 'ASC') { $ordermode = 'DESC'; } if ($order == 'name') { $order = 'realname ' . $ordermode . ', name'; } if ($limit != 0) { $limitsql = serendipity_db_limit_sql(serendipity_db_limit($start, $limit)); } if ($strict_directory) { $cond['parts']['directory'] = " AND i.path = '" . serendipity_db_escape_string($directory) . "'\n"; } elseif (!empty($directory)) { $cond['parts']['directory'] = " AND i.path LIKE '" . serendipity_db_escape_string($directory) . "%'\n"; } if (!empty($filename)) { $cond['parts']['filename'] = " AND (i.name like '%" . serendipity_db_escape_string($filename) . "%' OR\n i.realname like '%" . serendipity_db_escape_string($filename) . "%')\n"; } if (!is_array($keywords)) { if (!empty($keywords)) { $keywords = explode(';', $keywords); } else { $keywords = array(); } } if (count($keywords) > 0) { $cond['parts']['keywords'] = " AND (mk.property IN ('" . serendipity_db_implode("', '", $keywords, 'string') . "'))\n"; $cond['joinparts']['keywords'] = true; } foreach ($filter as $f => $fval) { if (!isset($orderfields[$f]) || empty($fval)) { continue; } if (is_array($fval)) { if (empty($fval['from']) || empty($fval['to'])) { continue; } if ($orderfields[$f]['type'] == 'date') { $fval['from'] = serendipity_convertToTimestamp(trim($fval['from'])); $fval['to'] = serendipity_convertToTimestamp(trim($fval['to'])); } if (substr($f, 0, 3) === 'bp.') { $realf = substr($f, 3); $cond['parts']['filter'] .= " AND (bp2.property = '{$realf}' AND bp2.value >= " . (int) $fval['from'] . " AND bp2.value <= " . (int) $fval['to'] . ")\n"; } else { $cond['parts']['filter'] .= " AND ({$f} >= " . (int) $fval['from'] . " AND {$f} <= " . (int) $fval['to'] . ")\n"; } } elseif ($f == 'i.authorid') { $cond['parts']['filter'] .= " AND (\n (hp.property = 'authorid' AND hp.value = " . (int) $fval . ")\n OR\n (i.authorid = " . (int) $fval . ")\n )\n"; $cond['joinparts']['hiddenproperties'] = true; } elseif ($orderfields[$f]['type'] == 'int') { if (substr($f, 0, 3) === 'bp.') { $realf = substr($f, 3); $cond['parts']['filter'] .= " AND (bp2.property = '{$realf}' AND bp2.value = '" . serendipity_db_escape_string(trim($fval)) . "')\n"; } else { $cond['parts']['filter'] .= " AND ({$f} = '" . serendipity_db_escape_string(trim($fval)) . "')\n"; } } else { if (substr($f, 0, 3) === 'bp.') { $realf = substr($f, 3); $cond['parts']['filter'] .= " AND (bp2.property = '{$realf}' AND bp2.value LIKE '%" . serendipity_db_escape_string(trim($fval)) . "%')\n"; } else { $cond['parts']['filter'] .= " AND ({$f} LIKE '%" . serendipity_db_escape_string(trim($fval)) . "%')\n"; } } $cond['joinparts']['filterproperties'] = true; } if (isset($serendipity['authorid']) && !serendipity_checkPermission('adminImagesViewOthers')) { $cond['parts']['authorid'] .= " AND (i.authorid = 0 OR i.authorid = " . (int) $serendipity['authorid'] . ")\n"; } $cond['and'] = 'WHERE 1=1 ' . implode("\n", $cond['parts']); $cond['args'] = func_get_args(); serendipity_plugin_api::hook_event('fetch_images_sql', $cond); serendipity_ACL_SQL($cond, false, 'directory'); if ($cond['joinparts']['keywords']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS mk\n ON (mk.mediaid = i.id AND mk.property_group = 'base_keyword')\n"; } if (substr($order, 0, 3) === 'bp.') { $cond['orderproperty'] = substr($order, 3); $cond['orderkey'] = 'bp.value'; $order = 'bp.value'; $cond['joinparts']['properties'] = true; } else { $cond['orderkey'] = "''"; } if ($cond['joinparts']['properties']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS bp\n ON (bp.mediaid = i.id AND bp.property_group = 'base_property' AND bp.property = '{$cond['orderproperty']}')\n"; } if ($cond['joinparts']['filterproperties']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS bp2\n ON (bp2.mediaid = i.id AND bp2.property_group = 'base_property')\n"; } if ($cond['joinparts']['hiddenproperties']) { $cond['joins'] .= "\n LEFT OUTER JOIN {$serendipity['dbPrefix']}mediaproperties AS hp\n ON (hp.mediaid = i.id AND hp.property_group = 'base_hidden')\n"; } if ($serendipity['dbType'] == 'postgres' || $serendipity['dbType'] == 'pdo-postgres') { $cond['group'] = ''; $cond['distinct'] = 'DISTINCT'; } else { $cond['group'] = 'GROUP BY i.id'; $cond['distinct'] = ''; } $basequery = "FROM {$serendipity['dbPrefix']}images AS i\n LEFT OUTER JOIN {$serendipity['dbPrefix']}authors AS a\n ON i.authorid = a.authorid\n {$cond['joins']}\n\n {$cond['and']}"; $query = "SELECT {$cond['distinct']} i.id, {$cond[orderkey]} AS orderkey, i.name, i.extension, i.mime, i.size, i.dimensions_width, i.dimensions_height, i.date, i.thumbnail_name, i.authorid, i.path, i.hotlink, i.realname,\n a.realname AS authorname\n {$basequery}\n {$cond['group']}\n ORDER BY {$order} {$ordermode} {$limitsql}"; $rs = serendipity_db_query($query, false, 'assoc'); if (!is_array($rs) && $rs !== true && $rs !== 1) { echo '<div>' . $rs . '</div>'; return array(); } elseif (!is_array($rs)) { return array(); } $total_query = "SELECT count(i.id)\n {$basequery}\n GROUP BY i.id"; $total_rs = serendipity_db_query($total_query, false, 'num'); if (is_array($total_rs)) { $total = count($total_rs); } return $rs; }
/** * 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])) { // Moved from above: only get image data if we're actually going to do something $this->set_valid_image_data(); // Get dimensions of image, only if not text-only if ($this->image_name) { // Is this a single-image bar, or a single segment? $ratio = $this->image_width / $this->image_height; if ($ratio < $this->max_segment_ratio) { // This is probably a single segment. Square segments // will have a ratio of 0.3; long, flat segments won't // get up to 1.0 unless they're 3 times as wide as they // are tall; full-bar images with square segments will // be 1.666; and full-bar images with tall, narrow // segments will be greater than 1.0 unless they're // nearly twice as high as they are wide. $this->image_width = $this->image_width * 5; } } switch ($event) { //Javascript for ajax functionality case 'frontend_footer': if ($this->get_config('ajax') == true) { ?> <script type="text/javascript"> /*<![CDATA[ */ ajaxloader = new Image(); ajaxloader.src = "<?php echo $serendipity['baseURL']; ?> plugins/serendipity_event_karma/img/ajax-loader.gif"; for (i=1;i<6;i++) { jQuery('.serendipity_karmaVoting_link'+i).click(function(event) { event.preventDefault(); karmaId = jQuery(this).attr('href').match(/\[karmaId\]=([0-9]+)/); vote(jQuery(this).html(),karmaId[1]); }); } function vote(karmaVote,karmaId) { // Send the data using post and put the results in place jQuery('#karma_vote'+karmaId).parent().children('.serendipity_karmaVoting_links').replaceWith('<div class="serendipity_karmaVoting_links ajaxloader"><img src="<?php echo $serendipity['baseURL']; ?> plugins/serendipity_event_karma/img/ajax-loader.gif" border="0" alt="ajax-loader" /></div>'); jQuery.post("<?php echo $serendipity['baseURL'] . $serendipity['permalinkPluginPath']; ?> /karma-ajaxquery", { karmaVote: karmaVote, karmaId: karmaId }, function(data) { jQuery('#karma_vote'+karmaId).parent().replaceWith(data); }); } /* ]]>*/ </script> <?php } // Hook for ajax calls // Hook for ajax calls case 'external_plugin': $theUri = (string) str_replace('&', '&', $eventData); $uri_parts = explode('?', $theUri); // 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 'karma-ajaxquery': $this->performkarmaVote(); $q = "SELECT SUM(votes) AS votes, SUM(points) AS points, SUM(visits) AS visits\n FROM " . $serendipity['dbPrefix'] . "karma\n WHERE entryid = '" . (int) $_POST['karmaId'] . "';"; $sql = serendipity_db_query($q); $track_clicks = serendipity_db_bool($this->get_config('visits_active', true)); $track_karma = serendipity_db_bool($this->get_config('karma_active', true)); $enough_votes = $track_karma && $sql[0]['votes'] >= $this->get_config('min_disp_votes', 0); $enough_visits = $track_clicks && $sql[0]['visits'] >= $this->get_config('min_disp_visits', 0); $textual_msg = true; $textual_current = true; $textual_visits = true; if ($this->image_name != '0') { $textual_msg = $this->get_config('textual_msg', 'true'); $textual_current = $this->get_config('textual_current', 'true'); $textual_visits = $this->get_config('textual_visits', 'true'); } $temp = $this->karmaVoted((int) $_POST['karmaVote'], $sql[0]['points'], $sql[0]['votes']); $myvote = $temp['myvote']; $msg = $temp['msg']; $bar = $temp['bar']; $temp = $this->createkarmaBlock((int) $_POST['karmaId'], $textual_msg, $msg, $bar, $enough_votes, $textual_current, $enough_visits, $textual_visits, $sql[0]['points'], $sql[0]['votes']); $karma_block = $temp['karma_block']; $points = $temp['points']; echo sprintf($karma_block, $myvote, $points, $sql[0]['votes'], $sql[0]['visits'], ''); break; } return true; break; // Early hook, before any page is displayed // Early hook, before any page is displayed case 'frontend_configure': $this->performkarmaVote(); return true; break; // CSS generation hooks // CSS generation hooks case 'backend_header': if ($serendipity['GET']['adminModule'] == 'event_display' && $serendipity['GET']['adminAction'] == 'karmalog' || $serendipity['GET']['adminModule'] == 'plugins') { // Generate the CSS for the graphical rating bar selector // // The CSS appears to be generated in a completely // different instance of Serendipity, as if index.php gets // called separately for the CSS. // // Note that the css_backend hook adds properties to the // serendipity_admin.css, but that file is *always* // cached. We use backend_header and add the CSS to the // HEAD styles to make it dynamic. (Edit: with 2.0 this has changed) // Get the CSS, set $this->image_name so we'll output the // standard graphical CSS prologue if any images are found. $this->createRatingSelector(); print "<style type='text/css'>\n"; $align = 'center'; $bg = $this->get_config('preview_bg', false); if (!empty($bg)) { if (strpos($bg, ';') !== false || strpos($bg, ',') !== false) { $bg = 'red'; } print "\n.serendipity_karmaVote_selectorTable {\n background: {$bg};\n}\n"; } print "\n.serendipityAdminContent .serendipity_karmaVoting_links {\n margin: 5px;\n}\n"; if ($serendipity['version'][0] > 1) { print "\n</style>\n"; } } if ($serendipity['version'][0] > 1) { break; return true; } case 'css_backend': case 'css': // Some CSS notes: // // .serendipity_karmaVoting is the class for the karma wrapper/container, // including the text explanations, messages, and rating bar. // (currently a div) // .serendipity_karmaVoting a specifies the links for the text-mode // rating bar // .serendipity_karmaError is the class for any text indicating an // error condition // .serendipity_karmaSuccess is the class for any text indicating // successful operation // .serendipity_karmaVoting_links is the container for the graphical // rating bar (currently an ol) // .serendipity_karmaVoting_links a indicates the various voting links in // the graphical rating bar // .serendipity_karmaVoting_current-rating is the class for the current // rating in the graphical rating bar // a.serendipity_karmaVoting_link1, _link2, etc are the classes applied // to the individual voting links // Note that there are two possible template types: early // templates that only handle the text rating bars, and // newer templates that understand the graphical raters. // We check for both types and act appropriately. /*--JAM: Let's just skip this whole hassle if (!$align) { $align = $this->get_config('alignment', 'detect'); } if ($align == 'detect') { */ $align = $this->get_config('alignment'); // Try to let the template take care of it if ($this->image_name == '0') { // Text-only rating bar is used if (strpos($eventData, '.serendipity_karmaVoting')) { // Template is handling all our CSS return true; } } /* --JAM: else { // Graphical rating bar is used if (strpos($eventData, '.serendipity_karmaVoting_images')) { // Template is handling all our CSS return true; } // Check for old text-only templates $pos = strpos($eventData, '.serendipity_karmaVoting'); while ($pos && ($align == 'detect')) { // Find text-align: in the current block $endpos = strpos($eventData, '}', $pos); if (!$endpos) { // Broken CSS break; } $alignpos = strpos($eventData, 'text-align:', $pos); // Can't check for comments, or I would. Hope // the first is the correct one. if ($alignpos && $alignpos < $endpos) { $start = $alignpos + 11; $alignend = strpos($eventData, ';', $alignpos); if ($alignend) { // All valid. Pull out the alignment. $len = $alignend - $start; $align = trim(substr($eventData, $start, $len)); } } $pos = strpos($eventData, '.serendipity_karmaVoting', $endpos); } // I should have a valid alignment or 'detect' in $align now. } } // If we couldn't detect the alignment, guess 'right' if ($align == 'detect') { $align = 'right'; } --JAM: END COMMENT BLOCK */ if ($serendipity['version'][0] < 2 && $event == 'backend_header') { print "<style type='text/css'>\n"; } // Since errors might be printed at any time, always // output the text-mode CSS print <<<EOS .serendipity_karmaVoting { text-align: {$align}; font-size: 7pt; margin: 0px; } .serendipity_karmaVoting a { font-size: 7pt; text-decoration: none; } .serendipity_karmaVoting a:hover { color: green; } .serendipity_karmaError { color: #FF8000; } .serendipity_karmaSuccess { color: green; } EOS; // Only output the image CSS if it's needed if ($this->image_name != '0') { $img = $serendipity['baseURL'] . "plugins/serendipity_event_karma/img/" . $this->image_name; $h = $this->image_height / 3; $w = $this->image_width; switch ($align) { case 'left': $margin = '0px auto 0px 0px'; break; case 'center': $margin = '0px auto'; break; case 'right': default: $margin = '0px 0px 0px auto'; break; } // The CSS here is lifted largely from // http://komodomedia.com/blog/index.php/2007/01/20/css-star-rating-redux/ // // Note, however that margin has been changed for // multiple cases and all unitless measurements have // been specified in pixels. Additionally, measures // have been taken to align the text. print <<<END_IMG_CSS .serendipity_karmaVoting_links, .serendipity_karmaVoting_links a:hover, .serendipity_karmaVoting_current-rating { background: url({$img}) left; font-size: 0; } .ajaxloader { background-image: none; } .serendipity_karmaVoting_links { position: relative; width: {$w}px; height: {$h}px; overflow: hidden; list-style: none; margin: {$margin}; padding: 0; background-position: left top; text-align: center; } .serendipity_karmaVoting_links li { display: inline; } .serendipity_karmaVoting_links a , .serendipity_karmaVoting_current-rating { position:absolute; top: 0; left: 0; text-indent: -9000em; height: {$h}px; line-height: {$h}px; outline: none; overflow: hidden; border: none; } .serendipity_karmaVoting_links a:hover { background-position: left bottom; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link1 { width: 20%; z-index: 6; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link2 { width: 40%; z-index: 5; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link3 { width: 60%; z-index: 4; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link4 { width: 80%; z-index: 3; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link5 { width: 100%; z-index: 2; } .serendipity_karmaVoting_links .serendipity_karmaVoting_current-rating { z-index: 1; background-position: left center; } END_IMG_CSS; // Add selector images CSS, if necessary if (!empty($this->select_css)) { print $this->select_css; } } // End if image bar defined if ($serendipity['version'][0] < 2 && $event == 'backend_header') { print "\n</style>\n"; } return true; break; //--TODO: Comment the functionality of this event hook. //--TODO: Comment the functionality of this event hook. case 'event_additional_statistics': $sql = array(); $sql['visits_top'] = array('visits', 'DESC'); $sql['visits_bottom'] = array('visits', 'ASC'); $sql['votes_top'] = array('votes', 'DESC'); $sql['votes_bottom'] = array('votes', 'ASC'); $sql['points_top'] = array('points', 'DESC'); $sql['points_bottom'] = array('points', 'ASC'); foreach ($sql as $key => $rows) { $q = "SELECT e.id,\n e.title,\n e.timestamp,\n SUM(k.{$rows[0]}) AS no\n FROM {$serendipity['dbPrefix']}karma\n AS k\n JOIN {$serendipity['dbPrefix']}entries\n AS e\n ON k.entryid = e.id\n WHERE k.{$rows[0]} IS NOT NULL AND k.{$rows[0]} != 0\n GROUP BY e.id, e.title, e.timestamp ORDER BY no {$rows[1]} LIMIT {$addData['maxitems']}"; $sql_rows = serendipity_db_query($q); ?> <section> <h3><?php echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($key)); ?> </h3> <dl> <?php if (is_array($sql_rows)) { foreach ($sql_rows as $id => $row) { ?> <dt><a href="<?php echo serendipity_archiveURL($row['id'], $row['title'], 'serendipityHTTPPath', true, array('timestamp' => $row['timestamp'])); ?> "><?php echo function_exists('serendipity_specialchars') ? serendipity_specialchars($row['title']) : htmlspecialchars($row['title'], ENT_COMPAT, LANG_CHARSET); ?> </a></dt> <dd><?php echo $row['no']; ?> <?php echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($rows[0]) . '_NO'); ?> </dd> <?php } } ?> </dl> </section> <?php } return true; break; // Add voting information to entries // Add voting information to entries case 'entry_display': // Update database if necessary if ($this->get_config('dbversion', 0) != PLUGIN_KARMA_DB_VERSION) { $this->checkScheme(); } // Find the ID of this entry if (isset($serendipity['GET']['id'])) { $entryid = (int) serendipity_db_escape_string($serendipity['GET']['id']); } elseif (preg_match(PAT_COMMENTSUB, $_SERVER['REQUEST_URI'], $matches)) { $entryid = (int) $matches[1]; } else { $entryid = false; } // If we're actually reading the entry, not voting or editing it... if ($entryid && empty($serendipity['GET']['adminAction']) && !$serendipity['GET']['karmaVote']) { // Update the number of visits // Are we supposed to track visits? $track_clicks = serendipity_db_bool($this->get_config('visits_active', true)) && $this->track_clicks_allowed_by_user(); if ($track_clicks && $_SERVER['REQUEST_METHOD'] == 'GET') { $sql = serendipity_db_query("UPDATE {$serendipity['dbPrefix']}karma \n SET visits = visits + 1 \n WHERE entryid = {$entryid}", true); if (serendipity_db_affected_rows() < 1) { serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}karma (entryid, points, votes, lastvote, visits) \n VALUES ('{$entryid}', 0, 0, 0, 1)"); } } } // Set a cookie to look for later, verifying that cookies are enabled serendipity_setCookie('check', '1'); switch ($this->karmaVote) { case 'nocookie': // Users with no cookies won't be able to vote. $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_NOCOOKIE . '</div>'; // Continue until output // Continue until output case 'timeout2': if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_CLOSED . '</div>'; } // Continue until output // Continue until output case 'timeout': if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . sprintf(PLUGIN_KARMA_TIMEOUT, $this->karmaTimeOut) . '</div>'; } // Continue until output // Continue until output case 'alreadyvoted': if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_ALREADYVOTED . '</div>'; } // Continue until output // Continue until output case 'invalid1': case 'invalid2': case 'invalid': // Set message if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_INVALID . '</div>'; } // Continue until output /* OUTPUT MESSAGE */ //--TODO: Shouldn't this work with the cache plugin, too? if ($addData['extended']) { $eventData[0]['exflag'] = 1; $eventData[0]['add_footer'] .= $msg; } else { $elements = count($eventData); // Find the right container to store our message in. for ($i = 0; $i < $elements; $i++) { if ($eventData[$i]['id'] == $this->karmaId) { $eventData[$i]['add_footer'] .= $msg; } } } break; case 'voted': default: // If there's no data, there's no need to go on if (!is_array($eventData)) { return; } // Find out what the admin wants $track_clicks = serendipity_db_bool($this->get_config('visits_active', true)); $track_karma = serendipity_db_bool($this->get_config('karma_active', true)); if (serendipity_db_bool($this->get_config('karma_active_registered', false))) { if (!serendipity_userLoggedIn()) { $track_karma = false; } } $track_exits = serendipity_db_bool($this->get_config('exits_active', true)); // Get the limits $now = time(); $karmatime = $this->get_config('max_karmatime', 7); $max_karmatime = $karmatime * 24 * 60 * 60; // Accept infinite voting if ($max_karmatime <= 0) { $max_karmatime = $now; } //--TODO: Ensure that this works with the Custom Permalinks plugin // (We've seen trouble; it votes correctly, but redirects to the front page) $url = serendipity_currentURL(true); // Voting is only allowed on entries. Therefore voting URLs must be // either single-entry URLs or summary URLs. serendipity_currentURL // converts them to an "ErrorDocument-URI", so we can focus on the // query portion of the URI. // // Single-entry URLs should be well-defined. They can be permalinks, // of course; otherwise they're of the configured pattern. // // Summary URLs could be a little harder. The summary pages that // include entries are: frontpage, category, author, and archives. // It's possible a plugin would show entries, but if that's the case // we don't need to allow the user to vote on them. Still, that's // a lot of URLs to check for. // // Then there's the problem of the rest of the query. It could // include stuff we really want to keep around, like template // overrides or something. One can even add serendipity variables // to the URL in extreme cases. // // It seems that canonicalizing the URL will be quite difficult. // The only thing we can say for certain is that whatever the // current URL is, it got us to this page, and we'd like to return // to this page after we cast our vote. // Remove any clutter from our previous voting activity $url_parts = parse_url(serendipity_currentURL(true)); if (!empty($url_parts['query'])) { $exclude = array('serendipity[karmaVote]', 'serendipity[karmaId]'); // I tried using parse_str, but it gave me very weird results // with embedded arrays //parse_str($url_parts['query'], $q_parts); $q_parts = array(); // I don't know why this URL has been HTML encoded. Oh well. $pairs = explode('&', $url_parts['query']); foreach ($pairs as $pair) { $parts = explode('=', $pair); $q_parts[$parts[0]] = $parts[1]; } foreach ($q_parts as $key => $value) { if (in_array($key, $exclude)) { $rm = preg_quote("{$key}={$value}"); $url = preg_replace("@(&|&)?{$rm}@", '', $url); } } } if (substr($url, -1) != '?') { $url .= '&'; } // Get the cookie data (past votes, etc) $karma = isset($serendipity['COOKIE']['karmaVote']) ? unserialize($serendipity['COOKIE']['karmaVote']) : array(); // Get all required entry IDs, making keys match keys in eventData $entries = array(); if ($addData['extended'] || $addData['preview']) { // We're in extended or preview mode, we only need the current ID $eventData[0]['exflag'] = 1; $entries[0] = (int) $eventData[0]['id']; } elseif (!serendipity_db_bool($this->get_config('extended_only', false))) { // We're in overview mode, and we want rating bars for all the entry IDs foreach (array_keys($eventData) as $key) { if (isset($eventData[$key]['id'])) { $entries[$key] = (int) $eventData[$key]['id']; } } } // Fetch votes for all entry IDs. Store them in an array for later usage. $q = 'SELECT k.entryid, SUM(votes) AS votes, SUM(points) AS points, SUM(visits) AS visits FROM ' . $serendipity['dbPrefix'] . 'karma AS k WHERE k.entryid IN (' . implode(', ', $entries) . ') GROUP BY k.entryid'; $sql = serendipity_db_query($q); $rows = array(); if ($sql && is_array($sql)) { foreach ($sql as $row) { $rows[$row['entryid']] = array('votes' => $row['votes'], 'points' => $row['points'], 'visits' => $row['visits']); } } $this->prepareExits($entries); // Add karma block to the footer of each entry // // The entries array was populated, above, so its keys match the eventData array, // and overview entries are skipped if "extended only" is enabled foreach (array_keys($entries) as $i) { // Get the statistics $entryid = $eventData[$i]['id']; $votes = !empty($rows[$entryid]['votes']) ? $rows[$entryid]['votes'] : 0; $points = !empty($rows[$entryid]['points']) ? $rows[$entryid]['points'] : 0; $visits = !empty($rows[$entryid]['visits']) ? $rows[$entryid]['visits'] : 0; $enough_votes = $track_karma && $votes >= $this->get_config('min_disp_votes', 0); $enough_visits = $track_clicks && $visits >= $this->get_config('min_disp_visits', 0); $textual_msg = true; $textual_current = true; $textual_visits = true; if ($this->image_name != '0') { $textual_msg = $this->get_config('textual_msg', 'true'); $textual_current = $this->get_config('textual_current', 'true'); $textual_visits = $this->get_config('textual_visits', 'true'); } // Where's the footer? Normally it would be // in eventData[n]['add_footer'] but if the // cache plugin is used, it's in // eventData[n]['properties']['ep_cache_add_footer']. // This method retrieves it either way. $footer =& $this->getFieldReference('add_footer', $eventData[$i]); // Depending on what existed, $footer could // be referencing the cached version, the // uncached version, or even a new empty // string. In particular, if $eventData[$i] // has no properties, and no 'add_footer' key, // $footer is referencing a new empty string, // so adding a karma bar to $footer would do // nothing. // // We could be referencing an empty uncached // 'add_footer', but empty cache entries are // never returned. // // Reference a footer that will be printed if (empty($footer) && !isset($eventData[$i]['add_footer']) && is_array($eventData[$i])) { $eventData[$i]['add_footer'] = ''; $footer =& $eventData[$i]['add_footer']; // It's still empty, but it's referencing // the right place. } if ($track_exits) { $footer .= $this->getExits($entryid, true); } // Pick the appropriate intro msg and rating bar // No msg or bar if karma is disabled if ($track_karma) { if (isset($karma[$entryid])) { // We already voted for this one $temp = $this->karmaVoted($karma[$entryid], $points, $votes); $myvote = $temp['myvote']; $msg = $temp['msg']; $bar = $temp['bar']; } elseif ($eventData[$i]['timestamp'] < $now - $max_karmatime) { // Too late to vote for this one $msg = '<div class="serendipity_karmaClosed">' . sprintf(PLUGIN_KARMA_CLOSED, $karmatime) . '</div>'; // Just a current rating bar, if any $bar = $this->createRatingBar(null, $points, $votes); } else { // We can vote for this; make the whole voting block $rate_msg = $this->get_config('rate_msg', PLUGIN_KARMA_VOTETEXT); $msg = '<div class="serendipity_karmaVoting_text">' . $rate_msg . '</div>'; // Full voting bar $bar = $this->createRatingBar($entryid, $points, $votes); } } // Create the karma block $temp = $this->createkarmaBlock($entryid, $textual_msg, $msg, $bar, $enough_votes, $textual_current, $enough_visits, $textual_visits, $points, $votes); $karma_block = $temp['karma_block']; $points = $temp['points']; /* print("<h3>--DEBUG: Karma block code:</h3>\n<pre>\n"); print_r(htmlspecialchars($karma_block)); print("\n</pre>\n"); */ // Substitute the % stuff and add it to the footer $eventData[$i]['properties']['myvote'] = $myvote; $eventData[$i]['properties']['points'] = $points; $eventData[$i]['properties']['votes'] = $votes; $eventData[$i]['properties']['visits'] = $visits; $footer .= sprintf($karma_block, $myvote, $points, $votes, $visits, $url); } // foreach key in entries } // End switch on karma voting status return true; break; // Display the Karma Log link on the sidebar // Display the Karma Log link on the sidebar case 'backend_sidebar_admin_appearance': ?> <li><a href="?serendipity[adminModule]=event_display&serendipity[adminAction]=karmalog"><?php echo PLUGIN_KARMA_DISPLAY_LOG; ?> </a></li> <?php return true; break; // Display the Karma Log! //case 'external_plugin': // Display the Karma Log! //case 'external_plugin': case 'backend_sidebar_entries_event_display_karmalog': // Print any stored messages //foreach ($serendipity['karma_messages'] as $msg) { // print("<div class='serendipityAdminInfo'>$msg</div>\n"); //} // Was I asked to process any votes? if (($serendipity['POST']['delete_button'] || $serendipity['POST']['approve_button']) && sizeof($serendipity['POST']['delete']) != 0 && serendipity_checkFormToken()) { foreach ($serendipity['POST']['delete'] as $d => $i) { $kdata = $serendipity['POST']['karmalog' . $i]; // validate posted variables // posted points $ppoints = $kdata['points']; if (!is_numeric($ppoints) || (int) $ppoints < -2 || (int) $ppoints > 2) { print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n"; return false; } // posted id $pid = $kdata['entryid']; if (!is_numeric($pid)) { print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n"; return false; } // posted IP $pip = long2ip(ip2long($kdata['ip'])); if ($pip == -1 || $pip === FALSE) { print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n"; return false; } // posted user agent (need a better validator, I think) $puser_agent = $kdata['user_agent']; if (serendipity_db_escape_string($puser_agent) != $puser_agent) { print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n"; return false; } // posted vote time $pvotetime = $kdata['votetime']; $unixsecs = date('U', $kdata['votetime']); if ($pvotetime != $unixsecs) { print "<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_INVALID_INPUT . "</span>\n"; return false; } // Remove karma from entry? if ($serendipity['POST']['delete_button']) { // Fetch vote total for the entry IDs $q = 'SELECT k.* FROM ' . $serendipity['dbPrefix'] . 'karma AS k WHERE k.entryid IN (' . $pid . ') GROUP BY k.entryid'; $sql = serendipity_db_query($q); if (is_array($sql)) { $karma = $sql[0]; $update = sprintf("UPDATE {$serendipity['dbPrefix']}karma\n SET points = %s,\n votes = %s\n WHERE entryid = %s", serendipity_db_escape_string($karma['points'] - $ppoints), serendipity_db_escape_string($karma['votes'] - 1), serendipity_db_escape_string($pid)); $updated = serendipity_db_query($update); if ($updated != 1) { printf("<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_REMOVE_ERROR . "</span>\n", $pid); // Don't delete from karma log if we couldn't take away the points continue; } } else { // This will only happen if someone is messing with the karma table or submit data printf("<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_UPDATE_ERROR . "</span>", $pid); continue; } } // Remove vote from log (approved or deleted, doesn't matter) $del = sprintf("DELETE FROM {$serendipity['dbPrefix']}karmalog\n WHERE entryid = %s AND ip = '%s' AND user_agent LIKE '%%%s%%' AND votetime = %s LIMIT 1", serendipity_db_escape_string($pid), serendipity_db_escape_string($pip), serendipity_db_escape_string($puser_agent), serendipity_db_escape_string($pvotetime)); $deleted = serendipity_db_query($del); // User feedback if ($deleted == 1) { if ($serendipity['POST']['delete_button']) { printf("<span class='msg_success'><span class='icon-ok-circled'></span> " . PLUGIN_KARMA_REMOVED_POINTS . "</span>\n", $ppoints, $pid); } else { printf("<span class='msg_success'><span class='icon-ok-circled'></span> " . PLUGIN_KARMA_APPROVED_POINTS . "</span>\n", $ppoints, $pid); } } else { printf("<span class='msg_error'><span class='icon-attention-circled'></span> " . PLUGIN_KARMA_REMOVE_ERROR . "</span>\n", $pid); } } } // URL; expected to be event_display and karmalog, respectively $url = '?serendipity[adminModule]=' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['adminModule']) : htmlspecialchars($serendipity['GET']['adminModule'], ENT_COMPAT, LANG_CHARSET)) . '&serendipity[adminAction]=' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['adminAction']) : htmlspecialchars($serendipity['GET']['adminAction'], ENT_COMPAT, LANG_CHARSET)); // Filters print "\n<h2>" . PLUGIN_KARMA_DISPLAY_LOG . "</h2>\n<form id='karmafilters' name='karmafilters' action='' method='get'>\n <input name='serendipity[adminModule]' type='hidden' value='{$serendipity['GET']['adminModule']}'>\n <input name='serendipity[adminAction]' type='hidden' value='{$serendipity['GET']['adminAction']}'>\n\n <ul class='filters_toolbar clearfix plainList'>\n <li><a class='button_link' href='#serendipity_admin_filters' title='" . FILTERS . "'><span class='icon-filter'></span><span class='visuallyhidden'> " . FILTERS . "</span></a></li>\n <li><a class='button_link' href='#serendipity_admin_sort' title='" . SORT_ORDER . "'><span class='icon-sort'></span><span class='visuallyhidden'> " . SORT_ORDER . "</span></a></li>\n </ul>\n\n <fieldset id='serendipity_admin_filters' class='additional_info filter_pane'>\n <legend><span class='visuallyhidden'>" . FILTERS . "</span></legend>\n\n <div class='clearfix'>\n <div class='form_field'>\n <label for='serendipity_filter_useragent'>User Agent</label>\n <input id='serendipity_filter_useragent' name='serendipity[filter][user_agent]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['user_agent']) : htmlspecialchars($serendipity['GET']['filter']['user_agent'], ENT_COMPAT, LANG_CHARSET)) . "'>\n </div>\n\n <div class='form_field'>\n <label for='serendipity_filter_ip'>" . IP . "</label>\n <input id='serendipity_filter_ip' name='serendipity[filter][ip]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['ip']) : htmlspecialchars($serendipity['GET']['filter']['ip'], ENT_COMPAT, LANG_CHARSET)) . "'>\n </div>\n\n <div class='form_field'>\n <label for='serendipity_filter_entryid'>Entry ID</label>\n <input id='serendipity_filter_entryid' name='serendipity[filter][entryid]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['entryid']) : htmlspecialchars($serendipity['GET']['filter']['entryid'], ENT_COMPAT, LANG_CHARSET)) . "'>\n </div>\n\n <div class='form_field'>\n <label for='serendipity_filter_title'>Entry title</label>\n <input id='serendipity_filter_title' name='serendipity[filter][title]' type='text' value='" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($serendipity['GET']['filter']['title']) : htmlspecialchars($serendipity['GET']['filter']['title'], ENT_COMPAT, LANG_CHARSET)) . "'>\n </div>\n </div>\n\n <div class='form_buttons'>\n <input name='submit' type='submit' value='" . GO . "'>\n </div>\n </fieldset>\n"; // Set all filters into $and and $searchString if (!empty($serendipity['GET']['filter']['entryid'])) { $val = $serendipity['GET']['filter']['entryid']; $and .= "AND l.entryid = '" . serendipity_db_escape_string($val) . "'"; $searchString .= "&serendipity['filter']['entryid']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET)); } if (!empty($serendipity['GET']['filter']['ip'])) { $val = $serendipity['GET']['filter']['ip']; $and .= "AND l.ip = '" . serendipity_db_escape_string($val) . "'"; $searchString .= "&serendipity['filter']['ip']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET)); } if (!empty($serendipity['GET']['filter']['user_agent'])) { $val = $serendipity['GET']['filter']['user_agent']; $and .= "AND l.user_agent LIKE '%" . serendipity_db_escape_string($val) . "%'"; $searchString .= "&serendipity['filter']['user_agent']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET)); } if (!empty($serendipity['GET']['filter']['title'])) { $val = $serendipity['GET']['filter']['title']; $and .= "AND e.title LIKE '%" . serendipity_db_escape_string($val) . "%'"; $searchString .= "&serendipity['filter']['title']=" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($val) : htmlspecialchars($val, ENT_COMPAT, LANG_CHARSET)); } // Sorting (controls go after filtering controls in form above) $sort_order = array('votetime' => DATE, 'user_agent' => USER_AGENT, 'title' => TITLE, 'entryid' => 'ID'); if (empty($serendipity['GET']['sort']['ordermode']) || $serendipity['GET']['sort']['ordermode'] != 'ASC') { $desc = true; $serendipity['GET']['sort']['ordermode'] = 'DESC'; } if (!empty($serendipity['GET']['sort']['order']) && !empty($sort_order[$serendipity['GET']['sort']['order']])) { $curr_order = $serendipity['GET']['sort']['order']; $orderby = serendipity_db_escape_string($curr_order . ' ' . $serendipity['GET']['sort']['ordermode']); } else { $curr_order = 'votetime'; $orderby = 'votetime ' . serendipity_db_escape_string($serendipity['GET']['sort']['ordermode']); } print "\n <fieldset id='serendipity_admin_sort' class='additional_info filter_pane'>\n <legend><span class='visuallyhidden'>" . SORT_ORDER . "</span></legend>\n\n <div class='clearfix'>\n <div class='form_select'>\n <label for='serendipity_sort_order'>" . SORT_BY . "</label>\n <select id='serendipity_sort_order' name='serendipity[sort][order]'>\n"; foreach ($sort_order as $order => $val) { print "\n <option value='{$order}'" . ($curr_order == $order ? " selected='selected'" : '') . ">{$val}</option>\n"; } print "\n </select>\n </div>\n <div class='form_select'>\n <label for='serendipity_sort_ordermode'>" . SORT_ORDER . "</label>\n <select id='serendipity_sort_ordermode' name='serendipity[sort][ordermode]'>\n <option value='DESC'" . ($desc ? " selected='selected'" : '') . ">" . SORT_ORDER_DESC . "</option>\n <option value='ASC'" . ($desc ? '' : " selected='selected'") . ">" . SORT_ORDER_ASC . "</option>\n </select>\n </div>\n </div>\n\n <div class='form_buttons'>\n <input name='submit' type='submit' value='" . GO . "'>\n </div>\n </fieldset>\n</form>\n"; // Paging (partly ripped from include/admin/comments.inc.php) $commentsPerPage = (int) (!empty($serendipity['GET']['filter']['perpage']) ? $serendipity['GET']['filter']['perpage'] : 25); $sql = serendipity_db_query("SELECT COUNT(*) AS total FROM {$serendipity['dbPrefix']}karmalog l WHERE 1 = 1 " . $and, true); if (is_string($sql)) { print "<span class='msg_error'><span class='icon-attention-circled'></span> " . $sql . "</span>\n"; } $totalVotes = is_array($sql) && is_int($sql['total']) ? $sql['total'] : 0; $pages = $commentsPerPage == COMMENTS_FILTER_ALL ? 1 : ceil($totalVotes / (int) $commentsPerPage); $page = (int) $serendipity['GET']['page']; if ($page == 0 || $page > $pages) { $page = 1; } if ($page > 1) { $linkPrevious = $url . '&serendipity[page]=' . ($page - 1) . $searchString; } if ($pages > $page) { $linkNext = $url . '&serendipity[page]=' . ($page + 1) . $searchString; } if ($commentsPerPage == COMMENTS_FILTER_ALL) { $limit = ''; } else { $limit = serendipity_db_limit_sql(serendipity_db_limit(($page - 1) * (int) $commentsPerPage, (int) $commentsPerPage)); } // Variables for display if ($linkPrevious) { $linkPrevious = '<a class="button_link" href="' . $linkPrevious . '" title="' . PREVIOUS . '"><span class="icon-left-dir"></span><span class="visuallyhidden"> ' . PREVIOUS . '</span></a>'; } else { $linkPrevious = '<span class="visuallyhidden">' . NO_ENTRIES_TO_PRINT . '</span>'; } if ($linkNext) { $linkNext = '<a class="button_link" href="' . $linkNext . '" title="' . NEXT . '"><span class="visuallyhidden">' . NEXT . ' </span><span class="icon-right-dir"></span></a>'; } else { $linkNext = '<span class="visuallyhidden">' . NO_ENTRIES_TO_PRINT . '</span>'; } $paging = sprintf(PAGE_BROWSE_COMMENTS, $page, $pages, $totalVotes); // Retrieve the next batch of karma votes // [entryid, points, ip, user_agent, votetime] $sql = serendipity_db_query("SELECT l.entryid AS entryid, l.points AS points, l.ip AS ip, l.user_agent AS user_agent, l.votetime AS votetime, e.title AS title FROM {$serendipity['dbPrefix']}karmalog l\n LEFT JOIN {$serendipity['dbPrefix']}entries e ON (e.id = l.entryid)\n WHERE 1 = 1 " . $and . "\n ORDER BY {$orderby} {$limit}"); // Start the form for display and deleting if (is_array($sql)) { print "<form action='' method='post' name='formMultiDelete' id='formMultiDelete'>\n" . serendipity_setFormToken(); // Start the vote table print "\n<div class='clearfix karma_pane'>\n<ul id='karmalog' class='clearfix karmalog plainList zebra_list'>\n"; // Print each vote $i = 0; foreach ($sql as $vote) { $i++; // entryid, title, points, ip, user_agent, votetime if (strlen($vote['title']) > 40) { $votetitle = substr($vote['title'], 0, 40) . '…'; } else { $votetitle = $vote['title']; } $entrylink = serendipity_archiveURL($vote['entryid'], $vote['title'], 'serendipityHTTPPath', true); $entryFilterHtml = "<a class='button_link filter_karma' href='{$url}&serendipity[filter][entryid]={$vote['entryid']}' title='" . FILTERS . "'><span class='icon-filter'></span><span class='visuallyhidden'>" . FILTERS . "</span></a>"; $ipFilterHtml = "<a class='button_link filter_karma' href='{$url}&serendipity[filter][ip]={$vote['ip']}' title='" . FILTERS . "'><span class='icon-filter'></span><span class='visuallyhidden'>" . FILTERS . "</span></a>"; $timestr = strftime('%a %b %d %Y, %H:%M:%S', $vote['votetime']); $cssClass = $i % 2 == 0 ? 'even' : 'odd'; $barClass = str_replace(array('.', ' '), array('_', '_'), $this->image_name); $barHtml = $this->createRatingBar(null, $vote['points'], 1, $barClass); $barHtml = sprintf($barHtml, 'what', $vote['points'], '1'); print "\n <li id='karma_{$i}' class='{$cssClass} clearfix'>\n <input type='hidden' name='serendipity[karmalog{$i}][points]' value='{$vote['points']}'>\n <input type='hidden' name='serendipity[karmalog{$i}][entryid]' value='{$vote['entryid']}'>\n <input type='hidden' name='serendipity[karmalog{$i}][votetime]' value='{$vote['votetime']}'>\n <input type='hidden' name='serendipity[karmalog{$i}][ip]' value='{$vote['ip']}'>\n <input type='hidden' name='serendipity[karmalog{$i}][user_agent]' value='{$vote['user_agent']}'>\n\n <div class='form_check'>\n <input id='multidelete_karma_{$i}' class='multidelete' type='checkbox' name='serendipity[delete][{$i}]' value='{$i}' data-multidelid='karma_{$i}'>\n <label for='multidelete_karma_{$i}' class='visuallyhidden'>" . TOGGLE_SELECT . "</label>\n </div>\n\n <h4><a href='{$entrylink}' title='ID: {$vote['entryid']}'>{$votetitle}</a>\n <button class='toggle_info button_link' type='button' data-href='#karma_data_{$i}'><span class='icon-info-circled'></span><span class='visuallyhidden'> " . MORE . "</span></button>\n {$entryFilterHtml}\n </h4>\n\n {$barHtml}\n\n <div id='karma_data_{$i}' class='additional_info'>\n <dl class='clearfix comment_data'>\n <dt>" . ON . "</dt>\n <dd>{$timestr}</dd>\n <dt>IP</dt>\n <dd>{$vote['ip']} {$ipFilterHtml}</dd>\n <dt><abbr title='User-Agent' lang='en'>UA</abbr></dt>\n <dd>{$vote['user_agent']}</dd>\n </dl>\n </div>\n </li>\n"; } // End the vote table print "\n </ul>\n "; // Print the footer paging table print "\n<nav class='pagination'>\n <h3>{$paging}</h3>\n <ul class='clearfix'>\n <li class='prev'>{$linkPrevious}</li>\n <li class='next'>{$linkNext}</li>\n </ul>\n</nav>\n</div>\n"; if (is_array($sql)) { print "\n<div class='form_buttons'>\n<input class='invert_selection' name='toggle' type='button' value='" . INVERT_SELECTIONS . "'> \n<input class='state_cancel' name='serendipity[delete_button]' type='submit' title='" . PLUGIN_KARMA_DELETE_VOTES . "' value='" . DELETE . "'>\n</div>\n</form>\n"; } } else { print "\n<span class='msg_notice'><span class='icon-info-circled'></span> No logs to display. You need to enable karma logging, if you want to see single votes displayed here.</span>\n"; } return true; break; default: return false; } // End switch on event hooks } else { return false; } }
/** * Display HTML output data of a Exit/Referrer list * * @access public * @see serendipity_displayTopExits() * @see serendipity_displayTopReferrers() * @param string Name of the DB table to show data from (exits|referrers) * @param boolean Whether to use HTML links for URLs * @param int Interval for which the top exits are aggregated * @return */ function serendipity_displayTopUrlList($list, $limit, $use_links = true, $interval = 7) { global $serendipity; if ($limit) { $limit = serendipity_db_limit_sql($limit); } /* HACK */ if (preg_match('/^mysqli?/', $serendipity['dbType'])) { /* Nonportable SQL due to MySQL date functions, * but produces rolling 7 day totals, which is more * interesting */ $query = "SELECT scheme, host, SUM(count) AS total\n FROM {$serendipity['dbPrefix']}{$list}\n WHERE day > date_sub(current_date, interval " . (int) $interval . " day)\n GROUP BY host\n ORDER BY total DESC, host\n {$limit}"; } else { /* Portable version of the same query */ $query = "SELECT scheme, host, SUM(count) AS total\n FROM {$serendipity['dbPrefix']}{$list}\n GROUP BY scheme, host\n ORDER BY total DESC, host\n {$limit}"; } $rows = serendipity_db_query($query); echo "<span class='serendipityReferer'>"; if (is_array($rows)) { foreach ($rows as $row) { if ($use_links) { printf('<a href="%1$s://%2$s" title="%2$s" >%2$s</a> (%3$s)<br />', htmlspecialchars($row['scheme']), htmlspecialchars($row['host']), htmlspecialchars($row['total'])); } else { printf('%1$s (%2$s)<br />', htmlspecialchars($row['host']), htmlspecialchars($row['total'])); } } } echo "</span>"; }
function event_hook($event, &$bag, &$eventData, $addData = null) { global $serendipity; $hooks =& $bag->get('event_hooks'); if (isset($hooks[$event])) { // Moved from above: only get image data if we're actually going to do something $this->set_valid_image_data(); // Get dimensions of image, only if not text-only if ($this->image_name) { // Is this a single-image bar, or a single segment? $ratio = $this->image_width / $this->image_height; if ($ratio < $max_segment_ratio) { // This is probably a single segment. Square segments // will have a ratio of 0.3; long, flat segments won't // get up to 1.0 unless they're 3 times as wide as they // are tall; full-bar images with square segments will // be 1.666; and full-bar images with tall, narrow // segments will be greater than 1.0 unless they're // nearly twice as high as they are wide. $this->image_width = $this->image_width * 5; } } switch ($event) { // Early hook, before any page is displayed case 'frontend_configure': // Make sure the karmaVote cookie is set, even if empty <a name="#1" /> if (!isset($serendipity['COOKIE']['karmaVote'])) { serendipity_setCookie('karmaVote', serialize(array())); } // If user didn't vote, we're done. if (!isset($serendipity['GET']['karmaId']) || !isset($serendipity['GET']['karmaVote'])) { return; } // Get URL vote data $this->karmaId = (int) $serendipity['GET']['karmaId']; $this->karmaVoting = (int) $serendipity['GET']['karmaVote']; // karmaVote cookie was just set (see name="#1"); this boils down to // "if check cookie isn't 1, there's no real cookie". // The check cookie gets set when a rater is displayed, // so you've got no business voting if you haven't even // seen the rater yet. if (!isset($serendipity['COOKIE']['karmaVote']) or $serendipity['COOKIE']['check'] != '1') { $this->karmaVote = 'nocookie'; return; } // Everything is ready. Get the cookie vote data. $karma = unserialize($serendipity['COOKIE']['karmaVote']); // Stop on invalid votes (cookie invalid, or URL data incorrect) if (!is_array($karma) || !is_numeric($this->karmaVoting) || !is_numeric($this->karmaId) || $this->karmaVoting > 2 || $this->karmaVoting < -2) { $this->karmaVote = 'invalid1'; return; } // Stop if the cookie says we already voted if (!empty($karma[$this->karmaId])) { $this->karmaVote = 'alreadyvoted'; return; } // We don't want bots hitting the karma-voting $agent = $_SERVER['HTTP_USER_AGENT']; if (stristr($agent, 'google') || stristr($agent, 'LinkWalker') || stristr($agent, 'zermelo') || stristr($agent, 'NimbleCrawler')) { $this->karmaVote = 'invalid1'; return; } // Voting takes place here. // // Get voting data from the database (keeps all entries, // even if no karma match) $q = 'SELECT * FROM ' . $serendipity['dbPrefix'] . 'entries AS e LEFT OUTER JOIN ' . $serendipity['dbPrefix'] . 'karma AS k ON e.id = k.entryid WHERE e.id = ' . serendipity_db_escape_string($this->karmaId) . ' LIMIT 1'; $row = serendipity_db_query($q, true); // If there's no entry with this ID, we're done // // --TODO: Modify the plugin to allow arbitrary voting with generated IDs if (!isset($row) || !is_array($row)) { $this->karmaVote = 'invalid2'; return; } $now = time(); if ($row['votes'] === '0' || $row['votes'] > 0) { // Votes for this entry already exist. Do some checking. $max_entrytime = $this->get_config('max_entrytime', 1440) * 60; $max_votetime = $this->get_config('max_votetime', 5) * 60; $max_karmatime = $this->get_config('max_karmatime', 7) * 24 * 60 * 60; // Allow infinite voting when 0 or negative if ($max_karmatime <= 0) { $max_karmatime = $now; } // If the entry's timestamp is too old for voting, // we're done. if ($row['timestamp'] < $now - $max_karmatime) { $this->karmaVote = 'timeout2'; return; } // If the entry is in the grace period, or votes // aren't too close together, record the vote. if ($row['timestamp'] > $now - $max_entrytime || $row['lastvote'] + $max_votetime < $now || $row['lastvote'] == 0) { // Update votes $q = sprintf("UPDATE {$serendipity['dbPrefix']}karma\n SET points = %s,\n votes = %s,\n lastvote = %s\n WHERE entryid = %s", $row['points'] + $this->karmaVoting, $row['votes'] + 1, $now, $this->karmaId); serendipity_db_query($q); } else { // Entry was too recently voted upon. Figure out // how long until voting will be allowed (in minutes). $this->karmaVote = 'timeout'; $this->karmaTimeOut = abs(ceil(($now - ($row['lastvote'] + $max_votetime)) / 60)); return; } } else { // No row. Use INSERT instead of UPDATE. $q = sprintf("INSERT INTO {$serendipity['dbPrefix']}karma\n (entryid, points, votes, lastvote, visits)\n VALUES (%s, %s, %s, %s, %s)", $this->karmaId, $this->karmaVoting, 1, $now, 0); $sql = serendipity_db_query($q); } // Log the vote if (serendipity_db_bool($this->get_config('logging', false))) { $q = sprintf("INSERT INTO {$serendipity['dbPrefix']}karmalog\n (entryid, points, ip, user_agent, votetime)\n VALUES (%s, %s, '%s', '%s', %s)", $this->karmaId, $this->karmaVoting, serendipity_db_escape_string($_SERVER['REMOTE_ADDR']), substr(serendipity_db_escape_string($_SERVER['HTTP_USER_AGENT']), 0, 255), $now); $sql = serendipity_db_query($q); if (is_string($sql)) { mail($serendipity['serendipityEmail'], 'KARMA ERROR', $q . '<br />' . $sql . '<br />'); } } // Set the cookie that we already voted for this entry $karma[$this->karmaId] = $this->karmaVoting; $this->karmaVote = 'voted'; serendipity_setCookie('karmaVote', serialize($karma)); return true; break; // CSS generation hooks // CSS generation hooks case 'backend_header': // Generate the CSS for the graphical rating bar selector // // The CSS appears to be generated in a completely // different instance of Serendipity, as if index.php gets // called separately for the CSS. // // Note that the css_backend hook adds properties to the // serendipity_admin.css, but that file is *always* // cached. We use backend_header and add the CSS to the // HEAD styles to make it dynamic. // Get the CSS, set $this->image_name so we'll output the // standard graphical CSS prologue if any images are found. $this->createRatingSelector(); print "<style type='text/css'>\n"; $align = 'center'; $bg = $this->get_config('preview_bg', false); if (!empty($bg)) { if (strpos($bg, ';') !== false || strpos($bg, ',') !== false) { $bg = 'red'; } print "\n.serendipity_karmaVote_selectorTable {\n background: {$bg};\n}\n"; } print "\n.serendipityAdminContent .serendipity_karmaVoting_links {\n margin: 5px;\n}\n"; case 'css': // Some CSS notes: // // .serendipity_karmaVoting is the class for the karma wrapper/container, // including the text explanations, messages, and rating bar. // (currently a div) // .serendipity_karmaVoting a specifies the links for the text-mode // rating bar // .serendipity_karmaError is the class for any text indicating an // error condition // .serendipity_karmaSuccess is the class for any text indicating // successful operation // .serendipity_karmaVoting_links is the container for the graphical // rating bar (currently an ol) // .serendipity_karmaVoting_links a indicates the various voting links in // the graphical rating bar // .serendipity_karmaVoting_current-rating is the class for the current // rating in the graphical rating bar // a.serendipity_karmaVoting_link1, _link2, etc are the classes applied // to the individual voting links // Note that there are two possible template types: early // templates that only handle the text rating bars, and // newer templates that understand the graphical raters. // We check for both types and act appropriately. /*--JAM: Let's just skip this whole hassle if (!$align) { $align = $this->get_config('alignment', 'detect'); } if ($align == 'detect') { */ $align = $this->get_config('alignment', 'center'); // Try to let the template take care of it if ($this->image_name == '0') { // Text-only rating bar is used if (strpos($eventData, '.serendipity_karmaVoting')) { // Template is handling all our CSS return true; } } /* --JAM: else { // Graphical rating bar is used if (strpos($eventData, '.serendipity_karmaVoting_images')) { // Template is handling all our CSS return true; } // Check for old text-only templates $pos = strpos($eventData, '.serendipity_karmaVoting'); while ($pos && ($align == 'detect')) { // Find text-align: in the current block $endpos = strpos($eventData, '}', $pos); if (!$endpos) { // Broken CSS break; } $alignpos = strpos($eventData, 'text-align:', $pos); // Can't check for comments, or I would. Hope // the first is the correct one. if ($alignpos && $alignpos < $endpos) { $start = $alignpos + 11; $alignend = strpos($eventData, ';', $alignpos); if ($alignend) { // All valid. Pull out the alignment. $len = $alignend - $start; $align = trim(substr($eventData, $start, $len)); } } $pos = strpos($eventData, '.serendipity_karmaVoting', $endpos); } // I should have a valid alignment or 'detect' in $align now. } } // If we couldn't detect the alignment, guess 'right' if ($align == 'detect') { $align = 'right'; } --JAM: END COMMENT BLOCK */ // Since errors might be printed at any time, always // output the text-mode CSS print <<<EOS .serendipity_karmaVoting { text-align: {$align}; font-size: 7pt; margin: 0px; } .serendipity_karmaVoting a { font-size: 7pt; text-decoration: none; } .serendipity_karmaVoting a:hover { color: green; } .serendipity_karmaError { color: #FF8000; } .serendipity_karmaSuccess { color: green; } EOS; // Only output the image CSS if it's needed if ($this->image_name != '0') { $img = $serendipity['baseURL'] . "plugins/serendipity_event_karma/img/" . $this->image_name; $h = $this->image_height / 3; $w = $this->image_width; switch ($align) { case 'left': $margin = '0px auto 0px 0px'; break; case 'center': $margin = '0px auto'; break; case 'right': default: $margin = '0px 0px 0px auto'; break; } // The CSS here is lifted largely from // http://komodomedia.com/blog/index.php/2007/01/20/css-star-rating-redux/ // // Note, however that margin has been changed for // multiple cases and all unitless measurements have // been specified in pixels. Additionally, measures // have been taken to align the text. print <<<END_IMG_CSS .serendipity_karmaVoting_links, .serendipity_karmaVoting_links a:hover, .serendipity_karmaVoting_current-rating { background: url({$img}) left; font-size: 0; } .serendipity_karmaVoting_links { position: relative; width: {$w}px; height: {$h}px; overflow: hidden; list-style: none; margin: {$margin}; padding: 0px; background-position: left top; text-align: center; } .serendipity_karmaVoting_links li { display: inline; } .serendipity_karmaVoting_links a , .serendipity_karmaVoting_current-rating { position:absolute; top: 0px; left: 0px; text-indent: -9000em; height: {$h}px; line-height: {$h}px; outline: none; overflow: hidden; border: none; } .serendipity_karmaVoting_links a:hover { background-position: left bottom; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link1 { width: 20%; z-index: 6; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link2 { width: 40%; z-index: 5; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link3 { width: 60%; z-index: 4; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link4 { width: 80%; z-index: 3; } .serendipity_karmaVoting_links a.serendipity_karmaVoting_link5 { width: 100%; z-index: 2; } .serendipity_karmaVoting_links .serendipity_karmaVoting_current-rating { z-index: 1; background-position: left center; } END_IMG_CSS; // Add selector images CSS, if necessary if (!empty($this->select_css)) { print $this->select_css; } } // End if image bar defined if ($event == 'backend_header') { print "\n</style>\n"; } return true; break; //--TODO: Comment the functionality of this event hook. //--TODO: Comment the functionality of this event hook. case 'event_additional_statistics': $sql = array(); $sql['visits_top'] = array('visits', 'DESC'); $sql['visits_bottom'] = array('visits', 'ASC'); $sql['votes_top'] = array('votes', 'DESC'); $sql['votes_bottom'] = array('votes', 'ASC'); $sql['points_top'] = array('points', 'DESC'); $sql['points_bottom'] = array('points', 'ASC'); foreach ($sql as $key => $rows) { $q = "SELECT e.id,\n e.title,\n e.timestamp,\n SUM(k.{$rows[0]}) AS no\n FROM {$serendipity['dbPrefix']}karma\n AS k\n JOIN {$serendipity['dbPrefix']}entries\n AS e\n ON k.entryid = e.id\n WHERE k.{$rows[0]} IS NOT NULL AND k.{$rows[0]} != 0\n GROUP BY e.id, e.title, e.timestamp ORDER BY no {$rows[1]} LIMIT {$addData['maxitems']}"; $sql_rows = serendipity_db_query($q); ?> <dt><strong><?php echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($key)); ?> </strong></dt> <dl> <?php if (is_array($sql_rows)) { foreach ($sql_rows as $id => $row) { ?> <dt><strong><a href="<?php echo serendipity_archiveURL($row['id'], $row['title'], 'serendipityHTTPPath', true, array('timestamp' => $row['timestamp'])); ?> "><?php echo htmlspecialchars($row['title']); ?> </a></strong></dt> <dd><?php echo $row['no']; ?> <?php echo constant('PLUGIN_KARMA_STATISTICS_' . strtoupper($rows[0]) . '_NO'); ?> </dd> <?php } } ?> </dl> <?php } return true; break; // Add voting information to entries // Add voting information to entries case 'entry_display': // Update database if necessary if ($this->get_config('dbversion', 0) != PLUGIN_KARMA_DB_VERSION) { $this->checkScheme(); } // Find the ID of this entry if (isset($serendipity['GET']['id'])) { $entryid = (int) serendipity_db_escape_string($serendipity['GET']['id']); } elseif (preg_match(PAT_COMMENTSUB, $_SERVER['REQUEST_URI'], $matches)) { $entryid = (int) $matches[1]; } else { $entryid = false; } // If we're actually reading the entry, not voting or editing it... if ($entryid && empty($serendipity['GET']['adminAction']) && !$serendipity['GET']['karmaVote']) { // Update the number of visits // Are we supposed to track visits? $track_clicks = serendipity_db_bool($this->get_config('visits_active', true)) && $this->track_clicks_allowed_by_user(); if ($track_clicks && $_SERVER['REQUEST_METHOD'] == 'GET') { $sql = serendipity_db_query("UPDATE {$serendipity['dbPrefix']}karma \n SET visits = visits + 1 \n WHERE entryid = {$entryid}", true); if (serendipity_db_affected_rows() < 1) { serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}karma (entryid, points, votes, lastvote, visits) \n VALUES ('{$entryid}', 0, 0, 0, 1)"); } } } // Set a cookie to look for later, verifying that cookies are enabled serendipity_setCookie('check', '1'); switch ($this->karmaVote) { case 'nocookie': // Users with no cookies won't be able to vote. $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_NOCOOKIE . '</div>'; // Continue until output // Continue until output case 'timeout2': if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_CLOSED . '</div>'; } // Continue until output // Continue until output case 'timeout': if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . sprintf(PLUGIN_KARMA_TIMEOUT, $this->karmaTimeOut) . '</div>'; } // Continue until output // Continue until output case 'alreadyvoted': if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_ALREADYVOTED . '</div>'; } // Continue until output // Continue until output case 'invalid1': case 'invalid2': case 'invalid': // Set message if (!isset($msg)) { $msg = '<div class="serendipity_karmaVoting serendipity_karmaError"><a id="karma_vote' . $this->karmaId . '"></a>' . PLUGIN_KARMA_INVALID . '</div>'; } // Continue until output /* OUTPUT MESSAGE */ //--TODO: Shouldn't this work with the cache plugin, too? if ($addData['extended']) { $eventData[0]['exflag'] = 1; $eventData[0]['add_footer'] .= $msg; } else { $elements = count($eventData); // Find the right container to store our message in. for ($i = 0; $i < $elements; $i++) { if ($eventData[$i]['id'] == $this->karmaId) { $eventData[$i]['add_footer'] .= $msg; } } } break; case 'voted': default: // If there's no data, there's no need to go on if (!is_array($eventData)) { return; } // Find out what the admin wants $track_clicks = serendipity_db_bool($this->get_config('visits_active', true)); $track_karma = serendipity_db_bool($this->get_config('karma_active', true)); if (serendipity_db_bool($this->get_config('karma_active_registered', false))) { if (!serendipity_userLoggedIn()) { $track_karma = false; } } $track_exits = serendipity_db_bool($this->get_config('exits_active', true)); // Get the limits $now = time(); $karmatime = $this->get_config('max_karmatime', 7); $max_karmatime = $karmatime * 24 * 60 * 60; // Accept infinite voting if ($max_karmatime <= 0) { $max_karmatime = $now; } //--TODO: Ensure that this works with the Custom Permalinks plugin // (We've seen trouble; it votes correctly, but redirects to the front page) $url = serendipity_currentURL(true); // Voting is only allowed on entries. Therefore voting URLs must be // either single-entry URLs or summary URLs. serendipity_currentURL // converts them to an "ErrorDocument-URI", so we can focus on the // query portion of the URI. // // Single-entry URLs should be well-defined. They can be permalinks, // of course; otherwise they're of the configured pattern. // // Summary URLs could be a little harder. The summary pages that // include entries are: frontpage, category, author, and archives. // It's possible a plugin would show entries, but if that's the case // we don't need to allow the user to vote on them. Still, that's // a lot of URLs to check for. // // Then there's the problem of the rest of the query. It could // include stuff we really want to keep around, like template // overrides or something. One can even add serendipity variables // to the URL in extreme cases. // // It seems that canonicalizing the URL will be quite difficult. // The only thing we can say for certain is that whatever the // current URL is, it got us to this page, and we'd like to return // to this page after we cast our vote. // Remove any clutter from our previous voting activity $url_parts = parse_url(serendipity_currentURL(true)); if (!empty($url_parts['query'])) { $exclude = array('serendipity[karmaVote]', 'serendipity[karmaId]'); // I tried using parse_str, but it gave me very weird results // with embedded arrays //parse_str($url_parts['query'], $q_parts); $q_parts = array(); // I don't know why this URL has been HTML encoded. Oh well. $pairs = explode('&', $url_parts['query']); foreach ($pairs as $pair) { $parts = explode('=', $pair); $q_parts[$parts[0]] = $parts[1]; } foreach ($q_parts as $key => $value) { if (in_array($key, $exclude)) { $rm = preg_quote("{$key}={$value}"); $url = preg_replace("@(&|&)?{$rm}@", '', $url); } } } if (substr($url, -1) != '?') { $url .= '&'; } // Get the cookie data (past votes, etc) $karma = isset($serendipity['COOKIE']['karmaVote']) ? unserialize($serendipity['COOKIE']['karmaVote']) : array(); // Get all required entry IDs, making keys match keys in eventData $entries = array(); if ($addData['extended'] || $addData['preview']) { // We're in extended or preview mode, we only need the current ID $eventData[0]['exflag'] = 1; $entries[0] = (int) $eventData[0]['id']; } elseif (!serendipity_db_bool($this->get_config('extended_only', false))) { // We're in overview mode, and we want rating bars for all the entry IDs foreach (array_keys($eventData) as $key) { if (isset($eventData[$key]['id'])) { $entries[$key] = (int) $eventData[$key]['id']; } } } // Fetch votes for all entry IDs. Store them in an array for later usage. $q = 'SELECT k.entryid, SUM(votes) AS votes, SUM(points) AS points, SUM(visits) AS visits FROM ' . $serendipity['dbPrefix'] . 'karma AS k WHERE k.entryid IN (' . implode(', ', $entries) . ') GROUP BY k.entryid'; $sql = serendipity_db_query($q); $rows = array(); if ($sql && is_array($sql)) { foreach ($sql as $row) { $rows[$row['entryid']] = array('votes' => $row['votes'], 'points' => $row['points'], 'visits' => $row['visits']); } } $this->prepareExits($entries); // Add karma block to the footer of each entry // // The entries array was populated, above, so its keys match the eventData array, // and overview entries are skipped if "extended only" is enabled foreach (array_keys($entries) as $i) { // Get the statistics $entryid = $eventData[$i]['id']; $votes = !empty($rows[$entryid]['votes']) ? $rows[$entryid]['votes'] : 0; $points = !empty($rows[$entryid]['points']) ? $rows[$entryid]['points'] : 0; $visits = !empty($rows[$entryid]['visits']) ? $rows[$entryid]['visits'] : 0; $enough_votes = $track_karma && $votes >= $this->get_config('min_disp_votes', 0); $enough_visits = $track_clicks && $visits >= $this->get_config('min_disp_visits', 0); $textual_msg = true; $textual_current = true; $textual_visits = true; if ($this->image_name != '0') { $textual_msg = $this->get_config('textual_msg', 'true'); $textual_current = $this->get_config('textual_current', 'true'); $textual_visits = $this->get_config('textual_visits', 'true'); } // Where's the footer? Normally it would be // in eventData[n]['add_footer'] but if the // cache plugin is used, it's in // eventData[n]['properties']['ep_cache_add_footer']. // This method retrieves it either way. $footer =& $this->getFieldReference('add_footer', $eventData[$i]); // Depending on what existed, $footer could // be referencing the cached version, the // uncached version, or even a new empty // string. In particular, if $eventData[$i] // has no properties, and no 'add_footer' key, // $footer is referencing a new empty string, // so adding a karma bar to $footer would do // nothing. // // We could be referencing an empty uncached // 'add_footer', but empty cache entries are // never returned. // // Reference a footer that will be printed if (empty($footer) && !isset($eventData[$i]['add_footer']) && is_array($eventData[$i])) { $eventData[$i]['add_footer'] = ''; $footer =& $eventData[$i]['add_footer']; // It's still empty, but it's referencing // the right place. } if ($track_exits) { $footer .= $this->getExits($entryid, true); } // Pick the appropriate intro msg and rating bar // No msg or bar if karma is disabled if ($track_karma) { if (isset($karma[$entryid])) { // We already voted for this one $msg = '<div class="serendipity_karmaSuccess">' . PLUGIN_KARMA_VOTED . '</div>'; $myvote = $karma[$entryid]; if ($this->get_config('rate_with_words', false)) { $myvote = $this->wordRating($myvote, 1); } elseif ($this->image_name != '0') { $myvote = $this->imageRating($myvote, 1); } // Just a current rating bar, if any $bar = $this->createRatingBar(null, $points, $votes); } elseif ($eventData[$i]['timestamp'] < $now - $max_karmatime) { // Too late to vote for this one $msg = '<div class="serendipity_karmaClosed">' . sprintf(PLUGIN_KARMA_CLOSED, $karmatime) . '</div>'; // Just a current rating bar, if any $bar = $this->createRatingBar(null, $points, $votes); } else { // We can vote for this; make the whole voting block $rate_msg = $this->get_config('rate_msg', PLUGIN_KARMA_VOTETEXT); $msg = '<div class="serendipity_karmaVoting_text">' . $rate_msg . '</div>'; // Full voting bar $bar = $this->createRatingBar($entryid, $points, $votes); } } // Create the karma block $image_class = ''; if ($this->image_name != '0') { $image_class = ' serendipity_karmaVoting_images'; } $karma_block = "<div class='serendipity_karmaVoting{$image_class}'><a id='karma_vote{$entryid}'></a>"; if ($textual_msg) { $karma_block .= $msg; } $karma_block .= $bar; if ($enough_votes && $textual_current) { $curr_msg = $this->get_config('curr_msg', PLUGIN_KARMA_CURRENT); $karma_block .= '<span class="serendipity_karmaVoting_current">' . $curr_msg . '</span>'; } if ($enough_visits && $textual_visits) { $karma_block .= '<span class="serendipity_karmaVoting_visits">' . PLUGIN_KARMA_VISITSCOUNT . '</span>'; } $karma_block .= "\n</div>\n"; // Adjust rating points if ($this->get_config('rate_with_words', false)) { $points = $this->wordRating($points, $votes); } elseif ($this->image_name != '0') { $points = $this->imageRating($points, $votes); } /* print("<h3>--DEBUG: Karma block code:</h3>\n<pre>\n"); print_r(htmlspecialchars($karma_block)); print("\n</pre>\n"); */ // Substitute the % stuff and add it to the footer $eventData[$i]['properties']['myvote'] = $myvote; $eventData[$i]['properties']['points'] = $points; $eventData[$i]['properties']['votes'] = $votes; $eventData[$i]['properties']['visits'] = $visits; $footer .= sprintf($karma_block, $myvote, $points, $votes, $visits, $url); } // foreach key in entries } // End switch on karma voting status return true; break; // Display the Karma Log link on the sidebar // Display the Karma Log link on the sidebar case 'backend_sidebar_entries': ?> <li class="serendipitySideBarMenuLink serendipitySideBarMenuEntryLinks"> <a href="?serendipity[adminModule]=event_display&serendipity[adminAction]=karmalog"> <?php echo PLUGIN_KARMA_DISPLAY_LOG; ?> </a> </li> <?php return true; break; // Display the Karma Log! //case 'external_plugin': // Display the Karma Log! //case 'external_plugin': case 'backend_sidebar_entries_event_display_karmalog': // Print any stored messages //foreach ($serendipity['karma_messages'] as $msg) { // print("<div class='serendipityAdminInfo'>$msg</div>\n"); //} // Was I asked to process any votes? if (($serendipity['POST']['delete_button'] || $serendipity['POST']['approve_button']) && sizeof($serendipity['POST']['delete']) != 0 && serendipity_checkFormToken()) { foreach ($serendipity['POST']['delete'] as $d => $i) { $kdata = $serendipity['POST']['karmalog' . $i]; // validate posted variables // posted points $ppoints = $kdata['points']; if (!is_numeric($ppoints) || (int) $ppoints < -2 || (int) $ppoints > 2) { print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n"; return false; } // posted id $pid = $kdata['entryid']; if (!is_numeric($pid)) { print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n"; return false; } // posted IP $pip = long2ip(ip2long($kdata['ip'])); if ($pip == -1 || $pip === FALSE) { print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n"; return false; } // posted user agent (need a better validator, I think) $puser_agent = $kdata['user_agent']; if (serendipity_db_escape_string($puser_agent) != $puser_agent) { print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n"; return false; } // posted vote time $pvotetime = $kdata['votetime']; $unixsecs = date('U', $kdata['votetime']); if ($pvotetime != $unixsecs) { print "<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_INVALID_INPUT . "</div>\n"; return false; } // Remove karma from entry? if ($serendipity['POST']['delete_button']) { // Fetch vote total for the entry IDs $q = 'SELECT k.* FROM ' . $serendipity['dbPrefix'] . 'karma AS k WHERE k.entryid IN (' . $pid . ') GROUP BY k.entryid'; $sql = serendipity_db_query($q); if (is_array($sql)) { $karma = $sql[0]; $update = sprintf("UPDATE {$serendipity['dbPrefix']}karma\n SET points = %s,\n votes = %s\n WHERE entryid = %s", serendipity_db_escape_string($karma['points'] - $ppoints), serendipity_db_escape_string($karma['votes'] - 1), serendipity_db_escape_string($pid)); $updated = serendipity_db_query($update); if ($updated != 1) { printf("<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_REMOVE_ERROR . "</div>\n", $pid); // Don't delete from karma log if we couldn't take away the points continue; } } else { // This will only happen if someone is messing with the karma table or submit data printf("<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_UPDATE_ERROR . "</div>", $pid); continue; } } // Remove vote from log (approved or deleted, doesn't matter) $del = sprintf("DELETE FROM {$serendipity['dbPrefix']}karmalog\n WHERE entryid = %s AND ip = '%s' AND user_agent LIKE '%%%s%%' AND votetime = %s LIMIT 1", serendipity_db_escape_string($pid), serendipity_db_escape_string($pip), serendipity_db_escape_string($puser_agent), serendipity_db_escape_string($pvotetime)); $deleted = serendipity_db_query($del); // User feedback if ($deleted == 1) { if ($serendipity['POST']['delete_button']) { printf("<div class='serendipityAdminMsgSuccess'>" . PLUGIN_KARMA_REMOVED_POINTS . "</div>\n", $ppoints, $pid); } else { printf("<div class='serendipityAdminMsgSuccess'>" . PLUGIN_KARMA_APPROVED_POINTS . "</div>\n", $ppoints, $pid); } } else { printf("<div class='serendipityAdminMsgError'>" . PLUGIN_KARMA_REMOVE_ERROR . "</div>\n", $pid); } } } // URL; expected to be event_display and karmalog, respectively $url = '?serendipity[adminModule]=' . htmlspecialchars($serendipity['GET']['adminModule']) . '&serendipity[adminAction]=' . htmlspecialchars($serendipity['GET']['adminAction']); // Filters print "\n<form action='' method='get' name='karmafilters' id='karmafilters'>\n <input type='hidden' name='serendipity[adminModule]' value='{$serendipity['GET']['adminModule']}' />\n <input type='hidden' name='serendipity[adminAction]' value='{$serendipity['GET']['adminAction']}' />\n<table class='serendipity_admin_filters' width='100%'>\n<tr>\n <td colspan='4' class='serendipity_admin_filters_headline'><strong>" . FILTERS . "</strong></td>\n</tr>\n<tr>\n <td>User Agent:</td>\n <td><input class='input_textbox' type='text' name='serendipity[filter][user_agent]' size='15' value='" . htmlspecialchars($serendipity['GET']['filter']['user_agent']) . "' /></td>\n <td>" . IP . "</td>\n <td><input class='input_textbox' type='text' name='serendipity[filter][ip]' size='15' value='" . htmlspecialchars($serendipity['GET']['filter']['ip']) . "' /></td>\n</tr>\n<tr>\n <td>Entry ID:</td>\n <td><input class='input_textbox' type='text' name='serendipity[filter][entryid]' size='15' value='" . htmlspecialchars($serendipity['GET']['filter']['entryid']) . "' /></td>\n <td>Entry title:</td>\n <td><input class='input_textbox' type='text' name='serendipity[filter][title]' size='30' value='" . htmlspecialchars($serendipity['GET']['filter']['title']) . "' /></td>\n</tr>\n</table>\n"; // Set all filters into $and and $searchString if (!empty($serendipity['GET']['filter']['entryid'])) { $val = $serendipity['GET']['filter']['entryid']; $and .= "AND l.entryid = '" . serendipity_db_escape_string($val) . "'"; $searchString .= "&serendipity['filter']['entryid']=" . htmlspecialchars($val); } if (!empty($serendipity['GET']['filter']['ip'])) { $val = $serendipity['GET']['filter']['ip']; $and .= "AND l.ip = '" . serendipity_db_escape_string($val) . "'"; $searchString .= "&serendipity['filter']['ip']=" . htmlspecialchars($val); } if (!empty($serendipity['GET']['filter']['user_agent'])) { $val = $serendipity['GET']['filter']['user_agent']; $and .= "AND l.user_agent LIKE '%" . serendipity_db_escape_string($val) . "%'"; $searchString .= "&serendipity['filter']['user_agent']=" . htmlspecialchars($val); } if (!empty($serendipity['GET']['filter']['title'])) { $val = $serendipity['GET']['filter']['title']; $and .= "AND e.title LIKE '%" . serendipity_db_escape_string($val) . "%'"; $searchString .= "&serendipity['filter']['title']=" . htmlspecialchars($val); } // Sorting (controls go after filtering controls in form above) $sort_order = array('votetime' => DATE, 'user_agent' => USER_AGENT, 'title' => TITLE, 'entryid' => 'ID'); if (empty($serendipity['GET']['sort']['ordermode']) || $serendipity['GET']['sort']['ordermode'] != 'ASC') { $desc = true; $serendipity['GET']['sort']['ordermode'] = 'DESC'; } if (!empty($serendipity['GET']['sort']['order']) && !empty($sort_order[$serendipity['GET']['sort']['order']])) { $curr_order = $serendipity['GET']['sort']['order']; $orderby = serendipity_db_escape_string($curr_order . ' ' . $serendipity['GET']['sort']['ordermode']); } else { $curr_order = 'votetime'; $orderby = 'votetime ' . serendipity_db_escape_string($serendipity['GET']['sort']['ordermode']); } print "\n<div>" . SORT_BY . "\n<select name='serendipity[sort][order]'>\n"; foreach ($sort_order as $order => $val) { print "\n <option value='{$order}'" . ($curr_order == $order ? " selected='selected'" : '') . ">{$val}</option>\n"; } print "\n</select>\n<select name='serendipity[sort][ordermode]'>\n <option value='DESC'" . ($desc ? "selected='selected'" : '') . ">" . SORT_ORDER_DESC . "</option>\n <option value='ASC'" . ($desc ? '' : "selected='selected'") . ">" . SORT_ORDER_ASC . "</option>\n</select>\n</div>\n<input type='submit' name='submit' value=' - " . GO . " - ' class='serendipityPrettyButton input_button' /> \n</form>\n"; // Paging (partly ripped from include/admin/comments.inc.php) $commentsPerPage = (int) (!empty($serendipity['GET']['filter']['perpage']) ? $serendipity['GET']['filter']['perpage'] : 25); $sql = serendipity_db_query("SELECT COUNT(*) AS total FROM {$serendipity['dbPrefix']}karmalog l WHERE 1 = 1 " . $and, true); $totalVotes = $sql['total']; $pages = $commentsPerPage == COMMENTS_FILTER_ALL ? 1 : ceil($totalVotes / (int) $commentsPerPage); $page = (int) $serendipity['GET']['page']; if ($page == 0 || $page > $pages) { $page = 1; } if ($page > 1) { $linkPrevious = $url . '&serendipity[page]=' . ($page - 1) . $searchString; } if ($pages > $page) { $linkNext = $url . '&serendipity[page]=' . ($page + 1) . $searchString; } if ($commentsPerPage == COMMENTS_FILTER_ALL) { $limit = ''; } else { $limit = serendipity_db_limit_sql(serendipity_db_limit(($page - 1) * (int) $commentsPerPage, (int) $commentsPerPage)); } // Variables for display if ($linkPrevious) { $linkPrevious = '<a href="' . $linkPrevious . '" class="serendipityIconLink"><img src="' . serendipity_getTemplateFile('admin/img/previous.png') . '" /></a>'; } else { $linkPrevious = ' '; } if ($linkNext) { $linkNext = '<a href="' . $linkNext . '" class="serendipityIconLinkRight"><img src="' . serendipity_getTemplateFile('admin/img/next.png') . '" /></a>'; } else { $linkNext = ' '; } $paging = sprintf(PAGE_BROWSE_COMMENTS, $page, $pages, $totalVotes); // Retrieve the next batch of karma votes // [entryid, points, ip, user_agent, votetime] $sql = serendipity_db_query("SELECT l.entryid AS entryid, l.points AS points, l.ip AS ip, l.user_agent AS user_agent, l.votetime AS votetime, e.title AS title FROM {$serendipity['dbPrefix']}karmalog l\n LEFT JOIN {$serendipity['dbPrefix']}entries e ON (e.id = l.entryid)\n WHERE 1 = 1 " . $and . "\n ORDER BY {$orderby} {$limit}"); // Start the form for display and deleting if (is_array($sql)) { print "<form action='' method='post' name='formMultiDelete' id='formMultiDelete'>\n" . serendipity_setFormToken() . "\n<script type='text/javascript'>\nfunction invertSelection() {\n var f = document.formMultiDelete;\n for (var i = 0; i < f.elements.length; i++) {\n if( f.elements[i].type == 'checkbox' ) {\n f.elements[i].checked = !(f.elements[i].checked);\n }\n }\n}\n</script>\n"; // Print the header paging table print "\n<table width='100%' style='border-collapse: collapse;'>\n <tr>\n <td align='left'>{$linkPrevious}</td>\n <td align='center'>{$paging}</td>\n <td align='right'>{$linkNext}</td>\n </tr>\n</table>\n"; // Start the vote table print "\n<table class='karmalog' width='100%'>\n"; // Print each vote $i = 0; foreach ($sql as $vote) { $i++; // entryid, title, points, ip, user_agent, votetime $entrylink = serendipity_archiveURL($vote['entryid'], $vote['title'], 'serendipityHTTPPath', true); $entryFilterHtml = "<a class='serendipityIconLink' href='{$url}&serendipity[filter][entryid]={$vote['entryid']}'><img src='" . serendipity_getTemplateFile('admin/img/zoom.png') . "' /></a>"; $ipFilterHtml = "<a class='serendipityIconLink' href='{$url}&serendipity[filter][ip]={$vote['ip']}'><img src='" . serendipity_getTemplateFile('admin/img/zoom.png') . "' /></a>"; $timestr = strftime('%H:%M:%S<br />%n%a %b %d %Y', $vote['votetime']); $cssClass = 'serendipity_admin_list_item serendipity_admin_list_item_'; $cssClass .= $i % 2 == 0 ? 'even' : 'uneven'; $barClass = str_replace(array('.', ' '), array('_', '_'), $this->image_name); $barHtml = $this->createRatingBar(null, $vote['points'], 1, $barClass); $barHtml = sprintf($barHtml, 'what', $vote['points'], '1'); print "\n <tr class='{$cssClass}'>\n <td rowspan='2' width='20' align='center'>\n <input class='input_checkbox' type='checkbox' name='serendipity[delete][{$i}]' value='{$i}' tabindex='{$i}' />\n <input type='hidden' name='serendipity[karmalog{$i}][points]' value='{$vote['points']}' />\n <input type='hidden' name='serendipity[karmalog{$i}][entryid]' value='{$vote['entryid']}' />\n <input type='hidden' name='serendipity[karmalog{$i}][votetime]' value='{$vote['votetime']}' />\n <input type='hidden' name='serendipity[karmalog{$i}][ip]' value='{$vote['ip']}' />\n <input type='hidden' name='serendipity[karmalog{$i}][user_agent]' value='{$vote['user_agent']}' />\n </td>\n <td>{$barHtml}</td>\n <td colspan='2'><a href='{$entrylink}' title='{$vote['entryid']}' alt='{$vote['title']}'>{$vote['title']}</a> {$entryFilterHtml}</td>\n </tr>\n <tr class='{$cssClass}'>\n <td>{$timestr}</td>\n <td>{$vote['ip']} {$ipFilterHtml}</td>\n <td>{$vote['user_agent']}</td>\n </tr>\n"; } // End the vote table print "\n </table>\n "; if (is_array($sql)) { print "\n<input type='button' name='toggle' value='" . INVERT_SELECTIONS . "' onclick='invertSelection()' class='serendipityPrettyButton input_button' /> \n<input class='serendipityPrettyButton input_button' type='submit' value='" . PLUGIN_KARMA_DELETE_VOTES . "' name='serendipity[delete_button]' />\n<input class='serendipityPrettyButton input_button' type='submit' value='" . PLUGIN_KARMA_APPROVE_VOTES . "' name='serendipity[approve_button]' />\n</form>\n"; } // Print the footer paging table print "\n<table width='100%' style='border-collapse: collapse;'>\n <tr>\n <td align='left'>{$linkPrevious}</td>\n <td align='center'>{$paging}</td>\n <td align='right'>{$linkNext}</td>\n </tr>\n</table>\n"; } else { print "\n<div class='serendipityAdminMsgNotice'>No entries to display.</div>\n"; } return true; break; default: return false; } // End switch on event hooks } else { return false; } }
function getMyNotes($limited = true) { global $serendipity; $this->setupDB(); $sql = "SELECT a.noteid, a.authorid, a.notetime, a.subject, a.body, a.notetype,\n ar.realname\n FROM {$serendipity['dbPrefix']}adminnotes\n AS a\n\n JOIN {$serendipity['dbPrefix']}adminnotes_to_groups\n AS atg\n ON atg.noteid = a.noteid\n\n JOIN {$serendipity['dbPrefix']}authorgroups\n AS ag\n ON (ag.groupid = atg.groupid AND ag.authorid = {$serendipity['authorid']})\n\n JOIN {$serendipity['dbPrefix']}authors\n AS axs\n ON axs.authorid = ag.authorid\n\n JOIN {$serendipity['dbPrefix']}authors\n AS ar\n ON ar.authorid = a.authorid\n " . (is_int($limited) ? 'WHERE a.noteid = ' . (int) $limited : '') . "\n GROUP BY a.noteid\n ORDER BY a.notetime DESC"; if ($limited) { $sql .= ' ' . serendipity_db_limit_sql($this->get_config('limit')); } return serendipity_db_query($sql, is_int($limited) ? true : false, 'assoc'); }
function getAllRecyclerComments($page = false) { global $serendipity; if ($page === false) { $sql = "SELECT * FROM {$serendipity['dbPrefix']}spamblock_bayes_recycler ORDER BY id DESC"; } else { $first = $page * 20; $amount = 21; $sql = "SELECT * FROM {$serendipity['dbPrefix']}spamblock_bayes_recycler ORDER BY id DESC" . serendipity_db_limit_sql(sprintf("%d,%d", $first, $amount)); } $comments = serendipity_db_query($sql, false, 'assoc'); return $comments; }
$searchString .= '&' . serendipity_setFormToken('url'); /* Paging */ $sql = serendipity_db_query("SELECT COUNT(*) AS total FROM {$serendipity['dbPrefix']}comments c WHERE 1 = 1 " . ($c_type !== null ? " AND c.type = '{$c_type}' " : '') . $and, true); $totalComments = $sql['total']; $pages = $commentsPerPage == COMMENTS_FILTER_ALL ? 1 : ceil($totalComments / (int) $commentsPerPage); $page = (int) $serendipity['GET']['page']; if ($page == 0 || $page > $pages) { $page = 1; } $linkPrevious = 'serendipity_admin.php?serendipity[adminModule]=comments&serendipity[page]=' . ($page - 1) . $searchString; $linkNext = 'serendipity_admin.php?serendipity[adminModule]=comments&serendipity[page]=' . ($page + 1) . $searchString; $filter_vals = array(10, 20, 50, COMMENTS_FILTER_ALL); if ($commentsPerPage == COMMENTS_FILTER_ALL) { $limit = ''; } else { $limit = serendipity_db_limit_sql(serendipity_db_limit(($page - 1) * (int) $commentsPerPage, (int) $commentsPerPage)); } $sql = 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 " . ($c_type !== null ? " AND c.type = '{$c_type}' " : '') . $and . (!serendipity_checkPermission('adminEntriesMaintainOthers') ? 'AND e.authorid = ' . (int) $serendipity['authorid'] : '') . "\n ORDER BY c.id DESC {$limit}"); if (serendipity_checkPermission('adminComments')) { ob_start(); # This event has to get send here so the spamblock-plugin can block an author now and the comment_page show that on this pageload serendipity_plugin_api::hook_event('backend_comments_top', $sql); $data['backend_comments_top'] = ob_get_contents(); ob_end_clean(); } $data['commentsPerPage'] = $commentsPerPage; $data['totalComments'] = $totalComments; $data['pages'] = $pages; $data['page'] = $page; $data['linkPrevious'] = $linkPrevious; $data['linkNext'] = $linkNext;
function displayTopUrlList($list, $limit, $use_links = true, $filter_out = "", $daylimit = 7) { global $serendipity; if ($limit) { $limit = serendipity_db_limit_sql($limit); } $filter_out_sql = !$filter_out ? "" : "host NOT LIKE '" . join("' AND host NOT LIKE '", explode(";", preg_replace('@^;|;$@', '', str_replace("*", "%", $filter_out)))) . "'"; /* HACK */ if (preg_match('/^mysqli?/', $serendipity['dbType'])) { if ($filter_out) { $filter_out_sql = "AND " . $filter_out_sql; } /* Nonportable SQL due to MySQL date functions, * but produces rolling 7 day totals, which is more * interesting */ $query = "SELECT scheme, host, SUM(count) AS total\n FROM {$serendipity['dbPrefix']}{$list}\n WHERE " . ($daylimit > 0 ? "day > date_sub(current_date, interval " . (int) $daylimit . " day)" : "1 = 1") . "\n {$filter_out_sql}\n GROUP BY host\n ORDER BY total DESC, host\n {$limit}"; } else { if ($filter_out) { $filter_out_sql = "WHERE " . $filter_out_sql; } /* Portable version of the same query */ $query = "SELECT scheme, host, SUM(count) AS total\n FROM {$serendipity['dbPrefix']}{$list}\n {$filter_out_sql}\n GROUP BY scheme, host\n ORDER BY total DESC, host\n {$limit}"; } $rows = serendipity_db_query($query); echo "<span class='serendipityReferer'>"; if (is_array($rows)) { foreach ($rows as $row) { if ($use_links) { printf('<a href="%1$s://%2$s" title="%2$s" >%2$s</a> (%3$s)<br />', function_exists('serendipity_specialchars') ? serendipity_specialchars($row['scheme']) : htmlspecialchars($row['scheme'], ENT_COMPAT, LANG_CHARSET), function_exists('serendipity_specialchars') ? serendipity_specialchars($row['host']) : htmlspecialchars($row['host'], ENT_COMPAT, LANG_CHARSET), function_exists('serendipity_specialchars') ? serendipity_specialchars($row['total']) : htmlspecialchars($row['total'], ENT_COMPAT, LANG_CHARSET)); } else { printf('%1$s (%2$s)<br />', function_exists('serendipity_specialchars') ? serendipity_specialchars($row['host']) : htmlspecialchars($row['host'], ENT_COMPAT, LANG_CHARSET), function_exists('serendipity_specialchars') ? serendipity_specialchars($row['total']) : htmlspecialchars($row['total'], ENT_COMPAT, LANG_CHARSET)); } } } echo "</span>"; }
/** * Guestbook Select entries * * @param int $cp limit from * @param int $rp limit to * @param int $ap approved * @return mixed boolean/array $entries */ function getEntriesDB($cp, $rp, $ap) { global $serendipity; $whe = serendipity_db_bool($this->get_config('showapp')) || serendipity_db_bool($this->get_config('automoderate')) ? "WHERE approved={$ap}" : ''; // generate guestbook entries and send them to entries template $sql = "SELECT * FROM {$serendipity['dbPrefix']}guestbook {$whe} ORDER BY timestamp DESC "; $entries = serendipity_db_query($sql . serendipity_db_limit_sql(serendipity_db_limit($cp * $rp, $rp)), false, 'assoc'); return is_array($entries) ? $entries : false; }
function generate_content(&$title) { global $serendipity; $title = $this->get_config('title'); $max_entries = $this->get_config('max_entries'); $del_str = $this->get_config('delete'); $submit_str = $this->get_config('submit'); $timestamp = $this->get_config('timestamp'); $show_tip = serendipity_db_bool($this->get_config('show_tip')); $is_public = serendipity_db_bool($this->get_config('is_public')); // Create table, if not yet existant if ($this->get_config('version') != '0.3') { $q = "CREATE TABLE {$serendipity['dbPrefix']}quicklink (\n id {AUTOINCREMENT} {PRIMARY},\n timestamp int(10) {UNSIGNED} NULL,\n link varchar(255),\n label varchar(255),\n description text\n )"; @($sql = serendipity_db_schema_import($q)); $this->set_config('version', '0.3'); } //Put new link into the database if necessary if (($_SESSION['serendipityAuthedUser'] === true || $is_public === true) && !empty($_REQUEST['action']) && $_REQUEST['action'] == 'sendquicklink' && trim($_REQUEST['serendipity']['quicklink']) != '') { $sql = sprintf("INSERT INTO %squicklink (\n timestamp,\n link,\n label,\n description\n ) VALUES (\n %s,\n '%s',\n '%s',\n '%s'\n )", $serendipity['dbPrefix'], time(), serendipity_db_escape_string(trim($_REQUEST['serendipity']['quicklink'])), serendipity_db_escape_string(trim($_REQUEST['serendipity']['quicklinklabel'])), serendipity_db_escape_string(trim($_REQUEST['serendipity']['quicklinkdesc']))); serendipity_db_query($sql); } if (!$max_entries || !is_numeric($max_entries) || $max_entries < 1) { $max_entries = 15; } // if a delete link clicked! if (!empty($serendipity['GET']['action']) && $serendipity['GET']['action'] == 'quicklinkdelete' && $_SESSION['serendipityAuthedUser'] === true && $serendipity['serendipityUserlevel'] >= USERLEVEL_CHIEF) { $sql = sprintf("DELETE from %squicklink\n WHERE id = %d", $serendipity['dbPrefix'], (int) $serendipity['GET']['link_id']); serendipity_db_query($sql); } // if start is set if (!empty($serendipity['GET']['start'])) { $start = (int) $serendipity['GET']['start']; } else { $start = 0; } $next = $start + $max_entries; $prev = $start - $max_entries; // disable previous link if needed if ($prev < 0) { $prev = false; } $q = 'SELECT count(*) AS count FROM ' . $serendipity['dbPrefix'] . 'quicklink'; $sql = serendipity_db_query($q); // disable next link if needed if ($next >= $sql[0]['count']) { $next = false; } if ($_SESSION['serendipityAuthedUser'] === true || $is_public === true) { ?> <form action="<?php echo serendipity_currentURL(); ?> " method="post"> <div> <input type="hidden" name="action" value="sendquicklink" /> <input type="text" name="serendipity[quicklinklabel]" style="width: 90%" value="<?php echo PLUGIN_QUICKLINK_LABEL; ?> " onclick="if(this.value='<?php echo PLUGIN_QUICKLINK_LABEL; ?> ') this.value=''" /> <input type="text" name="serendipity[quicklink]" style="width: 90%" value="http://" dir="ltr" /> <textarea name="serendipity[quicklinkdesc]" cols="15" rows="2" style="width: 90%"></textarea> <input name='submit' type='submit' value='<?php echo $submit_str; ?> ' /> </div> </form><br /> <?php } ?> <div id="quick_link_tip" style="position:absolute; visibility: hidden"></div> <script language="JavaScript"><!-- var toolTipSTYLE=""; function initToolTips() { toolTipSTYLE = document.getElementById("quick_link_tip").style; toolTipSTYLE.visibility = "visible"; toolTipSTYLE.display = "none"; document.onmousemove = moveToMouseLoc; } function toolTip(msg, bg) { if(toolTip.arguments.length < 1) //hide { toolTipSTYLE.display = "none"; } else // show { if(!bg) bg = "#FFFFFF"; var content = '<table border="1" cellspacing="0" cellpadding="0" bgcolor="' + bg + '"><td><font size="-1"> \;' + msg + ' \;</font></td></table>'; document.getElementById("quick_link_tip").innerHTML = content; toolTipSTYLE.display='block' } } function moveToMouseLoc(e) { if (e && e.pageX) { x = e.pageX; y = e.pageY; toolTipSTYLE.left = x + 0 + 'px'; toolTipSTYLE.top = y + 20 + 'px'; } return true; } initToolTips(); //--></script> <div style="margin: 0px; padding: 0px; text-align: left;"> <?php $q = 'SELECT s.description AS description, s.link AS link, s.label AS label, s.timestamp AS stamp, s.id AS link_id FROM ' . $serendipity['dbPrefix'] . 'quicklink AS s ORDER BY s.timestamp DESC ' . serendipity_db_limit_sql(serendipity_db_limit($start, $max_entries)); $sql = serendipity_db_query($q); if ($sql && is_array($sql)) { foreach ($sql as $key => $row) { if (!preg_match('@^https?://@', trim($row['link']))) { $row['link'] = 'http://' . $row['link']; } $row['link'] = str_replace('javascript:', '', $row['link']); // create tool tip string $tip = ''; if ($show_tip == 'true') { $tip = function_exists('serendipity_specialchars') ? serendipity_specialchars(serendipity_strftime($timestamp, $row['stamp'])) : htmlspecialchars(serendipity_strftime($timestamp, $row['stamp']), ENT_COMPAT, LANG_CHARSET); if (trim($row['description']) != '') { $tip .= '<br />' . nl2br(function_exists('serendipity_specialchars') ? serendipity_specialchars($row['description']) : htmlspecialchars($row['description'], ENT_COMPAT, LANG_CHARSET)); } $tip = ' onMouseOver="toolTip(\'' . $tip . '\')" onMouseOut="toolTip()"'; } // create label of link if (trim($row['label']) == '' || $row['label'] == PLUGIN_QUICKLINK_LABEL) { $label = $row['link']; } else { $label = $row['label']; } // create link string $link = '<a href="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($row['link']) : htmlspecialchars($row['link'], ENT_COMPAT, LANG_CHARSET)) . '"' . $tip . ' target="_blank">' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($label) : htmlspecialchars($label, ENT_COMPAT, LANG_CHARSET)) . '</a>'; // create telete link string $deleteLink = ''; if ($_SESSION['serendipityAuthedUser'] === true && $serendipity['serendipityUserlevel'] >= USERLEVEL_CHIEF) { $deleteLink = ' | <a href="' . $serendipity['baseURL'] . $serendipity['indexFile'] . '?serendipity[action]=quicklinkdelete&serendipity[link_id]=' . $row['link_id'] . '" onclick="return confirm(\'' . PLUGIN_QUICKLINK_ALERT . '\');">' . $del_str . '</a>'; } $entry = array('link' => $link); serendipity_plugin_api::hook_event('frontend_display', $entry); echo $entry['link'] . $deleteLink . '<br />' . "\n\n"; } } if ($prev !== false || $next !== false) { if ($prev !== false) { echo '<br /><div align="center"><a href="' . $serendipity['baseURL'] . $serendipity['indexFile'] . '?serendipity[start]=' . $prev . '">' . PREVIOUS . '</a> | '; } else { echo '<br /><div align="center">' . PREVIOUS . ' | '; } if ($next !== false) { echo '<a href="' . $serendipity['baseURL'] . $serendipity['indexFile'] . '?serendipity[start]=' . $next . '">' . NEXT . '</a></div><br />' . "\n"; } else { echo NEXT . '</div><br />' . "\n"; } } ?> </div> <?php }
function generate_content(&$title) { global $serendipity; $number = $this->get_config('number'); $category = $this->get_config('category', 'none'); $title = $this->get_config('title', $this->title); $number_from_sw = $this->get_config('number_from'); if ($category == '_cur') { $category = $serendipity['GET']['category']; } $sql_join = ''; $sql_where = ''; if ($category != 'none' && is_numeric($category)) { $sql_join = 'LEFT OUTER JOIN ' . $serendipity['dbPrefix'] . 'entrycat AS ec ON e.id = ec.entryid LEFT OUTER JOIN ' . $serendipity['dbPrefix'] . 'category AS c ON ec.categoryid = c.categoryid'; $sql_where = ' AND (c.category_left BETWEEN ' . implode(' AND ', serendipity_fetchCategoryRange($category)) . ')'; } if (!$number || !is_numeric($number) || $number < 1) { $number = 10; } $sql_number = $number; switch ($number_from_sw) { case 'skip': $sql_number = serendipity_db_limit_sql(serendipity_db_limit($serendipity['fetchLimit'], $sql_number)); break; default: $sql_number = serendipity_db_limit_sql(serendipity_db_limit(0, $sql_number)); break; } $sortby = $this->get_config('sortby', 'comments'); switch ($sortby) { case 'comments': $entries_query = "SELECT e.id,\n e.title,\n e.comments AS points,\n e.timestamp\n FROM {$serendipity['dbPrefix']}entries AS e\n {$sql_join}\n WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "\n {$sql_where}\n ORDER BY e.comments DESC\n {$sql_number}"; break; case 'commentors': $entries_query = "SELECT c.author, count(c.id) AS points\n FROM {$serendipity['dbPrefix']}entries AS e\n JOIN {$serendipity['dbPrefix']}comments AS c\n ON c.entry_id = e.id\n {$sql_join}\n WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "\n AND c.status = 'approved'\n {$sql_where}\n GROUP BY c.author\n ORDER BY points DESC\n {$sql_number}"; break; case 'karma': $entries_query = "SELECT e.id,\n e.title,\n e.comments,\n e.timestamp,\n k.points AS points\n FROM {$serendipity['dbPrefix']}entries AS e\n {$sql_join}\n LEFT OUTER JOIN {$serendipity['dbPrefix']}karma AS k\n ON k.entryid = e.id\n WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "\n {$sql_where}\n GROUP BY e.id, e.title, e.comments, e.timestamp, k.visits\n ORDER BY k.points DESC\n {$sql_number}"; break; case 'visits': $entries_query = "SELECT e.id,\n e.title,\n e.comments,\n e.timestamp,\n k.visits AS points\n FROM {$serendipity['dbPrefix']}entries AS e\n {$sql_join}\n LEFT OUTER JOIN {$serendipity['dbPrefix']}karma AS k\n ON k.entryid = e.id\n WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "\n {$sql_where}\n GROUP BY e.id, e.title, e.comments, e.timestamp, k.visits\n ORDER BY k.visits DESC\n {$sql_number}"; break; case 'lowvisits': $entries_query = "SELECT e.id,\n e.title,\n e.comments,\n e.timestamp,\n k.visits AS points\n FROM {$serendipity['dbPrefix']}entries AS e\n {$sql_join}\n LEFT OUTER JOIN {$serendipity['dbPrefix']}karma AS k\n ON k.entryid = e.id\n WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "\n {$sql_where}\n GROUP BY e.id, e.title, e.comments, e.timestamp, k.visits \n ORDER BY k.visits ASC\n {$sql_number}"; break; case 'exits': $entries_query = "SELECT e.id,\n e.title,\n e.comments,\n e.timestamp,\n SUM(ex.count) AS points\n FROM {$serendipity['dbPrefix']}entries AS e\n {$sql_join}\n LEFT OUTER JOIN {$serendipity['dbPrefix']}exits AS ex\n ON ex.entry_id = e.id\n WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "\n {$sql_where}\n GROUP BY ex.entry_id\n ORDER BY points DESC\n {$sql_number}"; break; } $entries = serendipity_db_query($entries_query); $hidden = explode(',', trim($this->get_config('commentors_hide'))); echo '<ul class="plainList">'; if (isset($entries) && is_array($entries)) { foreach ($entries as $k => $entry) { if ($sortby == 'commentors') { if (in_array($entry['author'], $hidden)) { continue; } $entryLink = $serendipity['serendipityHTTPPath'] . ($serendipity['rewrite'] == 'none' ? $serendipity['indexFile'] . '?/' : '') . PATH_COMMENTS . '/' . urlencode($entry['author']); echo '<li><a href="' . $entryLink . '" title="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['author']) : htmlspecialchars($entry['author'], ENT_COMPAT, LANG_CHARSET)) . '">' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['author']) : htmlspecialchars($entry['author'], ENT_COMPAT, LANG_CHARSET)) . '</a>'; echo ' <span class="serendipitySideBarDate">(' . (!empty($entry['points']) ? function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['points']) : htmlspecialchars($entry['points'], ENT_COMPAT, LANG_CHARSET) : 0) . ')</span></li>'; } else { $entryLink = serendipity_archiveURL($entry['id'], $entry['title'], 'serendipityHTTPPath', true, array('timestamp' => $entry['timestamp'])); echo '<li><a href="' . $entryLink . '" title="' . (function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['title']) : htmlspecialchars($entry['title'], ENT_COMPAT, LANG_CHARSET)) . '">' . $entry['title'] . '</a>'; echo ' <span class="serendipitySideBarDate">(' . (!empty($entry['points']) ? function_exists('serendipity_specialchars') ? serendipity_specialchars($entry['points']) : htmlspecialchars($entry['points'], ENT_COMPAT, LANG_CHARSET) : 0) . ')</span></li>'; } } } echo '</ul>'; }
function showForum() { global $serendipity; if (!headers_sent()) { header('HTTP/1.0 200'); header('Status: 200 OK'); } $ERRORMSG = ""; $THREAD_UNREAD_ANNOUNCEMENT = "<img src=\"" . $this->DMA_forum_getRelPath() . "/img/thread_unread_announce.png\" width=\"20\" height=\"20\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_READ . "\" title=\"" . PLUGIN_FORUM_ALT_READ . "\" />"; $THREAD_READ_ANNOUNCEMENT = "<img src=\"" . $this->DMA_forum_getRelPath() . "/img/thread_read_announce.png\" width=\"20\" height=\"20\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_READ . "\" title=\"" . PLUGIN_FORUM_ALT_READ . "\" />"; $THREAD_UNREAD = "<img src=\"" . $this->DMA_forum_getRelPath() . "/img/thread_unread.png\" width=\"20\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_UNREAD . "\" title=\"" . PLUGIN_FORUM_ALT_UNREAD . "\" />"; $THREAD_HUGE_UNREAD = "<img src=\"" . $this->DMA_forum_getRelPath() . "/img/thread_huge_unread.png\" width=\"20\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_UNREAD . "\" title=\"" . PLUGIN_FORUM_ALT_UNREAD . "\" />"; $THREAD_READ = "<img src=\"" . $this->DMA_forum_getRelPath() . "/img/thread_read.png\" width=\"20\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_READ . "\" title=\"" . PLUGIN_FORUM_ALT_READ . "\" />"; $THREAD_HUGE_READ = "<img src=\"" . $this->DMA_forum_getRelPath() . "/img/thread_huge_read.png\" width=\"20\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_READ . "\" title=\"" . PLUGIN_FORUM_ALT_READ . "\" />"; $DEL_FILE_BUTTON = "<img src=\"" . serendipity_getTemplateFile('admin/img/delete.png') . "\" width=\"18\" height=\"18\" border=\"0\" alt=\"" . DELETE . "\" title=\"" . DELETE . "\" />"; if (!isset($_SESSION['forum_visited']) || intval($_SESSION['forum_visited']) <= 0) { if (serendipity_userLoggedIn()) { $sql = "SELECT visits, lastvisit FROM {$serendipity['dbPrefix']}dma_forum_users WHERE authorid = '" . intval($serendipity['authorid']) . "'"; $visits = serendipity_db_query($sql); if (is_array($visits) && count($visits) >= 1) { $q = "UPDATE {$serendipity['dbPrefix']}dma_forum_users SET visits = visits+1, lastvisit = '" . time() . "' WHERE authorid = '" . intval($serendipity['authorid']) . "'"; serendipity_db_query($q); } else { $q = "INSERT INTO {$serendipity['dbPrefix']}dma_forum_users (authorid, visits, lastvisit) VALUES ('" . intval($serendipity['authorid']) . "', '1', '" . time() . "')"; serendipity_db_query($q); } $_SESSION['forum_visited'] = 1; } } if (is_array($_COOKIE) && trim($_COOKIE['s9yread']) != "") { $READARRAY = unserialize(stripslashes(trim($_COOKIE['s9yread']))); } else { $READARRAY = array(); } // POST part if (isset($serendipity['POST']['action']) && trim($serendipity['POST']['action']) == "reply") { if (!isset($serendipity['POST']['authorname']) || trim($serendipity['POST']['authorname']) == "") { if (serendipity_userLoggedIn()) { $serendipity['POST']['authorname'] = $serendipity['serendipityUser']; } else { $serendipity['POST']['authorname'] = PLUGIN_FORUM_GUEST; } } if ($this->get_config('use_captchas')) { // Fake call to spamblock and other comment plugins. $ca = array('id' => 0, 'allow_comments' => 'true', 'moderate_comments' => false, 'last_modified' => 1, 'timestamp' => 1); $commentInfo = array('type' => 'NORMAL', 'source' => 'commentform', 'name' => $serendipity['POST']['authorname'], 'url' => '', 'comment' => $serendipity['POST']['comment'], 'email' => ''); serendipity_plugin_api::hook_event('frontend_saveComment', $ca, $commentInfo); } else { $ca['allow_comments'] = true; } if ($ca['allow_comments'] === false) { $ERRORMSG = PLUGIN_FORUM_ERR_WRONG_CAPTCHA_STRING; } else { $serendipity['POST']['title'] = trim($serendipity['POST']['title']); $serendipity['POST']['comment'] = trim($serendipity['POST']['comment']); $serendipity['POST']['authorname'] = trim($serendipity['POST']['authorname']); if (!isset($serendipity['POST']['comment']) || strlen(trim($serendipity['POST']['comment'])) <= 3) { $ERRORMSG = PLUGIN_FORUM_ERR_MISSING_MESSAGE; } else { $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE threadid='" . intval($serendipity['POST']['threadid']) . "'"; $thread = serendipity_db_query($sql); if ($thread[0]['flag'] == 1) { $ERRORMSG = PLUGIN_FORUM_ERR_THREAD_CLOSED; } else { if (trim($serendipity['POST']['comment']) == $_SESSION['lastposttext']) { $ERRORMSG = PLUGIN_FORUM_ERR_DOUBLE_POST; } elseif ($_SESSION['lastposttime'] >= time() - 10) { $ERRORMSG = PLUGIN_FORUM_ERR_POST_INTERVAL; } else { $now = time(); $postid = DMA_forum_InsertReply(intval($serendipity['POST']['boardid']), intval($serendipity['POST']['threadid']), intval($serendipity['POST']['replyto']), trim($serendipity['POST']['authorname']), trim($serendipity['POST']['title']), trim($serendipity['POST']['comment']), $this->get_config('itemsperpage'), $this->get_config('notifymail_from'), $this->get_config('notifymail_name'), $this->get_config('pageurl'), $this->get_config('admin_notify')); if (serendipity_userLoggedIn() && $this->get_config('fileupload_reguser') || $this->get_config('fileupload_guest')) { DMA_forum_uploadFiles($postid, $this->get_config('uploaddir')); if ($this->SUCCESS <= 0) { if (count($this->UPLOAD_TOOBIG) >= 1) { $ERRORMSG = PLUGIN_FORUM_ERR_FILE_TOO_BIG; } elseif (count($this->UPLOAD_NOTCOPIED) >= 1) { $ERRORMSG = PLUGIN_FORUM_ERR_FILE_NOT_COPIED; } } } } } } } if (serendipity_userLoggedIn()) { $POST_AUTHORNAME = $serendipity['serendipityUser']; } else { $POST_AUTHORNAME = trim($serendipity['POST']['authorname']); } $POST_TITLE = trim($serendipity['POST']['title']); $POST_MESSAGE = trim($serendipity['POST']['comment']); if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $_GET['boardid'] = intval($serendipity['POST']['boardid']); $_GET['threadid'] = intval($serendipity['POST']['threadid']); $_GET['replyto'] = intval($serendipity['POST']['replyto']); $_GET['quote'] = 0; } } elseif (isset($serendipity['POST']['action']) && trim($serendipity['POST']['action']) == "edit") { if (!isset($serendipity['POST']['authorname']) || trim($serendipity['POST']['authorname']) == "") { if (serendipity_userLoggedIn()) { $serendipity['POST']['authorname'] = $serendipity['serendipityUser']; } else { $serendipity['POST']['authorname'] = PLUGIN_FORUM_GUEST; } } $serendipity['POST']['title'] = trim($serendipity['POST']['title']); $serendipity['POST']['comment'] = trim($serendipity['POST']['comment']); $serendipity['POST']['authorname'] = trim($serendipity['POST']['authorname']); if (!isset($serendipity['POST']['comment']) || strlen(trim($serendipity['POST']['comment'])) <= 3) { $ERRORMSG = PLUGIN_FORUM_ERR_MISSING_MESSAGE; } else { $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE postid='" . intval($serendipity['POST']['edit']) . "'"; $post = serendipity_db_query($sql); if (serendipity_userLoggedIn() && ($serendipity['serendipityUser'] == $post[0]['authorname'] && $serendipity['authorid'] == $post[0]['authorid'] || $serendipity['serendipityUserlevel'] == 255)) { if (serendipity_userLoggedIn() && $serendipity['serendipityUserlevel'] == USERLEVEL_ADMIN) { if (isset($serendipity['POST']['announcement']) && intval($serendipity['POST']['announcement']) == 1) { $announce = 1; } else { $announce = 0; } } else { $announce = 0; } DMA_forum_EditReply(intval($serendipity['POST']['boardid']), intval($serendipity['POST']['threadid']), intval($serendipity['POST']['edit']), trim($serendipity['POST']['authorname']), trim($serendipity['POST']['title']), trim($serendipity['POST']['comment']), intval($serendipity['POST']['page']), $announce); if (serendipity_userLoggedIn() && $this->get_config('fileupload_reguser') || $this->get_config('fileupload_guest')) { DMA_forum_uploadFiles(intval($serendipity['POST']['edit']), $this->get_config('uploaddir')); if ($this->SUCCESS <= 0) { if (count($this->UPLOAD_TOOBIG) >= 1) { $ERRORMSG = PLUGIN_FORUM_ERR_FILE_TOO_BIG; } elseif (count($this->UPLOAD_NOTCOPIED) >= 1) { $ERRORMSG = PLUGIN_FORUM_ERR_FILE_NOT_COPIED; } } } } else { $ERRORMSG = PLUGIN_FORUM_ERR_EDIT_NOT_ALLOWED; } } if (serendipity_userLoggedIn()) { $POST_AUTHORNAME = $serendipity['serendipityUser']; } else { $POST_AUTHORNAME = trim($serendipity['POST']['authorname']); } $POST_TITLE = trim($serendipity['POST']['title']); $POST_MESSAGE = trim($serendipity['POST']['comment']); if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $_GET['boardid'] = intval($serendipity['POST']['boardid']); $_GET['threadid'] = intval($serendipity['POST']['threadid']); $_GET['edit'] = intval($serendipity['POST']['edit']); } } elseif (isset($serendipity['POST']['action']) && trim($serendipity['POST']['action']) == "delete") { if (!isset($serendipity['POST']['no']) || trim($serendipity['POST']['no']) == "") { if (!isset($serendipity['serendipityUserlevel']) || $serendipity['serendipityUserlevel'] != 255) { $ERRORMSG = PLUGIN_FORUM_ERR_DELETE_NOT_ALLOWED; } else { DMA_forum_DeletePost(intval($serendipity['POST']['boardid']), intval($serendipity['POST']['threadid']), intval($serendipity['POST']['delete']), intval($serendipity['POST']['page']), $this->get_config('uploaddir'), $this->get_config('itemsperpage')); } } if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $_GET['boardid'] = intval($serendipity['POST']['boardid']); $_GET['threadid'] = intval($serendipity['POST']['threadid']); } } elseif (isset($serendipity['POST']['action']) && trim($serendipity['POST']['action']) == "newthread") { if (!isset($serendipity['POST']['authorname']) || trim($serendipity['POST']['authorname']) == "") { if (serendipity_userLoggedIn()) { $serendipity['POST']['authorname'] = $serendipity['serendipityUser']; } else { $serendipity['POST']['authorname'] = PLUGIN_FORUM_GUEST; } } if ($this->get_config('use_captchas')) { // Fake call to spamblock and other comment plugins. $ca = array('id' => 0, 'allow_comments' => 'true', 'moderate_comments' => false, 'last_modified' => 1, 'timestamp' => 1); $commentInfo = array('type' => 'NORMAL', 'source' => 'commentform', 'name' => $serendipity['POST']['authorname'], 'url' => '', 'comment' => $serendipity['POST']['comment'], 'email' => ''); serendipity_plugin_api::hook_event('frontend_saveComment', $ca, $commentInfo); } else { $ca['allow_comments'] = true; } if ($ca['allow_comments'] === false) { $ERRORMSG = PLUGIN_FORUM_ERR_WRONG_CAPTCHA_STRING; } else { $serendipity['POST']['title'] = trim($serendipity['POST']['title']); $serendipity['POST']['comment'] = trim($serendipity['POST']['comment']); $serendipity['POST']['authorname'] = trim($serendipity['POST']['authorname']); if (!isset($serendipity['POST']['title']) || strlen(trim($serendipity['POST']['title'])) <= 3) { $ERRORMSG = PLUGIN_FORUM_ERR_MISSING_THREADTITLE; } elseif (!isset($serendipity['POST']['comment']) || strlen(trim($serendipity['POST']['comment'])) <= 3) { $ERRORMSG = PLUGIN_FORUM_ERR_MISSING_MESSAGE; } else { if (trim($serendipity['POST']['comment']) == $_SESSION['lastthreadtext']) { $ERRORMSG = PLUGIN_FORUM_ERR_DOUBLE_THREAD; } elseif ($_SESSION['lastposttime'] >= time() - 10) { $ERRORMSG = PLUGIN_FORUM_ERR_POST_INTERVAL; } else { $now = time(); if (serendipity_userLoggedIn() && $serendipity['serendipityUserlevel'] == USERLEVEL_ADMIN) { if (isset($serendipity['POST']['announcement']) && intval($serendipity['POST']['announcement']) == 1) { $announce = 1; } else { $announce = 0; } } else { $announce = 0; } $postid = DMA_forum_InsertThread(intval($serendipity['POST']['boardid']), trim($serendipity['POST']['authorname']), trim($serendipity['POST']['title']), trim($serendipity['POST']['comment']), $announce, $this->get_config('notifymail_from'), $this->get_config('notifymail_name'), $this->get_config('pageurl'), $this->get_config('admin_notify')); if (serendipity_userLoggedIn() && $this->get_config('fileupload_reguser') || $this->get_config('fileupload_guest')) { DMA_forum_uploadFiles($postid, $this->get_config('uploaddir')); if ($this->SUCCESS <= 0) { if (count($this->UPLOAD_TOOBIG) >= 1) { $ERRORMSG = PLUGIN_FORUM_ERR_FILE_TOO_BIG; } elseif (count($this->UPLOAD_NOTCOPIED) >= 1) { $ERRORMSG = PLUGIN_FORUM_ERR_FILE_NOT_COPIED; } } } } } } if (serendipity_userLoggedIn()) { $POST_AUTHORNAME = $serendipity['serendipityUser']; } else { $POST_AUTHORNAME = trim($serendipity['POST']['authorname']); } $POST_TITLE = trim($serendipity['POST']['title']); $POST_MESSAGE = trim($serendipity['POST']['comment']); if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $_GET['boardid'] = intval($serendipity['POST']['boardid']); $_GET['action'] = "newthread"; } else { $_GET['boardid'] = intval($serendipity['POST']['boardid']); unset($_GET['action']); } } // GET part if (isset($_GET['replyto']) && !isset($_GET['edit']) && !isset($_GET['delete']) && (isset($_GET['boardid']) && intval($_GET['boardid']) >= 1) && (isset($_GET['threadid']) && intval($_GET['threadid']) >= 1)) { // replyform $filename = 'templates/replyform.tpl'; if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $serendipity['smarty']->assign('ERRORMSG', $ERRORMSG); } if (isset($_GET['quote']) && intval($_GET['quote']) >= 1) { $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE postid='" . intval($_GET['replyto']) . "'"; $post = serendipity_db_query($sql); } if (!isset($POST_MESSAGE) || trim($POST_MESSAGE) == "") { if (isset($_GET['quote']) && intval($_GET['quote']) >= 1) { $POST_MESSAGE = "[quote=" . stripslashes($post[0]['authorname']) . "]" . stripslashes($post[0]['message']) . "[/quote]\n\n"; } } if (!isset($POST_TITLE) || trim($POST_TITLE) == "") { if (isset($_GET['quote']) && intval($_GET['quote']) >= 1) { $POST_TITLE = "Re: " . stripslashes($post[0]['title']); } } if (serendipity_userLoggedIn()) { $POST_AUTHORNAME = $serendipity['serendipityUser']; } $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE threadid='" . intval($_GET['threadid']) . "'"; $thread = serendipity_db_query($sql); $serendipity['smarty']->assign(array('pagetitle' => $this->get_config('pagetitle'), 'headline' => $this->get_config('headline'), 'threadtitle' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($thread[0]['title']))) : htmlspecialchars(stripslashes(trim($thread[0]['title'])), ENT_COMPAT, LANG_CHARSET), 'bgcolor2' => $this->get_config('bgcolor2'), 'ACTUALURL' => $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']), 'boardid' => intval($_GET['boardid']), 'threadid' => intval($_GET['threadid']), 'replyto' => intval($_GET['replyto']), 'relpath' => $this->DMA_forum_getRelPath(), 'POST_AUTHORNAME' => function_exists('serendipity_specialchars') ? serendipity_specialchars($POST_AUTHORNAME) : htmlspecialchars($POST_AUTHORNAME, ENT_COMPAT, LANG_CHARSET), 'POST_TITLE' => function_exists('serendipity_specialchars') ? serendipity_specialchars($POST_TITLE) : htmlspecialchars($POST_TITLE, ENT_COMPAT, LANG_CHARSET), 'POST_MESSAGE' => function_exists('serendipity_specialchars') ? serendipity_specialchars($POST_MESSAGE) : htmlspecialchars($POST_MESSAGE, ENT_COMPAT, LANG_CHARSET))); $serendipity['smarty']->assign('bbcode', BBCODE); if (serendipity_userLoggedIn() && $this->get_config('fileupload_reguser') || $this->get_config('fileupload_guest')) { $upload_max_filesize = ini_get('upload_max_filesize'); $upload_max_filesize = preg_replace('/M/', '000000', $upload_max_filesize); $MAX_FILE_SIZE = intval($upload_max_filesize); $MAX_SIZE_PER_FILE = $MAX_FILE_SIZE / 1000000 . " MB"; $max_possible = intval($this->get_config('max_simultaneous_fileuploads')); if ($max_possible >= intval($this->get_config('max_files_per_post'))) { $max_possible = intval($this->get_config('max_files_per_post')); } if (serendipity_userLoggedIn()) { $authorid = intval($serendipity['authorid']); } else { $authorid = 0; } $sql = "SELECT COUNT(*) FROM {$serendipity['dbPrefix']}dma_forum_uploads WHERE authorid = '" . $authorid . "'"; $uploadnum = serendipity_db_query($sql); $uploaduserrest = intval($this->get_config('max_files_per_user')) - intval($uploadnum[0][0]); if ($max_possible >= $uploaduserrest) { $max_possible = $uploaduserrest; } $uploads = array(); for ($x = 0; $x < $max_possible; $x++) { $uploads[] = $x + 1; } $serendipity['smarty']->assign(array('uploadform' => true, 'MAX_FILE_SIZE' => $MAX_FILE_SIZE, 'MAX_SIZE_PER_FILE' => $MAX_SIZE_PER_FILE, 'uploads' => $uploads, 'uploads_post_left' => intval($this->get_config('max_files_per_post')), 'uploads_user_left' => $uploaduserrest)); } if ($this->get_config('use_captchas')) { $serendipity['smarty']->assign('commentform_entry', array('timestamp' => 1)); } } elseif (!isset($_GET['replyto']) && isset($_GET['edit']) && !isset($_GET['delete']) && (isset($_GET['boardid']) && intval($_GET['boardid']) >= 1) && (isset($_GET['threadid']) && intval($_GET['threadid']) >= 1)) { // editform $filename = 'templates/editform.tpl'; if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE threadid='" . intval($_GET['threadid']) . "'"; $thread = serendipity_db_query($sql); $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE postid='" . intval($_GET['edit']) . "'"; $post = serendipity_db_query($sql); if (serendipity_userLoggedIn() && ($serendipity['serendipityUser'] == $post[0]['authorname'] && $serendipity['authorid'] == $post[0]['authorid'] || $serendipity['serendipityUserlevel'] == 255)) { $serendipity['smarty']->assign('CANEDIT', true); } else { $ERRORMSG = PLUGIN_FORUM_ERR_EDIT_NOT_ALLOWED; } if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $serendipity['smarty']->assign('ERRORMSG', $ERRORMSG); } $serendipity['smarty']->assign(array('pagetitle' => $this->get_config('pagetitle'), 'headline' => $this->get_config('headline'), 'threadtitle' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($thread[0]['title']))) : htmlspecialchars(stripslashes(trim($thread[0]['title'])), ENT_COMPAT, LANG_CHARSET), 'bgcolor2' => $this->get_config('bgcolor2'), 'ACTUALURL' => $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&page=" . intval($_GET['page']), 'boardid' => intval($_GET['boardid']), 'threadid' => intval($_GET['threadid']), 'relpath' => $this->DMA_forum_getRelPath(), 'page' => intval($_GET['page']), 'edit' => intval($_GET['edit']), 'POST_AUTHORNAME' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($post[0]['authorname']))) : htmlspecialchars(stripslashes(trim($post[0]['authorname'])), ENT_COMPAT, LANG_CHARSET), 'POST_TITLE' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($post[0]['title']))) : htmlspecialchars(stripslashes(trim($post[0]['title'])), ENT_COMPAT, LANG_CHARSET), 'POST_MESSAGE' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($post[0]['message']))) : htmlspecialchars(stripslashes(trim($post[0]['message'])), ENT_COMPAT, LANG_CHARSET))); $serendipity['smarty']->assign('bbcode', BBCODE); if (serendipity_userLoggedIn() && $serendipity['serendipityUserlevel'] == USERLEVEL_ADMIN) { $serendipity['smarty']->assign('announcement', true); if (intval($thread[0]['announce']) == 1) { $serendipity['smarty']->assign('checked', " checked"); } else { $serendipity['smarty']->assign('checked', ""); } } if (serendipity_userLoggedIn() && $this->get_config('fileupload_reguser') || $this->get_config('fileupload_guest')) { $upload_max_filesize = ini_get('upload_max_filesize'); $upload_max_filesize = preg_replace('/M/', '000000', $upload_max_filesize); $MAX_FILE_SIZE = intval($upload_max_filesize); $MAX_SIZE_PER_FILE = $MAX_FILE_SIZE / 1000000 . " MB"; $max_possible = intval($this->get_config('max_simultaneous_fileuploads')); if ($max_possible >= intval($this->get_config('max_files_per_post'))) { $max_possible = intval($this->get_config('max_files_per_post')); } if (serendipity_userLoggedIn()) { $authorid = intval($serendipity['authorid']); } else { $authorid = 0; } $sql = "SELECT COUNT(*) FROM {$serendipity['dbPrefix']}dma_forum_uploads WHERE authorid = '" . $authorid . "'"; $uploadnum = serendipity_db_query($sql); $uploaduserrest = intval($this->get_config('max_files_per_user')) - intval($uploadnum[0][0]); if ($max_possible >= $uploaduserrest) { $max_possible = $uploaduserrest; } $sql = "SELECT COUNT(*) FROM {$serendipity['dbPrefix']}dma_forum_uploads WHERE postid = '" . intval($_GET['edit']) . "'"; $postuploadnum = serendipity_db_query($sql); $uploadpostrest = intval($this->get_config('max_files_per_post')) - intval($postuploadnum[0][0]); if ($max_possible >= $uploadpostrest) { $max_possible = $uploadpostrest; } $uploads = array(); for ($x = 0; $x < $max_possible; $x++) { $uploads[] = $x + 1; } $serendipity['smarty']->assign(array('uploadform' => true, 'MAX_FILE_SIZE' => $MAX_FILE_SIZE, 'MAX_SIZE_PER_FILE' => $MAX_SIZE_PER_FILE, 'uploads' => $uploads, 'uploads_post_left' => $uploadpostrest, 'uploads_user_left' => $uploaduserrest)); } } elseif (!isset($_GET['replyto']) && !isset($_GET['edit']) && isset($_GET['delete']) && (isset($_GET['boardid']) && intval($_GET['boardid']) >= 1) && (isset($_GET['threadid']) && intval($_GET['threadid']) >= 1)) { // deleteform $filename = 'templates/deleteform.tpl'; if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE threadid='" . intval($_GET['threadid']) . "'"; $thread = serendipity_db_query($sql); $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE postid='" . intval($_GET['delete']) . "'"; $post = serendipity_db_query($sql); if (serendipity_userLoggedIn() && $serendipity['serendipityUserlevel'] == 255) { $serendipity['smarty']->assign('CANDELETE', true); } else { $ERRORMSG = PLUGIN_FORUM_ERR_DELETE_NOT_ALLOWED; } if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $serendipity['smarty']->assign('ERRORMSG', $ERRORMSG); } if ($this->get_config('apply_markup')) { $temp_array = array('body' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($post[0]['message']))) : htmlspecialchars(stripslashes(trim($post[0]['message'])), ENT_COMPAT, LANG_CHARSET)); serendipity_plugin_api::hook_event('frontend_display', $temp_array); $post['message'] = trim($temp_array['body']); } else { $post['message'] = nl2br(function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($post[0]['message']))) : htmlspecialchars(stripslashes(trim($post[0]['message'])), ENT_COMPAT, LANG_CHARSET)); } $serendipity['smarty']->assign(array('pagetitle' => $this->get_config('pagetitle'), 'headline' => $this->get_config('headline'), 'threadtitle' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($thread[0]['title']))) : htmlspecialchars(stripslashes(trim($thread[0]['title'])), ENT_COMPAT, LANG_CHARSET), 'bgcolor1' => $this->get_config('bgcolor1'), 'bgcolor2' => $this->get_config('bgcolor2'), 'ACTUALURL' => $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&page=" . intval($_GET['page']), 'boardid' => intval($_GET['boardid']), 'threadid' => intval($_GET['threadid']), 'page' => intval($_GET['page']), 'delete' => intval($_GET['delete']), 'POST_AUTHORNAME' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($post[0]['authorname']))) : htmlspecialchars(stripslashes(trim($post[0]['authorname'])), ENT_COMPAT, LANG_CHARSET), 'POST_DATE' => date($this->get_config('dateformat') . " " . $this->get_config('timeformat'), $post[0]['postdate']), 'POST_TITLE' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($post[0]['title']))) : htmlspecialchars(stripslashes(trim($post[0]['title'])), ENT_COMPAT, LANG_CHARSET), 'POST_MESSAGE' => $post['message'], 'relpath' => $this->DMA_forum_getRelPath())); } elseif (isset($_GET['action']) && trim($_GET['action']) == "close") { $sql = "UPDATE {$serendipity['dbPrefix']}dma_forum_threads SET\n flag = '1'\n WHERE threadid = '" . intval($_GET['threadid']) . "'"; serendipity_db_query($sql); } elseif (isset($_GET['action']) && trim($_GET['action']) == "reopen") { $sql = "UPDATE {$serendipity['dbPrefix']}dma_forum_threads SET\n flag = '0'\n WHERE threadid = '" . intval($_GET['threadid']) . "'"; serendipity_db_query($sql); } if (isset($_GET['delfile']) && intval($_GET['delfile']) >= 1) { $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_uploads WHERE uploadid = '" . intval($_GET['delfile']) . "'"; $upload = serendipity_db_query($sql); if (serendipity_userLoggedIn() && ($serendipity['serendipityUserlevel'] == USERLEVEL_ADMIN || intval($upload[0]['authorid']) == intval($serendipity['authorid']))) { @unlink($this->get_config('uploaddir') . "/" . $upload[0]['sysfilename']); $q = "DELETE FROM {$serendipity['dbPrefix']}dma_forum_uploads WHERE uploadid = '" . intval($_GET['delfile']) . "'"; $sql = serendipity_db_query($q); } } if (isset($_GET['subscribe']) && intval($_GET['subscribe']) == 1 && isset($_GET['threadid'])) { if (serendipity_userLoggedIn()) { $sql = "SELECT notifymails FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE threadid='" . intval($_GET['threadid']) . "'"; $notifymails = serendipity_db_query($sql); if (trim($thread[0]['notifymails']) != "") { $NOTIFYARRAY = unserialize(stripslashes(trim($thread[0]['notifymails']))); } else { $NOTIFYARRAY = array(); } $NOTIFYARRAY[] = trim($serendipity['email']); $updatearray = trim(serialize($NOTIFYARRAY)); $sql = "UPDATE {$serendipity['dbPrefix']}dma_forum_threads SET notifymails = '" . $updatearray . "' WHERE threadid='" . intval($_GET['threadid']) . "'"; serendipity_db_query($sql); } } elseif (isset($_GET['unsubscribe']) && intval($_GET['unsubscribe']) == 1 && isset($_GET['threadid'])) { if (serendipity_userLoggedIn()) { $sql = "SELECT notifymails FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE threadid='" . intval($_GET['threadid']) . "'"; $notifymails = serendipity_db_query($sql); if (trim($thread[0]['notifymails']) != "") { $NOTIFYARRAY = unserialize(stripslashes(trim($thread[0]['notifymails']))); } else { $NOTIFYARRAY = array(); } $newarray = DMA_forum_array_remove($NOTIFYARRAY, trim($serendipity['email'])); if (count($newarray) <= 0) { $updatearray = ""; } else { $updatearray = trim(serialize($NOTIFYARRAY)); } $sql = "UPDATE {$serendipity['dbPrefix']}dma_forum_threads SET notifymails = '" . $updatearray . "' WHERE threadid='" . intval($_GET['threadid']) . "'"; serendipity_db_query($sql); } } /** Jahr des getrigen Tages */ $yesterday_year = intval(date("Y", time() - 86400)); /** Monat des getrigen Tages */ $yesterday_month = intval(date("n", time() - 86400)); /** Tageszahl des getrigen Tages */ $yesterday_day = intval(date("j", time() - 86400)); /** Letzter Timestamp des getrigen Tages (23:59:59 Uhr) */ $yesterday_lasttstamp = mktime(23, 59, 59, $yesterday_month, $yesterday_day, $yesterday_year); /** Erster Timestamp des getrigen Tages (00:00:00 Uhr) */ $yesterday_firsttstamp = mktime(0, 0, 0, $yesterday_month, $yesterday_day, $yesterday_year); if ((!isset($_GET['boardid']) || intval($_GET['boardid']) <= 0) && (!isset($_GET['replyto']) && !isset($_GET['edit']) && !isset($_GET['delete']) && !isset($_GET['quote']))) { // BOARDLIST $filename = 'templates/boardlist.tpl'; if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } $serendipity['smarty']->assign('pagetitle', $this->get_config('pagetitle')); $serendipity['smarty']->assign('headline', $this->get_config('headline')); $BOARDLIST = ""; $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_boards ORDER BY sortorder"; $boards = serendipity_db_query($sql); $mainpage_link = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "\">" . $this->get_config('pagetitle') . "</a>"; $serendipity['smarty']->assign('MAINPAGE', $mainpage_link); if (is_array($boards) && count($boards) >= 1) { $serendipity['smarty']->assign('bgcolor_head', $this->get_config('bgcolor_head')); for ($a = 0, $b = count($boards); $a < $b; $a++) { if (intval($boards[$a]['threads']) >= 1) { if (intval($boards[$a]['lastposttime']) >= intval($yesterday_lasttstamp) + 1) { $lastpost = "<span style=\"color:" . $this->get_config('color_today') . ";font-weight:bolder\">" . PLUGIN_FORUM_TODAY . " " . date($this->get_config('timeformat'), $boards[$a]['lastposttime']) . "</span><br />"; } elseif (intval($boards[$a]['lastposttime']) <= intval($yesterday_lasttstamp) && intval($boards[$a]['lastposttime']) >= intval($yesterday_firsttstamp)) { $lastpost = "<span style=\"color:" . $this->get_config('color_yesterday') . "\">" . PLUGIN_FORUM_YESTERDAY . " " . date($this->get_config('timeformat'), $boards[$a]['lastposttime']) . "</span><br />"; } else { $lastpost = date($this->get_config('dateformat') . " " . $this->get_config('timeformat'), $boards[$a]['lastposttime']) . "<br />"; } $lastpost .= (function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes($boards[$a]['lastauthorname'])) : htmlspecialchars(stripslashes($boards[$a]['lastauthorname']), ENT_COMPAT, LANG_CHARSET)) . " "; $sql = "SELECT COUNT(*) FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE threadid='" . intval($boards[$a]['lastthreadid']) . "'"; $postnum = serendipity_db_query($sql); $page = ceil(intval($postnum[0][0]) / intval($this->get_config('itemsperpage'))); $lastpost .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($boards[$a]['boardid']) . "&threadid=" . intval($boards[$a]['lastthreadid']) . "&page=" . $page . "#" . intval($boards[$a]['lastpostid']) . "\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/icon_latest_reply.gif\" width=\"18\" height=\"9\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_DIRECTGOTOPOST . "\" title=\"" . PLUGIN_FORUM_ALT_DIRECTGOTOPOST . "\" /></a>"; $boards[$a]['lastpost'] = $lastpost; } else { $boards[$a]['lastpost'] = PLUGIN_FORUM_NO_ENTRIES; } if ($thiscolor == $this->get_config('bgcolor2')) { $thiscolor = $this->get_config('bgcolor1'); } else { $thiscolor = $this->get_config('bgcolor2'); } $boards[$a]['color'] = $thiscolor; $boards[$a]['name'] = function_exists('serendipity_specialchars') ? serendipity_specialchars($boards[$a]['name']) : htmlspecialchars($boards[$a]['name'], ENT_COMPAT, LANG_CHARSET); $temp_array = array('body' => function_exists('serendipity_specialchars') ? serendipity_specialchars(trim(stripslashes($boards[$a]['description']))) : htmlspecialchars(trim(stripslashes($boards[$a]['description'])), ENT_COMPAT, LANG_CHARSET)); serendipity_plugin_api::hook_event('frontend_display', $temp_array); $boards[$a]['description'] = trim($temp_array['body']); } $serendipity['smarty']->assign(array('pagetitle' => $this->get_config('pagetitle'), 'headline' => $this->get_config('headline'), 'pageurl' => $this->get_config('pageurl'), 'boards' => $boards)); } else { $noboards .= PLUGIN_FORUM_NO_BOARDS; $serendipity['smarty']->assign('noboards', $noboards); } } elseif (intval($_GET['boardid']) >= 1 && (!isset($_GET['threadid']) || intval($_GET['threadid']) <= 0) && (!isset($_GET['replyto']) && !isset($_GET['edit']) && !isset($_GET['delete']) && !isset($_GET['quote']))) { // New thread if (isset($_GET['action']) && trim($_GET['action']) == "newthread") { $filename = 'templates/newthread.tpl'; if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_boards WHERE boardid='" . intval($_GET['boardid']) . "'"; $board = serendipity_db_query($sql); if (serendipity_userLoggedIn()) { $POST_AUTHORNAME = $serendipity['serendipityUser']; } if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $serendipity['smarty']->assign('ERRORMSG', $ERRORMSG); } $serendipity['smarty']->assign('bbcode', BBCODE); $serendipity['smarty']->assign(array('pagetitle' => $this->get_config('pagetitle'), 'headline' => $this->get_config('headline'), 'bgcolor2' => $this->get_config('bgcolor2'), 'ACTUALURL' => $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']), 'boardid' => intval($_GET['boardid']), 'POST_AUTHORNAME' => function_exists('serendipity_specialchars') ? serendipity_specialchars($POST_AUTHORNAME) : htmlspecialchars($POST_AUTHORNAME, ENT_COMPAT, LANG_CHARSET), 'POST_TITLE' => function_exists('serendipity_specialchars') ? serendipity_specialchars($POST_TITLE) : htmlspecialchars($POST_TITLE, ENT_COMPAT, LANG_CHARSET), 'POST_MESSAGE' => function_exists('serendipity_specialchars') ? serendipity_specialchars($POST_MESSAGE) : htmlspecialchars($POST_MESSAGE, ENT_COMPAT, LANG_CHARSET), 'relpath' => $this->DMA_forum_getRelPath(), 'newthreadurl' => $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&action=newthread&boardid=" . intval($_GET['boardid']), 'boardname' => function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes(trim($board[0]['name']))) : htmlspecialchars(stripslashes(trim($board[0]['name'])), ENT_COMPAT, LANG_CHARSET))); if (serendipity_userLoggedIn() && $serendipity['serendipityUserlevel'] == USERLEVEL_ADMIN) { $serendipity['smarty']->assign('announcement', true); } if (serendipity_userLoggedIn() && $this->get_config('fileupload_reguser') || $this->get_config('fileupload_guest')) { $upload_max_filesize = ini_get('upload_max_filesize'); $upload_max_filesize = preg_replace('/M/', '000000', $upload_max_filesize); $MAX_FILE_SIZE = intval($upload_max_filesize); $MAX_SIZE_PER_FILE = $MAX_FILE_SIZE / 1000000 . " MB"; $max_possible = intval($this->get_config('max_simultaneous_fileuploads')); if ($max_possible >= intval($this->get_config('max_files_per_post'))) { $max_possible = intval($this->get_config('max_files_per_post')); } if (serendipity_userLoggedIn()) { $authorid = intval($serendipity['authorid']); } else { $authorid = 0; } $sql = "SELECT COUNT(*) FROM {$serendipity['dbPrefix']}dma_forum_uploads WHERE authorid = '" . $authorid . "'"; $uploadnum = serendipity_db_query($sql); $uploaduserrest = intval($this->get_config('max_files_per_user')) - intval($uploadnum[0][0]); if ($max_possible >= $uploaduserrest) { $max_possible = $uploaduserrest; } $uploads = array(); for ($x = 0; $x < $max_possible; $x++) { $uploads[] = $x + 1; } $serendipity['smarty']->assign(array('uploadform' => true, 'MAX_FILE_SIZE' => $MAX_FILE_SIZE, 'MAX_SIZE_PER_FILE' => $MAX_SIZE_PER_FILE, 'uploads' => $uploads, 'uploads_post_left' => intval($this->get_config('max_files_per_post')), 'uploads_user_left' => $uploaduserrest)); } if ($this->get_config('use_captchas')) { $serendipity['smarty']->assign('commentform_entry', array('timestamp' => 1)); } } else { // THREADLIST $filename = 'templates/threadlist.tpl'; if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } $serendipity['smarty']->assign('pagetitle', $this->get_config('pagetitle')); $serendipity['smarty']->assign('headline', $this->get_config('headline')); $serendipity['smarty']->assign('relpath', $this->DMA_forum_getRelPath()); $serendipity['smarty']->assign('newthreadurl', $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&action=newthread&boardid=" . intval($_GET['boardid'])); $THREADLIST = ""; $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_boards WHERE boardid='" . intval($_GET['boardid']) . "'"; $board = serendipity_db_query($sql); // paging if (isset($_GET['page']) && intval($_GET['page']) >= 1) { $page = intval($_GET['page']); } else { $page = 1; } $postnum = intval($board[0]['threads']); $maxpages = ceil($postnum / intval($this->get_config('itemsperpage'))); if ($maxpages >= 2) { if (!isset($page) or trim($page) == "" or $page <= 0) { $page = 1; } if ($page > $maxpages) { $page = $maxpages; } $multiplicator = $page * intval($this->get_config('itemsperpage')) - intval($this->get_config('itemsperpage')); if (!isset($page) or $page == 1) { $LIMIT = serendipity_db_limit(0, intval($this->get_config('itemsperpage'))); } else { $LIMIT = serendipity_db_limit($multiplicator, intval($this->get_config('itemsperpage'))); } $LIMIT = serendipity_db_limit_sql($LIMIT); $paging = ""; if ($page > 1) { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&page=1\">1</a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&page=" . ($page - 10) . "\"><<</a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&page=" . ($page - 1) . "\"><</a> "; } elseif ($page == 1) { $paging .= "[ 1 ] "; } if ($maxpages >= 2) { for ($b = $page - 5; $b <= $page + 5; $b++) { if ($b > 1 and $b < $maxpages) { if ($b == $page) { $paging .= "[ " . $b . " ] "; } elseif ($b >= $maxpages) { } else { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&page=" . $b . "\">" . $b . "</a> "; } } } } if ($page < $maxpages) { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&page=" . ($page + 1) . "\">></a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&page=" . ($page + 10) . "\">>></a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&page=" . $maxpages . "\">" . $maxpages . "</a> "; } elseif ($page == $maxpages and $page != 1) { $paging .= "[ " . $maxpages . " ]"; } if (isset($paging) && trim($paging) != "") { $serendipity['smarty']->assign('paging', $paging); } } else { $LIMIT = ""; } $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE boardid='" . intval($_GET['boardid']) . "' ORDER BY announce DESC, lastposttime DESC" . $LIMIT; $threads = serendipity_db_query($sql); $mainpage_link = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "\">" . $this->get_config('pagetitle') . "</a>"; $threadlist_link = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "\">" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($board[0]['name']) : htmlspecialchars($board[0]['name'], ENT_COMPAT, LANG_CHARSET)) . "</a>"; $serendipity['smarty']->assign('MAINPAGE', $mainpage_link); $serendipity['smarty']->assign('THREADLIST', $threadlist_link); if (is_array($threads) && count($threads) >= 1) { $serendipity['smarty']->assign('bgcolor_head', $this->get_config('bgcolor_head')); for ($a = 0, $b = count($threads); $a < $b; $a++) { if (intval($threads[$a]['lastpostid']) >= 1) { if (intval($threads[$a]['lastposttime']) >= intval($yesterday_lasttstamp) + 1) { $lastpost = "<span style=\"color:" . $this->get_config('color_today') . ";font-weight:bolder\">" . PLUGIN_FORUM_TODAY . " " . date($this->get_config('timeformat'), $threads[$a]['lastposttime']) . "</span><br />"; } elseif (intval($threads[$a]['lastposttime']) <= intval($yesterday_lasttstamp) && intval($threads[$a]['lastposttime']) >= intval($yesterday_firsttstamp)) { $lastpost = "<span style=\"color:" . $this->get_config('color_yesterday') . "\">" . PLUGIN_FORUM_YESTERDAY . " " . date($this->get_config('timeformat'), $threads[$a]['lastposttime']) . "</span><br />"; } else { $lastpost = date($this->get_config('dateformat') . " " . $this->get_config('timeformat'), $threads[$a]['lastposttime']) . "<br />"; } $lastpost .= (function_exists('serendipity_specialchars') ? serendipity_specialchars(stripslashes($threads[$a]['lastauthorname'])) : htmlspecialchars(stripslashes($threads[$a]['lastauthorname']), ENT_COMPAT, LANG_CHARSET)) . " "; $sql = "SELECT COUNT(*) FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE threadid='" . intval($threads[$a]['threadid']) . "'"; $postnum = serendipity_db_query($sql); $page = ceil(intval($postnum[0][0]) / intval($this->get_config('itemsperpage'))); $lastpost .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($threads[$a]['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=" . $page . "#" . intval($threads[$a]['lastpostid']) . "\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/icon_latest_reply.gif\" width=\"18\" height=\"9\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_DIRECTGOTOPOST . "\" title=\"" . PLUGIN_FORUM_ALT_DIRECTGOTOPOST . "\" /></a>"; } else { $lastpost = PLUGIN_FORUM_NO_REPLIES; } $threads[$a]['lastpost'] = $lastpost; if ($thiscolor == $this->get_config('bgcolor2')) { $thiscolor = $this->get_config('bgcolor1'); } else { $thiscolor = $this->get_config('bgcolor2'); } $threads[$a]['color'] = $thiscolor; $threads[$a]['title'] = function_exists('serendipity_specialchars') ? serendipity_specialchars($threads[$a]['title']) : htmlspecialchars($threads[$a]['title'], ENT_COMPAT, LANG_CHARSET); if (intval($threads[$a]['announce']) == 1 && intval($threads[$a + 1]['announce']) != 1) { $threads[$a]['trenner'] = true; } else { $threads[$a]['trenner'] = false; } if (intval($threads[$a]['announce']) == 1) { $threads[$a]['icon'] = $THREAD_UNREAD_ANNOUNCEMENT; if (isset($READARRAY[intval($threads[$a]['threadid'])]) && intval($READARRAY[intval($threads[$a]['threadid'])]) >= intval($threads[$a]['lastposttime'])) { $threads[$a]['icon'] = $THREAD_READ_ANNOUNCEMENT; } } else { if (intval($threads[$a]['replies']) >= 15) { $threads[$a]['icon'] = $THREAD_HUGE_UNREAD; } else { $threads[$a]['icon'] = $THREAD_UNREAD; } if (isset($READARRAY[intval($threads[$a]['threadid'])]) && intval($READARRAY[intval($threads[$a]['threadid'])]) >= intval($threads[$a]['lastposttime'])) { if (intval($threads[$a]['replies']) >= 15) { $threads[$a]['icon'] = $THREAD_HUGE_READ; } else { $threads[$a]['icon'] = $THREAD_READ; } } } $paging = ""; $sql = "SELECT COUNT(*) FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE threadid='" . intval($threads[$a]['threadid']) . "'"; $postnum = serendipity_db_query($sql); $maxpages = ceil(intval($postnum[0][0]) / intval($this->get_config('itemsperpage'))); if ($maxpages >= 2) { $paging = PLUGIN_FORUM_PAGES . ": "; if ($maxpages <= 10) { $pages = ""; for ($c = 0; $c < $maxpages; $c++) { if ($pages != "") { $pages .= ", "; } $pages .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=" . ($c + 1) . "\">" . ($c + 1) . "</a>"; } $paging .= $pages; } elseif ($maxpages <= 20) { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=1\">1</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=2\">2</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=3\">3</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=4\">4</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=5\">5</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=10\">10</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=" . $maxpages . "\">" . $maxpages . "</a>"; } elseif ($maxpages <= 50) { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=1\">1</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=2\">2</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=3\">3</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=4\">4</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=10\">10</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=20\">20</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=" . $maxpages . "\">" . $maxpages . "</a>"; } else { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=1\">1</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=2\">2</a>, "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=3\">3</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=10\">10</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=20\">20</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=50\">50</a>"; $paging .= "... <a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($threads[$a]['threadid']) . "&page=" . $maxpages . "\">" . $maxpages . "</a>"; } } if ($paging != "") { $threads[$a]['paging'] = $paging; } } $serendipity['smarty']->assign(array('pagetitle' => $this->get_config('pagetitle'), 'headline' => $this->get_config('headline'), 'pageurl' => $this->get_config('pageurl'), 'threads' => $threads)); } else { $nothreads .= PLUGIN_FORUM_NO_THREADS; $serendipity['smarty']->assign('nothreads', $nothreads); } } } elseif (intval($_GET['boardid']) >= 1 && intval($_GET['threadid']) >= 1 && (!isset($_GET['replyto']) && !isset($_GET['edit']) && !isset($_GET['delete']) && !isset($_GET['quote']))) { // POSTS $filename = 'templates/postlist.tpl'; if (!is_object($serendipity['smarty'])) { serendipity_smarty_init(); } $serendipity['smarty']->assign('pagetitle', $this->get_config('pagetitle')); $serendipity['smarty']->assign('headline', $this->get_config('headline')); if (isset($ERRORMSG) && trim($ERRORMSG) != "") { $serendipity['smarty']->assign('ERRORMSG', $ERRORMSG); } $q = "UPDATE {$serendipity['dbPrefix']}dma_forum_threads SET views = views+1 WHERE threadid = '" . intval($_GET['threadid']) . "'"; serendipity_db_query($q); // Set the cookie for threadicon (read/unread) $cookie = array('setthreadcookie' => intval($_GET['threadid'])); serendipity_plugin_api::hook_event('external_plugin', $cookie); $POSTLIST = ""; $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_boards WHERE boardid='" . intval($_GET['boardid']) . "'"; $board = serendipity_db_query($sql); $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_threads WHERE threadid='" . intval($_GET['threadid']) . "'"; $thread = serendipity_db_query($sql); $mainpage_link = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "\">" . $this->get_config('pagetitle') . "</a>"; $threadlist_link = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "\">" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($board[0]['name']) : htmlspecialchars($board[0]['name'], ENT_COMPAT, LANG_CHARSET)) . "</a>"; $posts_link = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "\">" . (function_exists('serendipity_specialchars') ? serendipity_specialchars($thread[0]['title']) : htmlspecialchars($thread[0]['title'], ENT_COMPAT, LANG_CHARSET)) . "</a>"; $serendipity['smarty']->assign('MAINPAGE', $mainpage_link); $serendipity['smarty']->assign('THREADLIST', $threadlist_link); $serendipity['smarty']->assign('POSTS', $posts_link); // paging if (isset($_GET['page']) && intval($_GET['page']) >= 1) { $page = intval($_GET['page']); } else { $page = 1; } $postnum = intval($thread[0]['replies']) + 1; $maxpages = ceil($postnum / intval($this->get_config('itemsperpage'))); if ($maxpages >= 2) { if (!isset($page) or trim($page) == "" or $page <= 0) { $page = 1; } if ($page > $maxpages) { $page = $maxpages; } $multiplicator = $page * intval($this->get_config('itemsperpage')) - intval($this->get_config('itemsperpage')); if (!isset($page) or $page == 1) { $LIMIT = serendipity_db_limit(0, intval($this->get_config('itemsperpage'))); } else { $LIMIT = serendipity_db_limit($multiplicator, intval($this->get_config('itemsperpage'))); } $LIMIT = serendipity_db_limit_sql($LIMIT); $paging = ""; if ($page > 1) { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "&page=1\">1</a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "&page=" . ($page - 10) . "\"><<</a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "&page=" . ($page - 1) . "\"><</a> "; } elseif ($page == 1) { $paging .= "[ 1 ] "; } if ($maxpages >= 2) { for ($b = $page - 5; $b <= $page + 5; $b++) { if ($b > 1 and $b < $maxpages) { if ($b == $page) { $paging .= "[ " . $b . " ] "; } elseif ($b >= $maxpages) { } else { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "&page=" . $b . "\">" . $b . "</a> "; } } } } if ($page < $maxpages) { $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "&page=" . ($page + 1) . "\">></a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "&page=" . ($page + 10) . "\">>></a> "; $paging .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($thread[0]['threadid']) . "&page=" . $maxpages . "\">" . $maxpages . "</a> "; } elseif ($page == $maxpages and $page != 1) { $paging .= "[ " . $maxpages . " ]"; } if (isset($paging) && trim($paging) != "") { $serendipity['smarty']->assign('paging', $paging); } } else { $LIMIT = ""; } $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_posts WHERE threadid='" . intval($_GET['threadid']) . "' ORDER BY postdate ASC" . $LIMIT; $posts = serendipity_db_query($sql); if (is_array($posts) && count($posts) >= 1) { $serendipity['smarty']->assign('threadtitle', function_exists('serendipity_specialchars') ? serendipity_specialchars($thread[0]['title']) : htmlspecialchars($thread[0]['title'], ENT_COMPAT, LANG_CHARSET)); $serendipity['smarty']->assign('bgcolor_head', $this->get_config('bgcolor_head')); for ($a = 0, $b = count($posts); $a < $b; $a++) { if ($thiscolor == $this->get_config('bgcolor2')) { $thiscolor = $this->get_config('bgcolor1'); } else { $thiscolor = $this->get_config('bgcolor2'); } $posts[$a]['color'] = $thiscolor; if ($this->get_config('apply_markup')) { if ($this->get_config('unreg_nomarkups') && (!isset($posts[$a]['authorid']) || intval($posts[$a]['authorid']) <= 0)) { $posts[$a]['message'] = nl2br(function_exists('serendipity_specialchars') ? serendipity_specialchars(trim(stripslashes($posts[$a]['message']))) : htmlspecialchars(trim(stripslashes($posts[$a]['message'])), ENT_COMPAT, LANG_CHARSET)); } else { $temp_array = array('body' => function_exists('serendipity_specialchars') ? serendipity_specialchars(trim(stripslashes($posts[$a]['message']))) : htmlspecialchars(trim(stripslashes($posts[$a]['message'])), ENT_COMPAT, LANG_CHARSET)); serendipity_plugin_api::hook_event('frontend_display', $temp_array); $posts[$a]['message'] = trim($temp_array['body']); } } else { $posts[$a]['message'] = nl2br(function_exists('serendipity_specialchars') ? serendipity_specialchars(trim(stripslashes($posts[$a]['message']))) : htmlspecialchars(trim(stripslashes($posts[$a]['message'])), ENT_COMPAT, LANG_CHARSET)); } unset($email); unset($gravatar_array); unset($posts[$a]['gravatar']); $authorid = intval(trim($posts[$a]['authorid'])); if ($authorid >= 1) { $sql = "SELECT email FROM {$serendipity['dbPrefix']}authors WHERE authorid = '" . $authorid . "'"; $email = serendipity_db_query($sql); $gravatar_array = array('comment' => "", 'email' => trim($email[0][0])); serendipity_plugin_api::hook_event('frontend_display', $gravatar_array); if (isset($gravatar_array['comment']) && trim($gravatar_array['comment']) != "") { $posts[$a]['gravatar'] = $gravatar_array['comment']; } } $POSTBUTTONS = ""; if ($thread[0]['flag'] != 1) { $POSTBUTTONS = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&replyto=" . $posts[$a]['postid'] . "&quote=0\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/reply.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_REPLY . "\" title=\"" . PLUGIN_FORUM_ALT_REPLY . "\" /></a> "; $POSTBUTTONS .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&replyto=" . $posts[$a]['postid'] . "&quote=1\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/quote.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_QUOTE . "\" title=\"" . PLUGIN_FORUM_ALT_QUOTE . "\" /></a> "; } if (serendipity_userLoggedIn() && ($serendipity['serendipityUser'] == $posts[$a]['authorname'] && $serendipity['authorid'] == $posts[$a]['authorid'] || $serendipity['serendipityUserlevel'] == 255)) { $POSTBUTTONS .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&page=" . $page . "&edit=" . $posts[$a]['postid'] . "\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/edit.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_EDIT . "\" title=\"" . PLUGIN_FORUM_ALT_EDIT . "\" /></a> "; } if (serendipity_userLoggedIn() && $serendipity['serendipityUserlevel'] == 255) { $POSTBUTTONS .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&page=" . $page . "&delete=" . $posts[$a]['postid'] . "\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/delete.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_DELETE_POST . "\" title=\"" . PLUGIN_FORUM_ALT_DELETE_POST . "\" /></a> "; } $posts[$a]['postbuttons'] = $POSTBUTTONS; $AUTHORDETAILS = ""; if (isset($posts[$a]['authorid']) && intval($posts[$a]['authorid']) >= 1) { $AUTHORDETAILS .= "<b>" . PLUGIN_FORUM_REG_USER . "</b><br />"; $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_users WHERE authorid = '" . intval($posts[$a]['authorid']) . "'"; $userdetails = serendipity_db_query($sql); if (is_array($userdetails) && count($userdetails) >= 1) { $AUTHORDETAILS .= PLUGIN_FORUM_POSTS . ": " . intval($userdetails[0]['posts']) . "<br />"; $AUTHORDETAILS .= PLUGIN_FORUM_VISITS . ": " . intval($userdetails[0]['visits']) . "<br />"; } else { $AUTHORDETAILS .= PLUGIN_FORUM_POSTS . ": 0<br />"; $AUTHORDETAILS .= PLUGIN_FORUM_VISITS . ": 0<br />"; } } $sql = "SELECT * FROM {$serendipity['dbPrefix']}dma_forum_uploads WHERE postid = '" . $posts[$a]['postid'] . "'"; $uploads = serendipity_db_query($sql); if (is_array($uploads) && count($uploads) >= 1) { $posts[$a]['uploads'] = true; for ($y = 0, $z = count($uploads); $y < $z; $y++) { $filesize = DMA_forum_calcFilesize($uploads[$y]['filesize']); $mime = DMA_forum_getMime(function_exists('serendipity_specialchars') ? serendipity_specialchars(basename($uploads[$y]['realfilename'])) : htmlspecialchars(basename($uploads[$y]['realfilename']), ENT_COMPAT, LANG_CHARSET), $this->DMA_forum_getRelPath()); $fileicon = "<img src=\"" . $mime['ICON'] . "\" width=\"18\" height=\"20\" border=\"0\" />"; $content_type = $mime['TYPE']; $posts[$a]['upload'][$y]['filename'] = "<a href=\"" . $serendipity['baseURL'] . ($serendipity['rewrite'] == "none" ? $serendipity['indexFile'] . "?/" : "") . "plugin/forumdl_" . intval($uploads[$y]['uploadid']) . "\">" . (function_exists('serendipity_specialchars') ? serendipity_specialchars(basename($uploads[$y]['realfilename'])) : htmlspecialchars(basename($uploads[$y]['realfilename']), ENT_COMPAT, LANG_CHARSET)) . "</a>"; $posts[$a]['upload'][$y]['filesize'] = $filesize; $posts[$a]['upload'][$y]['fileicon'] = $fileicon; $posts[$a]['upload'][$y]['filetype'] = $content_type; $posts[$a]['upload'][$y]['dlcount'] = intval($uploads[$y]['dlcount']); if (serendipity_userLoggedIn() && ($serendipity['serendipityUserlevel'] == USERLEVEL_ADMIN || intval($uploads[$y]['authorid']) == intval($serendipity['authorid']))) { $posts[$a]['upload'][$y]['delbutton'] = "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&page=" . $page . "&delfile=" . intval($uploads[$y]['uploadid']) . "#" . intval($posts[$a]['postid']) . "\">" . $DEL_FILE_BUTTON . "</a>"; } } } else { $posts[$a]['uploads'] = false; } $posts[$a]['authordetails'] = $AUTHORDETAILS; $posts[$a]['title'] = function_exists('serendipity_specialchars') ? serendipity_specialchars($posts[$a]['title']) : htmlspecialchars($posts[$a]['title'], ENT_COMPAT, LANG_CHARSET); $posts[$a]['authorname'] = function_exists('serendipity_specialchars') ? serendipity_specialchars($posts[$a]['authorname']) : htmlspecialchars($posts[$a]['authorname'], ENT_COMPAT, LANG_CHARSET); if (intval($posts[$a]['postdate']) >= intval($yesterday_lasttstamp) + 1) { $posts[$a]['postdate'] = "<span style=\"color:" . $this->get_config('color_today') . ";font-weight:bolder\">" . PLUGIN_FORUM_TODAY . " " . date($this->get_config('timeformat'), $posts[$a]['postdate']) . "</span>"; } elseif (intval($posts[$a]['postdate']) <= intval($yesterday_lasttstamp) && intval($posts[$a]['postdate']) >= intval($yesterday_firsttstamp)) { $posts[$a]['postdate'] = "<span style=\"color:" . $this->get_config('color_yesterday') . "\">" . PLUGIN_FORUM_YESTERDAY . " " . date($this->get_config('timeformat'), $posts[$a]['postdate']) . "</span>"; } else { $posts[$a]['postdate'] = date($this->get_config('dateformat') . " " . $this->get_config('timeformat'), $posts[$a]['postdate']); } } if (serendipity_userLoggedIn()) { if (trim($thread[0]['notifymails']) != "") { $NOTIFYARRAY = unserialize(stripslashes(trim($thread[0]['notifymails']))); } else { $NOTIFYARRAY = array(); } if (in_array($serendipity['email'], $NOTIFYARRAY)) { $serendipity['smarty']->assign('notify', 2); } else { $serendipity['smarty']->assign('notify', 1); } $subscribeurl = $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&page=" . $page . "&subscribe=1"; $unsubscribeurl = $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&page=" . $page . "&unsubscribe=1"; $serendipity['smarty']->assign('subscribeurl', $subscribeurl); $serendipity['smarty']->assign('unsubscribeurl', $unsubscribeurl); } $serendipity['smarty']->assign(array('pagetitle' => $this->get_config('pagetitle'), 'headline' => $this->get_config('headline'), 'pageurl' => $this->get_config('pageurl'), 'posts' => $posts)); } else { $noposts = PLUGIN_FORUM_NO_POSTS; $serendipity['smarty']->assign('noposts', $noposts); } // Display thread buttons regardless of number of posts $THREADBUTTONS = ""; if (serendipity_userLoggedIn() && $serendipity['serendipityUserlevel'] == 255) { if ($thread[0]['flag'] == 1) { $THREADBUTTONS .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&action=reopen\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/reopen.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_REOPEN . "\" title=\"" . PLUGIN_FORUM_ALT_REOPEN . "\" /></a> "; } else { $THREADBUTTONS .= "<a href=\"" . $serendipity['baseURL'] . "index.php?serendipity[subpage]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&action=close\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/close.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_CLOSE . "\" title=\"" . PLUGIN_FORUM_ALT_CLOSE . "\" /></a> "; } $THREADBUTTONS .= "<a href=\"" . $serendipity['baseURL'] . "serendipity_admin.php?serendipity[adminModule]=event_display&serendipity[adminAction]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&action=move\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/move.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_MOVE . "\" title=\"" . PLUGIN_FORUM_ALT_MOVE . "\" /></a> "; $THREADBUTTONS .= "<a href=\"" . $serendipity['baseURL'] . "serendipity_admin.php?serendipity[adminModule]=event_display&serendipity[adminAction]=" . $this->get_config('pageurl') . "&boardid=" . intval($_GET['boardid']) . "&threadid=" . intval($_GET['threadid']) . "&action=delete\"><img src=\"" . $this->DMA_forum_getRelPath() . "/img/delete.png\" width=\"60\" height=\"18\" border=\"0\" alt=\"" . PLUGIN_FORUM_ALT_DELETE . "\" title=\"" . PLUGIN_FORUM_ALT_DELETE . "\" /></a>"; } $serendipity['smarty']->assign('THREADBUTTONS', $THREADBUTTONS); } $serendipity['smarty']->assign('plugin_eventforum_not20', $serendipity['version'][0] < 2 ? true : false); $filename = $filename; $tfile = serendipity_getTemplateFile($filename, 'serendipityPath'); if (!$tfile || $tfile == $filename) { $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; }