PageRenderTime 56ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/wassup/lib/main.php

https://bitbucket.org/openfarmtech/weblog-content
PHP | 1339 lines | 1038 code | 116 blank | 185 comment | 223 complexity | 63386f157a0e14f1dedb76120f68e179 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.0, LGPL-3.0, BSD-3-Clause, GPL-3.0, LGPL-2.1, AGPL-3.0, CC-BY-SA-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. if (!class_exists('pagination')) { //in case another app uses this class...
  3. class pagination{
  4. /*
  5. Script Name: *Digg Style Paginator Class
  6. Script URI: http://www.mis-algoritmos.com/2007/05/27/digg-style-pagination-class/
  7. Description: Class in PHP that allows to use a pagination like a digg or sabrosus style.
  8. Script Version: 0.3.2
  9. Author: Victor De la Rocha
  10. Author URI: http://www.mis-algoritmos.com
  11. */
  12. /*Default values*/
  13. var $total_pages;
  14. var $limit;
  15. var $target;
  16. var $page;
  17. var $adjacents;
  18. var $showCounter;
  19. var $className;
  20. var $parameterName;
  21. var $urlF ;
  22. /*Buttons next and previous*/
  23. var $nextT;
  24. var $nextI;
  25. var $prevT;
  26. var $prevI;
  27. /*****/
  28. var $calculate;
  29. #Total items
  30. function items($value){$this->total_pages = intval($value);}
  31. #how many items to show per page
  32. function limit($value){$this->limit = intval($value);}
  33. #Page to sent the page value
  34. function target($value){$this->target = $value;}
  35. #Current page
  36. function currentPage($value){$this->page = intval($value);}
  37. #How many adjacent pages should be shown on each side of the current page?
  38. function adjacents($value){$this->adjacents = intval($value);}
  39. #show counter?
  40. function showCounter($value=""){$this->showCounter=($value===true)?true:false;}
  41. #to change the class name of the pagination div
  42. function changeClass($value=""){$this->className=$value;}
  43. function nextLabel($value){$this->nextT = $value;}
  44. function nextIcon($value){$this->nextI = $value;}
  45. function prevLabel($value){$this->prevT = $value;}
  46. function prevIcon($value){$this->prevI = $value;}
  47. #to change the class name of the pagination div
  48. function parameterName($value=""){$this->parameterName=$value;}
  49. #to change urlFriendly
  50. function urlFriendly($value="%"){
  51. if(eregi('^ *$',$value)){
  52. $this->urlF=false;
  53. return false;
  54. }
  55. $this->urlF=$value;
  56. }
  57. var $pagination;
  58. function pagination(){
  59. /*Set Default values*/
  60. $this->total_pages = null;
  61. $this->limit = null;
  62. $this->target = "";
  63. $this->page = 1;
  64. $this->adjacents = 2;
  65. $this->showCounter = false;
  66. $this->className = "pagination";
  67. $this->parameterName = "pages";
  68. $this->urlF = false;//urlFriendly
  69. /*Buttons next and previous*/
  70. $this->nextT = __("Next","wassup");
  71. $this->nextI = "&#187;"; //&#9658;
  72. $this->prevT = __("Previous","wassup");
  73. $this->prevI = "&#171;"; //&#9668;
  74. $this->calculate = false;
  75. }
  76. function show(){
  77. if(!$this->calculate)
  78. if($this->calculate())
  79. echo "<div class=\"$this->className\">$this->pagination</div>";
  80. }
  81. function get_pagenum_link($id){
  82. if(strpos($this->target,'?')===false)
  83. if($this->urlF)
  84. return str_replace($this->urlF,$id,$this->target);
  85. else
  86. return "$this->target?$this->parameterName=$id";
  87. else
  88. return "$this->target&$this->parameterName=$id";
  89. }
  90. function calculate(){
  91. $this->pagination = "";
  92. $this->calculate == true;
  93. $error = false;
  94. if($this->urlF and $this->urlF != '%' and strpos($this->target,$this->urlF)===false){
  95. //Es necesario especificar el comodin para sustituir
  96. echo 'Especificaste un wildcard para sustituir, pero no existe en el target<br />';
  97. $error = true;
  98. }elseif($this->urlF and $this->urlF == '%' and strpos($this->target,$this->urlF)===false){
  99. echo 'Es necesario especificar en el target el comodin';
  100. $error = true;
  101. }
  102. if($this->total_pages == null){
  103. echo __("It is necessary to specify the","wassup")." <strong>".__("number of pages","wassup")."</strong> (\$class->items(1000))<br />";
  104. $error = true;
  105. }
  106. if($this->limit == null){
  107. echo __("It is necessary to specify the","wassup")." <strong>".__("limit of items","wassup")."</strong> ".__("to show per page","wassup")." (\$class->limit(10))<br />";
  108. $error = true;
  109. }
  110. if($error)return false;
  111. $n = trim($this->nextT.' '.$this->nextI);
  112. $p = trim($this->prevI.' '.$this->prevT);
  113. /* Setup vars for query. */
  114. if($this->page)
  115. $start = ($this->page - 1) * $this->limit; //first item to display on this page
  116. else
  117. $start = 0; //if no page var is given, set start to 0
  118. /* Setup page vars for display. */
  119. if ($this->page == 0) $this->page = 1; //if no page var is given, default to 1.
  120. $prev = $this->page - 1; //previous page is page - 1
  121. $next = $this->page + 1; //next page is page + 1
  122. $lastpage = ceil($this->total_pages/$this->limit); //lastpage is = total pages / items per page, rounded up.
  123. $lpm1 = $lastpage - 1; //last page minus 1
  124. /*
  125. Now we apply our rules and draw the pagination object.
  126. We're actually saving the code to a variable in case we want to draw it more than once.
  127. */
  128. if($lastpage > 1){
  129. //anterior button
  130. if($this->page > 1)
  131. $this->pagination .= "<a href=\"".$this->get_pagenum_link($prev)."\">$p</a>";
  132. else
  133. $this->pagination .= "<span class=\"disabled\">$p</span>";
  134. //pages
  135. if ($lastpage < 7 + ($this->adjacents * 2)){//not enough pages to bother breaking it up
  136. for ($counter = 1; $counter <= $lastpage; $counter++){
  137. if ($counter == $this->page)
  138. $this->pagination .= "<span class=\"current\">$counter</span>";
  139. else
  140. $this->pagination .= "<a href=\"".$this->get_pagenum_link($counter)."\">$counter</a>";
  141. }
  142. }
  143. elseif($lastpage > 5 + ($this->adjacents * 2)){//enough pages to hide some
  144. //close to beginning; only hide later pages
  145. if($this->page < 1 + ($this->adjacents * 2)){
  146. for ($counter = 1; $counter < 4 + ($this->adjacents * 2); $counter++){
  147. if ($counter == $this->page)
  148. $this->pagination .= "<span class=\"current\">$counter</span>";
  149. else
  150. $this->pagination .= "<a href=\"".$this->get_pagenum_link($counter)."\">$counter</a>";
  151. }
  152. $this->pagination .= "...";
  153. $this->pagination .= "<a href=\"".$this->get_pagenum_link($lpm1)."\">$lpm1</a>";
  154. $this->pagination .= "<a href=\"".$this->get_pagenum_link($lastpage)."\">$lastpage</a>";
  155. }
  156. //in middle; hide some front and some back
  157. elseif($lastpage - ($this->adjacents * 2) > $this->page && $this->page > ($this->adjacents * 2)){
  158. $this->pagination .= "<a href=\"".$this->get_pagenum_link(1)."\">1</a>";
  159. $this->pagination .= "<a href=\"".$this->get_pagenum_link(2)."\">2</a>";
  160. $this->pagination .= "...";
  161. for ($counter = $this->page - $this->adjacents; $counter <= $this->page + $this->adjacents; $counter++)
  162. if ($counter == $this->page)
  163. $this->pagination .= "<span class=\"current\">$counter</span>";
  164. else
  165. $this->pagination .= "<a href=\"".$this->get_pagenum_link($counter)."\">$counter</a>";
  166. $this->pagination .= "...";
  167. $this->pagination .= "<a href=\"".$this->get_pagenum_link($lpm1)."\">$lpm1</a>";
  168. $this->pagination .= "<a href=\"".$this->get_pagenum_link($lastpage)."\">$lastpage</a>";
  169. }
  170. //close to end; only hide early pages
  171. else{
  172. $this->pagination .= "<a href=\"".$this->get_pagenum_link(1)."\">1</a>";
  173. $this->pagination .= "<a href=\"".$this->get_pagenum_link(2)."\">2</a>";
  174. $this->pagination .= "...";
  175. for ($counter = $lastpage - (2 + ($this->adjacents * 2)); $counter <= $lastpage; $counter++)
  176. if ($counter == $this->page)
  177. $this->pagination .= "<span class=\"current\">$counter</span>";
  178. else
  179. $this->pagination .= "<a href=\"".$this->get_pagenum_link($counter)."\">$counter</a>";
  180. }
  181. }
  182. //siguiente button
  183. if ($this->page < $counter - 1)
  184. $this->pagination .= "<a href=\"".$this->get_pagenum_link($next)."\">$n</a>";
  185. else
  186. $this->pagination .= "<span class=\"disabled\">$n</span>";
  187. if($this->showCounter)$this->pagination .= "<div class=\"pagination_data\">($this->total_pages ".__("Pages","wassup").")</div>";
  188. }
  189. return true;
  190. }
  191. } //end class pagination
  192. } //end if !class_exists('pagination')
  193. if (!class_exists('Detector')) { //in case another app uses this class...
  194. //
  195. // Detector class (c) Mohammad Hafiz bin Ismail 2006
  196. // detect location by ipaddress
  197. // detect browser type and operating system
  198. //
  199. // November 27, 2006
  200. //
  201. // by : Mohammad Hafiz bin Ismail (info@mypapit.net)
  202. //
  203. // You are allowed to use this work under the terms of
  204. // Creative Commons Attribution-Share Alike 3.0 License
  205. //
  206. // Reference : http://creativecommons.org/licenses/by-sa/3.0/
  207. //
  208. class Detector {
  209. var $town;
  210. var $state;
  211. var $country;
  212. var $Ctimeformatode;
  213. var $longitude;
  214. var $latitude;
  215. var $ipaddress;
  216. var $txt;
  217. var $browser;
  218. var $browser_version;
  219. var $os_version;
  220. var $os;
  221. var $useragent;
  222. function Detector($ip="", $ua="")
  223. {
  224. $apiserver="http://showip.fakap.net/txt/";
  225. if ($ip != "") {
  226. if (preg_match('/\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/',$ip,$matches))
  227. {
  228. $this->ipaddress=$ip;
  229. }
  230. else { $this->ipaddress = "0.0.0.0"; }
  231. //uncomment this below if CURL doesnt work
  232. $this->txt=file_get_contents($apiserver . "$ip");
  233. $wtf=$this->txt;
  234. $this->processTxt($wtf);
  235. }
  236. $this->useragent=$ua;
  237. $this->check_os($ua);
  238. $this->check_browser($ua);
  239. }
  240. function processTxt($wtf)
  241. {
  242. // $tok = strtok($txt, ',');
  243. $this->town = strtok($wtf,',');
  244. $this->state = strtok(',');
  245. $this->country=strtok(',');
  246. $this->ccode = strtok(',');
  247. $this->latitude=strtok(',');
  248. $this->longitude=strtok(',');
  249. }
  250. function check_os($useragent) {
  251. $os = "N/A"; $version = "";
  252. if (preg_match("/Windows NT 5.1/",$useragent,$match)) {
  253. $os = "WinXP"; $version = "";
  254. } elseif (preg_match("/Windows NT 5.2/",$useragent,$match)) {
  255. $os = "Win2003"; $version = "";
  256. } elseif (preg_match("/Windows NT 6.0/",$useragent,$match)) {
  257. $os = "WinVista"; $version = "";
  258. } elseif (preg_match("/(?:Windows NT 5.0|Windows 2000)/",$useragent,$match)) {
  259. $os = "Win2000"; $version = "";
  260. } elseif (preg_match("/Windows ME/",$useragent,$match)) {
  261. $os = "WinME"; $version = "";
  262. } elseif (preg_match("/(?:WinNT|Windows\s?NT)\s?([0-9\.]+)?/",$useragent,$match)) {
  263. $os = "WinNT"; $version = $match[1];
  264. } elseif (preg_match("/Mac OS X/",$useragent,$match)) {
  265. $os = "MacOSX"; $version = "";
  266. } elseif (preg_match("/(Mac_PowerPC|Macintosh)/",$useragent,$match)) {
  267. $os = "MacPPC"; $version = "";
  268. } elseif (preg_match("/(?:Windows95|Windows 95|Win95|Win 95)/",$useragent,$match)) {
  269. $os = "Win95"; $version = "";
  270. } elseif (preg_match("/(?:Windows98|Windows 98|Win98|Win 98|Win 9x)/",$useragent,$match)) {
  271. $os = "Win98"; $version = "";
  272. } elseif (preg_match("/(?:WindowsCE|Windows CE|WinCE|Win CE)/",$useragent,$match)) {
  273. $os = "WinCE"; $version = "";
  274. } elseif (preg_match("/PalmOS/",$useragent,$match)) {
  275. $os = "PalmOS";
  276. } elseif (preg_match("/\(PDA(?:.*)\)(.*)Zaurus/",$useragent,$match)) {
  277. $os = "Sharp Zaurus";
  278. } elseif (preg_match("/Linux\s*((?:i[0-9]{3})?\s*(?:[0-9]\.[0-9]{1,2}\.[0-9]{1,2})?\s*(?:i[0-9]{3})?)?/",$useragent,$match)) {
  279. $os = "Linux"; $version = $match[1];
  280. } elseif (preg_match("/NetBSD\s*((?:i[0-9]{3})?\s*(?:[0-9]\.[0-9]{1,2}\.[0-9]{1,2})?\s*(?:i[0-9]{3})?)?/",$useragent,$match)) {
  281. $os = "NetBSD"; $version = $match[1];
  282. } elseif (preg_match("/OpenBSD\s*([0-9\.]+)?/",$useragent,$match)) {
  283. $os = "OpenBSD"; $version = $match[1];
  284. } elseif (preg_match("/CYGWIN\s*((?:i[0-9]{3})?\s*(?:[0-9]\.[0-9]{1,2}\.[0-9]{1,2})?\s*(?:i[0-9]{3})?)?/",$useragent,$match)) {
  285. $os = "CYGWIN"; $version = $match[1];
  286. } elseif (preg_match("/SunOS\s*([0-9\.]+)?/",$useragent,$match)) {
  287. $os = "SunOS"; $version = $match[1];
  288. } elseif (preg_match("/IRIX\s*([0-9\.]+)?/",$useragent,$match)) {
  289. $os = "SGI IRIX"; $version = $match[1];
  290. } elseif (preg_match("/FreeBSD\s*((?:i[0-9]{3})?\s*(?:[0-9]\.[0-9]{1,2})?\s*(?:i[0-9]{3})?)?/",$useragent,$match)) {
  291. $os = "FreeBSD"; $version = $match[1];
  292. } elseif (preg_match("/SymbianOS\/([0-9.]+)/i",$useragent,$match)) {
  293. $os = "SymbianOS"; $version = $match[1];
  294. } elseif (preg_match("/Symbian\/([0-9.]+)/i",$useragent,$match)) {
  295. $os = "Symbian"; $version = $match[1];
  296. } elseif (preg_match("/PLAYSTATION 3/",$useragent,$match)) {
  297. $os = "Playstation"; $version = 3;
  298. }
  299. $this->os = $os;
  300. $this->os_version = $version;
  301. }
  302. function check_browser($useragent) {
  303. $browser = "";
  304. if (preg_match("/^Mozilla(?:.*)compatible;\sMSIE\s(?:.*)Opera\s([0-9\.]+)/",$useragent,$match)) {
  305. $browser = "Opera";
  306. } elseif (preg_match("/^Opera\/([0-9\.]+)/",$useragent,$match)) {
  307. $browser = "Opera";
  308. } elseif (preg_match("/^Mozilla(?:.*)compatible;\siCab\s([0-9\.]+)/",$useragent,$match)) {
  309. $browser = "iCab";
  310. } elseif (preg_match("/^iCab\/([0-9\.]+)/",$useragent,$match)) {
  311. $browser = "iCab";
  312. } elseif (preg_match("/^Mozilla(?:.*)compatible;\sMSIE\s([0-9\.]+)/",$useragent,$match)) {
  313. $browser = "IE";
  314. } elseif (preg_match("/^(?:.*)compatible;\sMSIE\s([0-9\.]+)/",$useragent,$match)) {
  315. $browser = "IE";
  316. } elseif (preg_match("/^Mozilla(?:.*)(?:.*)Chrome/",$useragent,$match)) {
  317. $browser = "Google Chrome";
  318. } elseif (preg_match("/^Mozilla(?:.*)(?:.*)Safari\/([0-9\.]+)/",$useragent,$match)) {
  319. $browser = "Safari";
  320. } elseif (preg_match("/^Mozilla(?:.*)\(Macintosh(?:.*)OmniWeb\/v([0-9\.]+)/",$useragent,$match)) {
  321. $browser = "Omniweb";
  322. } elseif (preg_match("/^Mozilla(?:.*)\(compatible; Google Desktop/",$useragent,$match)) {
  323. $browser = "Google Desktop";
  324. } elseif (preg_match("/^Mozilla(?:.*)\(compatible;\sOmniWeb\/([0-9\.v-]+)/",$useragent,$match)) {
  325. $browser = "Omniweb";
  326. } elseif (preg_match("/^Mozilla(?:.*)Gecko(?:.*?)(?:Camino|Chimera)\/([0-9\.]+)/",$useragent,$match)) {
  327. $browser = "Camino";
  328. } elseif (preg_match("/^Mozilla(?:.*)Gecko(?:.*?)Netscape\/([0-9\.]+)/",$useragent,$match)) {
  329. $browser = "Netscape";
  330. } elseif (preg_match("/^Mozilla(?:.*)Gecko(?:.*?)(?:Fire(?:fox|bird)|Phoenix)\/([0-9\.]+)/",$useragent,$match)) {
  331. $browser = "Firefox";
  332. } elseif (preg_match("/^Mozilla(?:.*)Gecko(?:.*?)Minefield\/([0-9\.]+)/",$useragent,$match)) {
  333. $browser = "Minefield";
  334. } elseif (preg_match("/^Mozilla(?:.*)Gecko(?:.*?)Epiphany\/([0-9\.]+)/",$useragent,$match)) {
  335. $browser = "Epiphany";
  336. } elseif (preg_match("/^Mozilla(?:.*)Galeon\/([0-9\.]+)\s(?:.*)Gecko/",$useragent,$match)) {
  337. $browser = "Galeon";
  338. } elseif (preg_match("/^Mozilla(?:.*)Gecko(?:.*?)K-Meleon\/([0-9\.]+)/",$useragent,$match)) {
  339. $browser = "K-Meleon";
  340. } elseif (preg_match("/^Mozilla(?:.*)rv:([0-9\.]+)\)\sGecko/",$useragent,$match)) {
  341. $browser = "Mozilla";
  342. } elseif (preg_match("/^Mozilla(?:.*)compatible;\sKonqueror\/([0-9\.]+);/",$useragent,$match)) {
  343. $browser = "Konqueror";
  344. } elseif (preg_match("/^Mozilla\/(?:[34]\.[0-9]+)(?:.*)AvantGo\s([0-9\.]+)/",$useragent,$match)) {
  345. $browser = "AvantGo";
  346. } elseif (preg_match("/^Mozilla(?:.*)NetFront\/([34]\.[0-9]+)/",$useragent,$match)) {
  347. $browser = "NetFront";
  348. } elseif (preg_match("/^Mozilla\/([34]\.[0-9]+)/",$useragent,$match)) {
  349. $browser = "Netscape";
  350. } elseif (preg_match("/^Liferea\/([0-9\.]+)/",$useragent,$match)) {
  351. $browser = "Liferea";
  352. } elseif (preg_match("/^curl\/([0-9\.]+)/",$useragent,$match)) {
  353. $browser = "curl";
  354. } elseif (preg_match("/^links\/([0-9\.]+)/i",$useragent,$match)) {
  355. $browser = "Links";
  356. } elseif (preg_match("/^links\s?\(([0-9\.]+)/i",$useragent,$match)) {
  357. $browser = "Links";
  358. } elseif (preg_match("/^lynx\/([0-9a-z\.]+)/i",$useragent,$match)) {
  359. $browser = "Lynx";
  360. } elseif (preg_match("/^Wget\/([0-9\.]+)/i",$useragent,$match)) {
  361. $browser = "Wget";
  362. } elseif (preg_match("/^Xiino\/([0-9\.]+)/i",$useragent,$match)) {
  363. $browser = "Xiino";
  364. } elseif (preg_match("/^W3C_Validator\/([0-9\.]+)/i",$useragent,$match)) {
  365. $browser = "W3C Validator";
  366. } elseif (preg_match("/^Jigsaw(?:.*) W3C_CSS_Validator_(?:[A-Z]+)\/([0-9\.]+)/i",$useragent,$match)) {
  367. $browser = "W3C CSS Validator";
  368. } elseif (preg_match("/^Dillo\/([0-9\.]+)/i",$useragent,$match)) {
  369. $browser = "Dillo";
  370. } elseif (preg_match("/^amaya\/([0-9\.]+)/i",$useragent,$match)) {
  371. $browser = "Amaya";
  372. } elseif (preg_match("/^DocZilla\/([0-9\.]+)/i",$useragent,$match)) {
  373. $browser = "DocZilla";
  374. } elseif (preg_match("/^fetch\slibfetch\/([0-9\.]+)/i",$useragent,$match)) {
  375. $browser = "FreeBSD libfetch";
  376. } elseif (preg_match("/^Nokia([0-9a-zA-Z\-.]+)\/([0-9\.]+)/i",$useragent,$match)) {
  377. $browser="Nokia";
  378. } elseif (preg_match("/^SonyEricsson([0-9a-zA-Z\-.]+)\/([a-zA-Z0-9\.]+)/i",$useragent,$match)) {
  379. $browser="SonyEricsson";
  380. }
  381. //$version = $match[1];
  382. //restrict version to major and minor version #'s
  383. preg_match("/^\d+(\.\d+)?/",$match[1],$majorvers);
  384. $version = $majorvers[0];
  385. $this->browser = $browser;
  386. $this->browser_version = $version;
  387. }
  388. } //end class Detector
  389. } //end if !class_exists('Detector')
  390. function wassup_get_time() {
  391. $timeright = gmdate("U");
  392. $offset = (get_option("gmt_offset")*60*60);
  393. $timeright = ($timeright + $offset) ;
  394. return $timeright;
  395. }
  396. /*
  397. # PHP Calendar (version 2.3), written by Keith Devens
  398. # http://keithdevens.com/software/php_calendar
  399. # see example at http://keithdevens.com/weblog
  400. # License: http://keithdevens.com/software/license
  401. */
  402. //
  403. // Currently not used in WassUp it's a next implementation idea
  404. //
  405. function generate_calendar($year, $month, $days = array(), $day_name_length = 3, $month_href = NULL, $first_day = 0, $pn = array()){
  406. $first_of_month = gmmktime(0,0,0,$month,1,$year);
  407. #remember that mktime will automatically correct if invalid dates are entered
  408. # for instance, mktime(0,0,0,12,32,1997) will be the date for Jan 1, 1998
  409. # this provides a built in "rounding" feature to generate_calendar()
  410. $day_names = array(); #generate all the day names according to the current locale
  411. for($n=0,$t=(3+$first_day)*86400; $n<7; $n++,$t+=86400) #January 4, 1970 was a Sunday
  412. $day_names[$n] = ucfirst(gmstrftime('%A',$t)); #%A means full textual day name
  413. list($month, $year, $month_name, $weekday) = explode(',',gmstrftime('%m,%Y,%B,%w',$first_of_month));
  414. $weekday = ($weekday + 7 - $first_day) % 7; #adjust for $first_day
  415. $title = htmlentities(ucfirst($month_name)).'&nbsp;'.$year; #note that some locales don't capitalize month and day names
  416. #Begin calendar. Uses a real <caption>. See http://diveintomark.org/archives/2002/07/03
  417. @list($p, $pl) = each($pn); @list($n, $nl) = each($pn); #previous and next links, if applicable
  418. if($p) $p = '<span class="calendar-prev">'.($pl ? '<a href="'.htmlspecialchars($pl).'">'.$p.'</a>' : $p).'</span>&nbsp;';
  419. if($n) $n = '&nbsp;<span class="calendar-next">'.($nl ? '<a href="'.htmlspecialchars($nl).'">'.$n.'</a>' : $n).'</span>';
  420. $calendar = '<table class="calendar">'."\n".
  421. '<caption class="calendar-month">'.$p.($month_href ? '<a href="'.htmlspecialchars($month_href).'">'.$title.'</a>' : $title).$n."</caption>\n<tr>";
  422. if($day_name_length){ #if the day names should be shown ($day_name_length > 0)
  423. #if day_name_length is >3, the full name of the day will be printed
  424. foreach($day_names as $d)
  425. $calendar .= '<th abbr="'.htmlentities($d).'">'.htmlentities($day_name_length < 4 ? substr($d,0,$day_name_length) : $d).'</th>';
  426. $calendar .= "</tr>\n<tr>";
  427. }
  428. if($weekday > 0) $calendar .= '<td colspan="'.$weekday.'">&nbsp;</td>'; #initial 'empty' days
  429. for($day=1,$days_in_month=gmdate('t',$first_of_month); $day<=$days_in_month; $day++,$weekday++){
  430. if($weekday == 7){
  431. $weekday = 0; #start a new week
  432. $calendar .= "</tr>\n<tr>";
  433. }
  434. if(isset($days[$day]) and is_array($days[$day])){
  435. @list($link, $classes, $content) = $days[$day];
  436. if(is_null($content)) $content = $day;
  437. $calendar .= '<td'.($classes ? ' class="'.htmlspecialchars($classes).'">' : '>').
  438. ($link ? '<a href="'.htmlspecialchars($link).'">'.$content.'</a>' : $content).'</td>';
  439. }
  440. else $calendar .= "<td>$day</td>";
  441. }
  442. if($weekday != 7) $calendar .= '<td colspan="'.(7-$weekday).'">&nbsp;</td>'; #remaining "empty" days
  443. return $calendar."</tr>\n</table>\n";
  444. }
  445. //Truncate $input string to a length of $max
  446. function stringShortener($input, $max=0, $separator="(...)", $exceedFromEnd=0){
  447. if(!$input || !is_string($input)){return false;};
  448. //Replace all %-hex chars with literals and trim the input string
  449. // of whitespaces ...because it's shorter and more legible.
  450. // -Helene D. 11/18/07
  451. $instring = trim(stripslashes(rawurldecode(html_entity_decode($input)))," +\t"); //insecure
  452. $inputlen=strlen($instring);
  453. $max=(is_numeric($max))?(integer)$max:$inputlen;
  454. //if($max>=$inputlen){return $input;}; //caused security loophole ...only $outstring should be returned
  455. if ($max < $inputlen) {
  456. $separator=($separator)?$separator:"(...)";
  457. $modulus=(($max%2));
  458. $halfMax=floor($max/2);
  459. $begin="";
  460. if(!$modulus){$begin=substr($instring, 0, $halfMax);}
  461. else{$begin=(!$exceedFromEnd)? substr($instring, 0, $halfMax+1) : substr($instring, 0, $halfMax);}
  462. $end="";
  463. if(!$modulus){$end=substr($instring,$inputlen-$halfMax);}
  464. else{$end=($exceedFromEnd)? substr($instring,$inputlen-$halfMax-1) :substr($instring,$inputlen-$halfMax);}
  465. $extracted=substr($instring, strpos($instring,$begin)+strlen($begin), $inputlen-$max );
  466. $outstring = $begin.$separator.$end;
  467. if (strlen($outstring) >= $inputlen) { //Because "Fir(...)fox" is longer than "Firefox"
  468. $outstring = $instring;
  469. }
  470. //# use WordPress 2.x function attribute_escape and 1.2.x
  471. // function wp_specialchars to make malicious code
  472. // harmless when echoed to the screen
  473. $outstring=attribute_escape(wp_specialchars($outstring,ENT_QUOTES));
  474. } else {
  475. $outstring = attribute_escape(wp_specialchars($instring,ENT_QUOTES));
  476. }
  477. return $outstring;
  478. } //end function stringShortener
  479. //# Return a value of true if url argument is a root url and false when
  480. //# url constains a subdirectory path or query parameters...
  481. //# - Helene D. 2007
  482. function url_rootcheck($urltocheck) {
  483. $isroot = false;
  484. //url must begin with 'http://'
  485. if (strncasecmp($urltocheck,'http://',7) == 0) {
  486. $isroot = true;
  487. $urlparts=parse_url($urltocheck);
  488. if (!empty($urlparts['path']) && $urlparts['path'] != "/") {
  489. $isroot=false;
  490. } elseif (!empty($urlparts['query'])) {
  491. $isroot=false;
  492. }
  493. }
  494. return $isroot;
  495. }
  496. //#from a page/post url input, output a url with "$blogurl" prepended for
  497. //# blogs that have wordpress installed in a separate folder
  498. //# -Helene D. 1/22/08
  499. function wAddSiteurl($inputurl) {
  500. $wpurl = rtrim(get_bloginfo('wpurl'),"/");
  501. $blogurl = rtrim(get_bloginfo('home'),"/");
  502. if (strcasecmp($blogurl, $wpurl) == 0) {
  503. $outputurl=$inputurl;
  504. } elseif (stristr($inputurl,$blogurl) === FALSE && url_rootcheck($blogurl)) {
  505. $outputurl=$blogurl."/".ltrim($inputurl,"/");
  506. } else {
  507. $outputurl=$inputurl;
  508. }
  509. $outputurl = rawurldecode(html_entity_decode($outputurl)); //dangerous
  510. $outputurl = wCleanURL($outputurl); //safe
  511. return $outputurl;
  512. }
  513. //sanitize url of potentially dangerous code before display
  514. function wCleanURL($url="") {
  515. if (empty($url)) {
  516. return;
  517. }
  518. //$urlstring = stripslashes($url);
  519. if (function_exists('esc_url')) { //#WP 2.8+
  520. $cleaned_url = esc_url(stripslashes($url));
  521. } else {
  522. $cleaned_url = clean_url(stripslashes($url));
  523. }
  524. if (empty($cleaned_url)) { //oops, clean_url chomp
  525. $cleaned_url = attribute_escape(stripslashes($url));
  526. }
  527. return $cleaned_url;
  528. } //end function
  529. //Output wassup records in Digg spy style...
  530. function spyview ($from_date="",$to_date="",$rows="999",$spytype="",$spy_datasource="") {
  531. global $wpdb, $wp_version, $debug_mode;
  532. $whereis="";
  533. if ($spytype == 'spider') {
  534. $whereis = " AND spider!=''";
  535. } elseif ($spytype == 'nospider') {
  536. $whereis = " AND spider=''";
  537. } elseif ($spytype == 'spam') {
  538. $whereis = " AND spam>0";
  539. } elseif ($spytype == 'nospam') {
  540. $whereis = " AND spam=0";
  541. } elseif ($spytype == 'nospamspider') {
  542. $whereis = " AND spam=0 AND spider=''";
  543. } elseif ($spytype == 'searchengine') {
  544. $whereis = " AND searchengine!='' AND search!=''";
  545. } elseif ($spytype == 'referrer') {
  546. $whereis = " AND referrer!='' AND referrer NOT LIKE '%$wpurl%' AND searchengine='' AND search=''";
  547. } elseif ($spytype == 'comauthor') {
  548. $whereis = " AND comment_author!=''";
  549. } elseif ($spytype == 'loggedin') {
  550. $whereis = " AND username!=''";
  551. }
  552. //check for arguments...
  553. if(empty($to_date)) $to_date = wassup_get_time();
  554. if (empty($from_date)) $from_date = ($to_date - 5);
  555. if (empty($spy_datasource)) {
  556. //temp table is default data source unless not exists
  557. $spy_datasource = $wpdb->prefix . "wassup_tmp";
  558. if ($wpdb->get_var("SHOW TABLES LIKE '$spy_datasource'") != $spy_datasource) {
  559. $spy_datasource = $wpdb->prefix . "wassup";
  560. }
  561. }
  562. if (function_exists('get_option')) {
  563. $wassup_settings = get_option('wassup_settings');
  564. }
  565. if (!empty($wassup_settings['wassup_screen_res'])) {
  566. $screen_res_size = (int) $wassup_settings['wassup_screen_res'];
  567. } else {
  568. $screen_res_size = 670;
  569. }
  570. $max_char_len = ($screen_res_size)/10;
  571. //set smaller screen_res_size to make room for sidebar in WP2.7+
  572. if (version_compare($wp_version, '2.7', '>=')) {
  573. $screen_res_size = $screen_res_size-160;
  574. $max_char_len = $max_char_len-16;
  575. }
  576. $wpurl = get_bloginfo('wpurl');
  577. $blogurl = get_bloginfo('home');
  578. $unclass = "sum-box";
  579. $qryC = $wpdb->get_results("SELECT id, wassup_id, `timestamp`, ip, hostname, searchengine, urlrequested, agent, referrer, spider, username, comment_author FROM $spy_datasource WHERE `timestamp` BETWEEN $from_date AND $to_date $whereis ORDER BY `timestamp` DESC");
  580. if (!empty($qryC)) {
  581. //restrict # of rows to display when needed...
  582. $row_count = 0;
  583. //display the rows...
  584. foreach ($qryC as $cv) {
  585. $unclass = "sum-box";
  586. if ( $row_count < (int)$rows ) {
  587. $timestamp = $cv->timestamp;
  588. $ip = @explode(",", $cv->ip);
  589. if ($cv->referrer != '') {
  590. if ($cv->searchengine != "" || stristr($cv->referrer,$wpurl)!=$cv->referrer) {
  591. if ($cv->searchengine == "") {
  592. $referrer = '<a href="'.wCleanURL($cv->referrer).'" target=_"BLANK"><span style="font-weight: bold;">'.stringShortener("{$cv->referrer}", round($max_char_len*.8,0)).'</span></a>';
  593. } else {
  594. $referrer = '<a href="'.wCleanURL($cv->referrer).'" target=_"BLANK">'.stringShortener("{$cv->referrer}", round($max_char_len*.9,0)).'</a>';
  595. }
  596. } else {
  597. $referrer = __('From your blog','wassup');
  598. }
  599. } else {
  600. $referrer = __('Direct hit','wassup');
  601. }
  602. // User is logged in or is a comment's author
  603. if ($cv->username != "") {
  604. $unclass .= "-log";
  605. $map_icon = "marker_loggedin.png";
  606. } elseif ($cv->comment_author != "") {
  607. $unclass .= "-aut";
  608. $map_icon = "marker_author.png";
  609. } elseif ($cv->spider != "") {
  610. $unclass .= "-spider";
  611. $map_icon = "marker_bot.png";
  612. } else {
  613. $map_icon = "marker_user.png";
  614. }
  615. // Start getting GEOIP info
  616. $location="";
  617. $lat = 0;
  618. $lon = 0;
  619. if (function_exists('curl_init')) {
  620. //TODO: save geo data in 'wassup_tmp_geoloc' table
  621. // so multi-page visits from save ip don't do
  622. // redundant curl lookups
  623. $geo_url = "http://api.hostip.info/get_html.php?ip=".$ip[0]."&position=true";
  624. $ci = curl_init();
  625. curl_setopt($ci, CURLOPT_URL, $geo_url);
  626. curl_setopt($ci, CURLOPT_HEADER,0);
  627. curl_setopt($ci, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  628. @curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 0);
  629. curl_setopt($ci, CURLOPT_RETURNTRANSFER, 1);
  630. $data = curl_exec($ci);
  631. curl_close($ci);
  632. $data = explode("\n",$data);
  633. $loc_country = "";
  634. $loc_city = "";
  635. if (stristr("unknown", $data[0]) === FALSE) {
  636. $loc_country = preg_replace('/country: /i', "", $data[0]);
  637. }
  638. if (!empty($data[1]) && stristr("unknown", $data[1]) === FALSE) {
  639. $loc_city = preg_replace('/city: /i', '', $data[1]);
  640. }
  641. $geoloc = trim($loc_country." ".$loc_city);
  642. if ($debug_mode) {
  643. echo "<!--\n Curl data: \n"; //debug
  644. echo var_dump($data); //debug
  645. echo "\n geoloc=$geoloc \n"; //debug
  646. echo "-->\n"; //debug
  647. }
  648. if ($wassup_settings['wassup_geoip_map'] == 1) {
  649. $gkey = $wassup_settings['wassup_googlemaps_key'];
  650. if ($geoloc != "") {
  651. $geocode = geocodeWassUp($geoloc, $gkey);
  652. if($geocode[0] != 200) {
  653. $lat = explode(":", $data[2]);
  654. $lat = $lat[1];
  655. $lon = explode(":", $data[3]);
  656. $lon = $lon[1];
  657. } else {
  658. $lat = $geocode[2];
  659. $lon = $geocode[3];
  660. }
  661. }
  662. }
  663. $location = $data[0];
  664. if (!empty($data[1])) {
  665. $location .= " - ".$data[1];
  666. }
  667. echo "<!-- heartbeat -->\n";
  668. } //end if curl_init
  669. // Print the JS code to add marker on the map
  670. if ($wassup_settings['wassup_geoip_map'] == 1) {
  671. if ($lat!=0 && $lon!=0) {
  672. $item_id = $cv->id;
  673. $img_dir = WASSUPURL.'/img';
  674. echo "
  675. <script type=\"text/javascript\">
  676. var icon$item_id = new GIcon();
  677. icon$item_id.image = '".$img_dir."/".$map_icon."';
  678. icon$item_id.shadow = '$img_dir/shadow.png';
  679. icon$item_id.iconSize = new GSize(20.0, 34.0);
  680. icon$item_id.shadowSize = new GSize(38.0, 34.0);
  681. icon$item_id.iconAnchor = new GPoint(10.0, 17.0);
  682. icon$item_id.infoWindowAnchor = new GPoint(10.0, 17.0);
  683. var point = new GLatLng($lat,$lon);
  684. var marker$item_id = new GMarker(point, icon$item_id);
  685. map.addOverlay(marker$item_id);
  686. GEvent.addListener(marker$item_id, 'click', function() {
  687. marker$item_id.openInfoWindowHtml('<div style=\"white-space:nowrap\"><div class=\"bubble\">Ip: ".
  688. $ip[0]
  689. ."<br />Hour: ".
  690. gmdate('H:i:s', $timestamp)
  691. ."<br />Request: <a href=".
  692. wAddSiteurl($cv->urlrequested)
  693. ." target=\"_BLANK\">".
  694. stringShortener($cv->urlrequested, round($max_char_len*.9,0))
  695. ."</a><br />".
  696. "</div></div>');
  697. });
  698. map.panTo(new GLatLng($lat,$lon),3);
  699. </script>";
  700. } //end if $lat!=0
  701. } // end if wassup_geoip_map
  702. ?>
  703. <div class="sum-spy">
  704. <span class="<?php print $unclass; ?>">
  705. <?php print $ip[0]; ?></span>
  706. <div class="sum-det-spy"><span class="det1">
  707. <?php
  708. print '<a href="'.wAddSiteurl("{$cv->urlrequested}").'" target="_BLANK">';
  709. print stringShortener("{$cv->urlrequested}", round($max_char_len*.9,0)); ?>
  710. </a></span><br />
  711. <span class="det2"><strong><?php print gmdate("H:i:s", $timestamp); ?> - </strong>
  712. <?php
  713. print $referrer;
  714. if (!empty($location)) {
  715. print "<br />".$location;
  716. } ?>
  717. </span>
  718. </div>
  719. </div>
  720. <?php
  721. } //end if row_count
  722. $row_count=$row_count+1;
  723. } //end foreach
  724. } else {
  725. //display "no activity" periodically so we know spy is running...
  726. if ((int)$to_date%59 == 0 ) {
  727. echo '<div class="sum-spy"><span class="det3">'.gmdate("H:i:s",$to_date).' - '.__("No visitor activity","wassup").' &nbsp; &nbsp; :-( &nbsp; </span></div>';
  728. }
  729. } //end if !empty($qryC)
  730. } //end function spyview
  731. // Geocoding location with Google Maps
  732. function geocodeWassUp($location, $key) {
  733. //Three parts to the querystring: q is address, output is the format (
  734. $address = urlencode($location);
  735. $url = "http://maps.google.com/maps/geo?q=".$address."&output=csv&key=".$key;
  736. $ch = curl_init();
  737. curl_setopt($ch, CURLOPT_URL, $url);
  738. curl_setopt($ch, CURLOPT_HEADER,0);
  739. curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  740. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
  741. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  742. $data = curl_exec($ch);
  743. curl_close($ch);
  744. $data = explode(",",$data);
  745. if ($data[0] == 200) {
  746. return $data;
  747. } else {
  748. $error = $data[0];
  749. return $error;
  750. }
  751. }
  752. /* wGetStats- Return an associative array containing the top statistics
  753. * numbers of "stat_type" from wassup table. Associative array fields are
  754. * 'top_count', 'top_item', and optionally, 'top_link', when data is url.
  755. * Results are sorted in descending count order and known spam is
  756. * automatically excluded when spam check is enabled in 'Wassup Options'.
  757. * Input parameters are 'stat_type'=[name of any column in wassup table],
  758. * and 2 optional parameters:
  759. * stat_limit=N-- limits results to the top N values. Default=10.
  760. * stat_condition='mysql where clause'-- usually a date range clause on
  761. * `timestamp`. Defaults to 24 hours.
  762. * Used by action.php TopTen and wassup_widget to retrieve statistics data.
  763. * - Helene D. 2009-03-04
  764. */
  765. function wGetStats($stat_type, $stat_limit=10, $stat_condition="") {
  766. global $wpdb, $debug_mode;
  767. $wassup_settings = get_option('wassup_settings');
  768. $top_ten = unserialize(html_entity_decode($wassup_settings['wassup_top10']));
  769. $wpurl = get_bloginfo('wpurl');
  770. $blogurl = get_bloginfo('home');
  771. $table_name = (!empty($wassup_settings['wassup_table']))? $wassup_settings['wassup_table'] : $wpdb->prefix . "wassup";
  772. $table_tmp_name = $table_name . "_tmp";
  773. if (empty($stat_limit) || !(is_numeric($stat_limit))) {
  774. $stat_limit=10;
  775. }
  776. if (empty($stat_condition)) {
  777. $to_date = wassup_get_time();
  778. $from_date = ((int)$to_date - 24*(60*60)); //24 hours
  779. $stat_condition = " `timestamp` >= $from_date ";
  780. }
  781. //exclude spam if it is being recorded
  782. if ($wassup_settings['wassup_spamcheck'] == 1) {
  783. $spam_condition = " AND spam=0";
  784. } else {
  785. $spam_condition = "";
  786. }
  787. $stat_condition .= $spam_condition;
  788. //get the stats data
  789. //top search phrases...
  790. if ($stat_type == "searches") {
  791. $stat_results = $wpdb->get_results("SELECT count(search) AS top_count, search AS top_item, referrer AS top_link FROM $table_name WHERE $stat_condition AND search!='' AND spider='' GROUP BY search ORDER BY top_count DESC LIMIT $stat_limit");
  792. //top external referrers...
  793. } elseif ($stat_type == "referrers") {
  794. //exclude internal referrals
  795. $url = parse_url($blogurl);
  796. $sitedomain = $url['host'];
  797. $exclude_list = $sitedomain;
  798. if ($wpurl != $blogurl) {
  799. $url = parse_url($wpurl);
  800. $wpdomain = $url['host'];
  801. $exclude_list .= ",".$wpdomain;
  802. }
  803. //exclude external referrers
  804. if (!empty($top_ten['topreferrer_exclude'])) {
  805. $exclude_list .= ",".$top_ten['topreferrer_exclude'];
  806. }
  807. //create mysql conditional statement to exclude referrers
  808. $exclude_referrers = "";
  809. $exclude_array = array_unique(explode(",", $exclude_list));
  810. foreach ($exclude_array as $exclude_domain) {
  811. $exclude_domain = trim($exclude_domain);
  812. if ($exclude_domain != "" ) {
  813. $exclude_referrers .= " AND referrer NOT LIKE 'http://".$exclude_domain."%' AND referrer NOT LIKE 'http://www.".$exclude_domain."%'";
  814. }
  815. }
  816. $stat_results = $wpdb->get_results("SELECT count(*) AS top_count, LOWER(referrer) AS top_item, referrer AS top_link FROM $table_name WHERE $stat_condition AND referrer!='' AND search='' AND spider='' $exclude_referrers GROUP BY top_item ORDER BY top_count DESC LIMIT $stat_limit");
  817. //top url requests...
  818. } elseif ($stat_type == "urlrequested") {
  819. $stat_results = $wpdb->get_results("SELECT count(*) AS top_count, LOWER(REPLACE(urlrequested, '/', '')) AS top_group, LOWER(urlrequested) AS top_item, urlrequested AS top_link FROM $table_name WHERE $stat_condition GROUP BY top_group ORDER BY top_count DESC LIMIT $stat_limit");
  820. //top browser...
  821. } elseif ($stat_type == "browser") {
  822. $stat_results = $wpdb->get_results("SELECT count(*) AS top_count, SUBSTRING_INDEX(SUBSTRING_INDEX(browser, ' 0.', 1), '.', 1) AS top_item FROM $table_name WHERE $stat_condition AND `browser`!='' AND `browser` NOT LIKE 'N/A%' AND `spider`='' GROUP BY top_item ORDER BY top_count DESC LIMIT $stat_limit");
  823. //top os...
  824. } elseif ($stat_type == "os") {
  825. $stat_results = $wpdb->get_results("SELECT count(os) as top_count, `os` AS top_item FROM $table_name WHERE $stat_condition AND `os`!='' AND `os` NOT LIKE 'N/A%' AND spider='' GROUP BY top_item ORDER BY top_count DESC LIMIT $stat_limit");
  826. //top language/locale..
  827. } elseif ($stat_type == "language" || $stat_type == "locale") {
  828. $stat_results = $wpdb->get_results("SELECT count(LOWER(language)) as top_count, LOWER(language) as top_item FROM $table_name WHERE $stat_condition AND language!='' AND spider='' GROUP BY top_item ORDER BY top_count DESC LIMIT $stat_limit");
  829. } else {
  830. //TODO: check that wp_wassup.$stat_type column exist and is char
  831. if (!empty($stat_type)) {
  832. $stat_results = $wpdb->get_results("SELECT count($stat_type) AS top_count, `$stat_type` AS top_item FROM $table_name WHERE $stat_condition AND `$stat_type`!='' AND `$stat_type` NOT LIKE 'N/A%' GROUP BY `$stat_type` ORDER BY top_count DESC LIMIT $stat_limit");
  833. }
  834. }
  835. if (!empty($stat_results[0]->top_count)) {
  836. return $stat_results;
  837. } else {
  838. return array();
  839. }
  840. } //end function wGetStats
  841. function backup_wassup($savefile="") { //untested
  842. global $wpdb, $wassup_options;
  843. //# save to server file, $savefile - alternate method to export wassup table.
  844. //# Useful when browser keeps timing out during export. -Helene D. 2009-03-16
  845. if (!empty($savefile)) {
  846. $savedir = dirname($savefile);
  847. } else {
  848. $savefile="wassup_backup.php";
  849. $savedir = "";
  850. }
  851. //use web root or home directory for backup, if full path not specified
  852. if ($savedir == "" || preg_match('#^/#',$savefile)==0) {
  853. if (!empty($_ENV['DOCUMENT_ROOT'])) {
  854. $savedir = $_ENV['DOCUMENT_ROOT'];
  855. $savefile = rtrim($_ENV['DOCUMENT_ROOT'],'/').'/'.$savefile;
  856. } elseif (!empty($_ENV['HOME'])) {
  857. $savedir = $_ENV['HOME'];
  858. $savefile = rtrim($_ENV['HOME'],'/').'/'.$savefile;
  859. }
  860. }
  861. if (!$wassup_options->isWritableFolder($savedir)) {
  862. //unable to save to file
  863. $wassup_options->wassup_alert_message = "ERROR: Unable to Save file to $savedir";
  864. $wassup_option->saveOptions();
  865. return false;
  866. } else {
  867. $records = $wpdb->get_results("SELECT * FROM $table_name");
  868. $wassup_rec = array_map('stripslashes',$records);
  869. $fb = @fopen($savefile,'w');
  870. if (!$fb) {
  871. $wassup_options->wassup_alert_message = "ERROR: Unable to backup to file, $savefile";
  872. $wassup_option->saveOptions();
  873. return false;
  874. } else {
  875. $bytes=0;
  876. foreach ($records as $record) {
  877. $wassup_data=sprintf("INSERT INTO `wp_wassup` (`wassup_id`, `timestamp`, `ip`, `hostname`, `urlrequested`, `agent`, `referrer`, `search`, `searchpage`, `os`, `browser`, `language`, `screen_res`, `searchengine`, `spider`, `feed`, `username`, `comment_author`, `spam`) VALUES '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'\n", mysql_real_escape_string($record->wassup_id),
  878. mysql_real_escape_string($record->timestamp),
  879. mysql_real_escape_string($record->ip),
  880. mysql_real_escape_string($record->hostname),
  881. mysql_real_escape_string($record->urlrequested),
  882. mysql_real_escape_string($record->agent),
  883. mysql_real_escape_string($record->referrer),
  884. mysql_real_escape_string($record->search),
  885. mysql_real_escape_string($record->searchpage),
  886. mysql_real_escape_string($record->os),
  887. mysql_real_escape_string($record->browser),
  888. mysql_real_escape_string($record->language),
  889. mysql_real_escape_string($record->screen_res),
  890. mysql_real_escape_string($record->searchengine),
  891. mysql_real_escape_string($record->spider),
  892. mysql_real_escape_string($record->feed),
  893. mysql_real_escape_string($record->username),
  894. mysql_real_escape_string($record->comment_author),
  895. mysql_real_escape_string($record->spam));
  896. $bytes += fwrite($fb, $wassup_data);
  897. } //end foreach
  898. fclose($fb);
  899. $wassup_options->wassup_alert_message = "$bytes Wassup data bytes saved file to $savefile";
  900. $wassup_option->saveOptions();
  901. return $bytes;
  902. } //end else fb
  903. } //end else wassup_options
  904. } //end function
  905. // How many digits have an integer
  906. function digit_count($n, $base=10) {
  907. if($n == 0) return 1;
  908. if($base == 10) {
  909. # using the built-in log10(x)
  910. # might be more accurate than log(x)/log(10).
  911. return 1 + floor(log10(abs($n)));
  912. }else{
  913. # here logB(x) = log(x)/log(B) will have to do.
  914. return 1 + floor(log(abs($n))/ log($base));
  915. }
  916. }
  917. //Round the integer to the next near 10
  918. function roundup($value) {
  919. $dg = digit_count($value);
  920. if ($dg <= 2) {
  921. $dg = 1;
  922. } else {
  923. $dg = ($dg-2);
  924. }
  925. return (ceil(intval($value)/pow(10, $dg))*pow(10, $dg)+pow(10, $dg));
  926. }
  927. function chart_data($Wvisits, $pages=null, $atime=null, $type, $charttype=null, $axes=null, $chart_type=null) {
  928. global $debug_mode;
  929. $chartAPIdata = false;
  930. // Port of JavaScript from http://code.google.com/apis/chart/
  931. // http://james.cridland.net/code
  932. // First, find the maximum value from the values given
  933. if ($axes == 1) {
  934. $maxValue = roundup(max(array_merge($Wvisits, $pages)));
  935. //$maxValue = roundup(max($Wvisits));
  936. $halfValue = ($maxValue/2);
  937. $maxPage = $maxValue;
  938. } else {
  939. $maxValue = roundup(max($Wvisits));
  940. $halfValue = ($maxValue/2);
  941. $maxPage = roundup(max($pages));
  942. $halfPage = ($maxPage/2);
  943. }
  944. // A list of encoding characters to help later, as per Google's example
  945. $simpleEncoding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  946. $chartData = "s:";
  947. // Chart type has two datasets
  948. if ($charttype == "main") {
  949. $label_time = "";
  950. for ($i = 0; $i < count($Wvisits); $i++) {
  951. $currentValue = $Wvisits[$i];
  952. $currentTime = $atime[$i];
  953. if ($chart_type == "dashboard") {
  954. $label_time="|";
  955. } else {
  956. $label_time.=str_replace(' ', '+', $currentTime)."|";
  957. }
  958. if ($currentValue > -1) {
  959. $chartData.=substr($simpleEncoding,61*($currentValue/$maxValue),1);
  960. } else {
  961. $chartData.='_';
  962. }
  963. }
  964. // Add pageviews line to the chart
  965. if (count($pages) != 0) {
  966. $chartData.=",";
  967. for ($i = 0; $i < count($pages); $i++) {
  968. $currentPage = $pages[$i];
  969. $currentTime = $atime[$i];
  970. if ($currentPage > -1) {
  971. $chartData.=substr($simpleEncoding,61*($currentPage/$maxPage),1);
  972. } else {
  973. $chartData.='_';
  974. }
  975. }
  976. }
  977. // Return the chart data - and let the Y axis to show the maximum value
  978. if ($axes == 1) {
  979. $chartAPIdata=$chartData."&chxt=x,y&chxl=0:|".$label_time."1:|0|".$halfValue."|".$maxValue."&chxs=0,6b6b6b,9";
  980. } else {
  981. $chartAPIdata=$chartData."&chxt=x,y,r&chxl=0:|".$label_time."1:|0|".$halfValue."|".$maxValue."|2:|0|".$halfPage."|".$maxPage."&chxs=0,6b6b6b,9";
  982. }
  983. // Chart type has one one dataset
  984. // It's unused now
  985. } else {
  986. for ($i = 0; $i < count($Wvisits); $i++) {
  987. $currentValue = $Wvisits[$i];
  988. $currentTime = $atime[$i];
  989. $label_time.=str_replace(' ', '+', $currentTime)."|";
  990. if ($currentValue > -1) {
  991. $chartData.=substr($simpleEncoding,61*($currentValue/$maxValue),1);
  992. } else {
  993. $chartData.='_';
  994. }
  995. }
  996. $chartAPIdata=$chartData."&chxt=x,y&chxl=0:|".$label_time."|1:|0|".$halfValue."|".$maxValue."&chxs=0,6b6b6b,9";
  997. }
  998. return $chartAPIdata;
  999. } //end function
  1000. // Used to show main visitors details query, to count items and to extract data for main chart
  1001. class MainItems {
  1002. // declare variables
  1003. var $tableName;
  1004. var $from_date;
  1005. var $to_date;
  1006. var $searchString;
  1007. var $whereis;
  1008. var $ItemsType;
  1009. var $Limit;
  1010. var $Last;
  1011. var $WpUrl;
  1012. /* Constructor */
  1013. function mainitems($table_name,$date_from,$date_to,$whereis=null,$limit=null) {
  1014. global $wpdb;
  1015. $this->tableName = $table_name;
  1016. $this->from_date = $date_from;
  1017. $this->to_date = $date_to;
  1018. $this->whereis = $whereis;
  1019. $this->limit = $limit;
  1020. }
  1021. /* Methods */
  1022. // Function to show main query and count items
  1023. function calc_tot($Type, $Search="", $specific_where_clause=null, $distinct_type=null) {
  1024. global $wpdb, $wassup_options, $debug_mode;
  1025. $this->ItemsType = $Type;
  1026. $this->searchString = $Search;
  1027. $ss = "";
  1028. if (!empty($Search) || !empty($specific_where_clause)) {
  1029. $ss = $this->buildSearch($Search,$specific_where_clause);
  1030. }
  1031. // Switch by every (global) items type (visits, pageviews, spams, etc...)
  1032. switch ($Type) {
  1033. // This is the MAIN query to show the chronology
  1034. case "main":
  1035. //## Extend mysql wait timeout to 2.5 minutes and extend
  1036. //# php script timeout to 3 minutes to prevent script
  1037. //# hangs with large tables on slow server.
  1038. if (!ini_get('safe_mode')) @set_time_limit(3*60);
  1039. $results = $wpdb->query("SET wait_timeout = 160");
  1040. //TODO: use a subquery for MySQL 5+
  1041. //main query
  1042. // - retrieve one row per wassup_id with timestamp = max(timestamp) (ie. latest record)
  1043. // "sql_buffer_result" select option helps in cases where it takes a long time to retrieve results. -Helene D. 2/29/09
  1044. $qry = sprintf("SELECT SQL_BUFFER_RESULT *, max(`timestamp`) as max_timestamp, count(wassup_id) as page_hits FROM %s WHERE `timestamp` >= %s %s %s GROUP BY wassup_id ORDER BY max_timestamp DESC %s",
  1045. $this->tableName,
  1046. $this->from_date,
  1047. $ss,
  1048. $this->whereis,
  1049. $this->Limit);
  1050. $results = $wpdb->get_results($qry);
  1051. //return $results;
  1052. break;
  1053. case "count":
  1054. // These are the queries to count the items hits/pages/spam
  1055. $qry = sprintf("SELECT COUNT(%s `wassup_id`) AS itemstot FROM %s WHERE `timestamp` >= %s %s %s",
  1056. $distinct_type,
  1057. $this->tableName,
  1058. $this->from_date,
  1059. $ss,
  1060. $this->whereis);
  1061. $results = $wpdb->get_var($qry);
  1062. //$itemstot = $wpdb->get_var($qry);
  1063. //return $itemstot;
  1064. break;
  1065. } //end switch
  1066. if (!empty($results)) {
  1067. return $results;
  1068. } else {
  1069. return false;
  1070. }
  1071. } //end function calc_tot
  1072. // $Ctype = chart's type by time
  1073. // $Res = resolution
  1074. // $Search = string to add to where clause
  1075. function TheChart($Ctype, $Res, $chart_height, $Search="", $axes_type, $chart_bg, $chart_type=null) {
  1076. global $wpdb, $debug_mode;
  1077. $mysqlversion=substr(mysql_get_server_info(),0,3);
  1078. $this->searchString = $Search;
  1079. $this->Last = $Ctype;
  1080. //# MySql 'FROM_UNIXTIME' converts a UTC timestamp to a
  1081. //# local datetime based on the server host timezone(TZ).
  1082. //# Wassup's 'timestamp' is neither UTC nor server host
  1083. //# time. It is Wordpress time and must be converted to
  1084. //# UTC minus the TZ difference between the server host
  1085. //# and Wordpress time offset to get an accurate output
  1086. //# from 'FROM_UNIXTIME'
  1087. $WPoffset = (int)(get_option("gmt_offset")*60*60);
  1088. $UTCoffset = $WPoffset + ((int)date('Z') - $WPoffset);
  1089. //
  1090. //#for US/Euro date display: USA Timezone=USA date format.
  1091. //TODO: Use date format in Wordpress to determine x-axis format
  1092. if (in_array(date('T'), array("ADT","AST","AKDT","AKST","CDT","CST","EDT","EST","HADT","HAST","MDT","MST","PDT","PST"))) {
  1093. $USAdate = true;
  1094. } else {
  1095. $USAdate = false;
  1096. }
  1097. // Options by chart type
  1098. switch ($Ctype) {
  1099. case .4:
  1100. $label = __("Last 6 Hours", "wassup");
  1101. $strto = "6 hours";
  1102. $Ctimeformat = "%H";
  1103. $x_axes_label = "%H:00";
  1104. break;
  1105. case 7:
  1106. $label = __("Last 7 Days", "wassup");
  1107. $strto = "7 days";
  1108. $Ctimeformat = "%d";
  1109. if ($USAdate) { $x_axes_label = "%a %b %d"; }
  1110. else { $x_axes_label = "%a %d %b"; }
  1111. break;
  1112. case 30:
  1113. $label = __("Last Month", "wassup");
  1114. $strto = "30 days";
  1115. $Ctimeformat = "%d";
  1116. if ($USAdate) { $x_axes_label = " %b %d"; }
  1117. else { $x_axes_label = "%d %b"; }
  1118. break;
  1119. case 90:
  1120. $label = __("Last 3 Months", "wassup");
  1121. $strto = "3 months";
  1122. $Ctimeformat = "%u";
  1123. $x_axes_label = "%b, wk-%u";
  1124. break;
  1125. case 180:
  1126. $label = __("Last 6 Months", "wassup");
  1127. $strto = "6 months";
  1128. $Ctimeformat = "%m";
  1129. $x_axes_label = " %b %Y";
  1130. break;
  1131. case 365:
  1132. $label = __("Last Year", "wassup");
  1133. $strto = "12 months";
  1134. $Ctimeformat = "%m";
  1135. $x_axes_label = "%b %Y";
  1136. break;
  1137. case 0:
  1138. $label = __("All Time", "wassup");
  1139. $strto = "";
  1140. $Ctimeformat = "%m";
  1141. $x_axes_label = "%b %Y";
  1142. break;
  1143. case 1:
  1144. default:
  1145. $label = __("Last 24 Hours", "wassup");
  1146. $strto = "24 hours";
  1147. $Ctimeformat = "%H";
  1148. $x_axes_label = "%H:00";
  1149. }
  1150. // Add Search variable to WHERE clause
  1151. $ss = $this->buildSearch($Search);
  1152. $hour_todate = $this->to_date;
  1153. if ($strto != "") {
  1154. $hour_fromdate = strtotime("-".$strto, $hour_todate);
  1155. } else {
  1156. $hour_fromdate = 0;
  1157. }
  1158. //if ($hour_fromdate == "") $hour_fromdate = strtotime("-24 hours", $hour_todate);
  1159. $qry = sprintf("SELECT COUNT(DISTINCT `wassup_id`) as items, COUNT(`wassup_id`) as pages, DATE_FORMAT(FROM_UNIXTIME(CAST((`timestamp` - %s) AS UNSIGNED)), '%s') as thedate FROM %s WHERE `timestamp` > %s %s %s GROUP BY DATE_FORMAT(FROM_UNIXTIME(CAST((`timestamp` - %s) AS UNSIGNED)), '%s') ORDER BY `timestamp`",
  1160. $UTCoffset,
  1161. $x_axes_label,
  1162. $this->tableName,
  1163. $hour_fromdate,
  1164. $this->whereis,
  1165. $ss,
  1166. $UTCoffset,
  1167. $Ctimeformat);
  1168. $aitems = $wpdb->get_results($qry,ARRAY_A);
  1169. // Extract arrays for Visits, Pages and X_Axis_Label
  1170. if (count($aitems) > 0) {
  1171. foreach ($aitems as $bhits) {

Large files files are truncated, but you can click here to view the full file