PageRenderTime 73ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://bitbucket.org/openfarmtech/weblog-content
PHP | 1821 lines | 1477 code | 155 blank | 189 comment | 270 complexity | d632a67d04c9672898e3b7bd78a05cde MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.0, LGPL-3.0, BSD-3-Clause, GPL-3.0, LGPL-2.1, AGPL-3.0, CC-BY-SA-3.0

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

  1. <?php
  2. /*
  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. 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";
  217. if($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus') {
  218. // Show all statistics which are based on wp_stats [stat logging: Full and Full+]
  219. $navi = array(
  220. 'downloads_per_media_file' => __('Downloads Per Media File', 'podpress'),
  221. 'downloads_per_post' => __('Downloads Per Post', 'podpress'),
  222. 'topips' => __('Downloads Per IP Address', 'podpress'),
  223. 'graphbydate' => __('Graph by Date', 'podpress'),
  224. 'rawstats' => __('Raw Stats', 'podpress'),
  225. );
  226. echo ' <ul id="podPress_navi">'."\n";
  227. foreach ($navi AS $key => $value) {
  228. $active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'downloads_per_media_file'))) ? ' class="current"': null;
  229. echo ' <li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a>';
  230. if($this->checkGD()) {
  231. if ($value == __('Graph by Date', 'podpress')) {
  232. echo ' (<a href="'.$baseurl.'graphbydatealt" title="'.sprintf(__('An alternative view of the %1$s', 'podpress'), __('Graph by Date', 'podpress')).'">'. __('alt', 'podpress').'</a>)';
  233. }
  234. }
  235. echo '</li>'."\n";
  236. }
  237. echo ' </ul>'."\n";
  238. // bot management menu (since 8.8.5 beta 3)
  239. $navi2 = array(
  240. 'botdb_mark_bots' => __('Select / Deselect Bots', 'podpress'),
  241. 'botdb_list' => __('List of Bots', 'podpress'),
  242. );
  243. echo ' <ul id="podPress_navi">'."\n";
  244. foreach ($navi2 AS $key => $value) {
  245. $active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'quickcounts'))) ? ' class="current"': null;
  246. echo ' <li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a></li>'."\n";
  247. }
  248. echo ' </ul>'."\n";
  249. } else {
  250. // Show all statistics which are based on wp_statcounts [stat logging: Counts Only]
  251. // old: $_GET['display'] = 'downloads_per_media_file';
  252. $navi = array(
  253. 'quickcounts' => __('Quick Counts', 'podpress'),
  254. 'graphbypost' => __('Graph by Post', 'podpress'),
  255. );
  256. echo ' <ul id="podPress_navi">'."\n";
  257. foreach ($navi AS $key => $value) {
  258. $active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'quickcounts'))) ? ' class="current"': null;
  259. echo ' <li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a>';
  260. if($this->checkGD()) {
  261. if($value == __('Graph by Post', 'podpress')) {
  262. echo ' (<a href="'.$baseurl.'graphbypostalt" title="'.sprintf(__('An alternative view of the %1$s', 'podpress'), __('Graph by Post', 'podpress')).'">'. __('alt', 'podpress').'</a>)';
  263. }
  264. }
  265. echo '</li>'."\n";
  266. }
  267. echo ' </ul>'."\n";
  268. }
  269. // Set Paging-Settings
  270. $start = (isset($_GET['start'])) ? $this->podSafeDigit($_GET['start']): 0;
  271. //~ ####################
  272. //~ Limit is limits the number of rows of the statistic tables
  273. $limit = 25;
  274. //~ ####################
  275. // 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)
  276. if (FALSE == isset($_GET['display']) OR FALSE !== empty($_GET['display'])) {
  277. if ($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus') {
  278. $show_this_page = 'downloads_per_media_file';
  279. } else {
  280. $show_this_page = 'quickcounts';
  281. }
  282. } else {
  283. $show_this_page = $_GET['display'];
  284. }
  285. Switch($show_this_page) {
  286. case 'botdb_list':
  287. // ntm: stat logging: Full and Full+
  288. podPress_isAuthorized();
  289. $botdb = get_option('podpress_botdb');
  290. if ( 'botdb' == $_POST['podPress_submitted'] ) {
  291. if ( function_exists('check_admin_referer') ) {
  292. check_admin_referer('podPress_botdb_nonce');
  293. }
  294. $IPs = $_POST['podpress_remote_ips'];
  295. $fullbotnames = stripslashes_deep($_POST['podpress_user_agents']);
  296. if ( is_array($botdb) ) {
  297. $something_removed=FALSE;
  298. if ( is_array($IPs) and is_array($botdb['IP'])) {
  299. $botdb['IP'] = array_diff($botdb['IP'], $IPs);
  300. sort($botdb['IP']);
  301. }
  302. if ( is_array($fullbotnames) and is_array($botdb['fullbotnames'])) {
  303. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $fullbotnames);
  304. sort($botdb['fullbotnames']);
  305. }
  306. }
  307. $updated=update_option('podpress_botdb', $botdb);
  308. if (isset($updated) AND $updated == TRUE) {
  309. echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
  310. }
  311. }
  312. echo ' <div class="wrap">'."\n";
  313. echo ' <fieldset class="options">'."\n";
  314. echo ' <legend>'.__('The list of IP addresses and names of bots', 'podpress').'</legend>'."\n";
  315. echo ' <form method="post">'."\n";
  316. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  317. wp_nonce_field('podPress_botdb_nonce');
  318. }
  319. echo ' <table class="the-list-x widefat">'."\n";
  320. echo ' <thead>'."\n";
  321. 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";
  322. echo ' </thead>'."\n";
  323. echo ' <tbody>'."\n";
  324. $nobots = FALSE;
  325. if (is_array($botdb) and (is_array($botdb['fullbotnames']) OR is_array($botdb['IP'])) ) {
  326. $botnames_len = count($botdb['fullbotnames']);
  327. $IPs_len = count($botdb['IP']);
  328. $rows_total = max($botnames_len, $IPs_len);
  329. if ( $rows_total > ($start+$limit) ) {
  330. $high = $start+$limit;
  331. } else {
  332. $high = $rows_total;
  333. }
  334. $low = ($start+1);
  335. for ($i=$low; $i <= $high; $i++) {
  336. $style = ($i % 2) ? '' : ' class="alternate"';
  337. echo ' <tr'.$style.'>'."\n";
  338. echo ' <td>'.($start +$i).'.</td>'."\n";
  339. if ($i <= ($IPs_len-$start)) {
  340. $col_ip = ' <td>'.stripslashes($botdb['IP'][($i-1)]).'</td>'."\n";
  341. $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";
  342. } else {
  343. $col_ip = $col_ip_chb = ' <td></td>'."\n";
  344. }
  345. if ($i <= ($botnames_len-$start)) {
  346. $col_botname = ' <td>'.stripslashes($botdb['fullbotnames'][($i-1)]).'</td>'."\n";
  347. $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";
  348. } else {
  349. $col_botname = $col_botname_chb = ' <td></td>'."\n";
  350. }
  351. echo $col_ip.$col_botname.$col_ip_chb.$col_botname_chb;
  352. echo ' </tr>'."\n";
  353. }
  354. if ( 0 == $botnames_len AND 0 == $IPs_len ) {
  355. $nobots = TRUE;
  356. }
  357. } else {
  358. $nobots = TRUE;
  359. }
  360. if (TRUE == $nobots) {
  361. echo ' <td colspan="5">'.__('Currently are no IP addresses or user agents marked as bots.', 'podpress').'</td>'."\n";
  362. }
  363. echo ' </tbody>'."\n";
  364. echo ' <tfood>'."\n";
  365. echo ' <tr>'."\n";
  366. echo ' <th colspan="5">'."\n";
  367. // Show paging
  368. echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
  369. echo ' </th>'."\n";
  370. echo ' </tr>'."\n";
  371. echo ' </tfood>'."\n";
  372. echo ' </table>'."\n";
  373. echo ' <p class="submit"> '."\n";
  374. echo ' <input type="submit" name="Submit" value="'.__('Remove elements', 'podpress').' &raquo;" /><br />'."\n";
  375. echo ' </p> '."\n";
  376. echo ' <input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
  377. echo ' </form>'."\n";
  378. echo ' </fieldset>'."\n";
  379. echo ' </div>';
  380. break;
  381. case 'botdb_mark_bots':
  382. // ntm: stat logging: Full and Full+
  383. podPress_isAuthorized();
  384. $blog_charset = get_bloginfo('charset');
  385. $botdb = get_option('podpress_botdb');
  386. if ( 'botdb' == $_POST['podPress_submitted'] ) {
  387. if ( function_exists('check_admin_referer') ) {
  388. check_admin_referer('podPress_botdb_nonce');
  389. }
  390. $IPs = $_POST['podpress_remote_ips'];
  391. $fullbotnames = stripslashes_deep($_POST['podpress_user_agents']);
  392. if (is_array($botdb)) {
  393. $current_IP_set = $_POST['podpress_current_IP_set'];
  394. $unique_current_data_IPs = array_unique($_POST['podpress_current_IP_set']);
  395. //add new bots
  396. if (is_array($IPs)) {
  397. $unique_IPs = array_unique($IPs);
  398. foreach ($unique_IPs as $IP) {
  399. if (is_array($botdb['IP'])) {
  400. if ( FALSE === array_search($IP, $botdb['IP']) ) {
  401. $botdb['IP'][] = $IP;
  402. }
  403. } else {
  404. $botdb['IP'][] = $IP;
  405. }
  406. }
  407. // eventually remove bots
  408. $unmarked_IPs = array_diff($unique_current_data_IPs, $unique_IPs);
  409. $botdb['IP'] = array_diff($botdb['IP'], $unmarked_IPs);
  410. sort($botdb['IP']);
  411. } else {
  412. if (is_array($botdb['IP'])) {
  413. $botdb['IP'] = array_diff($botdb['IP'], $unique_current_data_IPs);
  414. sort($botdb['IP']);
  415. }
  416. }
  417. $current_user_agent_set = $_POST['podpress_current_user_agent_set'];
  418. $unique_current_data_fbnames = array_unique($_POST['podpress_current_user_agent_set']);
  419. if (is_array($fullbotnames)) {
  420. $unique_fullbotnames = array_unique($fullbotnames);
  421. foreach ($unique_fullbotnames as $fullbotname) {
  422. if (is_array($botdb['fullbotnames'])) {
  423. if ( FALSE === array_search($fullbotname, $botdb['fullbotnames']) ) {
  424. $botdb['fullbotnames'][] = $fullbotname;
  425. }
  426. } else {
  427. $botdb['fullbotnames'][] = $fullbotname;
  428. }
  429. }
  430. // eventually remove bots
  431. $unmarked_fullbotnames = array_diff($unique_current_data_fbnames, $unique_fullbotnames);
  432. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unmarked_fullbotnames);
  433. sort($botdb['fullbotnames']);
  434. } else {
  435. // eventually remove bots
  436. if (is_array($botdb['fullbotnames'])) {
  437. $botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unique_current_data_fbnames);
  438. sort($botdb['fullbotnames']);
  439. }
  440. }
  441. } else {
  442. //add new bots (first time)
  443. if (is_array($IPs)) {
  444. $unique_IPs = array_unique($IPs);
  445. foreach ($unique_IPs as $IP) {
  446. $botdb['IP'][] = $IP;
  447. }
  448. }
  449. if (is_array($fullbotnames)) {
  450. $unique_fullbotnames = array_unique($fullbotnames);
  451. foreach ($unique_fullbotnames as $fullbotname) {
  452. $botdb['fullbotnames'][] = $fullbotname;
  453. }
  454. }
  455. }
  456. $updated=update_option('podpress_botdb', $botdb);
  457. if (isset($updated) AND $updated == TRUE) {
  458. echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
  459. }
  460. }
  461. $where='';
  462. $rows_total = intval($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip, user_agent) AS total FROM '.$wpdb->prefix.'podpress_stats '.$where));
  463. $query_string = 'SELECT DISTINCT remote_ip, user_agent FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY dt DESC LIMIT '.$start.', '.$limit;
  464. $stats = $wpdb->get_results($query_string);
  465. echo ' <div class="wrap">'."\n";
  466. echo ' <fieldset class="options">'."\n";
  467. echo ' <legend>'.__('Which IP address or user agent name is from a web bot?', 'podpress').'</legend>'."\n";
  468. 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";
  469. echo ' <form method="post">'."\n";
  470. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  471. wp_nonce_field('podPress_botdb_nonce');
  472. }
  473. echo "\n".' <table class="the-list-x widefat">'."\n";
  474. echo ' <thead>'."\n";
  475. 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";
  476. echo ' </thead>'."\n";
  477. echo ' <tbody>'."\n";
  478. if(0 < count($stats)) {
  479. $i = 0;
  480. foreach ($stats as $stat) {
  481. ++$i;
  482. $alternate = ($i % 2) ? '' : 'alternate';
  483. $bot_style = '';
  484. $ip_chb_checked = '';
  485. $name_chb_checked = '';
  486. if (TRUE == is_array($botdb)) {
  487. if (TRUE == is_array($botdb['IP']) AND FALSE !== array_search($stat->remote_ip, $botdb['IP'])) {
  488. $bot_style = ' podpress_is_bot';
  489. $ip_chb_checked = ' checked="checked"';
  490. }
  491. if (TRUE == is_array($botdb['fullbotnames']) AND FALSE !== array_search($stat->user_agent, $botdb['fullbotnames'])) {
  492. $bot_style = ' podpress_is_bot';
  493. $name_chb_checked = ' checked="checked"';
  494. }
  495. }
  496. echo ' <tr id ="podpress_ip_user_agent_row_'.($i).'" class="'.$alternate.$bot_style.'">'."\n";
  497. echo ' <td>'.($start+$i).'</td>'."\n";
  498. echo ' <td>'.$stat->remote_ip.'<input type="hidden" name="podpress_current_IP_set[]" value="'.$stat->remote_ip.'" /></td>'."\n";
  499. 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";
  500. 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";
  501. 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";
  502. echo ' </tr>'."\n";
  503. }
  504. } else {
  505. echo '<td colspan="5">'.__('No downloads yet.','podpress')."</td>\n";
  506. }
  507. echo ' </tbody>'."\n";
  508. echo ' <tfood>'."\n";
  509. echo ' <tr>'."\n";
  510. echo ' <th colspan="5">'."\n";
  511. // Show paging
  512. echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
  513. echo ' </th>'."\n";
  514. echo ' </tr>'."\n";
  515. echo ' </tfood>'."\n";
  516. echo ' </table>'."\n";
  517. echo ' <p class="submit"> '."\n";
  518. echo ' <input type="submit" name="Submit" value="'.__('Update Options', 'podpress').' &raquo;" /><br />'."\n";
  519. echo ' </p> '."\n";
  520. echo ' <input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
  521. echo ' </form>'."\n";
  522. echo ' </fieldset>'."\n";
  523. echo ' </div>';
  524. break;
  525. case 'downloads_per_media_file':
  526. // ntm: stat logging: Full and Full+
  527. $where = $this->wherestr_to_exclude_bots('pod');
  528. $query_string = "SELECT COUNT(DISTINCT pod.media) as total_rows FROM ".$wpdb->prefix."podpress_stats as pod ".$where;
  529. $rows_total = intval($wpdb->get_var($query_string));
  530. $query_string = "SELECT DISTINCT (pod.media) FROM ".$wpdb->prefix."podpress_stats as pod ".$where." LIMIT ".$start.", ".$limit;
  531. $posts_with_podpressmedia = $wpdb->get_results($query_string);
  532. $nr_postswpm = count($posts_with_podpressmedia);
  533. if ( 0 < $nr_postswpm) {
  534. $i=1;
  535. if (FALSE == empty($where)) {
  536. $where_posts = "AND pod.media IN (";
  537. } else {
  538. $where_posts = "WHERE pod.media IN (";
  539. }
  540. foreach ($posts_with_podpressmedia as $post) {
  541. if ($i == $nr_postswpm) {
  542. $where_posts .= "'".$post->media."'";
  543. } else {
  544. $where_posts .= "'".$post->media."', ";
  545. }
  546. $i++;
  547. }
  548. $where_posts .= ") ";
  549. } else {
  550. $where_posts = '';
  551. }
  552. $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";
  553. $stat_data_sets = $wpdb->get_results($query_string);
  554. if (FALSE == empty($where)) {
  555. $where_or_and = "AND";
  556. } else {
  557. $where_or_and = "WHERE";
  558. }
  559. $methods = Array('feed', 'web', 'play');
  560. foreach ($methods as $method) {
  561. $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";
  562. $downloads_col = $wpdb->get_col($query_string);
  563. switch ($method) {
  564. case 'feed' :
  565. $feed_max = intval($downloads_col[0]);
  566. break;
  567. case 'web' :
  568. $web_max = intval($downloads_col[0]);
  569. break;
  570. case 'play' :
  571. $play_max = intval($downloads_col[0]);
  572. break;
  573. }
  574. }
  575. $query_string="SELECT COUNT(*) as downloads, pod.media FROM ".$wpdb->prefix."podpress_stats AS pod ".$where." GROUP BY pod.media ORDER BY downloads DESC";
  576. $downloads_col = $wpdb->get_col($query_string);
  577. $total_max = intval($downloads_col[0]);
  578. // prepare the query result for the output:
  579. // - if a media file was not downloaded by one or more method then add this method and a int(0) to the media file
  580. foreach ($stat_data_sets as $stat_data_set) {
  581. $feed = $web = $play = 0;
  582. switch ($stat_data_set->method) {
  583. case 'feed' :
  584. $feed = intval($stat_data_set->downloads);
  585. break;
  586. case 'web' :
  587. $web = intval($stat_data_set->downloads);
  588. break;
  589. case 'play' :
  590. $play = intval($stat_data_set->downloads);
  591. break;
  592. }
  593. $total_sum = $feed+$web+$play;
  594. $stats[$stat_data_set->media]['feed'] += $feed;
  595. $stats[$stat_data_set->media]['web'] += $web;
  596. $stats[$stat_data_set->media]['play'] += $play;
  597. $stats[$stat_data_set->media]['total'] += $total_sum;
  598. }
  599. // sort the media files by their 'total' value
  600. if (is_array($stats)) {
  601. uasort($stats, array(self, 'sort_downloads_per_media_desc'));
  602. }
  603. echo ' <div class="wrap">'."\n";
  604. echo ' <fieldset class="options">'."\n";
  605. echo ' <legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  606. echo ' <table class="the-list-x widefat">'."\n";
  607. echo ' <thead>';
  608. echo " <tr>\n";
  609. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  610. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  611. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  612. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
  613. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  614. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  615. echo ' </tr>'."\n";
  616. echo ' <tr>'."\n";
  617. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  618. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  619. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  620. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  621. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  622. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  623. echo ' </tr>'."\n";
  624. echo ' </thead>';
  625. echo ' <tbody>';
  626. if (0 < count($stat_data_sets)) {
  627. $i = 0;
  628. foreach ( $stats as $media => $downloads_per_method ) {
  629. $i++;
  630. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  631. $highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
  632. $highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
  633. $highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
  634. $highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
  635. $perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  636. $perc_web = number_format(($downloads_per_method['web'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  637. $perc_play = number_format(($downloads_per_method['play'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  638. echo ' <tr'.$style.'>'."\n";
  639. echo ' <td>'.($start +$i).'.</td>'."\n";
  640. echo ' <td>'.podPress_strlimiter2(urldecode($media), 50, TRUE).'</td>'."\n";
  641. 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";
  642. echo ' <td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
  643. 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";
  644. echo ' <td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
  645. 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";
  646. echo ' <td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
  647. 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";
  648. echo ' </tr>'."\n";
  649. }
  650. } else {
  651. if (FALSE == empty($where)) {
  652. echo '<td colspan="9">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  653. } else {
  654. echo '<td colspan="9">'.__('No downloads yet.','podpress')."</td>\n";
  655. }
  656. }
  657. echo ' </tbody>';
  658. echo ' <tfood>'."\n";
  659. echo ' <tr>'."\n";
  660. echo ' <th colspan="9">'."\n";
  661. // Show paging
  662. echo $this->paging2($start, $limit, $rows_total, __('Ranks','podpress'));
  663. echo ' </th>'."\n";
  664. echo ' </tr>'."\n";
  665. echo ' </tfood>'."\n";
  666. echo ' </table>'."\n";
  667. echo ' </fieldset>'."\n";
  668. echo ' </div>';
  669. break;
  670. case 'rawstats':
  671. // ntm: stat logging: Full and Full+
  672. $date_format = get_option('date_format');
  673. $time_format = get_option('time_format');
  674. $botdb = get_option('podpress_botdb');
  675. $where = '';
  676. $rows_total = $wpdb->get_var('SELECT COUNT(*) FROM '.$wpdb->prefix.'podpress_stats '.$where);
  677. $stats = $wpdb->get_results('SELECT * FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY id DESC LIMIT '.$start.', '.$limit);
  678. echo ' <div class="wrap">'."\n";
  679. echo ' <fieldset class="options">'."\n";
  680. echo ' <legend>'.__('The raw list', 'podpress').'</legend>'."\n";
  681. echo ' <table class="the-list-x widefat">'."\n"; //width="100%" cellpadding="1" cellspacing="1"
  682. echo ' <thead>';
  683. 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";
  684. echo ' </thead>';
  685. echo ' <tbody>';
  686. if(0 < count($stats)) {
  687. if ( TRUE === is_array($botdb['IP']) OR TRUE === is_array($botdb['fullbotnames']) ) {
  688. $i = 0;
  689. foreach ($stats as $stat) {
  690. ++$i;
  691. $style = ($i % 2) ? '' : 'alternate';
  692. if ( (FALSE !== empty($botdb['fullbotnames']) OR FALSE === array_search($stat->user_agent, $botdb['fullbotnames']))) {
  693. if ( (FALSE !== empty($botdb['IP']) OR FALSE === array_search($stat->remote_ip, $botdb['IP']))) {
  694. $bot_style = '';
  695. } else {
  696. $bot_style = ' podpress_is_bot';
  697. }
  698. } else {
  699. $bot_style = ' podpress_is_bot';
  700. }
  701. echo ' <tr class="'.$style.$bot_style.'">'."\n";
  702. echo ' <td>'.($start +$i).'.</td>'."\n";
  703. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
  704. echo ' <td>'.$stat->method.'</td>'."\n";
  705. // iscifi : mod of stats output to create a link to domaintools.com whois lookup
  706. // domaintools seems faster and provides more concise infomation, url can not have trailing /
  707. 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";
  708. // OLD code where this .echo ' <td>'.$stat->remote_ip.'</td>'."\n";
  709. echo ' <td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
  710. echo ' <td>'.date($date_format.' - '.$time_format, intval($stat->dt)).'</td>'."\n";
  711. echo ' </tr>'."\n";
  712. }
  713. } else {
  714. $i = 0;
  715. foreach ($stats as $stat) {
  716. ++$i;
  717. $style = ($i % 2) ? '' : 'alternate';
  718. echo ' <tr class="'.$style.'">'."\n";
  719. echo ' <td>'.($start +$i).'.</td>'."\n";
  720. echo ' <td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
  721. echo ' <td>'.$stat->method.'</td>'."\n";
  722. // iscifi : mod of stats output to create a link to domaintools.com whois lookup
  723. // domaintools seems faster and provides more concise infomation, url can not have trailing /
  724. echo ' <td><a href="http://whois.domaintools.com/'.$stat->remote_ip.'" target="_blank">'.$stat->remote_ip.'</a></td>'."\n";
  725. // OLD code where this .echo ' <td>'.$stat->remote_ip.'</td>'."\n";
  726. echo ' <td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
  727. echo ' <td>'.date($date_format.' - '.$time_format, intval($stat->dt)).'</td>'."\n";
  728. echo ' </tr>'."\n";
  729. }
  730. }
  731. } else {
  732. echo '<td colspan="6">'.__('No downloads yet.','podpress').'</td>'."\n";
  733. }
  734. echo ' </tbody>';
  735. echo ' <tfood>'."\n";
  736. echo ' <tr>'."\n";
  737. echo ' <th colspan="6">'."\n";
  738. // Show paging
  739. echo $this->paging2($start, $limit, $rows_total, __('Hit','podpress'));
  740. echo ' </th>'."\n";
  741. echo ' </tr>'."\n";
  742. echo ' </tfood>'."\n";
  743. echo ' </table>'."\n";
  744. echo ' </fieldset>'."\n";
  745. echo ' </div>';
  746. break;
  747. case 'topips':
  748. // ntm: stat logging: Full and Full+
  749. $where = $this->wherestr_to_exclude_bots();
  750. $rows_total = ($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip) as uniq FROM '.$wpdb->prefix.'podpress_stats '.$where));
  751. $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;
  752. $stats = $wpdb->get_results($sql);
  753. echo ' <div class="wrap">'."\n";
  754. echo ' <fieldset class="options">'."\n";
  755. echo ' <legend>'.__('Top IP Addresses', 'podpress').'</legend>'."\n";
  756. echo ' <table class="the-list-x widefat">'."\n";
  757. echo ' <thead>';
  758. 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";
  759. echo ' </thead>';
  760. echo ' <tbody>';
  761. if(0<count($stats)) {
  762. $i = 0;
  763. foreach ($stats as $stat) {
  764. ++$i;
  765. $style = ($i % 2) ? '' : ' class="alternate"';
  766. echo ' <tr'.$style.'>'."\n";
  767. echo ' <td>'.($start +$i).'.</td>'."\n";
  768. echo ' <td>'.$stat->IPAddress.'</td>'."\n";
  769. echo ' <td>'.$stat->uniq.'</td>'."\n";
  770. echo ' <td>'.$stat->total.'</td>'."\n";
  771. echo ' </tr>'."\n";
  772. }
  773. } else {
  774. if (FALSE == empty($where)) {
  775. echo '<td colspan="4">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
  776. } else {
  777. echo '<td colspan="4">'.__('No downloads yet.','podpress')."</td>\n";
  778. }
  779. }
  780. echo ' </tbody>';
  781. echo ' <tfood>'."\n";
  782. echo ' <tr>'."\n";
  783. echo ' <th colspan="4">'."\n";
  784. // Show paging
  785. echo $this->paging2($start, $limit, $rows_total, __('IP Address','podpress'));
  786. echo ' </th>'."\n";
  787. echo ' </tr>'."\n";
  788. echo ' </tfood>'."\n";
  789. echo ' </table>'."\n";
  790. echo ' </fieldset>'."\n";
  791. echo ' </div>';
  792. break;
  793. case 'graphbydate':
  794. // ntm: stat logging: Full and Full+
  795. if ($this->checkGD() ) {//&& ($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus')
  796. $this->graphByDate();
  797. } else {
  798. $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.');
  799. }
  800. break;
  801. case 'graphbydatealt':
  802. // ntm: stat logging: Full and Full+
  803. $this->graphByDateAlt();
  804. break;
  805. case 'graphbypost':
  806. // ntm: stat logging: Counts Only
  807. 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>';
  808. if ($this->checkGD()) {
  809. $this->graphByPost();
  810. } else {
  811. $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.');
  812. }
  813. break;
  814. case 'graphbypostalt':
  815. // ntm: stat logging: Counts Only
  816. 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>';
  817. $this->graphByPostAlt();
  818. break;
  819. case 'downloads_per_post' :
  820. // ntm: stat logging: Full and Full+
  821. $where = $this->wherestr_to_exclude_bots('pod');
  822. // get the number of all post with podPress podcasts
  823. $query_string = "SELECT COUNT(DISTINCT postID) as posts FROM ".$wpdb->prefix."podpress_stats ".$where;
  824. // get all post with podPress podcasts
  825. $query_string="SELECT DISTINCT(pod.postID), p.post_title FROM ".$wpdb->prefix."podpress_stats AS pod LEFT JOIN ".$wpdb->prefix."posts AS p ON pod.postID = p.ID ".$where." ORDER BY pod.postID DESC";
  826. $posts_with_podpressmedia = $wpdb->get_results($query_string);
  827. echo ' <div class="wrap">'."\n";
  828. echo ' <fieldset class="options">'."\n";
  829. echo ' <legend>'.__('Downloads Per Post', 'podpress').'</legend>'."\n";
  830. echo ' <form method="post">'."\n";
  831. if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
  832. wp_nonce_field('podPress_downloads_per_post_nonce');
  833. }
  834. echo ' <label>'.__('Select a post with a media file (attached with podPress):', 'podpress').'</label><br />'."\n";
  835. echo ' <select id="post_with_podpressmedia" name="post_with_podpressmedia" size="5">'."\n";
  836. foreach ($posts_with_podpressmedia as $post) {
  837. if ($post->postID == $_POST['post_with_podpressmedia']) {
  838. $selected = ' selected="selected"';
  839. } else {
  840. $selected = '';
  841. }
  842. echo ' <option value="'.$post->postID.'"'.$selected.'>'.$post->post_title.'</option>'."\n";
  843. $post_titles[$post->postID] = $post->post_title;
  844. }
  845. echo ' </select>'."\n";
  846. echo ' <p class="submit"> '."\n";
  847. echo ' <input type="submit" name="Submit" value="'.__('Show the stats for this post', 'podpress').' &raquo;" /><br />'."\n";
  848. echo ' </p> '."\n";
  849. echo ' <input type="hidden" name="podPress_submitted" value="downloadsperpost" />'."\n";
  850. echo ' </form>'."\n";
  851. echo ' </fieldset>'."\n";
  852. echo ' </div><!-- .wrap -->'."\n";
  853. // show the statistics of the media files of the submitted post
  854. if ( 'downloadsperpost' == $_POST['podPress_submitted'] ) {
  855. if ( function_exists('check_admin_referer') ) {
  856. check_admin_referer('podPress_downloads_per_post_nonce');
  857. }
  858. if (FALSE == empty($where)) {
  859. $where_postID = "AND pod.postID = '".$_POST['post_with_podpressmedia']."' ";
  860. } else {
  861. $where_postID = "WHERE pod.postID = '".$_POST['post_with_podpressmedia']."' ";
  862. }
  863. $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";
  864. $stat_data_sets = $wpdb->get_results($query_string);
  865. // prepare the query result for the output:
  866. // - find the maximal downloads value for each download method
  867. // - if a media file was not downloaded by one or more method then add this method and a int(0) to the media file
  868. $feed_max = 0;
  869. $web_max = 0;
  870. $play_max = 0;
  871. $total_max = 0;
  872. foreach ($stat_data_sets as $stat_data_set) {
  873. $feed = 0;
  874. $web = 0;
  875. $play = 0;
  876. switch ($stat_data_set->method) {
  877. case 'feed' :
  878. $feed = intval($stat_data_set->downloads);
  879. $feed_max = max($feed_max, $feed);
  880. break;
  881. case 'web' :
  882. $web = intval($stat_data_set->downloads);
  883. $web_max = max($web_max, $web);
  884. break;
  885. case 'play' :
  886. $play = intval($stat_data_set->downloads);
  887. $play_max = max($play_max, $play);
  888. break;
  889. }
  890. $stats[$stat_data_set->media]['feed'] += $feed;
  891. $stats[$stat_data_set->media]['web'] += $web;
  892. $stats[$stat_data_set->media]['play'] += $play;
  893. $stats[$stat_data_set->media]['total'] += ($feed + $web + $play);
  894. $total_max = max($total_max, $stats[$stat_data_set->media]['total']);
  895. }
  896. // sort the media files by their 'total' value
  897. uasort($stats, array(self, 'sort_downloads_per_media_desc'));
  898. echo ' <div class="wrap">'."\n";
  899. echo ' <fieldset class="options">'."\n";
  900. echo ' <legend>'.__('Post:', 'podpress')." ".$post_titles[$_POST['post_with_podpressmedia']]." - ".__('Downloads Per Media File', 'podpress').'</legend>'."\n";
  901. echo ' <table class="the-list-x widefat">'."\n";
  902. echo ' <thead>';
  903. echo " <tr>\n";
  904. echo ' <th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
  905. echo ' <th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
  906. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
  907. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
  908. echo ' <th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
  909. echo ' <th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
  910. echo ' </tr>'."\n";
  911. echo ' <tr>'."\n";
  912. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  913. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  914. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  915. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  916. echo ' <th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
  917. echo ' <th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
  918. echo ' </tr>'."\n";
  919. echo ' </thead>';
  920. echo ' <tbody>';
  921. $mark_highest = FALSE;
  922. $nr_stat_data_sets = count($stat_data_sets);
  923. if (0 < $nr_stat_data_sets) {
  924. if ( 1 < $nr_stat_data_sets ) {
  925. $mark_highest = TRUE;
  926. }
  927. $i = 0;
  928. foreach ( $stats as $media => $downloads_per_method ) {
  929. $i++;
  930. $style = ($i % 2 != 0) ? '' : ' class="alternate"';
  931. if (TRUE === $mark_highest) {
  932. $highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
  933. $highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
  934. $highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
  935. $highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
  936. }
  937. $perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  938. $perc_web = number_format(($downloads_per_method['web'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  939. $perc_play = number_format(($downloads_per_method['play'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
  940. echo ' <tr'.$style.'>'."\n";
  941. echo ' <td>'.($start +$i).'.</td>'."\n";
  942. echo ' <td>'.podPress_strlimiter2(urldecode($media), 50, TRUE).'</td>'."\n";
  943. 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…

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