function smd_lately($atts, $thing=NULL) { global $prefs, $thisarticle, $permlink_mode; // Check logging is on if ( $prefs['logging'] != 'all') { trigger_error(smd_rv_gTxt('logging_enabled'), E_USER_NOTICE); return; } extract(lAtts(array( 'by' => 'SMD_CURRENT', // Default is the IP address of the current visitor. Can be empty for 'all' visitors 'section' => '', 'status' => '', 'time' => 'past', 'include' => '', 'exclude' => '', 'show_current' => 0, 'form' => '', 'limit' => 10, 'sort' => 'time desc', 'wraptag' => '', 'break' => 'br', 'class' => '__FUNCTION__', 'label' => '', 'labeltag' => '', 'delim' => ',', 'param_delim' => ':', 'debug' => 0, ), $atts)); // Sanitize sort options $sortBits = do_list($sort, " "); $sortBits[0] = (empty($sortBits[0])) ? 'time' : $sortBits[0]; if (!isset($sortBits[1]) || !in_array($sortBits[1], array('desc', 'asc'))) { $sortBits[1] = 'desc'; $sort = join(" ", $sortBits); } // IP address clause $ip = ''; if ($by == 'SMD_CURRENT') { if (function_exists('remote_addr')) { $ip = remote_addr(); } else { $ip = serverSet('REMOTE_ADDR'); if (($ip == '127.0.0.1' || $ip == serverSet('SERVER_ADDR')) && serverSet('HTTP_X_FORWARDED_FOR')) { $ips = explode(', ', serverSet('HTTP_X_FORWARDED_FOR')); $ip = $ips[0]; } } if ($ip) { $ip = " AND ip='".doSlash($ip)."'"; } } else if ($by == 'SMD_ALL') { $by = ''; } // Make sure we don't include the current article // Note the regexp is anchored to the end with a $ $thisicle = ''; if (isset($thisarticle)) { if (!$show_current) { $urltitle = $thisarticle['url_title']; $thisicle = " AND page NOT REGEXP '$urltitle$'"; } } // Filter out article_list pages and other (un)desirables $rules = array( "page NOT REGEXP '^/$'", // Goodbye front page "page NOT REGEXP 'q='", // Goodbye searches "page NOT REGEXP 'c='", // Goodbye cat lists "page NOT REGEXP 'category='", "page NOT REGEXP '^/category/'", "page NOT REGEXP 'author='", "page NOT REGEXP '^/author/'", ); if ($section) { $section = do_list($section, $delim); $subrule = array(); foreach ($section as $sec) { if ($permlink_mode == 'messy') { $subrule[] = "page REGEXP 's=$sec'"; } else { $subrule[] = "page REGEXP '^/$sec' AND page NOT REGEXP '^/$sec/?$'"; } } $subrule = '(' . join(' OR ', $subrule) . ')'; $rules[] = $subrule; } else { // Exclude any rows that just contain the section (i.e. article list pages) $allSecs = safe_column('name', 'txp_section', "1=1", $debug); $rules[] = "page NOT REGEXP '^/(" . join("|", $allSecs) . ")/?$'"; } // Process any manual includes if ($include) { $include = do_list($include, $delim); $subrules = array(); foreach ($include as $inc) { $regex = false; $column = 'ip'; $parts = do_list($inc, $param_delim); $match = array_pop($parts); foreach ($parts as $part) { switch ($part) { case "ip": case "host": case "page": case "refer": $column = $part; break; case "regex": $regex = true; } } $subrules[] = $regex ? "$column REGEXP '".doSlash(preg_quote($match))."'" : "$column = '".doSlash($match)."'"; } $rules[] = '('.join(' OR ', $subrules).')'; } // Process any manual excludes if ($exclude) { $exclude = do_list($exclude, $delim); foreach ($exclude as $exc) { $regex = false; $column = 'ip'; $parts = do_list($exc, $param_delim); $match = array_pop($parts); foreach ($parts as $part) { switch ($part) { case "ip": case "host": case "page": case "refer": $column = $part; break; case "regex": $regex = true; } } $rules[] = $regex ? "$column NOT REGEXP '".doSlash(preg_quote($match))."'" : "$column != '".doSlash($match)."'"; } } if ($debug) { echo "++ smd_lately RULES ++"; dmp($rules); } $rules = ' AND ' . join(' AND ', $rules); $query = 'SELECT count(page) as popularity, page, MAX(time) as time FROM '.PFX.'txp_log WHERE 1=1'.$ip.$thisicle.$rules.' AND status = 200 GROUP BY page ORDER BY '.$sort; $rs = getRows($query, $debug); if ($debug > 1) { dmp($rs); } // Set up counters and create query params $count = 0; $out = array(); if ($status) { $status = do_list($status, $delim); $stati = array(); foreach ($status as $stat) { if (empty($stat)) { continue; } else if (is_numeric($stat)) { $stati[] = $stat; } else { $stati[] = getStatusNum($stat); } } $status = " AND Status IN (".join(',', $stati).")"; } switch($time) { case "": case "any" : $time = ""; break; case "future" : $time = " AND Posted > CURDATE()"; break; default : $time = " AND Posted < CURDATE()"; break; } // Loop until limit reached if ($rs) { foreach ($rs as $row) { if ($limit > 0 && is_numeric($limit) && $count == $limit) break; $urlparts = explode('/', $row['page']); $darticle = safe_row('*, unix_timestamp(Posted) as uPosted, unix_timestamp(Expires) as uExpires, unix_timestamp(LastMod) as uLastMod', 'textpattern', "url_title='".$urlparts[count($urlparts)-1]."'".$status.$time, $debug); if ($debug > 2) { dmp($darticle); } if ($darticle) { $theTime = strtotime($row['time']); $replacements = array( "{smd_lately_count}" => $row['popularity'], "{smd_lately_fulldate}" => $row['time'], "{smd_lately_date}" => strftime("%F", $theTime), "{smd_lately_date_year}" => strftime("%Y", $theTime), "{smd_lately_date_month}" => strftime("%m", $theTime), "{smd_lately_date_monthname}" => strftime("%B", $theTime), "{smd_lately_date_day}" => strftime("%d", $theTime), "{smd_lately_date_dayname}" => strftime("%A", $theTime), "{smd_lately_time}" => strftime("%T", $theTime), "{smd_lately_time_hour}" => strftime("%H", $theTime), "{smd_lately_time_minute}" => strftime("%M", $theTime), "{smd_lately_time_second}" => strftime("%S", $theTime), ); article_push(); populateArticleData($darticle); $out[] = ($thing) ? parse(strtr($thing, $replacements)) : (($form) ? parse_form(strtr($form, $replacements)) : href($darticle['Title'], permlinkurl($darticle))); article_pop(); $count++; } } } return ($out) ? doLabel($label, $labeltag).doWrap($out, $wraptag, $break, $class) : ''; } // ------------------------ // Plugin-specific replacement strings - localise as required function smd_rv_gTxt($what, $atts = array()) { $lang = array( 'logging_enabled' => 'Logging must be set to "All hits" in Basic Pefs.', ); return strtr($lang[$what], $atts); }