PageRenderTime 63ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://github.com/bill742/verbalbrew
PHP | 1961 lines | 1585 code | 171 blank | 205 comment | 314 complexity | a5136e2db41d32c39249e679f9bee3d5 MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-3.0, AGPL-1.0, LGPL-2.1, GPL-2.0
  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 limiting 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 ( isset($_POST['podPress_submitted']) AND '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. if ( isset($_POST['podpress_maxrowsperpage']) AND FALSE == empty($_POST['podpress_maxrowsperpage']) AND $limit <= intval($_POST['podpress_maxrowsperpage']) ) {
  322. $this->settings['maxrowsperpage_'.$show_this_page] = intval($_POST['podpress_maxrowsperpage']);
  323. }
  324. if ( isset($this->settings['maxrowsperpage_'.$show_this_page]) AND is_int($this->settings['maxrowsperpage_'.$show_this_page]) AND $limit <= $this->settings['maxrowsperpage_'.$show_this_page] ) {
  325. $limit = $this->settings['maxrowsperpage_'.$show_this_page];
  326. }
  327. $result = podPress_update_option('podPress_config', $this->settings);
  328. $updated=update_option('podpress_botdb', $botdb);
  329. if (isset($updated) AND TRUE === $updated) {
  330. echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
  331. }
  332. }
  333. echo ' <div class="wrap">'."\n";
  334. echo ' <fieldset class="options">'."\n";
  335. echo ' <legend>'.__('The list of IP addresses and names of bots', 'podpress').'</legend>'."\n";
  336. echo ' <form method="post">'."\n";
  337. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  338. wp_nonce_field('podPress_botdb_nonce');
  339. }
  340. echo ' <table class="the-list-x widefat">'."\n";
  341. echo ' <thead>'."\n";
  342. 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";
  343. echo ' </thead>'."\n";
  344. echo ' <tbody>'."\n";
  345. $nobots = FALSE;
  346. if (is_array($botdb) and (is_array($botdb['fullbotnames']) OR is_array($botdb['IP'])) ) {
  347. $botnames_len = count($botdb['fullbotnames']);
  348. $IPs_len = count($botdb['IP']);
  349. $rows_total = max($botnames_len, $IPs_len);
  350. if ( $rows_total > ($start+$limit) ) {
  351. $high = $start+$limit;
  352. } else {
  353. $high = $rows_total;
  354. }
  355. $low = ($start+1);
  356. for ($i=$low; $i <= $high; $i++) {
  357. $style = ($i % 2) ? '' : ' class="alternate"';
  358. echo ' <tr'.$style.'>'."\n";
  359. echo ' <td>'.($start +$i).'.</td>'."\n";
  360. if ($i <= ($IPs_len-$start)) {
  361. $col_ip = ' <td>'.stripslashes($botdb['IP'][($i-1)]).'</td>'."\n";
  362. $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";
  363. } else {
  364. $col_ip = $col_ip_chb = ' <td></td>'."\n";
  365. }
  366. if ($i <= ($botnames_len-$start)) {
  367. $col_botname = ' <td>'.stripslashes($botdb['fullbotnames'][($i-1)]).'</td>'."\n";
  368. $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";
  369. } else {
  370. $col_botname = $col_botname_chb = ' <td></td>'."\n";
  371. }
  372. echo $col_ip.$col_botname.$col_ip_chb.$col_botname_chb;
  373. echo ' </tr>'."\n";
  374. }
  375. if ( 0 == $botnames_len AND 0 == $IPs_len ) {
  376. $nobots = TRUE;
  377. }
  378. } else {
  379. $nobots = TRUE;
  380. }
  381. if (TRUE == $nobots) {
  382. echo ' <td colspan="5">'.__('Currently are no IP addresses or user agents marked as bots.', 'podpress').'</td>'."\n";
  383. }
  384. echo ' </tbody>'."\n";
  385. echo ' <tfoot>'."\n";
  386. echo ' <tr>'."\n";
  387. echo ' <th colspan="5">'."\n";
  388. // Show paging
  389. echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
  390. echo ' </th>'."\n";
  391. echo ' </tr>'."\n";
  392. echo ' </tfoot>'."\n";
  393. echo ' </table>'."\n";
  394. $this->podpress_print_maxrowsperpage($limit);
  395. echo ' <p class="submit"> '."\n";
  396. echo ' <input class="button-primary" type="submit" name="Submit" value="'.__('Remove marked elements / Update options', 'podpress').' &raquo;" /><br />'."\n";
  397. echo ' </p> '."\n";
  398. echo ' <input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
  399. echo ' </form>'."\n";
  400. echo ' </fieldset>'."\n";
  401. echo ' </div>';
  402. break;
  403. case 'botdb_mark_bots':
  404. // ntm: stat logging: Full and Full+
  405. podPress_isAuthorized();
  406. $blog_charset = get_bloginfo('charset');
  407. $botdb = get_option('podpress_botdb');
  408. if ( isset($_POST['podPress_submitted']) AND 'botdb' == $_POST['podPress_submitted'] ) {
  409. if ( function_exists('check_admin_referer') ) {
  410. check_admin_referer('podPress_botdb_nonce');
  411. }
  412. $IPs = $_POST['podpress_remote_ips'];
  413. $fullbotnames = stripslashes_deep($_POST['podpress_user_agents']);
  414. if (is_array($botdb)) {
  415. $current_IP_set = $_POST['podpress_current_IP_set'];
  416. $unique_current_data_IPs = array_unique($_POST['podpress_current_IP_set']);
  417. //add new bots
  418. if (is_array($IPs)) {
  419. $unique_IPs = array_unique($IPs);
  420. foreach ($unique_IPs as $IP) {
  421. if (is_array($botdb['IP'])) {
  422. if ( FALSE === array_search($IP, $botdb['IP']) ) {
  423. $botdb['IP'][] = $IP;
  424. }
  425. } else {
  426. $botdb['IP'][] = $IP;
  427. }
  428. }
  429. // eventually remove bots
  430. $unmarked_IPs = array_diff($unique_current_data_IPs, $unique_IPs);
  431. $botdb['IP'] = array_diff($botdb['IP'], $unmarked_IPs);
  432. sort($botdb['IP']);
  433. } else {
  434. if (is_array($botdb['IP'])) {
  435. $botdb['IP'] = array_diff($botdb['IP'], $unique_current_data_IPs);
  436. sort($botdb['IP']);
  437. }
  438. }
  439. $current_user_agent_set = $_POST['podpress_current_user_agent_set'];
  440. $unique_current_data_fbnames = array_unique($_POST['podpress_current_user_agent_set']);
  441. if (is_array($fullbotnames)) {
  442. $unique_fullbotnames = array_unique($fullbotnames);
  443. foreach ($unique_fullbotnames as $fullbotname) {
  444. if (is_array($botdb['fullbotnames'])) {
  445. if ( FALSE === array_search($fullbotname, $botdb['fullbotnames']) ) {
  446. $botdb['fullbotnames'][] = $fullbotname;
  447. }
  448. } else {
  449. $botdb['fullbotnames'][] = $fullbotname;
  450. }
  451. }
  452. // eventually remove bots
  453. $unmarked_fullbotnames = array_diff($unique_current_data_fbnames, $unique_fullbotnames);
  454. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unmarked_fullbotnames);
  455. sort($botdb['fullbotnames']);
  456. } else {
  457. // eventually remove bots
  458. if (is_array($botdb['fullbotnames'])) {
  459. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unique_current_data_fbnames);
  460. sort($botdb['fullbotnames']);
  461. }
  462. }
  463. } else {
  464. //add new bots (first time)
  465. if (is_array($IPs)) {
  466. $unique_IPs = array_unique($IPs);
  467. foreach ($unique_IPs as $IP) {
  468. $botdb['IP'][] = $IP;
  469. }
  470. }
  471. if (is_array($fullbotnames)) {
  472. $unique_fullbotnames = array_unique($fullbotnames);
  473. foreach ($unique_fullbotnames as $fullbotname) {
  474. $botdb['fullbotnames'][] = $fullbotname;
  475. }
  476. }
  477. }
  478. if ( isset($_POST['podpress_maxrowsperpage']) AND FALSE == empty($_POST['podpress_maxrowsperpage']) AND $limit <= intval($_POST['podpress_maxrowsperpage']) ) {
  479. $this->settings['maxrowsperpage_'.$show_this_page] = intval($_POST['podpress_maxrowsperpage']);
  480. }
  481. if ( isset($this->settings['maxrowsperpage_'.$show_this_page]) AND is_int($this->settings['maxrowsperpage_'.$show_this_page]) AND $limit <= $this->settings['maxrowsperpage_'.$show_this_page] ) {
  482. $limit = $this->settings['maxrowsperpage_'.$show_this_page];
  483. }
  484. $result = podPress_update_option('podPress_config', $this->settings);
  485. $updated=update_option('podpress_botdb', $botdb);
  486. if (isset($updated) AND TRUE === $updated) {
  487. echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
  488. }
  489. }
  490. $where='';
  491. $rows_total = intval($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip, user_agent) AS total FROM '.$wpdb->prefix.'podpress_stats '.$where));
  492. $query_string = 'SELECT DISTINCT remote_ip, user_agent FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY dt DESC LIMIT '.$start.', '.$limit;
  493. $stats = $wpdb->get_results($query_string);
  494. echo ' <div class="wrap">'."\n";
  495. echo ' <fieldset class="options">'."\n";
  496. echo ' <legend>'.__('Which IP address or user agent name is from a web bot?', 'podpress').'</legend>'."\n";
  497. 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";
  498. echo ' <form method="post">'."\n";
  499. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  500. wp_nonce_field('podPress_botdb_nonce');
  501. }
  502. echo "\n".' <table class="the-list-x widefat">'."\n";
  503. echo ' <thead>'."\n";
  504. 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";
  505. echo ' </thead>'."\n";
  506. echo ' <tbody>'."\n";
  507. if(0 < count($stats)) {
  508. $i = 0;
  509. foreach ($stats as $stat) {
  510. ++$i;
  511. $alternate = ($i % 2) ? '' : 'alternate';
  512. $bot_style = '';
  513. $ip_chb_checked = '';
  514. $name_chb_checked = '';
  515. if (TRUE == is_array($botdb)) {
  516. if (TRUE == is_array($botdb['IP']) AND FALSE !== array_search($stat->remote_ip, $botdb['IP'])) {
  517. $bot_style = ' podpress_is_bot';
  518. $ip_chb_checked = ' checked="checked"';
  519. }
  520. if (TRUE == is_array($botdb['fullbotnames']) AND FALSE !== array_search($stat->user_agent, $botdb['fullbotnames'])) {
  521. $bot_style = ' podpress_is_bot';
  522. $name_chb_checked = ' checked="checked"';
  523. }
  524. }
  525. echo ' <tr id ="podpress_ip_user_agent_row_'.($i).'" class="'.$alternate.$bot_style.'">'."\n";
  526. echo ' <td>'.($start+$i).'</td>'."\n";
  527. echo ' <td>'.$stat->remote_ip.'<input type="hidden" name="podpress_current_IP_set[]" value="'.$stat->remote_ip.'" /></td>'."\n";
  528. 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";
  529. 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";
  530. 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";
  531. echo ' </tr>'."\n";
  532. }
  533. } else {
  534. echo '<td colspan="5">'.__('No downloads yet.','podpress')."</td>\n";
  535. }
  536. echo ' </tbody>'."\n";
  537. echo ' <tfoot>'."\n";
  538. echo ' <tr>'."\n";
  539. echo ' <th colspan="5">'."\n";
  540. // Show paging
  541. echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
  542. echo ' </th>'."\n";
  543. echo ' </tr>'."\n";
  544. echo ' </tfoot>'."\n";
  545. echo ' </table>'."\n";
  546. $this->podpress_print_maxrowsperpage($limit);
  547. echo ' <p class="submit"> '."\n";
  548. echo ' <input class="button-primary" type="submit" name="Submit" value="'.__('Update Options', 'podpress').' &raquo;" /><br />'."\n";
  549. echo ' </p> '."\n";
  550. echo ' <input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
  551. echo ' </form>'."\n";
  552. echo ' </fieldset>'."\n";
  553. echo ' </div>';
  554. break;
  555. case 'downloads_per_media_file':
  556. // ntm: stat logging: Full and Full+
  557. $where = $this->wherestr_to_exclude_bots('pod');
  558. $query_string = "SELECT COUNT(DISTINCT pod.media) as total_rows FROM ".$wpdb->prefix."podpress_stats as pod ".$where;
  559. $rows_total = intval($wpdb->get_var($query_string));
  560. if ( isset($_POST['podPress_submitted']) AND $show_this_page == $_POST['podPress_submitted'] ) {
  561. if ( isset($_POST['podpress_maxrowsperpage']) AND FALSE == empty($_POST['podpress_maxrowsperpage']) AND $limit <= intval($_POST['podpress_maxrowsperpage']) ) {
  562. $this->settings['maxrowsperpage_'.$show_this_page] = intval($_POST['podpress_maxrowsperpage']);
  563. }
  564. $result = podPress_update_option('podPress_config', $this->settings);
  565. }
  566. if ( isset($this->settings['maxrowsperpage_'.$show_this_page]) AND is_int($this->settings['maxrowsperpage_'.$show_this_page]) AND $limit <= $this->settings['maxrowsperpage_'.$show_this_page] ) {
  567. $limit = $this->settings['maxrowsperpage_'.$show_this_page];
  568. }
  569. $query_string = "SELECT DISTINCT (pod.media) FROM ".$wpdb->prefix."podpress_stats as pod ".$where." LIMIT ".$start.", ".$limit;
  570. $posts_with_podpressmedia = $wpdb->get_results($query_string);
  571. $nr_postswpm = count($posts_with_podpressmedia);
  572. if ( 0 < $nr_postswpm) {
  573. $i=1;
  574. if (FALSE == empty($where)) {
  575. $where_posts = "AND pod.media IN (";
  576. } else {
  577. $where_posts = "WHERE pod.media IN (";
  578. }
  579. foreach ($posts_with_podpressmedia as $post) {
  580. if ($i == $nr_postswpm) {
  581. $where_posts .= "'".$wpdb->escape($post->media)."'";
  582. } else {
  583. $where_posts .= "'".$wpdb->escape($post->media)."', ";
  584. }
  585. $i++;
  586. }
  587. $where_posts .= ") ";
  588. } else {
  589. $where_posts = '';
  590. }
  591. $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";
  592. $stat_data_sets = $wpdb->get_results($query_string);
  593. if (FALSE == empty($where)) {
  594. $where_or_and = "AND";
  595. } else {
  596. $where_or_and = "WHERE";
  597. }
  598. $methods = Array('feed', 'web', 'play');
  599. foreach ($methods as $method) {
  600. $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";
  601. $downloads_col = $wpdb->get_col($query_string);
  602. switch ($method) {
  603. case 'feed' :
  604. $feed_max = intval($downloads_col[0]);
  605. break;
  606. case 'web' :
  607. $web_max = intval($downloads_col[0]);
  608. break;
  609. case 'play' :
  610. $play_max = intval($downloads_col[0]);
  611. break;
  612. }
  613. }
  614. $query_string="SELECT COUNT(*) as downloads, pod.media FROM ".$wpdb->prefix."podpress_stats AS pod ".$where." GROUP BY pod.media ORDER BY downloads DESC";
  615. $downloads_col = $wpdb->get_col($query_string);
  616. $total_max = intval($downloads_col[0]);
  617. // prepare the query result for the output:
  618. // - if a media file was not downloaded by one or more method then add this method and a int(0) to the media file
  619. foreach ($stat_data_sets as $stat_data_set) {
  620. $feed = $web = $play = 0;
  621. switch ($stat_data_set->method) {
  622. case 'feed' :
  623. $feed = intval($stat_data_set->downloads);
  624. break;
  625. case 'web' :
  626. $web = intval($stat_data_set->downloads);
  627. break;
  628. case 'play' :
  629. $play = intval($stat_data_set->downloads);
  630. break;
  631. }
  632. $total_sum = $feed+$web+$play;
  633. $stats[$stat_data_set->media]['feed'] += $feed;
  634. $stats[$stat_data_set->media]['web'] += $web;
  635. $stats[$stat_data_set->media]['play'] += $play;
  636. $stats[$stat_data_set->media]['total'] += $total_sum;
  637. }
  638. // sort the media files by their 'total' value
  639. if ( is_array($stats) AND FALSE == empty($stats) AND method_exists($this, 'sort_downloads_per_media_desc') ) {
  640. uasort($stats, array($this, 'sort_downloads_per_media_desc'));
  641. }
  642. echo ' <div class="wrap">'."\n";
  643. echo ' <fieldset class="options">'."\n";
  644. echo ' <legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  645. echo ' <table class="the-list-x widefat">'."\n";
  646. echo ' <thead>';
  647. echo " <tr>\n";
  648. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  649. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  650. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  651. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
  652. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  653. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  654. echo ' </tr>'."\n";
  655. echo ' <tr>'."\n";
  656. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  657. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  658. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  659. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  660. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  661. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  662. echo ' </tr>'."\n";
  663. echo ' </thead>';
  664. echo ' <tbody>';
  665. if (0 < count($stat_data_sets)) {
  666. $i = 0;
  667. foreach ( $stats as $media => $downloads_per_method ) {
  668. $i++;
  669. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  670. $highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
  671. $highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
  672. $highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
  673. $highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
  674. $perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  675. $perc_web = number_format(($downloads_per_method['web'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  676. $perc_play = number_format(($downloads_per_method['play'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  677. echo ' <tr'.$style.'>'."\n";
  678. echo ' <td>'.($start +$i).'.</td>'."\n";
  679. echo ' <td>'.podPress_strlimiter2(urldecode($media), 50, TRUE).'</td>'."\n";
  680. 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";
  681. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  682. 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";
  683. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  684. 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";
  685. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  686. 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";
  687. echo ' </tr>'."\n";
  688. }
  689. } else {
  690. if (FALSE == empty($where)) {
  691. echo '<td colspan="9">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  692. } else {
  693. echo '<td colspan="9">'.__('No downloads yet.','podpress')."</td>\n";
  694. }
  695. }
  696. echo ' </tbody>';
  697. echo ' <tfoot>'."\n";
  698. echo ' <tr>'."\n";
  699. echo ' <th colspan="9">'."\n";
  700. // Show paging
  701. echo $this->paging2($start, $limit, $rows_total, __('Ranks','podpress'));
  702. echo ' </th>'."\n";
  703. echo ' </tr>'."\n";
  704. echo ' </tfoot>'."\n";
  705. echo ' </table>'."\n";
  706. echo ' <form method="post">'."\n";
  707. $this->podpress_print_maxrowsperpage($limit, TRUE);
  708. echo ' <input type="hidden" name="podPress_submitted" value="'.$show_this_page.'" />'."\n";
  709. echo ' </form>'."\n";
  710. echo ' </fieldset>'."\n";
  711. echo ' </div>';
  712. break;
  713. case 'rawstats':
  714. // ntm: stat logging: Full and Full+
  715. $date_format = get_option('date_format');
  716. $time_format = get_option('time_format');
  717. $botdb = get_option('podpress_botdb');
  718. $where = '';
  719. if ( isset($_POST['podPress_submitted']) AND $show_this_page == $_POST['podPress_submitted'] ) {
  720. if ( isset($_POST['podpress_maxrowsperpage']) AND FALSE == empty($_POST['podpress_maxrowsperpage']) AND $limit <= intval($_POST['podpress_maxrowsperpage']) ) {
  721. $this->settings['maxrowsperpage_'.$show_this_page] = intval($_POST['podpress_maxrowsperpage']);
  722. }
  723. $result = podPress_update_option('podPress_config', $this->settings);
  724. }
  725. if ( isset($this->settings['maxrowsperpage_'.$show_this_page]) AND is_int($this->settings['maxrowsperpage_'.$show_this_page]) AND $limit <= $this->settings['maxrowsperpage_'.$show_this_page] ) {
  726. $limit = $this->settings['maxrowsperpage_'.$show_this_page];
  727. }
  728. $rows_total = $wpdb->get_var('SELECT COUNT(*) FROM '.$wpdb->prefix.'podpress_stats '.$where);
  729. $stats = $wpdb->get_results('SELECT * FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY id DESC LIMIT '.$start.', '.$limit);
  730. echo ' <div class="wrap">'."\n";
  731. echo ' <fieldset class="options">'."\n";
  732. echo ' <legend>'.__('The raw list', 'podpress').'</legend>'."\n";
  733. echo ' <table class="the-list-x widefat">'."\n"; //width="100%" cellpadding="1" cellspacing="1"
  734. echo ' <thead>';
  735. 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";
  736. echo ' </thead>';
  737. echo ' <tbody>';
  738. if(0 < count($stats)) {
  739. if ( TRUE === is_array($botdb['IP']) OR TRUE === is_array($botdb['fullbotnames']) ) {
  740. $i = 0;
  741. foreach ($stats as $stat) {
  742. ++$i;
  743. $style = ($i % 2) ? '' : 'alternate';
  744. if ( (FALSE !== empty($botdb['fullbotnames']) OR FALSE === array_search($stat->user_agent, $botdb['fullbotnames']))) {
  745. if ( (FALSE !== empty($botdb['IP']) OR FALSE === array_search($stat->remote_ip, $botdb['IP']))) {
  746. $bot_style = '';
  747. } else {
  748. $bot_style = ' podpress_is_bot';
  749. }
  750. } else {
  751. $bot_style = ' podpress_is_bot';
  752. }
  753. echo ' <tr class="'.$style.$bot_style.'">'."\n";
  754. echo ' <td>'.($start +$i).'.</td>'."\n";
  755. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
  756. echo ' <td>'.$stat->method.'</td>'."\n";
  757. // iscifi : mod of stats output to create a link to domaintools.com whois lookup
  758. // domaintools seems faster and provides more concise infomation, url can not have trailing /
  759. 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";
  760. // OLD code where this .echo ' <td>'.$stat->remote_ip.'</td>'."\n";
  761. echo ' <td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
  762. echo ' <td>'.date($date_format.' - '.$time_format, intval($stat->dt)).'</td>'."\n";
  763. echo ' </tr>'."\n";
  764. }
  765. } else {
  766. $i = 0;
  767. foreach ($stats as $stat) {
  768. ++$i;
  769. $style = ($i % 2) ? '' : 'alternate';
  770. echo ' <tr class="'.$style.'">'."\n";
  771. echo ' <td>'.($start +$i).'.</td>'."\n";
  772. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
  773. echo ' <td>'.$stat->method.'</td>'."\n";
  774. // iscifi : mod of stats output to create a link to domaintools.com whois lookup
  775. // domaintools seems faster and provides more concise infomation, url can not have trailing /
  776. echo ' <td><a href="http://whois.domaintools.com/'.$stat->remote_ip.'" target="_blank">'.$stat->remote_ip.'</a></td>'."\n";
  777. // OLD code where this .echo ' <td>'.$stat->remote_ip.'</td>'."\n";
  778. echo ' <td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
  779. echo ' <td>'.date($date_format.' - '.$time_format, intval($stat->dt)).'</td>'."\n";
  780. echo ' </tr>'."\n";
  781. }
  782. }
  783. } else {
  784. echo '<td colspan="6">'.__('No downloads yet.','podpress').'</td>'."\n";
  785. }
  786. echo ' </tbody>';
  787. echo ' <tfoot>'."\n";
  788. echo ' <tr>'."\n";
  789. echo ' <th colspan="6">'."\n";
  790. // Show paging
  791. echo $this->paging2($start, $limit, $rows_total, __('Hit','podpress'));
  792. echo ' </th>'."\n";
  793. echo ' </tr>'."\n";
  794. echo ' </tfoot>'."\n";
  795. echo ' </table>'."\n";
  796. echo ' <form method="post">'."\n";
  797. $this->podpress_print_maxrowsperpage($limit, TRUE);
  798. echo ' <input type="hidden" name="podPress_submitted" value="'.$show_this_page.'" />'."\n";
  799. echo ' </form>'."\n";
  800. echo ' </fieldset>'."\n";
  801. echo ' </div>';
  802. break;
  803. case 'topips':
  804. // ntm: stat logging: Full and Full+
  805. $where = $this->wherestr_to_exclude_bots();
  806. $rows_total = ($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip) as uniq FROM '.$wpdb->prefix.'podpress_stats '.$where));
  807. if ( isset($_POST['podPress_submitted']) AND $show_this_page == $_POST['podPress_submitted'] ) {
  808. if ( isset($_POST['podpress_maxrowsperpage']) AND FALSE == empty($_POST['podpress_maxrowsperpage']) AND $limit <= intval($_POST['podpress_maxrowsperpage']) ) {
  809. $this->settings['maxrowsperpage_'.$show_this_page] = intval($_POST['podpress_maxrowsperpage']);
  810. }
  811. $result = podPress_update_option('podPress_config', $this->settings);
  812. }
  813. if ( isset($this->settings['maxrowsperpage_'.$show_this_page]) AND is_int($this->settings['maxrowsperpage_'.$show_this_page]) AND $limit <= $this->settings['maxrowsperpage_'.$show_this_page] ) {
  814. $limit = $this->settings['maxrowsperpage_'.$show_this_page];
  815. }
  816. $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;
  817. $stats = $wpdb->get_results($sql);
  818. echo ' <div class="wrap">'."\n";
  819. echo ' <fieldset class="options">'."\n";
  820. echo ' <legend>'.__('Top IP Addresses', 'podpress').'</legend>'."\n";
  821. echo ' <table class="the-list-x widefat">'."\n";
  822. echo ' <thead>';
  823. 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";
  824. echo ' </thead>';
  825. echo ' <tbody>';
  826. if(0<count($stats)) {
  827. $i = 0;
  828. foreach ($stats as $stat) {
  829. ++$i;
  830. $style = ($i % 2) ? '' : ' class="alternate"';
  831. echo ' <tr'.$style.'>'."\n";
  832. echo ' <td>'.($start +$i).'.</td>'."\n";
  833. echo ' <td>'.$stat->IPAddress.'</td>'."\n";
  834. echo ' <td>'.$stat->uniq.'</td>'."\n";
  835. echo ' <td>'.$stat->total.'</td>'."\n";
  836. echo ' </tr>'."\n";
  837. }
  838. } else {
  839. if (FALSE == empty($where)) {
  840. echo '<td colspan="4">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  841. } else {
  842. echo '<td colspan="4">'.__('No downloads yet.','podpress')."</td>\n";
  843. }
  844. }
  845. echo ' </tbody>';
  846. echo ' <tfoot>'."\n";
  847. echo ' <tr>'."\n";
  848. echo ' <th colspan="4">'."\n";
  849. // Show paging
  850. echo $this->paging2($start, $limit, $rows_total, __('IP Address','podpress'));
  851. echo ' </th>'."\n";
  852. echo ' </tr>'."\n";
  853. echo ' </tfoot>'."\n";
  854. echo ' </table>'."\n";
  855. echo ' <form method="post">'."\n";
  856. $this->podpress_print_maxrowsperpage($limit, TRUE);
  857. echo ' <input type="hidden" name="podPress_submitted" value="'.$show_this_page.'" />'."\n";
  858. echo ' </form>'."\n";
  859. echo ' </fieldset>'."\n";
  860. echo ' </div>';
  861. break;
  862. case 'graphbydate':
  863. // ntm: stat logging: Full and Full+
  864. if ($this->checkGD() ) {//&& ($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus')
  865. $this->graphByDate();
  866. } else {
  867. $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.');
  868. }
  869. break;
  870. case 'graphbydatealt':
  871. // ntm: stat logging: Full and Full+
  872. $this->graphByDateAlt();
  873. break;
  874. case 'graphbypost':
  875. // ntm: stat logging: Counts Only
  876. 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>';
  877. if ($this->checkGD()) {
  878. $this->graphByPost();
  879. } else {
  880. $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.');
  881. }
  882. break;
  883. case 'graphbypostalt':
  884. // ntm: stat logging: Counts Only
  885. 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>';
  886. $this->graphByPostAlt();
  887. break;
  888. case 'downloads_per_post' :
  889. // ntm: stat logging: Full and Full+
  890. $where = $this->wherestr_to_exclude_bots('pod');
  891. // get the number of all post with podPress podcasts
  892. //~ $query_string = "SELECT COUNT(DISTINCT postID) as posts FROM ".$wpdb->prefix."podpress_stats ".$where;
  893. // take only posts which are still in the wp_posts table. It is possible that the stats table contains stats of file which were only in posts which are deleted.
  894. if ( TRUE == empty($where) ) {
  895. $where_ID .= " WHERE p.ID = pod.postID";
  896. } else {
  897. $where_ID .= " AND p.ID = pod.postID";
  898. }
  899. // get all post with podPress podcasts
  900. $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.$where_ID." ORDER BY pod.postID DESC";
  901. $posts_with_podpressmedia = $wpdb->get_results($query_string);
  902. echo ' <div class="wrap">'."\n";
  903. echo ' <fieldset class="options">'."\n";
  904. echo ' <legend>'.__('Downloads Per Post', 'podpress').'</legend>'."\n";
  905. echo ' <form method="post">'."\n";
  906. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  907. wp_nonce_field('podPress_downloads_per_post_nonce');
  908. }
  909. echo ' <label>'.__('Select a post with a media file (attached with podPress):', 'podpress').'</label><br />'."\n";
  910. echo ' <select id="post_with_podpressmedia" name="post_with_podpressmedia" size="5">'."\n";
  911. foreach ($posts_with_podpressmedia as $post) {
  912. if ($post->postID == $_POST['post_with_podpressmedia']) {
  913. $selected = ' selected="selected"';
  914. } else {
  915. $selected = '';
  916. }
  917. echo ' <option value="'.$post->postID.'"'.$selected.'>'.$post->post_title.'</option>'."\n";
  918. $post_titles[$post->postID] = $post->post_title;
  919. }
  920. echo ' </select>'."\n";
  921. echo ' <p class="submit"> '."\n";
  922. echo ' <input type="submit" name="Submit" value="'.__('Show the stats for this post', 'podpress').' &raquo;" /><br />'."\n";
  923. echo ' </p> '."\n";
  924. echo ' <input type="hidden" name="podPress_submitted" value="downloadsperpost" />'."\n";
  925. echo ' </form>'."\n";
  926. echo ' </fieldset>'."\n";
  927. echo ' </div><!-- .wrap -->'."\n";
  928. // show the statistics of the media files of the submitted post
  929. if ( 'downloadsperpost' == $_POST['podPress_submitted'] ) {
  930. if ( function_exists('check_admin_referer') ) {
  931. check_admin_referer('podPress_downloads_per_post_nonce');
  932. }
  933. if (FALSE == empty($where)) {
  934. $where_postID = "AND pod.postID = '".$_POST['post_with_podpressmedia']."' ";
  935. } else {
  936. $where_postID = "WHERE pod.postID = '".$_POST['post_with_podpressmedia']."' ";
  937. }
  938. $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";
  939. $stat_data_sets = $wpdb->get_results($query_string);
  940. // prepare the query result for the output:
  941. // - find the maximal downloads value for each download method
  942. // - if a media file was not downloaded by one or more method then add this method and a int(0) to the media file
  943. $feed_max = 0;
  944. $web_max = 0;
  945. $play_max = 0;
  946. $total_max = 0;
  947. foreach ($stat_data_sets as $stat_data_set) {
  948. $feed = 0;
  949. $web = 0;
  950. $play = 0;
  951. switch ($stat_data_set->method) {
  952. case 'feed' :
  953. $feed = intval($stat_data_set->downloads);
  954. $feed_max = max($feed_max, $feed);
  955. break;
  956. case 'web' :
  957. $web = intval($stat_data_set->downloads);
  958. $web_max = max($web_max, $web);
  959. break;
  960. case 'play' :
  961. $play = intval($stat_data_set->downloads);
  962. $play_max = max($play_max, $play);
  963. break;
  964. }
  965. $stats[$stat_data_set->media]['feed'] += $feed;
  966. $stats[$stat_data_set->media]['web'] += $web;
  967. $stats[$stat_data_set->media]['play'] += $play;
  968. $stats[$stat_data_set->media]['total'] += ($feed + $web + $play);
  969. $total_max = max($total_max, $stats[$stat_data_set->media]['total']);
  970. }
  971. // sort the media files by their 'total' value
  972. if ( is_array($stats) AND FALSE == empty($stats) AND method_exists($this, 'sort_downloads_per_media_desc') ) {
  973. uasort($stats, array($this, 'sort_downloads_per_media_desc'));
  974. }
  975. echo ' <div class="wrap">'."\n";
  976. echo ' <fieldset class="options">'."\n";
  977. echo ' <legend>'.__('Post:', 'podpress')." ".$post_titles[$_POST['post_with_podpressmedia']]." - ".__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  978. echo ' <table class="the-list-x widefat">'."\n";
  979. echo ' <thead>';
  980. echo " <tr>\n";
  981. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  982. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  983. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  984. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
  985. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  986. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  987. echo ' </tr>'."\n";
  988. echo ' <tr>'."\n";
  989. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  990. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  991. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  992. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  993. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  994. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  995. echo ' </tr>'."\n";
  996. echo ' </thead>';
  997. echo ' <tbody>';
  998. $mark_highest = FALSE;
  999. $nr_stat_data_sets = count($stat_data_sets);
  1000. if (0 < $nr_stat_data_sets) {
  1001. if ( 1 < $nr_stat_data_sets ) {
  1002. $mark_highest = TRUE;
  1003. }
  1004. $i = 0;
  1005. foreach ( $stats as $media => $downloads_per_method ) {
  1006. $i++;
  1007. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  1008. if (TRUE === $mark_highest) {
  1009. $highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
  1010. $highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
  1011. $highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
  1012. $highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
  1013. }
  1014. $perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1015. $perc_web = number_format(($downloads_per_method['web'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1016. $perc_play = number_format(($downloads_per_method['play'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1017. echo ' <tr'.$style.'>'."\n";
  1018. echo ' <td>'.($start +$i).'.</td>'."\n";
  1019. echo ' <td>'.podPress_strlimiter2(urldecode($media), 50, TRUE).'</td>'."\n";
  1020. 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";
  1021. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  1022. 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";
  1023. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  1024. 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";
  1025. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  1026. 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";
  1027. echo ' </tr>'."\n";
  1028. }
  1029. } else {
  1030. if (FALSE == empty($where)) {
  1031. echo '<td colspan="9">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  1032. } else {
  1033. echo '<td colspan="9">'.__('No downloads yet.','podpress')."</td>\n";
  1034. }
  1035. }
  1036. echo ' </tbody>';
  1037. echo ' <tfoot>'."\n";
  1038. echo ' <tr>'."\n";
  1039. echo ' <th colspan="9">'."\n";
  1040. echo ' </th>'."\n";
  1041. echo ' </tr>'."\n";
  1042. echo ' </tfoot>'."\n";
  1043. echo ' </table>'."\n";
  1044. echo ' </fieldset>'."\n";
  1045. echo ' </div><!-- .wrap -->'."\n";
  1046. }
  1047. break;
  1048. case 'quickcounts':
  1049. // ntm: stat logging: Counts Only
  1050. // ntm: 'quickcounts' takes the data from the wp_podpress_statcounts table.
  1051. $total= $wpdb->get_var('SELECT COUNT(postID) FROM '.$wpdb->prefix.'podpress_statcounts WHERE postID != 0;');
  1052. if ($total > 0) {
  1053. if ( isset($_POST['podPress_submitted']) AND $show_this_page == $_POST['podPress_submitted'] ) {
  1054. if ( isset($_POST['podpress_maxrowsperpage']) AND FALSE == empty($_POST['podpress_maxrowsperpage']) AND $limit <= intval($_POST['podpress_maxrowsperpage']) ) {
  1055. $this->settings['maxrowsperpage_'.$show_this_page] = intval($_POST['podpress_maxrowsperpage']);
  1056. }
  1057. $result = podPress_update_option('podPress_config', $this->settings);
  1058. }
  1059. if ( isset($this->settings['maxrowsperpage_'.$show_this_page]) AND is_int($this->settings['maxrowsperpage_'.$show_this_page]) AND $limit <= $this->settings['maxrowsperpage_'.$show_this_page] ) {
  1060. $limit = $this->settings['maxrowsperpage_'.$show_this_page];
  1061. }
  1062. // Load highest values
  1063. $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';
  1064. $highest = $wpdb->get_results($sql);
  1065. $highest = $highest[0];
  1066. //~ $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 '
  1067. //~ . 'FROM '.$wpdb->prefix.'podpress_statcounts AS sc, '.$wpdb->prefix.'posts AS p '
  1068. //~ . 'WHERE (sc.postID = p.ID) ORDER BY p.post_date DESC LIMIT '.$start.', '.$limit.'';
  1069. $sql = 'SELECT sc.media, sc.total, sc.feed, sc.web, sc.play '
  1070. . 'FROM '.$wpdb->prefix.'podpress_statcounts AS sc '
  1071. . 'ORDER BY sc.media DESC LIMIT '.$start.', '.$limit.'';
  1072. $stats = $wpdb->get_results($sql);
  1073. $cnt_stats = count($stats);
  1074. if ( isset($_POST['podpress_quickcounts_view_options']) AND 'sortquickcountsbypost' == $_POST['podpress_quickcounts_view_options'] ) {
  1075. $this->settings['sortquickcountsbypost'] = TRUE;
  1076. } elseif ( isset($_POST['podpress_quickcounts_view_options']) AND 'sortquickcountsbymediafilenames' == $_POST['podpress_quickcounts_view_options'] ) {
  1077. $this->settings['sortquickcountsbypost'] = FALSE;
  1078. }
  1079. //~ printphpnotices_var_dump($_POST['podpress_quickcounts_view_options']);
  1080. //~ printphpnotices_var_dump($this->settings['sortquickcountsbypost']);
  1081. if ( isset($this->settings['sortquickcountsbypost']) AND TRUE === $this->settings['sortquickcountsbypost'] ) {
  1082. foreach ($stats as $stat) {
  1083. $where_instr_ar[] = 'INSTR(pm.meta_value, "'.$stat->media.'")';
  1084. }
  1085. if ( $cnt_stats > 1 ) {
  1086. $where_instr = implode(' OR ', $where_instr_ar);
  1087. } else {
  1088. $where_instr = $where_instr_ar[0];
  1089. }
  1090. $where = 'pm.meta_key="_podPressMedia" AND ('.$where_instr.')';
  1091. $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';
  1092. $postmeta_data = $wpdb->get_results($sql);
  1093. // get the highest post_id of posts which have a certain media file attached with podPress
  1094. // in other words get the last post which has a certain media file attached
  1095. foreach ($postmeta_data as $postmeta) {
  1096. $postmeta->post_id=intval($postmeta->post_id);
  1097. foreach ($stats as $stat) {
  1098. if (FALSE !== stristr($postmeta->meta_value, $stat->media)) {
  1099. //echo $postmeta->post_id.': '.$stat->media."\n";
  1100. $max_post_ids[$stat->media]['ID'] = max($max_post_ids[$stat->media]['ID'], $postmeta->post_id);
  1101. if ($max_post_ids[$stat->media]['ID'] == $postmeta->post_id) {
  1102. $max_post_ids[$stat->media]['title'] = $postmeta->post_title;
  1103. }
  1104. }
  1105. }
  1106. }
  1107. foreach ($max_post_ids as $media => $last_published_in_post) {
  1108. foreach ($stats as $stat) {
  1109. if ($stat->media == $media) {
  1110. $stat->postID = $last_published_in_post['ID'];
  1111. $stat->post_title = $last_published_in_post['title'];
  1112. $stats_new[] = $stat;
  1113. }
  1114. }
  1115. }
  1116. $stats=$stats_new;
  1117. unset($stats_new);
  1118. echo ' <div class="wrap">'."\n";
  1119. echo ' <fieldset class="options">'."\n";
  1120. echo ' <legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  1121. echo ' <p>'.__('sorted by the IDs of the posts in which the media files were last published (descending)', 'podpress').'</p>';
  1122. echo ' <table class="the-list-x widefat">'."\n";
  1123. echo ' <thead>';
  1124. echo " <tr>\n";
  1125. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  1126. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  1127. echo ' <th rowspan="2">'.__('last published in post', 'podpress')."</th>\n";
  1128. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  1129. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Download', 'podpress')."</th>\n";
  1130. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  1131. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  1132. echo ' </tr>'."\n";
  1133. echo ' <tr>'."\n";
  1134. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1135. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1136. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1137. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1138. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1139. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1140. echo ' </tr>'."\n";
  1141. echo ' </thead>';
  1142. echo ' <tbody>';
  1143. $date_format = get_option('date_format');
  1144. $time_format = get_option('time_format');
  1145. if ($cnt_stats > 0) {
  1146. $i = 0;
  1147. foreach ($stats AS $stat) {
  1148. $i++;
  1149. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  1150. $highest_feed = ($stat->feed == $highest->feed AND 0 < $highest->feed) ? ' podpress_stats_highest': '';
  1151. $highest_web = ($stat->web == $highest->web AND 0 < $highest->web) ? ' podpress_stats_highest': '';
  1152. $highest_play = ($stat->play == $highest->play AND 0 < $highest->play) ? ' podpress_stats_highest': '';
  1153. $highest_total = ($stat->total == $highest->total) ? ' podpress_stats_highest': '';
  1154. $perc_feed = number_format(($stat->feed * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1155. $perc_web = number_format(($stat->web * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1156. $perc_play = number_format(($stat->play * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1157. echo ' <tr'.$style.'>'."\n";
  1158. echo ' <td>'.($start +$i).'.</td>'."\n";
  1159. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 30, TRUE).'</td>'."\n";
  1160. if ( TRUE == version_compare($wp_version, '2.3', '<') ) {
  1161. 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";
  1162. } else {
  1163. 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";
  1164. }
  1165. 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";
  1166. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  1167. 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";
  1168. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  1169. 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";
  1170. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  1171. 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";
  1172. echo ' </tr>'."\n";
  1173. }
  1174. }
  1175. echo ' </tbody>'."\n";
  1176. echo ' <tfoot>'."\n";
  1177. echo ' <tr>'."\n";
  1178. echo ' <th colspan="10">'."\n";
  1179. } else {
  1180. echo ' <div class="wrap">'."\n";
  1181. echo ' <fieldset class="options">'."\n";
  1182. //echo ' <legend>'.__('The counts', 'podpress').'</legend>'."\n";
  1183. echo ' <legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  1184. echo ' <p>'.__('sorted by the names of the media files (descending)', 'podpress').'</p>';
  1185. echo ' <table class="the-list-x widefat">'."\n";
  1186. echo ' <thead>';
  1187. echo " <tr>\n";
  1188. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  1189. //~ echo ' <th rowspan="2">'.__('Post', 'podpress')."</th>\n";
  1190. //~ echo ' <th rowspan="2">'.__('Publication Date', 'podpress')."</th>\n";
  1191. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  1192. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  1193. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Download', 'podpress')."</th>\n";
  1194. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  1195. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  1196. echo ' </tr>'."\n";
  1197. echo ' <tr>'."\n";
  1198. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1199. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1200. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1201. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1202. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  1203. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  1204. echo ' </tr>'."\n";
  1205. echo ' </thead>';
  1206. echo ' <tbody>';
  1207. $date_format = get_option('date_format');
  1208. $time_format = get_option('time_format');
  1209. if ($cnt_stats > 0) {
  1210. $i = 0;
  1211. foreach ($stats AS $stat) {
  1212. $i++;
  1213. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  1214. $highest_feed = ($stat->feed == $highest->feed AND 0 < $highest->feed) ? ' podpress_stats_highest': '';
  1215. $highest_web = ($stat->web == $highest->web AND 0 < $highest->web) ? ' podpress_stats_highest': '';
  1216. $highest_play = ($stat->play == $highest->play AND 0 < $highest->play) ? ' podpress_stats_highest': '';
  1217. $highest_total = ($stat->total == $highest->total) ? ' podpress_stats_highest': '';
  1218. $perc_feed = number_format(($stat->feed * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1219. $perc_web = number_format(($stat->web * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1220. $perc_play = number_format(($stat->play * 100 / $stat->total), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1221. echo ' <tr'.$style.'>'."\n";
  1222. echo ' <td>'.($start +$i).'.</td>'."\n";
  1223. //~ if ( TRUE == version_compare($wp_version, '2.3', '<') ) {
  1224. //~ 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";
  1225. //~ } else {
  1226. //~ 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";
  1227. //~ }
  1228. //~ echo ' <td>'.date($date_format.' - '.$time_format, $stat->pdate).'</td>'."\n";
  1229. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 30, TRUE).'</td>'."\n";
  1230. 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";
  1231. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  1232. 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";
  1233. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  1234. 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";
  1235. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  1236. 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";
  1237. echo ' </tr>'."\n";
  1238. }
  1239. }
  1240. echo ' </tbody>'."\n";
  1241. echo ' <tfoot>'."\n";
  1242. echo ' <tr>'."\n";
  1243. //~ echo ' <th colspan="11">'."\n";
  1244. echo ' <th colspan="9">'."\n";
  1245. }
  1246. // Show paging
  1247. if ($_GET['display'] != 'graphbydate' && $_GET['display'] != 'graphbypost') {
  1248. echo $this->paging2($start, $limit, $total, __('Nr.', 'podpress'));
  1249. }
  1250. echo ' </th>'."\n";
  1251. echo ' </tr>'."\n";
  1252. echo ' </tfoot>'."\n";
  1253. echo ' </table>'."\n";
  1254. echo ' <form method="post">'."\n";
  1255. echo ' <div> '."\n";
  1256. $this->podpress_print_maxrowsperpage($limit);
  1257. echo ' <br /> '."\n";
  1258. if ( isset($this->settings['sortquickcountsbypost']) AND TRUE === $this->settings['sortquickcountsbypost'] ) {
  1259. echo ' <input type="radio" name="podpress_quickcounts_view_options" id="sortquickcountsbymediafilenames" value="sortquickcountsbymediafilenames" /> <label for="sortquickcountsbymediafilenames">'.__('sort the media files by their names', 'podpress')."</label><br />\n";
  1260. echo ' <input type="radio" name="podpress_quickcounts_view_options" id="sortquickcountsbypost" value="sortquickcountsbypost" checked="checked" /> <label for="sortquickcountsbypost">'.__('sort the media files by the IDs of the posts in which they were last published', 'podpress')."</label>\n";
  1261. } else {
  1262. echo ' <input type="radio" name="podpress_quickcounts_view_options" id="sortquickcountsbymediafilenames" value="sortquickcountsbymediafilenames" checked="checked" /> <label for="sortquickcountsbymediafilenames">'.__('sort the media files by their names', 'podpress')."</label><br />\n";
  1263. echo ' <input type="radio" name="podpress_quickcounts_view_options" id="sortquickcountsbypost" value="sortquickcountsbypost" /> <label for="sortquickcountsbypost">'.__('sort the media files by the IDs of the posts in which they were last published', 'podpress')."</label>\n";
  1264. }
  1265. echo ' </div> '."\n";
  1266. echo ' <p class="submit"> '."\n";
  1267. echo ' <input type="submit" class="button-primary" name="Submit" value="'.__('Update options', 'podpress').' &raquo;" /><br />'."\n";
  1268. echo ' </p> '."\n";
  1269. echo ' </form>'."\n";
  1270. echo ' </fieldset>'."\n";
  1271. echo ' </div>';
  1272. } else {
  1273. echo '<p>'.__('We\'re sorry. At the moment we don\'t have enough data collected to display the graph.', 'podpress')."</p>\n";
  1274. }
  1275. break;
  1276. default:
  1277. return;
  1278. }
  1279. echo '<div style="clear: both;"></div>'."\n";
  1280. echo '</div>';
  1281. }
  1282. #############################################
  1283. #############################################
  1284. /**
  1285. * sort_downloads_per_media_asc - is a callback function to sort arrays by their 'total' value ascending
  1286. * for more info: http://www.php.net/manual/en/function.uasort.php
  1287. *
  1288. * @package podPress
  1289. * @since 8.8.5 beta 3
  1290. *
  1291. * @param int $a
  1292. * @param int $b
  1293. *
  1294. * @return int 0 => equal, -1 => $a < $b, 1 => $a > $b
  1295. */
  1296. function sort_downloads_per_media_asc($a, $b) {
  1297. if ($a['total'] == $b['total']) {
  1298. return 0;
  1299. }
  1300. return ($a['total'] < $b['total']) ? -1 : 1;
  1301. }
  1302. #############################################
  1303. #############################################
  1304. /**
  1305. * sort_downloads_per_media_desc - is a callback function to sort arrays by their 'total' value descending
  1306. * for more info: http://www.php.net/manual/en/function.uasort.php
  1307. *
  1308. * @package podPress
  1309. * @since 8.8.5 beta 3
  1310. *
  1311. * @param int $a
  1312. * @param int $b
  1313. *
  1314. * @return int 0 => equal, -1 => $a < $b, 1 => $a > $b
  1315. */
  1316. function sort_downloads_per_media_desc($a, $b) {
  1317. if ($a['total'] == $b['total']) {
  1318. return 0;
  1319. }
  1320. return ($a['total'] > $b['total']) ? -1 : 1;
  1321. }
  1322. #############################################
  1323. #############################################
  1324. /**
  1325. podpress_print_maxrowsperpage() - prints a selectbox with numerical values
  1326. *
  1327. * @package podPress
  1328. * @since 8.8.10.13
  1329. *
  1330. * @param int $limit - the value which should be selected
  1331. * @param bool $do_submit - submit the form on change (add the necessary JS code if TRUE)
  1332. * @param int $min_limit - minimal number value
  1333. */
  1334. function podpress_print_maxrowsperpage($limit = 25, $do_submit = FALSE, $min_limit = 25) {
  1335. if ( TRUE === $do_submit ) {
  1336. echo ' <label for="podpress_maxrowsperpage">'.__('max. rows per page:', 'podpress') . '</label> <select id="podpress_maxrowsperpage" name="podpress_maxrowsperpage" onchange="this.form.submit();">'."\n";
  1337. } else {
  1338. echo ' <label for="podpress_maxrowsperpage">'.__('max. rows per page:', 'podpress') . '</label> <select id="podpress_maxrowsperpage" name="podpress_maxrowsperpage">'."\n";
  1339. }
  1340. for ($i = $min_limit; $i <= 150; $i += 5 ) {
  1341. if ( $i == $limit ) {
  1342. echo ' <option value="'.$i.'" selected="selected">'.$i.'</option>'."\n";
  1343. } else {
  1344. echo ' <option value="'.$i.'">'.$i.'</option>'."\n";
  1345. }
  1346. }
  1347. echo ' </select>'."\n";
  1348. }
  1349. /**
  1350. * Check GD-Library-Support
  1351. *
  1352. * @return unknown
  1353. */
  1354. function checkGD() {
  1355. if (!function_exists('gd_info')) {
  1356. /* php > 4.3 */
  1357. $info = gd_info();
  1358. if (isset($info) AND ($info['JPG Support'] == 1) AND ($info['FreeType Support'] == 1)) {
  1359. return true;
  1360. }
  1361. } else {
  1362. /* php < 4.3 */
  1363. ob_start();
  1364. phpinfo(8);
  1365. $info = ob_get_contents();
  1366. ob_end_clean();
  1367. $info = stristr($info, 'gd version');
  1368. preg_match('/\d/', $info, $match);
  1369. $gd_ver = $match[0];
  1370. if ($gd_ver > 0) {
  1371. return true;
  1372. }
  1373. }
  1374. return false;
  1375. }
  1376. #############################################
  1377. #############################################
  1378. function checkFontFile() {
  1379. clearstatcache();
  1380. /* check font */
  1381. $file = 'share-regular.ttf';
  1382. $fontface = ABSPATH.PLUGINDIR.'/podpress/optional_files/'.$file;
  1383. if (!file_exists($fontface)) {
  1384. $fontface = '../optional_files/'.$file;
  1385. }
  1386. if (!is_readable($fontface)) {
  1387. echo '<p>'.__('Could not include font-file. Please reinstall podPress.', 'podpress')."</p>\n";
  1388. return false;
  1389. }
  1390. $this->fontface = $fontface;
  1391. return true;
  1392. }
  1393. #############################################
  1394. #############################################
  1395. function graphByDate() {
  1396. // ntm: stat logging: Full and Full+
  1397. if ($this->checkWritableTempFileDir() && $this->checkFontFile()) {
  1398. $chronometry1 = getmicrotime();
  1399. $start = (isset($_GET['start'])) ? $this->podSafeDigit($_GET['start']): 0;
  1400. $image_width = 1800;
  1401. $image_height = 470;
  1402. $col_width = 20;
  1403. $filename = 'graph-by-date.jpg';
  1404. $file = $this->tempfilesystempath.'/'.$filename;
  1405. $sidemargin = 20;
  1406. $baseline = ($image_height - 90);
  1407. $topmargin = 60;
  1408. $maxheight = ($baseline - $topmargin);
  1409. $weeks = 15;
  1410. $timelimit = (time() - (($weeks * 7) * 86400));
  1411. $min_downloaddays = 4;
  1412. ini_set('memory_limit', '120M');
  1413. ini_set('max_execution_time', '60');
  1414. $start_memory = memory_get_usage();
  1415. $where = $this->wherestr_to_exclude_bots('', 'AND');
  1416. /* get the data in time range ($timelimit) */
  1417. $query = 'SELECT dt AS timestamp, DAYOFWEEK(FROM_UNIXTIME(dt)) AS weekday, method, '
  1418. . 'DATE_FORMAT(FROM_UNIXTIME(dt), "%Y-%m-%d") AS day '
  1419. . 'FROM '.$this->wpdb->prefix."podpress_stats WHERE dt >= '".$timelimit."' ".$where
  1420. . 'ORDER BY dt ASC;';
  1421. $data = $this->wpdb->get_results($query);
  1422. /* create array with grouped stats */
  1423. $stats = array();
  1424. $stats_total = array();
  1425. foreach ($data AS $idata) {
  1426. $stats[$idata->day][$idata->method]++;
  1427. $stats[$idata->day]['total']++;
  1428. $stats_total[$idata->method]++;
  1429. $stats_total['total']++;
  1430. }
  1431. /* get min an max values */
  1432. $value_min = 0;
  1433. $value_max = 0;
  1434. $i = 0;
  1435. $cnt_days = count($stats);
  1436. foreach ($stats AS $day => $idata) {
  1437. /* set min and max values */
  1438. if ($value_min == 0) {
  1439. $value_min = $idata['total'];
  1440. } elseif ($idata['total'] < $value_min) {
  1441. $value_min = $idata['total'];
  1442. } elseif ($idata['total'] > $value_max) {
  1443. $value_max = $idata['total'];
  1444. }
  1445. /* set first and last day */
  1446. if ($i == 0) {
  1447. $first_day = strtotime($day);
  1448. } elseif ($i == ($cnt_days - 1)) {
  1449. $last_day = strtotime($day);
  1450. }
  1451. $i++;
  1452. }
  1453. /* Do we have enough data? */
  1454. if (($value_max > 0) && ($cnt_days >= $min_downloaddays)) {
  1455. $h_cscale = ($maxheight / $value_max);
  1456. $h_vscale = ($maxheight / $value_min / 4);
  1457. $pos_x = ($sidemargin + 35);
  1458. $points = array( 'total' => array(0 => $pos_x, 1 => $baseline) );
  1459. foreach ($stats AS $day => $idata) {
  1460. $points['total'][] = $pos_x;
  1461. $points['total'][] = ($baseline - ($idata['total'] * $h_cscale));
  1462. $points['feed'][] = ($baseline - ($idata['feed'] * $h_cscale));
  1463. $points['web'][] = ($baseline - ($idata['web'] * $h_cscale));
  1464. $points['play'][] = ($baseline - ($idata['play'] * $h_cscale));
  1465. $pos_x = ($pos_x + $col_width);
  1466. }
  1467. $points['total'][] = ($pos_x - $col_width);
  1468. $points['total'][] = $baseline;
  1469. /* create image */
  1470. $chronometry2 = getmicrotime();
  1471. $image = imagecreatetruecolor($image_width, $image_height);
  1472. if (function_exists('imageantialias')) {
  1473. imageantialias($image, 1);
  1474. }
  1475. /* set colors */
  1476. $colors = array(
  1477. 'background' => imagecolorallocate($image, 51, 51, 51),
  1478. 'line' => imagecolorallocate($image, 79, 79, 79),
  1479. 'total' => imagecolorallocate($image, 79, 79, 79),
  1480. 'feed' => imagecolorallocate($image, 255, 0, 0),
  1481. 'web' => imagecolorallocate($image, 12, 223, 0),
  1482. 'play' => imagecolorallocate($image, 223, 204, 0),
  1483. 'text' => imagecolorallocate($image, 255, 255, 255),
  1484. 'copytext' => imagecolorallocate($image, 79, 79, 79),
  1485. 'days_first' => imagecolorallocate($image, 143, 143, 143),
  1486. 'days_other' => imagecolorallocate($image, 95, 95, 95),
  1487. /* gray-scales: 175 159 143 127 111 95 79 63 */
  1488. );
  1489. imagefill($image, 0, 0, $colors['background']);
  1490. /* create the legend */
  1491. imagettftext($image, 14, 0, $sidemargin, 25, $colors['text'], $this->fontface, get_option('blogname'));
  1492. 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));
  1493. /* Total stats */
  1494. $text_total = number_format($stats_total['total'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1495. $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]).'%)';
  1496. $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]).'%)';
  1497. $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]).'%)';
  1498. $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.' ';
  1499. imagettftext($image, 8, 0, $sidemargin, ($image_height - 15), $colors['text'], $this->fontface, $text_total);
  1500. $pos_y = ($image_height - 32);
  1501. imagefilledrectangle($image, ($sidemargin + 0), ($pos_y - 10), ($sidemargin + 10), ($pos_y - 0), $colors['total']);
  1502. imagettftext($image, 8, 0, ($sidemargin + 15), $pos_y, $colors['text'], $this->fontface, __('Total', 'podpress'));
  1503. imageline($image, ($sidemargin + 50), ($pos_y - 4), ($sidemargin + 60), ($pos_y - 4), $colors['feed']);
  1504. imagettftext($image, 8, 0, ($sidemargin + 65), $pos_y, $colors['text'], $this->fontface, __('Feed', 'podpress'));
  1505. imageline($image, ($sidemargin + 100), ($pos_y - 4), ($sidemargin + 110), ($pos_y - 4), $colors['web']);
  1506. imagettftext($image, 8, 0, ($sidemargin + 115), $pos_y, $colors['text'], $this->fontface, __('Download', 'podpress'));
  1507. imageline($image, ($sidemargin + 175), ($pos_y - 4), ($sidemargin + 185), ($pos_y - 4), $colors['play']);
  1508. imagettftext($image, 8, 0, ($sidemargin + 190), $pos_y, $colors['text'], $this->fontface, __('Play', 'podpress'));
  1509. imagettftext($image, 23, 0, ($image_width - 128), 30, $colors['copytext'], $this->fontface, 'podPress');
  1510. imagettftext($image, 8, 0, ($image_width - 115), 43, $colors['copytext'], $this->fontface, __('Plugin for WordPress', 'podpress'));
  1511. imagettftext($image, 6, 90, ($image_width - 15), ($image_height - 10), $colors['copytext'], $this->fontface, strftime($this->local_settings['creation_date'], time()).' ('.PODPRESS_VERSION.')');
  1512. /* draw total-stats */
  1513. $cnt_total = (count($points['total']) / 2);
  1514. imagefilledpolygon($image, $points['total'], $cnt_total, $colors['total']);
  1515. /* draw background-lines and scale-text */
  1516. $step = 0;
  1517. $h = (($baseline - $topmargin) / 10);
  1518. while ($step <= 10) {
  1519. $pos_y = ($topmargin + ($h * $step));
  1520. imageline($image, 0, ($topmargin + ($h * $step)), $image_width, ($topmargin + ($h * $step)), $colors['line']);
  1521. 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]));
  1522. $step++;
  1523. }
  1524. $pos_x = ($sidemargin + 35);
  1525. foreach ($stats AS $day => $idata) {
  1526. /* Web einzeichnen */
  1527. $weekday = date('w', strtotime($day));
  1528. $col_total_height = ($idata['total'] * $h_cscale);
  1529. if ($weekday == 1) {
  1530. $pos_y_start = ($baseline + 27);
  1531. imagettftext($image, 8, 0, ($pos_x + 3), ($baseline + 13), $colors['text'], $this->fontface, strftime($this->local_settings['short_date'], strtotime($day)));
  1532. $color = $colors['days_first'];
  1533. } else {
  1534. $pos_y_start = $baseline;
  1535. $color = $colors['days_other'];
  1536. }
  1537. imageline($image, $pos_x, $pos_y_start, $pos_x, ($baseline - $col_total_height), $color);
  1538. $pos_x = ($pos_x + $col_width);
  1539. }
  1540. /* Linien zeichen */
  1541. $topics = array('feed', 'web', 'play');
  1542. foreach ($topics AS $topic) {
  1543. $cnt_points = count($points[$topic]);
  1544. $pos_x = ($sidemargin + 35);
  1545. for ($i = 0; $i < ($cnt_points - 1); $i++) {
  1546. imageline($image, $pos_x, $points[$topic][$i], ($pos_x + $col_width), $points[$topic][$i + 1], $colors[$topic]);
  1547. $pos_x = ($pos_x + $col_width);
  1548. }
  1549. }
  1550. imagejpeg($image, $file, 100);
  1551. $chronometry_end = getmicrotime();
  1552. $chronometry1 = ($chronometry_end - $chronometry1);
  1553. $chronometry2 = ($chronometry_end - $chronometry2);
  1554. imagedestroy($image);
  1555. $end_memory = memory_get_usage();
  1556. $memory_used = podPress_bytes($end_memory-$start_memory);
  1557. /* Output */
  1558. echo '<div id="podPress_graph" style="width: '.$image_width.'px;">'."\n";
  1559. echo ' <p><img src="'.$this->tempfileurlpath.'/'.$filename.'" width="'.$image_width.'" height="'.$image_height.'" alt="podPress-Statistics" /></p>'."\n";
  1560. echo "</div>\n";
  1561. 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";
  1562. echo '<br/>'.__('Memory to generate the graph', 'podpress').': '.$memory_used.".</p>\n";
  1563. } else {
  1564. 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";
  1565. }
  1566. }
  1567. }
  1568. #############################################
  1569. #############################################
  1570. function graphByDateAlt($msg = '') {
  1571. // ntm: stat logging: Full and Full+
  1572. GLOBAL $wpdb;
  1573. $where = $this->wherestr_to_exclude_bots();
  1574. $sql = 'SELECT DATE_FORMAT(FROM_UNIXTIME(dt), "%a, %Y-%m-%d") AS title, DAYOFWEEK(FROM_UNIXTIME(dt)) AS weekday, COUNT(id) AS value '
  1575. . 'FROM '.$wpdb->prefix.'podpress_stats '.$where.'GROUP BY title ORDER BY dt DESC LIMIT 0, 100;';
  1576. $data = $wpdb->get_results($sql);
  1577. $data = array_reverse($data);
  1578. $splitter = array('weekday', '2');
  1579. echo ' <div class="wrap">'."\n";
  1580. echo ' <fieldset class="options">'."\n";
  1581. echo ' <legend>'.__('Downloads by date', 'podpress').' ('.__('Last 100 days', 'podpress').')</legend>'."\n";
  1582. echo $this->podGraph($data, $splitter);
  1583. if($msg != '') {
  1584. echo ' <p>'.$msg."</p>\n";
  1585. }
  1586. echo ' </fieldset>'."\n";
  1587. echo ' </div>';
  1588. }
  1589. #############################################
  1590. #############################################
  1591. function graphByPost() {
  1592. // ntm: stat logging: Counts Only
  1593. if ($this->checkWritableTempFileDir() && $this->checkFontFile()) {
  1594. $chronometry1 = getmicrotime();
  1595. $start = (isset($_GET['start'])) ? $this->podSafeDigit($_GET['start']): 0;
  1596. $limit = 20;
  1597. $image_width = 1200;
  1598. $image_height = 470;
  1599. $col_width = 25;
  1600. $col_space = 15;
  1601. $filename = 'graph-by-post.jpg';
  1602. $file = $this->tempfilesystempath.'/'.$filename;
  1603. $sidemargin = 20;
  1604. $baseline = ($image_height - 90);
  1605. $topmargin = 60;
  1606. $maxheight = ($baseline - $topmargin);
  1607. $timelimit = (time() - ((5 * 7) * 86400));
  1608. ini_set('memory_limit', '120M');
  1609. ini_set('max_execution_time', '60');
  1610. $start_memory = memory_get_usage();
  1611. /* get data */
  1612. $total = $this->wpdb->get_var('SELECT COUNT(postID) FROM '.$this->wpdb->prefix."podpress_statcounts WHERE postID != 0;");
  1613. $query = 'SELECT post_title AS title, total, feed, web, play, UNIX_TIMESTAMP(post_date) AS post_date '
  1614. . 'FROM '.$this->wpdb->prefix.'podpress_statcounts, '.$this->wpdb->prefix.'posts '
  1615. . 'WHERE '.$this->wpdb->prefix.'posts.ID = '.$this->wpdb->prefix.'podpress_statcounts.postID '
  1616. . 'AND postID !=0 GROUP BY postID ORDER BY post_date DESC LIMIT '.$start.', '.$limit.';';
  1617. $data = $this->wpdb->get_results($query);
  1618. $cnt_data = count($data);
  1619. $first_post = $data[($cnt_data - 1)]->post_date;
  1620. $last_post = $data[0]->post_date;
  1621. $stats = array();
  1622. foreach ($data AS $idata) {
  1623. $stats[$idata->day][$idata->method]++;
  1624. $stats[$idata->day]['total']++;
  1625. $stats_total[$idata->method]++;
  1626. $stats_total['total']++;
  1627. }
  1628. /* get min an max values */
  1629. $value_min = 0;
  1630. $value_max = 0;
  1631. $stats_total = array();
  1632. foreach ($data AS $idata) {
  1633. if ($value_min == 0) {
  1634. $value_min = $idata->total;
  1635. } elseif ($idata->total < $value_min) {
  1636. $value_min = $idata->total;
  1637. }
  1638. if ($idata->total > $value_max) {
  1639. $value_max = $idata->total;
  1640. }
  1641. $stats_total['feed'] = ($stats_total['feed'] + $idata->feed);
  1642. $stats_total['web'] = ($stats_total['web'] + $idata->web);
  1643. $stats_total['play'] = ($stats_total['play'] + $idata->play);
  1644. $stats_total['total'] = ($stats_total['total'] + $idata->total);
  1645. }
  1646. /* Do we have enough data? */
  1647. if (intval($value_max) > 0) {
  1648. $h_cscale = ($maxheight / $value_max);
  1649. $h_vscale = ($maxheight / $value_min / 4);
  1650. $w_scale = intval($image_width - (2 * $sidemargin) + intval(($image_width - (2 * $sidemargin)) / ($limit) / 4)) / ($limit);
  1651. /* create image */
  1652. $chronometry2 = getmicrotime();
  1653. $image = imagecreatetruecolor($image_width, $image_height);
  1654. if (function_exists('imageantialias')) {
  1655. imageantialias($image, 1);
  1656. }
  1657. $colors = array(
  1658. 'background' => imagecolorallocate($image, 51, 51, 51),
  1659. 'line' => imagecolorallocate($image, 79, 79, 79),
  1660. 'text' => imagecolorallocate($image, 255, 255, 255),
  1661. 'copytext' => imagecolorallocate($image, 79, 79, 79),
  1662. 'total' => imagecolorallocate($image, 0, 0, 0),
  1663. 'feed' => imagecolorallocate($image, 143, 53, 53),
  1664. 'web' => imagecolorallocate($image, 71, 143, 88),
  1665. 'play' => imagecolorallocate($image, 142, 143, 71),
  1666. );
  1667. imagefill($image, 0, 0, $colors['background']);
  1668. /* draw background-lines and scale-text */
  1669. $step = 0;
  1670. $h = (($baseline - $topmargin) / 10);
  1671. while ($step <= 10) {
  1672. $pos_y = ($topmargin + ($h * $step));
  1673. imageline($image, 0, ($topmargin + ($h * $step)), $image_width, ($topmargin + ($h * $step)), $colors['line']);
  1674. 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]));
  1675. $step++;
  1676. }
  1677. /* create the legend */
  1678. imagettftext($image, 14, 0, $sidemargin, 25, $colors['text'], $this->fontface, get_option('blogname'));
  1679. 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));
  1680. $text_total = number_format($stats_total['total'], 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1681. $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]).'%)';
  1682. $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]).'%)';
  1683. $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]).'%)';
  1684. $text_total = __('Total stats from displayed posts', 'podpress').': '.$text_total.' / '.__('Feed', 'podpress').': '.$text_feed.' / '.__('Download', 'podpress').': '.$text_web.' / '.__('Play', 'podpress').': '.$text_play.' ';
  1685. imagettftext($image, 8, 0, $sidemargin, ($image_height - 15), $colors['text'], $this->fontface, $text_total);
  1686. $pos_y = ($image_height - 32);
  1687. imagefilledrectangle($image, ($sidemargin + 0), ($pos_y - 10), ($sidemargin + 10), $pos_y, $colors['feed']);
  1688. imagettftext($image, 8, 0, ($sidemargin + 15), $pos_y, $colors['text'], $this->fontface, __('Feed', 'podpress'));
  1689. imagefilledrectangle($image, ($sidemargin + 50), ($pos_y - 10), ($sidemargin + 60), $pos_y, $colors['web']);
  1690. imagettftext($image, 8, 0, ($sidemargin + 65), $pos_y, $colors['text'], $this->fontface, __('Download', 'podpress'));
  1691. imagefilledrectangle($image, ($sidemargin + 125), ($pos_y - 10), ($sidemargin + 135), $pos_y, $colors['play']);
  1692. imagettftext($image, 8, 0, ($sidemargin + 140), $pos_y, $colors['text'], $this->fontface, __('Play', 'podpress'));
  1693. imagettftext($image, 23, 0, ($image_width - 128), 30, $colors['copytext'], $this->fontface, 'podPress');
  1694. imagettftext($image, 8, 0, ($image_width - 115), 43, $colors['copytext'], $this->fontface, __('Plugin for WordPress', 'podpress'));
  1695. imagettftext($image, 6, 90, ($image_width - 15), ($image_height - 10), $colors['copytext'], $this->fontface, strftime($this->local_settings['creation_date'], time()).' ('.PODPRESS_VERSION.')');
  1696. $pos_x = ($image_width - $sidemargin - 15);
  1697. /* draw the posts */
  1698. foreach ($data AS $idata) {
  1699. /* Total stats */
  1700. $col_total_height = ($idata->total * $h_cscale);
  1701. imageline($image, ($pos_x - 2), $baseline, ($pos_x - 2), ($baseline - $col_total_height), $colors['total']);
  1702. imagettftext($image, 8, 0, ($pos_x - $col_width - 3), ($baseline - 3 - ($idata->total * $h_cscale)), $colors['text'], $this->fontface, $idata->total);
  1703. /* Feeds */
  1704. $perc_feed = number_format(($idata->feed * 100 / $idata->total), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1705. $col_feed_height = ($idata->feed * $h_cscale);
  1706. if ($col_feed_height < 0) {
  1707. imagefilledrectangle($image, ($pos_x - $col_width - 3), $baseline, ($pos_x - 3), ($baseline - $col_feed_height), $colors['feed']);
  1708. } else {
  1709. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_feed_height), ($pos_x - 3), $baseline, $colors['feed']);
  1710. }
  1711. if ($col_feed_height > 11) {
  1712. imagettftext($image, 8, 0, ($pos_x - $col_width - 2), (($baseline - ($idata->feed * $h_cscale)) + 11), $colors['text'], $this->fontface, $perc_feed.'%');
  1713. }
  1714. /* Web */
  1715. $perc_web = number_format(($idata->web * 100 / $idata->total), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1716. $col_web_height = ($idata->web * $h_cscale);
  1717. if ($col_web_height < 0) {
  1718. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_feed_height), ($pos_x - 3), ($baseline - $col_web_height - $col_feed_height), $colors['web']);
  1719. } else {
  1720. imagefilledrectangle($image, ($pos_x - $col_width - 3), ($baseline - $col_web_height - $col_feed_height), ($pos_x - 3), ($baseline - $col_feed_height), $colors['web']);
  1721. }
  1722. if ($col_web_height > 11) {
  1723. imagettftext($image, 8, 0, ($pos_x - $col_width - 2), (($baseline - $col_web_height - $col_feed_height) + 11), $colors['text'], $this->fontface, $perc_web.'%');
  1724. }
  1725. /* Play */
  1726. $perc_play = number_format(($idata->play * 100 / $idata->total), 0, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  1727. $col_play_height = ($idata->play * $h_cscale);
  1728. if ($col_play_height < 0) {
  1729. 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']);
  1730. } else {
  1731. 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']);
  1732. }
  1733. if ($col_play_height > 11) {
  1734. 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.'%');
  1735. }
  1736. /* Set Date and Title */
  1737. $title = (strlen($idata->title) > 70) ? substr($idata->title, 0, 70).'...' : $idata->title;
  1738. imagettftext($image, 8, 90, ($pos_x + 10), $baseline, $colors['text'], $this->fontface, $title);
  1739. imagettftext($image, 8, 0, ($pos_x - $col_width - 3), ($baseline + 14), $colors['text'], $this->fontface, strftime($this->local_settings['short_date'], $idata->post_date));
  1740. $pos_x = ($pos_x - $col_width - $col_space - 15);
  1741. }
  1742. imagejpeg($image, $file, 100);
  1743. $chronometry_end = getmicrotime();
  1744. $chronometry1 = ($chronometry_end - $chronometry1);
  1745. $chronometry2 = ($chronometry_end - $chronometry2);
  1746. imagedestroy($image);
  1747. $end_memory = memory_get_usage();
  1748. $memory_used = podPress_bytes($end_memory-$start_memory);
  1749. echo '<div id="podPress_graph" style="width: '.$image_width.'px;">'."\n";
  1750. echo ' <p style="padding-top: 0;"><img src="'.$this->tempfileurlpath.'/'.$filename.'" width="'.$image_width.'" height="'.$image_height.'" alt="podPress-Statistics" /></p>'."\n";
  1751. echo $this->paging($start, $limit, $total, 'Posts');
  1752. echo ' <div class="clear"></div>'."\n";
  1753. echo "</div>\n";
  1754. 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";
  1755. echo '<br/>'.__('Memory to generate the graph', 'podpress').': '.$memory_used.".</p>\n";
  1756. } else {
  1757. echo '<p>'.__('We\'re sorry. At the moment we don\'t have enough data collected to display the graph.', 'podpress')."</p>\n";
  1758. }
  1759. }
  1760. }
  1761. #############################################
  1762. #############################################
  1763. function graphByPostAlt($msg = '') {
  1764. // ntm: stat logging: Counts Only
  1765. global $wpdb;
  1766. $sql = 'SELECT post_title AS title, SUM(total) AS value '
  1767. . 'FROM '.$wpdb->prefix.'podpress_statcounts, '.$wpdb->prefix.'posts '
  1768. . 'WHERE '.$wpdb->prefix.'posts.ID = '.$wpdb->prefix.'podpress_statcounts.postID '
  1769. . 'AND postID !=0 GROUP BY postID ORDER BY post_date DESC LIMIT 0, 100;';
  1770. $data = $wpdb->get_results($sql);
  1771. $data = array_reverse($data);
  1772. echo ' <div class="wrap">'."\n";
  1773. echo ' <fieldset class="options">'."\n";
  1774. echo ' <legend>'.__('Downloads by Post', 'podpress').' ('.__('Last 100 posts', 'podpress').')</legend>'."\n";
  1775. echo $this->podGraph($data);
  1776. echo ' </fieldset>'."\n";
  1777. if ($msg != '') {
  1778. echo ' <p>'.$msg."</p>\n";
  1779. }
  1780. echo ' </div>';
  1781. }
  1782. #############################################
  1783. #############################################
  1784. }
  1785. ?>