PageRenderTime 63ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/blog/wp-content/plugins/podpress/podpress_admin_stats_class.php

https://bitbucket.org/sergiohzlz/reportaprod
PHP | 1835 lines | 1489 code | 155 blank | 191 comment | 277 complexity | 668f50afdac4dd874a3b2e4d670a6f56 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /*
  3. License:
  4. ==============================================================================
  5. Copyright 2006 Dan Kuykendall (email : dan@kuykendall.org)
  6. Modifications: Jeff Norris (email : jeff@iscifi.tv)
  7. Thanks to The P2R Team ( prepare2respond.com ) for stats suggestions.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-107 USA
  19. */
  20. class podPressAdmin_class extends podPress_class {
  21. function podPressAdmin_class() {
  22. GLOBAL $wpdb;
  23. $this->path = get_option('siteurl').'/wp-admin/admin.php?page=podpress/podpress_stats.php';
  24. if (isset($_GET['display']) && is_string($_GET['display'])) {
  25. $this->path .= '&amp;display='.$_GET['display'];
  26. }
  27. // since 8.8.5 beta 3
  28. parent::wherestr_to_exclude_bots();
  29. $this->wpdb = $wpdb;
  30. /* set default language for graphs */
  31. $languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
  32. $primary_language = $languages[0];
  33. if (in_array($primary_language, array('de-de', 'de'))) {
  34. /* German specification */
  35. setlocale(LC_TIME, 'de_DE@euro:UTF-8', 'de_de:UTF-8', 'de_DE:UTF-8', 'de:UTF-8', 'ge:UTF-8', 'German_Germany.1252:UTF-8');
  36. $local_settings = array(
  37. 'numbers' => array(',', '.'),
  38. 'short_date' => '%a.%n%d.%m.%y',
  39. 'creation_date' => '%d.%m.%y',
  40. );
  41. } else {
  42. /* default specification: english */
  43. setlocale(LC_TIME, 'en_US:UTF-8', 'en_en:UTF-8', 'en:UTF-8');
  44. $local_settings = array(
  45. 'numbers' => array('.', ','),
  46. 'short_date' => '%a.%n%m/%d/%y',
  47. 'creation_date' => '%m/%d/%y',
  48. );
  49. }
  50. $this->local_settings = $local_settings;
  51. $this->podPress_class();
  52. return;
  53. }
  54. #############################################
  55. #############################################
  56. function podSafeDigit($digit = 0) {
  57. if (is_numeric($digit) && ($digit < 10000)) {
  58. $digit = abs((int)$digit);
  59. } else {
  60. $digit = 0;
  61. }
  62. return $digit;
  63. }
  64. #############################################
  65. #############################################
  66. function paging($start, $limit, $total, $text = null) {
  67. $pages = ceil($total / $limit);
  68. $actualpage = ceil($start / $limit);
  69. if ($pages > 0) {
  70. if ($start > 0) {
  71. $start_new = ($start - $limit < 0) ? 0 : ($start - $limit);
  72. $right = '<a href="'.$this->path.'&amp;start='.$start_new.'">'.__('Next Entries &raquo;').'</a>';
  73. }
  74. if ($start + $limit < $total) {
  75. $start_new = ($start + $limit);
  76. $left = '<a href="'.$this->path.'&amp;start='.$start_new.'">'.__('&laquo; Previous Entries').'</a>';
  77. }
  78. echo '<div id="podPress_paging">'."\n";
  79. echo ' <div id="podPress_pagingLeft">'."\n";
  80. if ($pages > 1) {
  81. if (!is_null($text)) {
  82. echo $text;
  83. }
  84. echo ' <select name="podPress_pageSelect" onchange="javascript: window.location = \''.$this->path.'&start=\'+this.value;">';
  85. $i = 0;
  86. while ($i < $total) {
  87. $selected = ($i == $start) ? ' selected="selected"': null;
  88. $newi = ($i + $limit);
  89. if ($newi > $total) {
  90. $newi = $total;
  91. }
  92. echo ' <option value="'.$i.'"'.$selected.'>'.ceil($total - ($newi - 1)).' - '.ceil($total - ($i)).'</option>';
  93. #$i = ($newi + 1);
  94. $i = $newi;
  95. }
  96. echo ' </select>';
  97. echo ' '.__('of', 'podpress').' '.$total;
  98. }
  99. echo ' </div>'."\n";
  100. echo ' <div id="podPress_pagingRight">';
  101. if ($start + $limit < $total) {
  102. echo $left;
  103. }
  104. if (($start + $limit < $total) AND ($start > 0)) {
  105. echo '&nbsp;&nbsp;|&nbsp;&nbsp;';
  106. }
  107. if ($start > 0) {
  108. echo $right;
  109. }
  110. echo " </div>\n";
  111. echo "</div>\n";
  112. }
  113. }
  114. // ntm: paging() revised for v8.8.5 beta 3
  115. // -'previous/next entries' string swaped
  116. // - '$text from x to y' - select box revised
  117. function paging2($start, $limit, $total, $text = null) {
  118. $pages = ceil($total / $limit);
  119. if ($pages > 0) {
  120. echo '<div id="podPress_paging">'."\n";
  121. echo ' <div id="podPress_pagingLeft">'."\n";
  122. if ($pages > 1) {
  123. if (!is_null($text)) {
  124. echo $text;
  125. }
  126. echo ' <select name="podPress_pageSelect" onchange="javascript: window.location = \''.$this->path.'&start=\'+this.value;">';
  127. $low = (1);
  128. for ($i=$low; $i <= $total; $i++) {
  129. $selected = (($i-1) == $start) ? ' selected="selected"': '';
  130. if ( ($i % $limit) == 1 ) {
  131. if ((($low-1)+$limit) < $total) {
  132. $high = ($low-1)+$limit;
  133. } else {
  134. $high = $total;
  135. }
  136. if ($low != $high) {
  137. echo ' <option value="'.($i-1).'"'.$selected.'>'.$low.' - '.$high.'</option>';
  138. } else {
  139. echo ' <option value="'.($i-1).'"'.$selected.'>'.$high.'</option>';
  140. }
  141. $low += $limit;
  142. }
  143. }
  144. echo ' </select>';
  145. echo ' '.__('of', 'podpress').' '.$total;
  146. }
  147. //echo '<p>'.$start.' | '.$limit.' | '.$total.' | '.$text.'</p>';
  148. echo ' </div>'."\n";
  149. if ($start + $limit < $total) {
  150. $right = '<a href="'.$this->path.'&amp;start='.($start+$limit).'">'.__('Next Entries &raquo;').'</a>';
  151. }
  152. if ($start > 0) {
  153. $left = '<a href="'.$this->path.'&amp;start='.($start-$limit).'">'.__('&laquo; Previous Entries').'</a>';
  154. }
  155. echo ' <div id="podPress_pagingRight">';
  156. if ($start > 0) {
  157. echo $left;
  158. }
  159. if (($start + $limit < $total) AND ($start > 0)) {
  160. echo '&nbsp;|&nbsp;';
  161. }
  162. if ($start + $limit < $total) {
  163. echo $right;
  164. }
  165. echo " </div>\n";
  166. echo "</div>\n";
  167. }
  168. }
  169. #############################################
  170. #############################################
  171. function podGetHighest($data) {
  172. $highest = 0;
  173. foreach ($data AS $key => $idata) {
  174. if ($idata->value > $highest) {
  175. $highest = $idata->value;
  176. }
  177. }
  178. return $highest;
  179. }
  180. #############################################
  181. #############################################
  182. function podGraph($data, $splitter = null) {
  183. $cnt_data = count($data);
  184. if ($cnt_data > 0) {
  185. $box_width = 600;
  186. $box_height = 400;
  187. $bar_margin = 2;
  188. $bar_width = floor(($box_width - ($cnt_data * $bar_margin)) / $cnt_data);
  189. $bar_width = ($bar_width < 2) ? 2: $bar_width;
  190. $highest = $this->podGetHighest($data);
  191. $factor = ($highest / $box_height);
  192. $output = '<div id="podGraph" style="height: '.$box_height.'px; width: '.$box_width.'px; float: left; border: 1px solid #ccc; padding: 0.5em;">';
  193. foreach ($data AS $key => $idata) {
  194. $image_height = floor($idata->value / $factor);
  195. $margin = ($box_height - $image_height);
  196. $bgcolor = (is_array($splitter) && ($idata->$splitter[0] == $splitter[1])) ? '#aaa': '#ccc';
  197. $bgcolor = ($image_height == $box_height) ? '#d00': $bgcolor;
  198. $output .= ' <div style="float: left; margin-top: '.$margin.'px; margin-right: '.$bar_margin.'px; height: '.$image_height.'px; background-color: '.$bgcolor.'; width: '.$bar_width.'px; cursor: help;'.$split.'" title="'.$idata->title.' ('.number_format($idata->value, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' x)"></div>'."\n";
  199. }
  200. $output .= "</div>\n";
  201. } else {
  202. $output = '<p>'.__('We\'re sorry. At the moment we don\'t have enough data collected to display the graph.', 'podpress')."</p>\n";
  203. }
  204. return $output;
  205. }
  206. #############################################
  207. #############################################
  208. function settings_stats_edit() {
  209. GLOBAL $wpdb, $wp_version;
  210. podPress_isAuthorized();
  211. $baseurl = get_option('siteurl') . '/wp-admin/admin.php?page=podpress/podpress_stats.php&display=';
  212. echo '<div class="wrap">'."\n";
  213. if ( TRUE == version_compare($wp_version, '2.7', '>=') ) {
  214. echo '<div id="podpress-icon" class="icon32"><br /></div>';
  215. }
  216. if ( TRUE == version_compare($wp_version, '2.8', '>=') ) {
  217. echo ' <h2>'.__('Download Statistics', 'podpress').'</h2>'."\n";
  218. // get the plugins version information via the WP plugins version check
  219. if ( TRUE == version_compare($wp_version, '2.9', '>=') ) {
  220. $versioninfo = get_site_transient( 'update_plugins' );
  221. } else {
  222. $versioninfo = get_transient( 'update_plugins' );
  223. }
  224. // If there is a new version then there is a 'response'. This is the method from the plugins page.
  225. if ( FALSE !== isset($versioninfo->response[plugin_basename(dirname(__FILE__).'/podpress.php')]->new_version) ) {
  226. echo '<div class="message updated"><p><a href="http://wordpress.org/extend/plugins/podpress/" target="_blank">'.__('a new podPress version is available', 'podpress').'</a></p></div>';
  227. }
  228. } else {
  229. echo ' <h2>'.__('Download Statistics', 'podpress').'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.mightyseek.com/podpress/#download" target="_new"><img src="http://www.mightyseek.com/podpress_downloads/versioncheck.php?current='.PODPRESS_VERSION.'" alt="'.__('Checking for updates... Failed.', 'podpress').'" border="0" /></a></h2>'."\n";
  230. }
  231. if($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus') {
  232. // Show all statistics which are based on wp_stats [stat logging: Full and Full+]
  233. $navi = array(
  234. 'downloads_per_media_file' => __('Downloads Per Media File', 'podpress'),
  235. 'downloads_per_post' => __('Downloads Per Post', 'podpress'),
  236. 'topips' => __('Downloads Per IP Address', 'podpress'),
  237. 'graphbydate' => __('Graph by Date', 'podpress'),
  238. 'rawstats' => __('Raw Stats', 'podpress'),
  239. );
  240. echo ' <ul id="podPress_navi">'."\n";
  241. foreach ($navi AS $key => $value) {
  242. $active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'downloads_per_media_file'))) ? ' class="current"': null;
  243. echo ' <li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a>';
  244. if($this->checkGD()) {
  245. if ($value == __('Graph by Date', 'podpress')) {
  246. echo ' (<a href="'.$baseurl.'graphbydatealt" title="'.sprintf(__('An alternative view of the %1$s', 'podpress'), __('Graph by Date', 'podpress')).'">'. __('alt', 'podpress').'</a>)';
  247. }
  248. }
  249. echo '</li>'."\n";
  250. }
  251. echo ' </ul>'."\n";
  252. // bot management menu (since 8.8.5 beta 3)
  253. $navi2 = array(
  254. 'botdb_mark_bots' => __('Select / Deselect Bots', 'podpress'),
  255. 'botdb_list' => __('List of Bots', 'podpress'),
  256. );
  257. echo ' <ul id="podPress_navi">'."\n";
  258. foreach ($navi2 AS $key => $value) {
  259. $active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'quickcounts'))) ? ' class="current"': null;
  260. echo ' <li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a></li>'."\n";
  261. }
  262. echo ' </ul>'."\n";
  263. } else {
  264. // Show all statistics which are based on wp_statcounts [stat logging: Counts Only]
  265. // old: $_GET['display'] = 'downloads_per_media_file';
  266. $navi = array(
  267. 'quickcounts' => __('Quick Counts', 'podpress'),
  268. 'graphbypost' => __('Graph by Post', 'podpress'),
  269. );
  270. echo ' <ul id="podPress_navi">'."\n";
  271. foreach ($navi AS $key => $value) {
  272. $active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'quickcounts'))) ? ' class="current"': null;
  273. echo ' <li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a>';
  274. if($this->checkGD()) {
  275. if($value == __('Graph by Post', 'podpress')) {
  276. echo ' (<a href="'.$baseurl.'graphbypostalt" title="'.sprintf(__('An alternative view of the %1$s', 'podpress'), __('Graph by Post', 'podpress')).'">'. __('alt', 'podpress').'</a>)';
  277. }
  278. }
  279. echo '</li>'."\n";
  280. }
  281. echo ' </ul>'."\n";
  282. }
  283. // Set Paging-Settings
  284. $start = (isset($_GET['start'])) ? $this->podSafeDigit($_GET['start']): 0;
  285. //~ ####################
  286. //~ Limit is limits the number of rows of the statistic tables
  287. $limit = 25;
  288. //~ ####################
  289. // ntm: since 8.8.5 beta 3 there are two different default statistic tables quickcounts and downloads_per_media_file that is why the default value has to be found before that Switch (and not with this Switch)
  290. if (FALSE == isset($_GET['display']) OR FALSE !== empty($_GET['display'])) {
  291. if ($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus') {
  292. $show_this_page = 'downloads_per_media_file';
  293. } else {
  294. $show_this_page = 'quickcounts';
  295. }
  296. } else {
  297. $show_this_page = $_GET['display'];
  298. }
  299. Switch($show_this_page) {
  300. case 'botdb_list':
  301. // ntm: stat logging: Full and Full+
  302. podPress_isAuthorized();
  303. $botdb = get_option('podpress_botdb');
  304. if ( 'botdb' == $_POST['podPress_submitted'] ) {
  305. if ( function_exists('check_admin_referer') ) {
  306. check_admin_referer('podPress_botdb_nonce');
  307. }
  308. $IPs = $_POST['podpress_remote_ips'];
  309. $fullbotnames = stripslashes_deep($_POST['podpress_user_agents']);
  310. if ( is_array($botdb) ) {
  311. $something_removed=FALSE;
  312. if ( is_array($IPs) and is_array($botdb['IP'])) {
  313. $botdb['IP'] = array_diff($botdb['IP'], $IPs);
  314. sort($botdb['IP']);
  315. }
  316. if ( is_array($fullbotnames) and is_array($botdb['fullbotnames'])) {
  317. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $fullbotnames);
  318. sort($botdb['fullbotnames']);
  319. }
  320. }
  321. $updated=update_option('podpress_botdb', $botdb);
  322. if (isset($updated) AND $updated == TRUE) {
  323. echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
  324. }
  325. }
  326. echo ' <div class="wrap">'."\n";
  327. echo ' <fieldset class="options">'."\n";
  328. echo ' <legend>'.__('The list of IP addresses and names of bots', 'podpress').'</legend>'."\n";
  329. echo ' <form method="post">'."\n";
  330. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  331. wp_nonce_field('podPress_botdb_nonce');
  332. }
  333. echo ' <table class="the-list-x widefat">'."\n";
  334. echo ' <thead>'."\n";
  335. echo ' <tr><th rowspan="2">'.__('Nr.', 'podpress').'</th><th rowspan="2">'.__('Bot IP Address', 'podpress').'</th><th rowspan="2">'.__('Bot User Agent', 'podpress').'</th><th colspan="2">'.__('Remove this', 'podpress').'</th></tr><tr><th>'.__('IP', 'podpress').'</th><th>'.__('Name', 'podpress').'</th></tr>'."\n";
  336. echo ' </thead>'."\n";
  337. echo ' <tbody>'."\n";
  338. $nobots = FALSE;
  339. if (is_array($botdb) and (is_array($botdb['fullbotnames']) OR is_array($botdb['IP'])) ) {
  340. $botnames_len = count($botdb['fullbotnames']);
  341. $IPs_len = count($botdb['IP']);
  342. $rows_total = max($botnames_len, $IPs_len);
  343. if ( $rows_total > ($start+$limit) ) {
  344. $high = $start+$limit;
  345. } else {
  346. $high = $rows_total;
  347. }
  348. $low = ($start+1);
  349. for ($i=$low; $i <= $high; $i++) {
  350. $style = ($i % 2) ? '' : ' class="alternate"';
  351. echo ' <tr'.$style.'>'."\n";
  352. echo ' <td>'.($start +$i).'.</td>'."\n";
  353. if ($i <= ($IPs_len-$start)) {
  354. $col_ip = ' <td>'.stripslashes($botdb['IP'][($i-1)]).'</td>'."\n";
  355. $col_ip_chb = ' <td><input type="checkbox" id="podpress_remote_ip_'.$i.'" name="podpress_remote_ips[]" value="'.$botdb['IP'][($i-1)].'" '.$ip_chb_checked.' /></td>'."\n";
  356. } else {
  357. $col_ip = $col_ip_chb = ' <td></td>'."\n";
  358. }
  359. if ($i <= ($botnames_len-$start)) {
  360. $col_botname = ' <td>'.stripslashes($botdb['fullbotnames'][($i-1)]).'</td>'."\n";
  361. $col_botname_chb = ' <td><input type="checkbox" id="podpress_user_agent_'.$i.'" name="podpress_user_agents[]" value="'.attribute_escape($botdb['fullbotnames'][($i-1)]).'" '.$name_chb_checked.' /></td>'."\n";
  362. } else {
  363. $col_botname = $col_botname_chb = ' <td></td>'."\n";
  364. }
  365. echo $col_ip.$col_botname.$col_ip_chb.$col_botname_chb;
  366. echo ' </tr>'."\n";
  367. }
  368. if ( 0 == $botnames_len AND 0 == $IPs_len ) {
  369. $nobots = TRUE;
  370. }
  371. } else {
  372. $nobots = TRUE;
  373. }
  374. if (TRUE == $nobots) {
  375. echo ' <td colspan="5">'.__('Currently are no IP addresses or user agents marked as bots.', 'podpress').'</td>'."\n";
  376. }
  377. echo ' </tbody>'."\n";
  378. echo ' <tfood>'."\n";
  379. echo ' <tr>'."\n";
  380. echo ' <th colspan="5">'."\n";
  381. // Show paging
  382. echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
  383. echo ' </th>'."\n";
  384. echo ' </tr>'."\n";
  385. echo ' </tfood>'."\n";
  386. echo ' </table>'."\n";
  387. echo ' <p class="submit"> '."\n";
  388. echo ' <input class="button-primary" type="submit" name="Submit" value="'.__('Remove elements', 'podpress').' &raquo;" /><br />'."\n";
  389. echo ' </p> '."\n";
  390. echo ' <input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
  391. echo ' </form>'."\n";
  392. echo ' </fieldset>'."\n";
  393. echo ' </div>';
  394. break;
  395. case 'botdb_mark_bots':
  396. // ntm: stat logging: Full and Full+
  397. podPress_isAuthorized();
  398. $blog_charset = get_bloginfo('charset');
  399. $botdb = get_option('podpress_botdb');
  400. if ( 'botdb' == $_POST['podPress_submitted'] ) {
  401. if ( function_exists('check_admin_referer') ) {
  402. check_admin_referer('podPress_botdb_nonce');
  403. }
  404. $IPs = $_POST['podpress_remote_ips'];
  405. $fullbotnames = stripslashes_deep($_POST['podpress_user_agents']);
  406. if (is_array($botdb)) {
  407. $current_IP_set = $_POST['podpress_current_IP_set'];
  408. $unique_current_data_IPs = array_unique($_POST['podpress_current_IP_set']);
  409. //add new bots
  410. if (is_array($IPs)) {
  411. $unique_IPs = array_unique($IPs);
  412. foreach ($unique_IPs as $IP) {
  413. if (is_array($botdb['IP'])) {
  414. if ( FALSE === array_search($IP, $botdb['IP']) ) {
  415. $botdb['IP'][] = $IP;
  416. }
  417. } else {
  418. $botdb['IP'][] = $IP;
  419. }
  420. }
  421. // eventually remove bots
  422. $unmarked_IPs = array_diff($unique_current_data_IPs, $unique_IPs);
  423. $botdb['IP'] = array_diff($botdb['IP'], $unmarked_IPs);
  424. sort($botdb['IP']);
  425. } else {
  426. if (is_array($botdb['IP'])) {
  427. $botdb['IP'] = array_diff($botdb['IP'], $unique_current_data_IPs);
  428. sort($botdb['IP']);
  429. }
  430. }
  431. $current_user_agent_set = $_POST['podpress_current_user_agent_set'];
  432. $unique_current_data_fbnames = array_unique($_POST['podpress_current_user_agent_set']);
  433. if (is_array($fullbotnames)) {
  434. $unique_fullbotnames = array_unique($fullbotnames);
  435. foreach ($unique_fullbotnames as $fullbotname) {
  436. if (is_array($botdb['fullbotnames'])) {
  437. if ( FALSE === array_search($fullbotname, $botdb['fullbotnames']) ) {
  438. $botdb['fullbotnames'][] = $fullbotname;
  439. }
  440. } else {
  441. $botdb['fullbotnames'][] = $fullbotname;
  442. }
  443. }
  444. // eventually remove bots
  445. $unmarked_fullbotnames = array_diff($unique_current_data_fbnames, $unique_fullbotnames);
  446. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unmarked_fullbotnames);
  447. sort($botdb['fullbotnames']);
  448. } else {
  449. // eventually remove bots
  450. if (is_array($botdb['fullbotnames'])) {
  451. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unique_current_data_fbnames);
  452. sort($botdb['fullbotnames']);
  453. }
  454. }
  455. } else {
  456. //add new bots (first time)
  457. if (is_array($IPs)) {
  458. $unique_IPs = array_unique($IPs);
  459. foreach ($unique_IPs as $IP) {
  460. $botdb['IP'][] = $IP;
  461. }
  462. }
  463. if (is_array($fullbotnames)) {
  464. $unique_fullbotnames = array_unique($fullbotnames);
  465. foreach ($unique_fullbotnames as $fullbotname) {
  466. $botdb['fullbotnames'][] = $fullbotname;
  467. }
  468. }
  469. }
  470. $updated=update_option('podpress_botdb', $botdb);
  471. if (isset($updated) AND $updated == TRUE) {
  472. echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
  473. }
  474. }
  475. $where='';
  476. $rows_total = intval($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip, user_agent) AS total FROM '.$wpdb->prefix.'podpress_stats '.$where));
  477. $query_string = 'SELECT DISTINCT remote_ip, user_agent FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY dt DESC LIMIT '.$start.', '.$limit;
  478. $stats = $wpdb->get_results($query_string);
  479. echo ' <div class="wrap">'."\n";
  480. echo ' <fieldset class="options">'."\n";
  481. echo ' <legend>'.__('Which IP address or user agent name is from a web bot?', 'podpress').'</legend>'."\n";
  482. echo ' <p>'.__('Probably not every counted download is a download of a real human listener. Some hits are eventually from so called <a href="http://en.wikipedia.org/wiki/Internet_bot" target="_blank" title="en.Wikipedia: Internet Bot">Internet bots</a>. Every downloader has an <a href="http://en.wikipedia.org/wiki/IP_address" target="_blank" title="en.Wikipedia: IP Address">IP address</a> and a <a href="http://en.wikipedia.org/wiki/User_agent" target="_blank" title="en.Wikipedia: User Agent">user agent</a> name. The user agent name indicates often very good whether it is the name of a browser of a real listener or a name of a bot. Whether a IP address is one of a bot or not is more difficult. But there are some websites which can help to find out more about an IP address. (Some bots are using IP addresses only temporarily.)<br />The list below shows all unique combinations of IP addresses and user agent names. It is possible to select (resp. deselect) only the IP address or the user agent name or both. Downloads of the selected IP addresses or user agents do not appear in the statistics.', 'podpress').'</p>'."\n";
  483. echo ' <form method="post">'."\n";
  484. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  485. wp_nonce_field('podPress_botdb_nonce');
  486. }
  487. echo "\n".' <table class="the-list-x widefat">'."\n";
  488. echo ' <thead>'."\n";
  489. echo ' <tr><th rowspan="2">'.__('Nr.', 'podpress').'</th><th rowspan="2">'.__('IP Address', 'podpress').'</th><th rowspan="2">'.__('User Agent', 'podpress').'</th><th colspan="2">'.__('Is it a bot?', 'podpress').'</th></tr><tr><th>'.__('IP', 'podpress').'</th><th>'.__('Name', 'podpress').'</th></tr>'."\n";
  490. echo ' </thead>'."\n";
  491. echo ' <tbody>'."\n";
  492. if(0 < count($stats)) {
  493. $i = 0;
  494. foreach ($stats as $stat) {
  495. ++$i;
  496. $alternate = ($i % 2) ? '' : 'alternate';
  497. $bot_style = '';
  498. $ip_chb_checked = '';
  499. $name_chb_checked = '';
  500. if (TRUE == is_array($botdb)) {
  501. if (TRUE == is_array($botdb['IP']) AND FALSE !== array_search($stat->remote_ip, $botdb['IP'])) {
  502. $bot_style = ' podpress_is_bot';
  503. $ip_chb_checked = ' checked="checked"';
  504. }
  505. if (TRUE == is_array($botdb['fullbotnames']) AND FALSE !== array_search($stat->user_agent, $botdb['fullbotnames'])) {
  506. $bot_style = ' podpress_is_bot';
  507. $name_chb_checked = ' checked="checked"';
  508. }
  509. }
  510. echo ' <tr id ="podpress_ip_user_agent_row_'.($i).'" class="'.$alternate.$bot_style.'">'."\n";
  511. echo ' <td>'.($start+$i).'</td>'."\n";
  512. echo ' <td>'.$stat->remote_ip.'<input type="hidden" name="podpress_current_IP_set[]" value="'.$stat->remote_ip.'" /></td>'."\n";
  513. echo ' <td>'.podPress_strlimiter2($stat->user_agent, 80, TRUE).'<input type="hidden" name="podpress_current_user_agent_set[]" value="'.attribute_escape($stat->user_agent).'" /></td>'."\n";
  514. echo ' <td><input type="checkbox" id="podpress_remote_ip_'.$i.'" name="podpress_remote_ips[]" value="'.$stat->remote_ip.'" onclick="podpress_mark_same_all_bots( \'remote_ips\' , '.$i.', '.($start).' );" '.$ip_chb_checked.' /></td>'."\n";
  515. echo ' <td><input type="checkbox" id="podpress_user_agent_'.$i.'" name="podpress_user_agents[]" value="'.attribute_escape($stat->user_agent).'" onclick="podpress_mark_same_all_bots( \'user_agent\' , '.$i.', '.($start).' );" '.$name_chb_checked.' /></td>'."\n";
  516. echo ' </tr>'."\n";
  517. }
  518. } else {
  519. echo '<td colspan="5">'.__('No downloads yet.','podpress')."</td>\n";
  520. }
  521. echo ' </tbody>'."\n";
  522. echo ' <tfood>'."\n";
  523. echo ' <tr>'."\n";
  524. echo ' <th colspan="5">'."\n";
  525. // Show paging
  526. echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
  527. echo ' </th>'."\n";
  528. echo ' </tr>'."\n";
  529. echo ' </tfood>'."\n";
  530. echo ' </table>'."\n";
  531. echo ' <p class="submit"> '."\n";
  532. echo ' <input class="button-primary" type="submit" name="Submit" value="'.__('Update Options', 'podpress').' &raquo;" /><br />'."\n";
  533. echo ' </p> '."\n";
  534. echo ' <input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
  535. echo ' </form>'."\n";
  536. echo ' </fieldset>'."\n";
  537. echo ' </div>';
  538. break;
  539. case 'downloads_per_media_file':
  540. // ntm: stat logging: Full and Full+
  541. $where = $this->wherestr_to_exclude_bots('pod');
  542. $query_string = "SELECT COUNT(DISTINCT pod.media) as total_rows FROM ".$wpdb->prefix."podpress_stats as pod ".$where;
  543. $rows_total = intval($wpdb->get_var($query_string));
  544. $query_string = "SELECT DISTINCT (pod.media) FROM ".$wpdb->prefix."podpress_stats as pod ".$where." LIMIT ".$start.", ".$limit;
  545. $posts_with_podpressmedia = $wpdb->get_results($query_string);
  546. $nr_postswpm = count($posts_with_podpressmedia);
  547. if ( 0 < $nr_postswpm) {
  548. $i=1;
  549. if (FALSE == empty($where)) {
  550. $where_posts = "AND pod.media IN (";
  551. } else {
  552. $where_posts = "WHERE pod.media IN (";
  553. }
  554. foreach ($posts_with_podpressmedia as $post) {
  555. if ($i == $nr_postswpm) {
  556. $where_posts .= "'".$post->media."'";
  557. } else {
  558. $where_posts .= "'".$post->media."', ";
  559. }
  560. $i++;
  561. }
  562. $where_posts .= ") ";
  563. } else {
  564. $where_posts = '';
  565. }
  566. $query_string="SELECT pod.media, pod.method, COUNT(*) as downloads FROM ".$wpdb->prefix."podpress_stats as pod ".$where.$where_posts."GROUP BY pod.method, pod.media ORDER BY pod.media DESC";
  567. $stat_data_sets = $wpdb->get_results($query_string);
  568. if (FALSE == empty($where)) {
  569. $where_or_and = "AND";
  570. } else {
  571. $where_or_and = "WHERE";
  572. }
  573. $methods = Array('feed', 'web', 'play');
  574. foreach ($methods as $method) {
  575. $query_string="SELECT COUNT(*) as downloads, pod.media FROM ".$wpdb->prefix."podpress_stats AS pod ".$where.$where_or_and." pod.method='".$method."' GROUP BY pod.media ORDER BY downloads DESC";
  576. $downloads_col = $wpdb->get_col($query_string);
  577. switch ($method) {
  578. case 'feed' :
  579. $feed_max = intval($downloads_col[0]);
  580. break;
  581. case 'web' :
  582. $web_max = intval($downloads_col[0]);
  583. break;
  584. case 'play' :
  585. $play_max = intval($downloads_col[0]);
  586. break;
  587. }
  588. }
  589. $query_string="SELECT COUNT(*) as downloads, pod.media FROM ".$wpdb->prefix."podpress_stats AS pod ".$where." GROUP BY pod.media ORDER BY downloads DESC";
  590. $downloads_col = $wpdb->get_col($query_string);
  591. $total_max = intval($downloads_col[0]);
  592. // prepare the query result for the output:
  593. // - if a media file was not downloaded by one or more method then add this method and a int(0) to the media file
  594. foreach ($stat_data_sets as $stat_data_set) {
  595. $feed = $web = $play = 0;
  596. switch ($stat_data_set->method) {
  597. case 'feed' :
  598. $feed = intval($stat_data_set->downloads);
  599. break;
  600. case 'web' :
  601. $web = intval($stat_data_set->downloads);
  602. break;
  603. case 'play' :
  604. $play = intval($stat_data_set->downloads);
  605. break;
  606. }
  607. $total_sum = $feed+$web+$play;
  608. $stats[$stat_data_set->media]['feed'] += $feed;
  609. $stats[$stat_data_set->media]['web'] += $web;
  610. $stats[$stat_data_set->media]['play'] += $play;
  611. $stats[$stat_data_set->media]['total'] += $total_sum;
  612. }
  613. // sort the media files by their 'total' value
  614. if (is_array($stats)) {
  615. uasort($stats, array(self, 'sort_downloads_per_media_desc'));
  616. }
  617. echo ' <div class="wrap">'."\n";
  618. echo ' <fieldset class="options">'."\n";
  619. echo ' <legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  620. echo ' <table class="the-list-x widefat">'."\n";
  621. echo ' <thead>';
  622. echo " <tr>\n";
  623. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  624. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  625. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  626. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
  627. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  628. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  629. echo ' </tr>'."\n";
  630. echo ' <tr>'."\n";
  631. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  632. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  633. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  634. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  635. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  636. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  637. echo ' </tr>'."\n";
  638. echo ' </thead>';
  639. echo ' <tbody>';
  640. if (0 < count($stat_data_sets)) {
  641. $i = 0;
  642. foreach ( $stats as $media => $downloads_per_method ) {
  643. $i++;
  644. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  645. $highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
  646. $highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
  647. $highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
  648. $highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
  649. $perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  650. $perc_web = number_format(($downloads_per_method['web'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  651. $perc_play = number_format(($downloads_per_method['play'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  652. echo ' <tr'.$style.'>'."\n";
  653. echo ' <td>'.($start +$i).'.</td>'."\n";
  654. echo ' <td>'.podPress_strlimiter2(urldecode($media), 50, TRUE).'</td>'."\n";
  655. echo ' <td class="podpress_stats_numbers_abs'.$highest_feed.'">'.number_format($downloads_per_method['feed'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  656. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  657. echo ' <td class="podpress_stats_numbers_abs'.$highest_web.'" >'.number_format($downloads_per_method['web'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  658. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  659. echo ' <td class="podpress_stats_numbers_abs'.$highest_play.'">'.number_format($downloads_per_method['play'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  660. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  661. echo ' <td class="podpress_stats_numbers_total'.$highest_total.'">'.number_format($downloads_per_method['total'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  662. echo ' </tr>'."\n";
  663. }
  664. } else {
  665. if (FALSE == empty($where)) {
  666. echo '<td colspan="9">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  667. } else {
  668. echo '<td colspan="9">'.__('No downloads yet.','podpress')."</td>\n";
  669. }
  670. }
  671. echo ' </tbody>';
  672. echo ' <tfood>'."\n";
  673. echo ' <tr>'."\n";
  674. echo ' <th colspan="9">'."\n";
  675. // Show paging
  676. echo $this->paging2($start, $limit, $rows_total, __('Ranks','podpress'));
  677. echo ' </th>'."\n";
  678. echo ' </tr>'."\n";
  679. echo ' </tfood>'."\n";
  680. echo ' </table>'."\n";
  681. echo ' </fieldset>'."\n";
  682. echo ' </div>';
  683. break;
  684. case 'rawstats':
  685. // ntm: stat logging: Full and Full+
  686. $date_format = get_option('date_format');
  687. $time_format = get_option('time_format');
  688. $botdb = get_option('podpress_botdb');
  689. $where = '';
  690. $rows_total = $wpdb->get_var('SELECT COUNT(*) FROM '.$wpdb->prefix.'podpress_stats '.$where);
  691. $stats = $wpdb->get_results('SELECT * FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY id DESC LIMIT '.$start.', '.$limit);
  692. echo ' <div class="wrap">'."\n";
  693. echo ' <fieldset class="options">'."\n";
  694. echo ' <legend>'.__('The raw list', 'podpress').'</legend>'."\n";
  695. echo ' <table class="the-list-x widefat">'."\n"; //width="100%" cellpadding="1" cellspacing="1"
  696. echo ' <thead>';
  697. echo ' <tr><th>'.__('Hit', 'podpress').'</th><th>'.__('Media File', 'podpress').'</th><th>'.__('Method', 'podpress').'</th><th>'.__('IP', 'podpress').'</th><th>'.__('User Agent', 'podpress').'</th><th>'.__('Timestamp', 'podpress').'</th></tr>'."\n";
  698. echo ' </thead>';
  699. echo ' <tbody>';
  700. if(0 < count($stats)) {
  701. if ( TRUE === is_array($botdb['IP']) OR TRUE === is_array($botdb['fullbotnames']) ) {
  702. $i = 0;
  703. foreach ($stats as $stat) {
  704. ++$i;
  705. $style = ($i % 2) ? '' : 'alternate';
  706. if ( (FALSE !== empty($botdb['fullbotnames']) OR FALSE === array_search($stat->user_agent, $botdb['fullbotnames']))) {
  707. if ( (FALSE !== empty($botdb['IP']) OR FALSE === array_search($stat->remote_ip, $botdb['IP']))) {
  708. $bot_style = '';
  709. } else {
  710. $bot_style = ' podpress_is_bot';
  711. }
  712. } else {
  713. $bot_style = ' podpress_is_bot';
  714. }
  715. echo ' <tr class="'.$style.$bot_style.'">'."\n";
  716. echo ' <td>'.($start +$i).'.</td>'."\n";
  717. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
  718. echo ' <td>'.$stat->method.'</td>'."\n";
  719. // iscifi : mod of stats output to create a link to domaintools.com whois lookup
  720. // domaintools seems faster and provides more concise infomation, url can not have trailing /
  721. echo ' <td><a href="http://whois.domaintools.com/'.$stat->remote_ip.'" target="_blank" title="'.__('Look for more details about this IP at whois.domaintools.com', 'podpress').'">'.$stat->remote_ip.'</a></td>'."\n";
  722. // OLD code where this .echo ' <td>'.$stat->remote_ip.'</td>'."\n";
  723. echo ' <td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
  724. echo ' <td>'.date($date_format.' - '.$time_format, intval($stat->dt)).'</td>'."\n";
  725. echo ' </tr>'."\n";
  726. }
  727. } else {
  728. $i = 0;
  729. foreach ($stats as $stat) {
  730. ++$i;
  731. $style = ($i % 2) ? '' : 'alternate';
  732. echo ' <tr class="'.$style.'">'."\n";
  733. echo ' <td>'.($start +$i).'.</td>'."\n";
  734. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
  735. echo ' <td>'.$stat->method.'</td>'."\n";
  736. // iscifi : mod of stats output to create a link to domaintools.com whois lookup
  737. // domaintools seems faster and provides more concise infomation, url can not have trailing /
  738. echo ' <td><a href="http://whois.domaintools.com/'.$stat->remote_ip.'" target="_blank">'.$stat->remote_ip.'</a></td>'."\n";
  739. // OLD code where this .echo ' <td>'.$stat->remote_ip.'</td>'."\n";
  740. echo ' <td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
  741. echo ' <td>'.date($date_format.' - '.$time_format, intval($stat->dt)).'</td>'."\n";
  742. echo ' </tr>'."\n";
  743. }
  744. }
  745. } else {
  746. echo '<td colspan="6">'.__('No downloads yet.','podpress').'</td>'."\n";
  747. }
  748. echo ' </tbody>';
  749. echo ' <tfood>'."\n";
  750. echo ' <tr>'."\n";
  751. echo ' <th colspan="6">'."\n";
  752. // Show paging
  753. echo $this->paging2($start, $limit, $rows_total, __('Hit','podpress'));
  754. echo ' </th>'."\n";
  755. echo ' </tr>'."\n";
  756. echo ' </tfood>'."\n";
  757. echo ' </table>'."\n";
  758. echo ' </fieldset>'."\n";
  759. echo ' </div>';
  760. break;
  761. case 'topips':
  762. // ntm: stat logging: Full and Full+
  763. $where = $this->wherestr_to_exclude_bots();
  764. $rows_total = ($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip) as uniq FROM '.$wpdb->prefix.'podpress_stats '.$where));
  765. $sql = 'SELECT remote_ip AS IPAddress, COUNT(DISTINCT remote_ip, media) as uniq, COUNT( * ) AS total FROM '.$wpdb->prefix.'podpress_stats '.$where.'GROUP BY remote_ip ORDER BY total DESC LIMIT '.$start.', '.$limit;
  766. $stats = $wpdb->get_results($sql);
  767. echo ' <div class="wrap">'."\n";
  768. echo ' <fieldset class="options">'."\n";
  769. echo ' <legend>'.__('Top IP Addresses', 'podpress').'</legend>'."\n";
  770. echo ' <table class="the-list-x widefat">'."\n";
  771. echo ' <thead>';
  772. echo ' <tr><th>'.__('Nr.', 'podpress').'</th><th>'.__('IP Address', 'podpress').'</th><th><abbr class="podpress_abbr" title="'.__('Only one download per file from this IP address has been counted. In other words: It is the number of different files which were downloaded from this IP address.','podpress').'">'.__('Unique Files', 'podpress').'</abbr></th><th>'.__('Total', 'podpress').'</th></tr>'."\n";
  773. echo ' </thead>';
  774. echo ' <tbody>';
  775. if(0<count($stats)) {
  776. $i = 0;
  777. foreach ($stats as $stat) {
  778. ++$i;
  779. $style = ($i % 2) ? '' : ' class="alternate"';
  780. echo ' <tr'.$style.'>'."\n";
  781. echo ' <td>'.($start +$i).'.</td>'."\n";
  782. echo ' <td>'.$stat->IPAddress.'</td>'."\n";
  783. echo ' <td>'.$stat->uniq.'</td>'."\n";
  784. echo ' <td>'.$stat->total.'</td>'."\n";
  785. echo ' </tr>'."\n";
  786. }
  787. } else {
  788. if (FALSE == empty($where)) {
  789. echo '<td colspan="4">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  790. } else {
  791. echo '<td colspan="4">'.__('No downloads yet.','podpress')."</td>\n";
  792. }
  793. }
  794. echo ' </tbody>';
  795. echo ' <tfood>'."\n";
  796. echo ' <tr>'."\n";
  797. echo ' <th colspan="4">'."\n";
  798. // Show paging
  799. echo $this->paging2($start, $limit, $rows_total, __('IP Address','podpress'));
  800. echo ' </th>'."\n";
  801. echo ' </tr>'."\n";
  802. echo ' </tfood>'."\n";
  803. echo ' </table>'."\n";
  804. echo ' </fieldset>'."\n";
  805. echo ' </div>';
  806. break;
  807. case 'graphbydate':
  808. // ntm: stat logging: Full and Full+
  809. if ($this->checkGD() ) {//&& ($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus')
  810. $this->graphByDate();
  811. } else {
  812. $this->graphByDateAlt('With <a href="http://us2.php.net/manual/en/ref.image.php">gdlib-support</a> you\'ll have access to more detailed graphicals stats. Please ask your provider.');
  813. }
  814. break;
  815. case 'graphbydatealt':
  816. // ntm: stat logging: Full and Full+
  817. $this->graphByDateAlt();
  818. break;
  819. case 'graphbypost':
  820. // ntm: stat logging: Counts Only
  821. echo '<p>'.__('<strong>Notice:</strong> This graph is only faultless if your podcast posts contain only one media file per post, each file has a unique name and if you change the media file name on a re-post (deleting a post and publishing the content in a new post)!', 'podpress').'</p>';
  822. if ($this->checkGD()) {
  823. $this->graphByPost();
  824. } else {
  825. $this->graphByPostAlt('With <a href="http://us2.php.net/manual/en/ref.image.php">gdlib-support</a> you\'ll have access to more detailed graphicals stats. Please ask your provider.');
  826. }
  827. break;
  828. case 'graphbypostalt':
  829. // ntm: stat logging: Counts Only
  830. echo '<p>'.__('<strong>Notice:</strong> This graph is only faultless if your podcast posts contain only one media file per post, each file has a unique name and if you change the media file name on a re-post (deleting a post and publishing the content in a new post)!', 'podpress').'</p>';
  831. $this->graphByPostAlt();
  832. break;
  833. case 'downloads_per_post' :
  834. // ntm: stat logging: Full and Full+
  835. $where = $this->wherestr_to_exclude_bots('pod');
  836. // get the number of all post with podPress podcasts
  837. $query_string = "SELECT COUNT(DISTINCT postID) as posts FROM ".$wpdb->prefix."podpress_stats ".$where;
  838. // get all post with podPress podcasts
  839. $query_string="SELECT DISTINCT(pod.postID), p.post_title FROM ".$wpdb->prefix."podpress_stats AS pod LEFT JOIN ".$wpdb->prefix."posts AS p ON pod.postID = p.ID ".$where." ORDER BY pod.postID DESC";
  840. $posts_with_podpressmedia = $wpdb->get_results($query_string);
  841. echo ' <div class="wrap">'."\n";
  842. echo ' <fieldset class="options">'."\n";
  843. echo ' <legend>'.__('Downloads Per Post', 'podpress').'</legend>'."\n";
  844. echo ' <form method="post">'."\n";
  845. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  846. wp_nonce_field('podPress_downloads_per_post_nonce');
  847. }
  848. echo ' <label>'.__('Select a post with a media file (attached with podPress):', 'podpress').'</label><br />'."\n";
  849. echo ' <select id="post_with_podpressmedia" name="post_with_podpressmedia" size="5">'."\n";
  850. foreach ($posts_with_podpressmedia as $post) {
  851. if ($post->postID == $_POST['post_with_podpressmedia']) {
  852. $selected = ' selected="selected"';
  853. } else {
  854. $selected = '';
  855. }
  856. echo ' <option value="'.$post->postID.'"'.$selected.'>'.$post->post_title.'</option>'."\n";
  857. $post_titles[$post->postID] = $post->post_title;
  858. }
  859. echo ' </select>'."\n";
  860. echo ' <p class="submit"> '."\n";
  861. echo ' <input type="submit" name="Submit" value="'.__('Show the stats for this post', 'podpress').' &raquo;" /><br />'."\n";
  862. echo ' </p> '."\n";
  863. echo ' <input type="hidden" name="podPress_submitted" value="downloadsperpost" />'."\n";
  864. echo ' </form>'."\n";
  865. echo ' </fieldset>'."\n";
  866. echo ' </div><!-- .wrap -->'."\n";
  867. // show the statistics of the media files of the submitted post
  868. if ( 'downloadsperpost' == $_POST['podPress_submitted'] ) {
  869. if ( function_exists('check_admin_referer') ) {
  870. check_admin_referer('podPress_downloads_per_post_nonce');
  871. }
  872. if (FALSE == empty($where)) {
  873. $where_postID = "AND pod.postID = '".$_POST['post_with_podpressmedia']."' ";
  874. } else {
  875. $where_postID = "WHERE pod.postID = '".$_POST['post_with_podpressmedia']."' ";
  876. }
  877. $query_string="SELECT pod.media, pod.method, COUNT(*) as downloads FROM ".$wpdb->prefix."podpress_stats as pod ".$where.$where_postID."GROUP BY pod.method, pod.media ORDER BY media DESC";
  878. $stat_data_sets = $wpdb->get_results($query_string);
  879. // prepare the query result for the output:
  880. // - find the maximal downloads value for each download method
  881. // - if a media file was not downloaded by one or more method then add this method and a int(0) to the media file
  882. $feed_max = 0;
  883. $web_max = 0;
  884. $play_max = 0;
  885. $total_max = 0;
  886. foreach ($stat_data_sets as $stat_data_set) {
  887. $feed = 0;
  888. $web = 0;
  889. $play = 0;
  890. switch ($stat_data_set->method) {
  891. case 'feed' :
  892. $feed = intval($stat_data_set->downloads);
  893. $feed_max = max($feed_max, $feed);
  894. break;
  895. case 'web' :
  896. $web = intval($stat_data_set->downloads);
  897. $web_max = max($web_max, $web);
  898. break;
  899. case 'play' :
  900. $play = intval($stat_data_set->downloads);
  901. $play_max = max($play_max, $play);
  902. break;
  903. }
  904. $stats[$stat_data_set->media]['feed'] += $feed;
  905. $stats[$stat_data_set->media]['web'] += $web;
  906. $stats[$stat_data_set->media]['play'] += $play;
  907. $stats[$stat_data_set->media]['total'] += ($feed + $web + $play);
  908. $total_max = max($total_max, $stats[$stat_data_set->media]['total']);
  909. }
  910. // sort the media files by their 'total' value
  911. uasort($stats, array(self, 'sort_downloads_per_media_desc'));
  912. echo ' <div class="wrap">'."\n";
  913. echo ' <fieldset class="options">'."\n";
  914. echo ' <legend>'.__('Post:', 'podpress')." ".$post_titles[$_POST['post_with_podpressmedia']]." - ".__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  915. echo ' <table class="the-list-x widefat">'."\n";
  916. echo ' <thead>';
  917. echo " <tr>\n";
  918. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  919. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  920. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  921. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
  922. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  923. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  924. echo ' </tr>'."\n";
  925. echo ' <tr>'."\n";
  926. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  927. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  928. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  929. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  930. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  931. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  932. echo ' </tr>'."\n";
  933. echo ' </thead>';
  934. echo ' <tbody>';
  935. $mark_highest = FALSE;
  936. $nr_stat_data_sets = count($stat_data_sets);
  937. if (0 < $nr_stat_data_sets) {
  938. if ( 1 < $nr_stat_data_sets ) {
  939. $mark_highest = TRUE;
  940. }
  941. $i = 0;
  942. foreach ( $stats as $media => $downloads_per_method ) {
  943. $i++;
  944. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  945. if (TRUE === $mark_highest) {
  946. $highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
  947. $highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
  948. $highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
  949. $highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
  950. }
  951. $perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  952. $perc_web = number_format(($downloads_per_method['web'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  953. $perc_play = number_format(($downloads_per_method['play'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  954. echo ' <tr'.$style.'>'."\n";
  955. echo ' <td>'.($start +$i).'.</td>'."\n";
  956. echo ' <td>'.podPress_strlimiter2(urldecode($media), 50, TRUE).'</td>'."\n";
  957. echo ' <td class="podpress_stats_numbers_abs'.$highest_feed.'">'.number_format($downloads_per_method['feed'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  958. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  959. echo ' <td class="podpress_stats_numbers_abs'.$highest_web.'" >'.number_format($downloads_per_method['web'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  960. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  961. echo ' <td class="podpress_stats_numbers_abs'.$highest_play.'">'.number_format($downloads_per_method['play'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  962. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  963. echo ' <td class="podpress_stats_numbers_total'.$highest_total.'">'.number_format($downloads_per_method['total'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  964. echo ' </tr>'."\n";
  965. }
  966. } else {
  967. if (FALSE == empty($where)) {
  968. echo '<td colspan="9">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  969. } else {
  970. echo '<td colspan="9">'.__('No downloads yet.','podpress')."</td>\n";
  971. }
  972. }
  973. echo ' </tbody>';
  974. echo ' <tfood>'."\n";
  975. echo ' <tr>'."\n";
  976. echo ' <th colspan="9">'."\n";
  977. echo ' </th>'."\n";
  978. echo ' </tr>'."\n";
  979. echo ' </tfood>'."\n";
  980. echo ' </table>'."\n";
  981. echo ' </fieldset>'."\n";
  982. echo ' </div><!-- .wrap -->'."\n";
  983. }
  984. break;
  985. case 'quickcounts':
  986. // ntm: stat logging: Counts Only
  987. // ntm: 'quickcounts' takes the data from the wp_podpress_statcounts table.
  988. $total= $wpdb->get_var('SELECT COUNT(postID) FROM '.$wpdb->prefix.'podpress_statcounts WHERE postID != 0;');
  989. if ($total > 0) {
  990. // Load highest values
  991. $sql = "SELECT 'blah' AS topic, MAX(total) AS total, MAX(feed) AS feed, MAX(web) AS web, MAX(play) AS play FROM ".$wpdb->prefix.'podpress_statcounts GROUP BY topic';
  992. $highest = $wpdb->get_results($sql);
  993. $highest = $highest[0];
  994. //~ $sql = 'SELECT sc.postID, sc.media, sc.total, sc.feed, sc.web, sc.play, p.post_title, p.post_date, UNIX_TIMESTAMP(p.post_date) AS pdate '
  995. //~ . 'FROM '.$wpdb->prefix.'podpress_statcounts AS sc, '.$wpdb->prefix.'posts AS p '
  996. //~ . 'WHERE (sc.postID = p.ID) ORDER BY p.post_date DESC LIMIT '.$start.', '.$limit.'';
  997. $sql = 'SELECT sc.media, sc.total, sc.feed, sc.web, sc.play '
  998. . 'FROM '.$wpdb->prefix.'podpress_statcounts AS sc '
  999. . 'ORDER BY sc.media DESC LIMIT '.$start.', '.$limit.'';
  1000. $stats = $wpdb->get_results($sql);
  1001. $cnt_stats = count($stats);
  1002. if ( isset($_POST['podPress_submitted']) AND 'sortquickcountsbypost' == $_POST['podPress_submitted'] ) {
  1003. foreach ($stats as $stat) {
  1004. $where_instr_ar[] = 'INSTR(pm.meta_value, "'.$stat->media.'")';
  1005. }
  1006. if ( $cnt_stats > 1 ) {
  1007. $where_instr = implode(' OR ', $where_instr_ar);
  1008. } else {
  1009. $where_instr = $where_instr_ar[0];
  1010. }
  1011. $where = 'pm.meta_key="podPressMedia" AND ('.$where_instr.')';
  1012. $sql = 'SELECT pm.post_id, pm.meta_key, pm.meta_value, p.post_title FROM '.$wpdb->prefix.'postmeta AS pm LEFT JOIN '.$wpdb->prefix.'posts AS p ON pm.post_id = p.ID WHERE '.$where.' ORDER BY pm.post_id DESC';
  1013. $postmeta_data = $wpdb->get_results($sql);
  1014. // get the highest post_id of posts which have a certain media file attached with podPress
  1015. // in other words get the last post which has a certain media file attached
  1016. foreach ($postmeta_data as $postmeta) {
  1017. $postmeta->post_id=intval($postmeta->post_id);
  1018. foreach ($stats as $stat) {
  1019. if (FALSE !== stristr($postmeta->meta_value, $stat->media)) {
  1020. //echo $postmeta->post_id.': '.$stat->media."\n";
  1021. $max_post_ids[$stat->media]['ID'] = max($max_post_ids[$stat->media]['ID'], $postmeta->post_id);
  1022. if ($max_post_ids[$stat->media]['ID'] == $postmeta->post_id) {
  1023. $max_post_ids[$stat->media]['title'] = $postmeta->post_title;
  1024. }
  1025. }
  1026. }
  1027. }
  1028. foreach ($max_post_ids as $media => $last_published_in_post) {
  1029. foreach ($stats as $stat) {
  1030. if ($stat->media == $media) {
  1031. $stat->postID = $last_published_in_post['ID'];
  1032. $stat->post_title = $last_published_in_post['title'];
  1033. $stats_new[] = $stat;
  1034. }
  1035. }
  1036. }
  1037. $stats=$stats_new;
  1038. unset($stats_new);
  1039. echo ' <div class="wrap">'."\n";
  1040. echo ' <fieldset class="options">'."\n";
  1041. echo ' <legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  1042. echo ' <p>'.__('sorted by the IDs of the posts in which the media files were last published (descending)', 'podpress').'</p>';
  1043. echo ' <table class="the-list-x widefat">'."\n";
  1044. echo ' <thead>';
  1045. echo " <tr>\n";
  1046. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  1047. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  1048. echo ' <th rowspan="2">'.__('last published in post', 'podpress')."</th>\n";
  1049. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  1050. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Download', 'podpress')."</th>\n";
  1051. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  1052. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  1053. echo ' </tr>'."\n";
  1054. echo ' <tr>'."\n";
  1055. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1056. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1057. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1058. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1059. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1060. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1061. echo ' </tr>'."\n";
  1062. echo ' </thead>';
  1063. echo ' <tbody>';
  1064. $date_format = get_option('date_format');
  1065. $time_format = get_option('time_format');
  1066. if ($cnt_stats > 0) {
  1067. $i = 0;
  1068. foreach ($stats AS $stat) {
  1069. $i++;
  1070. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  1071. $highest_feed = ($stat->feed == $highest->feed AND 0 < $highest->feed) ? ' podpress_stats_highest': '';
  1072. $highest_web = ($stat->web == $highest->web AND 0 < $highest->web) ? ' podpress_stats_highest': '';
  1073. $highest_play = ($stat->play == $highest->play AND 0 < $highest->play) ? ' podpress_stats_highest': '';
  1074. $highest_total = ($stat->total == $highest->total) ? ' podpress_stats_highest': '';
  1075. $perc_feed = number_format(($stat->feed * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1076. $perc_web = number_format(($stat->web * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1077. $perc_play = number_format(($stat->play * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1078. echo ' <tr'.$style.'>'."\n";
  1079. echo ' <td>'.($start +$i).'.</td>'."\n";
  1080. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 30, TRUE).'</td>'."\n";
  1081. if ( TRUE == version_compare($wp_version, '2.3', '<') ) {
  1082. echo ' <td><a href="'.get_option('siteurl').'/wp-admin/post.php?action=edit&amp;post='.$stat->postID.'" title="'.__('Edit this post','podpress').'">'.podPress_strlimiter2($stat->post_title, 30, TRUE).'</a></td>'."\n";
  1083. } else {
  1084. echo ' <td><a href="'.get_edit_post_link($stat->postID).'" title="'.__('Edit this post','podpress').'">'.podPress_strlimiter2($stat->post_title, 30, TRUE).'</a></td>'."\n";
  1085. }
  1086. echo ' <td class="podpress_stats_numbers_abs'.$highest_feed.'">'.number_format($stat->feed, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1087. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  1088. echo ' <td class="podpress_stats_numbers_abs'.$highest_web.'" >'.number_format($stat->web, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1089. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  1090. echo ' <td class="podpress_stats_numbers_abs'.$highest_play.'">'.number_format($stat->play, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1091. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  1092. echo ' <td class="podpress_stats_numbers_total'.$highest_total.'">'.number_format($stat->total, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1093. echo ' </tr>'."\n";
  1094. }
  1095. }
  1096. echo ' </tbody>'."\n";
  1097. echo ' <tfood>'."\n";
  1098. echo ' <tr>'."\n";
  1099. echo ' <th colspan="10">'."\n";
  1100. } else {
  1101. echo ' <div class="wrap">'."\n";
  1102. echo ' <fieldset class="options">'."\n";
  1103. //echo ' <legend>'.__('The counts', 'podpress').'</legend>'."\n";
  1104. echo ' <legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  1105. echo ' <p>'.__('sorted by the names of the media files (descending)', 'podpress').'</p>';
  1106. echo ' <table class="the-list-x widefat">'."\n";
  1107. echo ' <thead>';
  1108. echo " <tr>\n";
  1109. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  1110. //~ echo ' <th rowspan="2">'.__('Post', 'podpress')."</th>\n";
  1111. //~ echo ' <th rowspan="2">'.__('Publication Date', 'podpress')."</th>\n";
  1112. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  1113. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  1114. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Download', 'podpress')."</th>\n";
  1115. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  1116. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  1117. echo ' </tr>'."\n";
  1118. echo ' <tr>'."\n";
  1119. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1120. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1121. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1122. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1123. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1124. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1125. echo ' </tr>'."\n";
  1126. echo ' </thead>';
  1127. echo ' <tbody>';
  1128. $date_format = get_option('date_format');
  1129. $time_format = get_option('time_format');
  1130. if ($cnt_stats > 0) {
  1131. $i = 0;
  1132. foreach ($stats AS $stat) {
  1133. $i++;
  1134. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  1135. $highest_feed = ($stat->feed == $highest->feed AND 0 < $highest->feed) ? ' podpress_stats_highest': '';
  1136. $highest_web = ($stat->web == $highest->web AND 0 < $highest->web) ? ' podpress_stats_highest': '';
  1137. $highest_play = ($stat->play == $highest->play AND 0 < $highest->play) ? ' podpress_stats_highest': '';
  1138. $highest_total = ($stat->total == $highest->total) ? ' podpress_stats_highest': '';
  1139. $perc_feed = number_format(($stat->feed * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1140. $perc_web = number_format(($stat->web * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1141. $perc_play = number_format(($stat->play * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1142. echo ' <tr'.$style.'>'."\n";
  1143. echo ' <td>'.($start +$i).'.</td>'."\n";
  1144. //~ if ( TRUE == version_compare($wp_version, '2.3', '<') ) {
  1145. //~ echo ' <td><a href="'.get_option('siteurl').'/wp-admin/post.php?action=edit&amp;post='.$stat->postID.'" title="'.__('Edit this post','podpress').'">'.podPress_strlimiter2($stat->post_title, 30, TRUE).'</a></td>'."\n";
  1146. //~ } else {
  1147. //~ echo ' <td><a href="'.get_edit_post_link($stat->postID).'" title="'.__('Edit this post','podpress').'">'.podPress_strlimiter2($stat->post_title, 30, TRUE).'</a></td>'."\n";
  1148. //~ }
  1149. //~ echo ' <td>'.date($date_format.' - '.$time_format, $stat->pdate).'</td>'."\n";
  1150. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 30, TRUE).'</td>'."\n";
  1151. echo ' <td class="podpress_stats_numbers_abs'.$highest_feed.'">'.number_format($stat->feed, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1152. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  1153. echo ' <td class="podpress_stats_numbers_abs'.$highest_web.'" >'.number_format($stat->web, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1154. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  1155. echo ' <td class="podpress_stats_numbers_abs'.$highest_play.'">'.number_format($stat->play, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1156. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  1157. echo ' <td class="podpress_stats_numbers_total'.$highest_total.'">'.number_format($stat->total, 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])."</td>\n";
  1158. echo ' </tr>'."\n";
  1159. }
  1160. }
  1161. echo ' </tbody>'."\n";
  1162. echo ' <tfood>'."\n";
  1163. echo ' <tr>'."\n";
  1164. //~ echo ' <th colspan="11">'."\n";
  1165. echo ' <th colspan="9">'."\n";
  1166. }
  1167. // Show paging
  1168. if ($_GET['display'] != 'graphbydate' && $_GET['display'] != 'graphbypost') {
  1169. echo $this->paging2($start, $limit, $total, __('Nr.', 'podpress'));
  1170. }
  1171. echo ' </th>'."\n";
  1172. echo ' </tr>'."\n";
  1173. echo ' </tfood>'."\n";
  1174. echo ' </table>'."\n";
  1175. echo ' <form method="post">'."\n";
  1176. echo ' <p class="submit"> '."\n";
  1177. if ( isset($_POST['podPress_submitted']) AND 'sortquickcountsbypost' == $_POST['podPress_submitted'] ) {
  1178. echo ' <input type="submit" name="Submit" value="'.__('sort the media files by their names', 'podpress').' &raquo;" /><br />'."\n";
  1179. } else {
  1180. echo ' <input type="submit" name="Submit" value="'.__('sort the media files by the IDs of the posts in which they were last published', 'podpress').' &raquo;" /><br />'."\n";
  1181. echo ' <input type="hidden" name="podPress_submitted" value="sortquickcountsbypost" />'."\n";
  1182. }
  1183. echo ' </p> '."\n";
  1184. echo ' </form>'."\n";
  1185. echo ' </fieldset>'."\n";
  1186. echo ' </div>';
  1187. } else {
  1188. echo '<p>'.__('We\'re sorry. At the moment we don\'t have enough data collected to display the graph.', 'podpress')."</p>\n";
  1189. }
  1190. break;
  1191. default:
  1192. return;
  1193. }
  1194. echo '<div style="clear: both;"></div>'."\n";
  1195. echo '</div>';
  1196. }
  1197. #############################################
  1198. #############################################
  1199. /**
  1200. * sort_downloads_per_media_asc - is a callback function to sort arrays by their 'total' value ascending
  1201. * for more info: http://www.php.net/manual/en/function.uasort.php
  1202. *
  1203. * @package podPress
  1204. * @since 8.8.5 beta 3
  1205. *
  1206. * @param int $a
  1207. * @param int $b
  1208. *
  1209. * @return int 0 => equal, -1 => $a < $b, 1 => $a > $b
  1210. */
  1211. function sort_downloads_per_media_asc($a, $b) {
  1212. if ($a['total'] == $b['total']) {
  1213. return 0;
  1214. }
  1215. return ($a['total'] < $b['total']) ? -1 : 1;
  1216. }
  1217. #############################################
  1218. #############################################
  1219. /**
  1220. * sort_downloads_per_media_desc - is a callback function to sort arrays by their 'total' value descending
  1221. * for more info: http://www.php.net/manual/en/function.uasort.php
  1222. *
  1223. * @package podPress
  1224. * @since 8.8.5 beta 3
  1225. *
  1226. * @param int $a
  1227. * @param int $b
  1228. *
  1229. * @return int 0 => equal, -1 => $a < $b, 1 => $a > $b
  1230. */
  1231. function sort_downloads_per_media_desc($a, $b) {
  1232. if ($a['total'] == $b['total']) {
  1233. return 0;
  1234. }
  1235. return ($a['total'] > $b['total']) ? -1 : 1;
  1236. }
  1237. #############################################
  1238. #############################################
  1239. /**
  1240. * Check GD-Library-Support
  1241. *
  1242. * @return unknown
  1243. */
  1244. function checkGD() {
  1245. if (!function_exists('gd_info')) {
  1246. /* php > 4.3 */
  1247. $info = gd_info();
  1248. if (isset($info) AND ($info['JPG Support'] == 1) AND ($info['FreeType Support'] == 1)) {
  1249. return true;
  1250. }
  1251. } else {
  1252. /* php < 4.3 */
  1253. ob_start();
  1254. phpinfo(8);
  1255. $info = ob_get_contents();
  1256. ob_end_clean();
  1257. $info = stristr($info, 'gd version');
  1258. preg_match('/\d/', $info, $match);
  1259. $gd_ver = $match[0];
  1260. if ($gd_ver > 0) {
  1261. return true;
  1262. }
  1263. }
  1264. return false;
  1265. }
  1266. #############################################
  1267. #############################################
  1268. function checkFontFile() {
  1269. clearstatcache();
  1270. /* check font */
  1271. $file = 'share-regular.ttf';
  1272. $fontface = ABSPATH.PLUGINDIR.'/podpress/optional_files/'.$file;
  1273. if (!file_exists($fontface)) {
  1274. $fontface = '../optional_files/'.$file;
  1275. }
  1276. if (!is_readable($fontface)) {
  1277. echo '<p>'.__('Could not include font-file. Please reinstall podPress.', 'podpress')."</p>\n";
  1278. return false;
  1279. }
  1280. $this->fontface = $fontface;
  1281. return true;
  1282. }
  1283. #############################################
  1284. #############################################
  1285. function graphByDate() {
  1286. // ntm: stat logging: Full and Full+
  1287. if ($this->checkWritableTempFileDir() && $this->checkFontFile()) {
  1288. $chronometry1 = getmicrotime();
  1289. $start = (isset($_GET['start'])) ? $this->podSafeDigit($_GET['start']): 0;
  1290. $image_width = 1800;
  1291. $image_height = 470;
  1292. $col_width = 20;
  1293. $filename = 'graph-by-date.jpg';
  1294. $file = $this->tempFileSystemPath.'/'.$filename;
  1295. $sidemargin = 20;
  1296. $baseline = ($image_height - 90);
  1297. $topmargin = 60;
  1298. $maxheight = ($baseline - $topmargin);
  1299. $weeks = 15;
  1300. $timelimit = (time() - (($weeks * 7) * 86400));
  1301. $min_downloaddays = 4;
  1302. ini_set('memory_limit', '120M');
  1303. ini_set('max_execution_time', '60');
  1304. $start_memory = memory_get_usage();
  1305. $where = $this->wherestr_to_exclude_bots('', 'AND');
  1306. /* get the data in time range ($timelimit) */
  1307. $query = 'SELECT dt AS timestamp, DAYOFWEEK(FROM_UNIXTIME(dt)) AS weekday, method, '
  1308. . 'DATE_FORMAT(FROM_UNIXTIME(dt), "%Y-%m-%d") AS day '
  1309. . 'FROM '.$this->wpdb->prefix."podpress_stats WHERE dt >= '".$timelimit."' ".$where
  1310. . 'ORDER BY dt ASC;';
  1311. $data = $this->wpdb->get_results($query);
  1312. /* create array with grouped stats */
  1313. $stats = array();
  1314. $stats_total = array();
  1315. foreach ($data AS $idata) {
  1316. $stats[$idata->day][$idata->method]++;
  1317. $stats[$idata->day]['total']++;
  1318. $stats_total[$idata->method]++;
  1319. $stats_total['total']++;
  1320. }
  1321. /* get min an max values */
  1322. $value_min = 0;
  1323. $value_max = 0;
  1324. $i = 0;
  1325. $cnt_days = count($stats);
  1326. foreach ($stats AS $day => $idata) {
  1327. /* set min and max values */
  1328. if ($value_min == 0) {
  1329. $value_min = $idata['total'];
  1330. } elseif ($idata['total'] < $value_min) {
  1331. $value_min = $idata['total'];
  1332. } elseif ($idata['total'] > $value_max) {
  1333. $value_max = $idata['total'];
  1334. }
  1335. /* set first and last day */
  1336. if ($i == 0) {
  1337. $first_day = strtotime($day);
  1338. } elseif ($i == ($cnt_days - 1)) {
  1339. $last_day = strtotime($day);
  1340. }
  1341. $i++;
  1342. }
  1343. /* Do we have enough data? */
  1344. if (($value_max > 0) && ($cnt_days >= $min_downloaddays)) {
  1345. $h_cscale = ($maxheight / $value_max);
  1346. $h_vscale = ($maxheight / $value_min / 4);
  1347. $pos_x = ($sidemargin + 35);
  1348. $points = array( 'total' => array(0 => $pos_x, 1 => $baseline) );
  1349. foreach ($stats AS $day => $idata) {
  1350. $points['total'][] = $pos_x;
  1351. $points['total'][] = ($baseline - ($idata['total'] * $h_cscale));
  1352. $points['feed'][] = ($baseline - ($idata['feed'] * $h_cscale));
  1353. $points['web'][] = ($baseline - ($idata['web'] * $h_cscale));
  1354. $points['play'][] = ($baseline - ($idata['play'] * $h_cscale));
  1355. $pos_x = ($pos_x + $col_width);
  1356. }
  1357. $points['total'][] = ($pos_x - $col_width);
  1358. $points['total'][] = $baseline;
  1359. /* create image */
  1360. $chronometry2 = getmicrotime();
  1361. $image = imagecreatetruecolor($image_width, $image_height);
  1362. if (function_exists('imageantialias')) {
  1363. imageantialias($image, 1);
  1364. }
  1365. /* set colors */
  1366. $colors = array(
  1367. 'background' => imagecolorallocate($image, 51, 51, 51),
  1368. 'line' => imagecolorallocate($image, 79, 79, 79),
  1369. 'total' => imagecolorallocate($image, 79, 79, 79),
  1370. 'feed' => imagecolorallocate($image, 255, 0, 0),
  1371. 'web' => imagecolorallocate($image, 12, 223, 0),
  1372. 'play' => imagecolorallocate($image, 223, 204, 0),
  1373. 'text' => imagecolorallocate($image, 255, 255, 255),
  1374. 'copytext' => imagecolorallocate($image, 79, 79, 79),
  1375. 'days_first' => imagecolorallocate($image, 143, 143, 143),
  1376. 'days_other' => imagecolorallocate($image, 95, 95, 95),
  1377. /* gray-scales: 175 159 143 127 111 95 79 63 */
  1378. );
  1379. imagefill($image, 0, 0, $colors['background']);
  1380. /* create the legend */
  1381. imagettftext($image, 14, 0, $sidemargin, 25, $colors['text'], $this->fontface, get_option('blogname'));
  1382. imagettftext($image, 8, 0, $sidemargin, 42, $colors['text'], $this->fontface, sprintf(__('last %1$s weeks', 'podpress'), $weeks).' &#187; '.strftime('%d.%m.%Y', $first_day).' - '.strftime('%d.%m.%Y', $last_day));
  1383. /* Total stats */
  1384. $text_total = number_format($stats_total['total'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1385. $text_feed = number_format($stats_total['feed'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' ('.number_format(($stats_total['feed'] * 100 / $stats_total['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).'%)';
  1386. $text_web = number_format($stats_total['web'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' ('.number_format(($stats_total['web'] * 100 / $stats_total['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).'%)';
  1387. $text_play = number_format($stats_total['play'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' ('.number_format(($stats_total['play'] * 100 / $stats_total['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).'%)';
  1388. $text_total = html_entity_decode(__('Total stats in time range', 'podpress')).': '.$text_total.' / '.__('Feed', 'podpress').': '.$text_feed.' / '.__('Download', 'podpress').': '.$text_web.' / '.__('Play', 'podpress').': '.$text_play.' ';
  1389. imagettftext($image, 8, 0, $sidemargin, ($image_height - 15), $colors['text'], $this->fontface, $text_total);
  1390. $pos_y = ($image_height - 32);
  1391. imagefilledrectangle($image, ($sidemargin + 0), ($pos_y - 10), ($sidemargin + 10), ($pos_y - 0), $colors['total']);
  1392. imagettftext($image, 8, 0, ($sidemargin + 15), $pos_y, $colors['text'], $this->fontface, __('Total', 'podpress'));
  1393. imageline($image, ($sidemargin + 50), ($pos_y - 4), ($sidemargin + 60), ($pos_y - 4), $colors['feed']);
  1394. imagettftext($image, 8, 0, ($sidemargin + 65), $pos_y, $colors['text'], $this->fontface, __('Feed', 'podpress'));
  1395. imageline($image, ($sidemargin + 100), ($pos_y - 4), ($sidemargin + 110), ($pos_y - 4), $colors['web']);
  1396. imagettftext($image, 8, 0, ($sidemargin + 115), $pos_y, $colors['text'], $this->fontface, __('Download', 'podpress'));
  1397. imageline($image, ($sidemargin + 175), ($pos_y - 4), ($sidemargin + 185), ($pos_y - 4), $colors['play']);
  1398. imagettftext($image, 8, 0, ($sidemargin + 190), $pos_y, $colors['text'], $this->fontface, __('Play', 'podpress'));
  1399. imagettftext($image, 23, 0, ($image_width - 128), 30, $colors['copytext'], $this->fontface, 'podPress');
  1400. imagettftext($image, 8, 0, ($image_width - 115), 43, $colors['copytext'], $this->fontface, __('Plugin for WordPress', 'podpress'));
  1401. imagettftext($image, 6, 90, ($image_width - 15), ($image_height - 10), $colors['copytext'], $this->fontface, strftime($this->local_settings['creation_date'], time()).' ('.PODPRESS_VERSION.')');
  1402. /* draw total-stats */
  1403. $cnt_total = (count($points['total']) / 2);
  1404. imagefilledpolygon($image, $points['total'], $cnt_total, $colors['total']);
  1405. /* draw background-lines and scale-text */
  1406. $step = 0;
  1407. $h = (($baseline - $topmargin) / 10);
  1408. while ($step <= 10) {
  1409. $pos_y = ($topmargin + ($h * $step));
  1410. imageline($image, 0, ($topmargin + ($h * $step)), $image_width, ($topmargin + ($h * $step)), $colors['line']);
  1411. imagettftext($image, 8, 0, ($sidemargin), ($pos_y + 13), $colors['line'], $this->fontface, number_format((($baseline - $pos_y) / $h_cscale), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]));
  1412. $step++;
  1413. }
  1414. $pos_x = ($sidemargin + 35);
  1415. foreach ($stats AS $day => $idata) {
  1416. /* Web einzeichnen */
  1417. $weekday = date('w', strtotime($day));
  1418. $col_total_height = ($idata['total'] * $h_cscale);
  1419. if ($weekday == 1) {
  1420. $pos_y_start = ($baseline + 27);
  1421. imagettftext($image, 8, 0, ($pos_x + 3), ($baseline + 13), $colors['text'], $this->fontface, strftime($this->local_settings['short_date'], strtotime($day)));
  1422. $color = $colors['days_first'];
  1423. } else {
  1424. $pos_y_start = $baseline;
  1425. $color = $colors['days_other'];
  1426. }
  1427. imageline($image, $pos_x, $pos_y_start, $pos_x, ($baseline - $col_total_height), $color);
  1428. $pos_x = ($pos_x + $col_width);
  1429. }
  1430. /* Linien zeichen */
  1431. $topics = array('feed', 'web', 'play');
  1432. foreach ($topics AS $topic) {
  1433. $cnt_points = count($points[$topic]);
  1434. $pos_x = ($sidemargin + 35);
  1435. for ($i = 0; $i < ($cnt_points - 1); $i++) {
  1436. imageline($image, $pos_x, $points[$topic][$i], ($pos_x + $col_width), $points[$topic][$i + 1], $colors[$topic]);
  1437. $pos_x = ($pos_x + $col_width);
  1438. }
  1439. }
  1440. imagejpeg($image, $file, 100);
  1441. $chronometry_end = getmicrotime();
  1442. $chronometry1 = ($chronometry_end - $chronometry1);
  1443. $chronometry2 = ($chronometry_end - $chronometry2);
  1444. imagedestroy($image);
  1445. $end_memory = memory_get_usage();
  1446. $memory_used = podPress_bytes($end_memory-$start_memory);
  1447. /* Output */
  1448. echo '<div id="podPress_graph" style="width: '.$image_width.'px;">'."\n";
  1449. echo ' <p><img src="'.$this->tempFileURLPath.'/'.$filename.'" width="'.$image_width.'" height="'.$image_height.'" alt="podPress-Statistics" /></p>'."\n";
  1450. echo "</div>\n";
  1451. echo '<p>'.__('Time to generate the graph', 'podpress').': '.number_format($chronometry1, 3, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' '.__('seconds', 'podpress').' ('.__('image', 'podpress').': '.number_format($chronometry2, 3, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' '.__('seconds', 'podpress').").\n";
  1452. echo '<br/>'.__('Memory to generate the graph', 'podpress').': '.$memory_used.".</p>\n";
  1453. } else {
  1454. echo '<p>'.sprintf(__('We\'re sorry. At the moment we don\'t have enough data collected to display the graph. (Downloads on %1$s different days are necessary)', 'podpress'), $min_downloaddays)."</p>\n";
  1455. }
  1456. }
  1457. }
  1458. #############################################
  1459. #############################################
  1460. function graphByDateAlt($msg = '') {
  1461. // ntm: stat logging: Full and Full+
  1462. GLOBAL $wpdb;
  1463. $where = $this->wherestr_to_exclude_bots();
  1464. $sql = 'SELECT DATE_FORMAT(FROM_UNIXTIME(dt), "%a, %Y-%m-%d") AS title, DAYOFWEEK(FROM_UNIXTIME(dt)) AS weekday, COUNT(id) AS value '
  1465. . 'FROM '.$wpdb->prefix.'podpress_stats '.$where.'GROUP BY title ORDER BY dt DESC LIMIT 0, 100;';
  1466. $data = $wpdb->get_results($sql);
  1467. $data = array_reverse($data);
  1468. $splitter = array('weekday', '2');
  1469. echo ' <div class="wrap">'."\n";
  1470. echo ' <fieldset class="options">'."\n";
  1471. echo ' <legend>'.__('Downloads by date', 'podpress').' ('.__('Last 100 days', 'podpress').')</legend>'."\n";
  1472. echo $this->podGraph($data, $splitter);
  1473. if($msg != '') {
  1474. echo ' <p>'.$msg."</p>\n";
  1475. }
  1476. echo ' </fieldset>'."\n";
  1477. echo ' </div>';
  1478. }
  1479. #############################################
  1480. #############################################
  1481. function graphByPost() {
  1482. // ntm: stat logging: Counts Only
  1483. if ($this->checkWritableTempFileDir() && $this->checkFontFile()) {
  1484. $chronometry1 = getmicrotime();
  1485. $start = (isset($_GET['start'])) ? $this->podSafeDigit($_GET['start']): 0;
  1486. $limit = 20;
  1487. $image_width = 1200;
  1488. $image_height = 470;
  1489. $col_width = 25;
  1490. $col_space = 15;
  1491. $filename = 'graph-by-post.jpg';
  1492. $file = $this->tempFileSystemPath.'/'.$filename;
  1493. $sidemargin = 20;
  1494. $baseline = ($image_height - 90);
  1495. $topmargin = 60;
  1496. $maxheight = ($baseline - $topmargin);
  1497. $timelimit = (time() - ((5 * 7) * 86400));
  1498. ini_set('memory_limit', '120M');
  1499. ini_set('max_execution_time', '60');
  1500. $start_memory = memory_get_usage();
  1501. /* get data */
  1502. $total = $this->wpdb->get_var('SELECT COUNT(postID) FROM '.$this->wpdb->prefix."podpress_statcounts WHERE postID != 0;");
  1503. $query = 'SELECT post_title AS title, total, feed, web, play, UNIX_TIMESTAMP(post_date) AS post_date '
  1504. . 'FROM '.$this->wpdb->prefix.'podpress_statcounts, '.$this->wpdb->prefix.'posts '
  1505. . 'WHERE '.$this->wpdb->prefix.'posts.ID = '.$this->wpdb->prefix.'podpress_statcounts.postID '
  1506. . 'AND postID !=0 GROUP BY postID ORDER BY post_date DESC LIMIT '.$start.', '.$limit.';';
  1507. $data = $this->wpdb->get_results($query);
  1508. $cnt_data = count($data);
  1509. $first_post = $data[($cnt_data - 1)]->post_date;
  1510. $last_post = $data[0]->post_date;
  1511. $stats = array();
  1512. foreach ($data AS $idata) {
  1513. $stats[$idata->day][$idata->method]++;
  1514. $stats[$idata->day]['total']++;
  1515. $stats_total[$idata->method]++;
  1516. $stats_total['total']++;
  1517. }
  1518. /* get min an max values */
  1519. $value_min = 0;
  1520. $value_max = 0;
  1521. $stats_total = array();
  1522. foreach ($data AS $idata) {
  1523. if ($value_min == 0) {
  1524. $value_min = $idata->total;
  1525. } elseif ($idata->total < $value_min) {
  1526. $value_min = $idata->total;
  1527. }
  1528. if ($idata->total > $value_max) {
  1529. $value_max = $idata->total;
  1530. }
  1531. $stats_total['feed'] = ($stats_total['feed'] + $idata->feed);
  1532. $stats_total['web'] = ($stats_total['web'] + $idata->web);
  1533. $stats_total['play'] = ($stats_total['play'] + $idata->play);
  1534. $stats_total['total'] = ($stats_total['total'] + $idata->total);
  1535. }
  1536. /* Do we have enough data? */
  1537. if (intval($value_max) > 0) {
  1538. $h_cscale = ($maxheight / $value_max);
  1539. $h_vscale = ($maxheight / $value_min / 4);
  1540. $w_scale = intval($image_width - (2 * $sidemargin) + intval(($image_width - (2 * $sidemargin)) / ($limit) / 4)) / ($limit);
  1541. /* create image */
  1542. $chronometry2 = getmicrotime();
  1543. $image = imagecreatetruecolor($image_width, $image_height);
  1544. if (function_exists('imageantialias')) {
  1545. imageantialias($image, 1);
  1546. }
  1547. $colors = array(
  1548. 'background' => imagecolorallocate($image, 51, 51, 51),
  1549. 'line' => imagecolorallocate($image, 79, 79, 79),
  1550. 'text' => imagecolorallocate($image, 255, 255, 255),
  1551. 'copytext' => imagecolorallocate($image, 79, 79, 79),
  1552. 'total' => imagecolorallocate($image, 0, 0, 0),
  1553. 'feed' => imagecolorallocate($image, 143, 53, 53),
  1554. 'web' => imagecolorallocate($image, 71, 143, 88),
  1555. 'play' => imagecolorallocate($image, 142, 143, 71),
  1556. );
  1557. imagefill($image, 0, 0, $colors['background']);
  1558. /* draw background-lines and scale-text */
  1559. $step = 0;
  1560. $h = (($baseline - $topmargin) / 10);
  1561. while ($step <= 10) {
  1562. $pos_y = ($topmargin + ($h * $step));
  1563. imageline($image, 0, ($topmargin + ($h * $step)), $image_width, ($topmargin + ($h * $step)), $colors['line']);
  1564. imagettftext($image, 8, 0, ($sidemargin), ($pos_y + 13), $colors['line'], $this->fontface, number_format((($baseline - $pos_y) / $h_cscale), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]));
  1565. $step++;
  1566. }
  1567. /* create the legend */
  1568. imagettftext($image, 14, 0, $sidemargin, 25, $colors['text'], $this->fontface, get_option('blogname'));
  1569. imagettftext($image, 8, 0, $sidemargin, 42, $colors['text'], $this->fontface, __('Posts', 'podpress').' &#187; '.strftime('%d.%m.%Y', $first_post).' - '.strftime('%d.%m.%Y', $last_post));
  1570. $text_total = number_format($stats_total['total'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1571. $text_feed = number_format($stats_total['feed'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' ('.number_format(($stats_total['feed'] * 100 / $stats_total['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).'%)';
  1572. $text_web = number_format($stats_total['web'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' ('.number_format(($stats_total['web'] * 100 / $stats_total['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).'%)';
  1573. $text_play = number_format($stats_total['play'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' ('.number_format(($stats_total['play'] * 100 / $stats_total['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).'%)';
  1574. $text_total = __('Total stats from displayed posts', 'podpress').': '.$text_total.' / '.__('Feed', 'podpress').': '.$text_feed.' / '.__('Download', 'podpress').': '.$text_web.' / '.__('Play', 'podpress').': '.$text_play.' ';
  1575. imagettftext($image, 8, 0, $sidemargin, ($image_height - 15), $colors['text'], $this->fontface, $text_total);
  1576. $pos_y = ($image_height - 32);
  1577. imagefilledrectangle($image, ($sidemargin + 0), ($pos_y - 10), ($sidemargin + 10), $pos_y, $colors['feed']);
  1578. imagettftext($image, 8, 0, ($sidemargin + 15), $pos_y, $colors['text'], $this->fontface, __('Feed', 'podpress'));
  1579. imagefilledrectangle($image, ($sidemargin + 50), ($pos_y - 10), ($sidemargin + 60), $pos_y, $colors['web']);
  1580. imagettftext($image, 8, 0, ($sidemargin + 65), $pos_y, $colors['text'], $this->fontface, __('Download', 'podpress'));
  1581. imagefilledrectangle($image, ($sidemargin + 125), ($pos_y - 10), ($sidemargin + 135), $pos_y, $colors['play']);
  1582. imagettftext($image, 8, 0, ($sidemargin + 140), $pos_y, $colors['text'], $this->fontface, __('Play', 'podpress'));
  1583. imagettftext($image, 23, 0, ($image_width - 128), 30, $colors['copytext'], $this->fontface, 'podPress');
  1584. imagettftext($image, 8, 0, ($image_width - 115), 43, $colors['copytext'], $this->fontface, __('Plugin for WordPress', 'podpress'));
  1585. imagettftext($image, 6, 90, ($image_width - 15), ($image_height - 10), $colors['copytext'], $this->fontface, strftime($this->local_settings['creation_date'], time()).' ('.PODPRESS_VERSION.')');
  1586. $pos_x = ($image_width - $sidemargin - 15);
  1587. /* draw the posts */
  1588. foreach ($data AS $idata) {
  1589. /* Total stats */
  1590. $col_total_height = ($idata->total * $h_cscale);
  1591. imageline($image, ($pos_x - 2), $baseline, ($pos_x - 2), ($baseline - $col_total_height), $colors['total']);
  1592. imagettftext($image, 8, 0, ($pos_x - $col_width - 3), ($baseline - 3 - ($idata->total * $h_cscale)), $colors['text'], $this->fontface, $idata->total);
  1593. /* Feeds */
  1594. $perc_feed = number_format(($idata->feed * 100 / $idata->total), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1595. $col_feed_height = ($idata->feed * $h_cscale);
  1596. if ($col_feed_height < 0) {
  1597. imagefilledrectangle($image, ($pos_x - $col_width - 3), $baseline, ($pos_x - 3), ($baseline - $col_feed_height), $colors['feed']);
  1598. } else {
  1599. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_feed_height), ($pos_x - 3), $baseline, $colors['feed']);
  1600. }
  1601. if ($col_feed_height > 11) {
  1602. imagettftext($image, 8, 0, ($pos_x - $col_width - 2), (($baseline - ($idata->feed * $h_cscale)) + 11), $colors['text'], $this->fontface, $perc_feed.'%');
  1603. }
  1604. /* Web */
  1605. $perc_web = number_format(($idata->web * 100 / $idata->total), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1606. $col_web_height = ($idata->web * $h_cscale);
  1607. if ($col_web_height < 0) {
  1608. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_feed_height), ($pos_x - 3), ($baseline - $col_web_height - $col_feed_height), $colors['web']);
  1609. } else {
  1610. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_web_height - $col_feed_height), ($pos_x - 3), ($baseline - $col_feed_height), $colors['web']);
  1611. }
  1612. if ($col_web_height > 11) {
  1613. imagettftext($image, 8, 0, ($pos_x - $col_width - 2), (($baseline - $col_web_height - $col_feed_height) + 11), $colors['text'], $this->fontface, $perc_web.'%');
  1614. }
  1615. /* Play */
  1616. $perc_play = number_format(($idata->play * 100 / $idata->total), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1617. $col_play_height = ($idata->play * $h_cscale);
  1618. if ($col_play_height < 0) {
  1619. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_feed_height - $col_web_height), ($pos_x - 3), ($baseline - $col_play_height - $col_web_height - $col_feed_height), $colors['play']);
  1620. } else {
  1621. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_play_height - $col_web_height - $col_feed_height), ($pos_x - 3), ($baseline - $col_feed_height - $col_web_height), $colors['play']);
  1622. }
  1623. if ($col_play_height > 11) {
  1624. imagettftext($image, 8, 0, ($pos_x - $col_width - 2), (($baseline - $col_play_height - $col_web_height - $col_feed_height) + 11), $colors['text'], $this->fontface, $perc_play.'%');
  1625. }
  1626. /* Set Date and Title */
  1627. $title = (strlen($idata->title) > 70) ? substr($idata->title, 0, 70).'...' : $idata->title;
  1628. imagettftext($image, 8, 90, ($pos_x + 10), $baseline, $colors['text'], $this->fontface, $title);
  1629. imagettftext($image, 8, 0, ($pos_x - $col_width - 3), ($baseline + 14), $colors['text'], $this->fontface, strftime($this->local_settings['short_date'], $idata->post_date));
  1630. $pos_x = ($pos_x - $col_width - $col_space - 15);
  1631. }
  1632. imagejpeg($image, $file, 100);
  1633. $chronometry_end = getmicrotime();
  1634. $chronometry1 = ($chronometry_end - $chronometry1);
  1635. $chronometry2 = ($chronometry_end - $chronometry2);
  1636. imagedestroy($image);
  1637. $end_memory = memory_get_usage();
  1638. $memory_used = podPress_bytes($end_memory-$start_memory);
  1639. echo '<div id="podPress_graph" style="width: '.$image_width.'px;">'."\n";
  1640. echo ' <p style="padding-top: 0;"><img src="'.$this->tempFileURLPath.'/'.$filename.'" width="'.$image_width.'" height="'.$image_height.'" alt="podPress-Statistics" /></p>'."\n";
  1641. echo $this->paging($start, $limit, $total, 'Posts');
  1642. echo ' <div class="clear"></div>'."\n";
  1643. echo "</div>\n";
  1644. echo '<p>'.__('Time to generate the graph', 'podpress').': '.number_format($chronometry1, 3, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]).' seconds (image: '.number_format($chronometry2, 3, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1])." seconds).\n";
  1645. echo '<br/>'.__('Memory to generate the graph', 'podpress').': '.$memory_used.".</p>\n";
  1646. } else {
  1647. echo '<p>'.__('We\'re sorry. At the moment we don\'t have enough data collected to display the graph.', 'podpress')."</p>\n";
  1648. }
  1649. }
  1650. }
  1651. #############################################
  1652. #############################################
  1653. function graphByPostAlt($msg = '') {
  1654. // ntm: stat logging: Counts Only
  1655. global $wpdb;
  1656. $sql = 'SELECT post_title AS title, SUM(total) AS value '
  1657. . 'FROM '.$wpdb->prefix.'podpress_statcounts, '.$wpdb->prefix.'posts '
  1658. . 'WHERE '.$wpdb->prefix.'posts.ID = '.$wpdb->prefix.'podpress_statcounts.postID '
  1659. . 'AND postID !=0 GROUP BY postID ORDER BY post_date DESC LIMIT 0, 100;';
  1660. $data = $wpdb->get_results($sql);
  1661. $data = array_reverse($data);
  1662. echo ' <div class="wrap">'."\n";
  1663. echo ' <fieldset class="options">'."\n";
  1664. echo ' <legend>'.__('Downloads by Post', 'podpress').' ('.__('Last 100 posts', 'podpress').')</legend>'."\n";
  1665. echo $this->podGraph($data);
  1666. echo ' </fieldset>'."\n";
  1667. if ($msg != '') {
  1668. echo ' <p>'.$msg."</p>\n";
  1669. }
  1670. echo ' </div>';
  1671. }
  1672. #############################################
  1673. #############################################
  1674. }
  1675. ?>