PageRenderTime 392ms CodeModel.GetById 114ms app.highlight 162ms RepoModel.GetById 66ms app.codeStats 1ms

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

https://bitbucket.org/sergiohzlz/reportaprod
PHP | 1835 lines | 1489 code | 155 blank | 191 comment | 277 complexity | 668f50afdac4dd874a3b2e4d670a6f56 MD5 | raw file

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

   1<?php
   2/*
   3License:
   4 ==============================================================================
   5
   6    Copyright 2006  Dan Kuykendall  (email : dan@kuykendall.org)
   7    Modifications:  Jeff Norris     (email : jeff@iscifi.tv)
   8    Thanks to The P2R Team ( prepare2respond.com ) for stats suggestions.
   9
  10
  11    This program is free software; you can redistribute it and/or modify
  12    it under the terms of the GNU General Public License as published by
  13    the Free Software Foundation; either version 2 of the License, or
  14    (at your option) any later version.
  15
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20
  21    You should have received a copy of the GNU General Public License
  22    along with this program; if not, write to the Free Software
  23    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-107  USA
  24*/
  25class podPressAdmin_class extends podPress_class {
  26	function podPressAdmin_class() {
  27		GLOBAL $wpdb;
  28		
  29		$this->path = get_option('siteurl').'/wp-admin/admin.php?page=podpress/podpress_stats.php';
  30		if (isset($_GET['display']) && is_string($_GET['display'])) {
  31			$this->path .= '&amp;display='.$_GET['display'];
  32		}
  33		
  34		// since 8.8.5 beta 3
  35		parent::wherestr_to_exclude_bots();
  36		
  37		$this->wpdb                 = $wpdb;
  38
  39		/* set default language for graphs */
  40		$languages        = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
  41		$primary_language = $languages[0];
  42		if (in_array($primary_language, array('de-de', 'de'))) {
  43			/* German specification */
  44			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');
  45
  46			$local_settings = array(
  47			                        'numbers'       => array(',', '.'),
  48			                        'short_date'    => '%a.%n%d.%m.%y',
  49			                        'creation_date' => '%d.%m.%y',
  50			                      );
  51		} else {
  52			/* default specification: english */
  53			setlocale(LC_TIME, 'en_US:UTF-8', 'en_en:UTF-8', 'en:UTF-8');
  54
  55			$local_settings = array(
  56			                        'numbers' => array('.', ','),
  57			                        'short_date' => '%a.%n%m/%d/%y',
  58			                        'creation_date' => '%m/%d/%y',
  59			                       );
  60		}
  61		$this->local_settings = $local_settings;
  62
  63		$this->podPress_class();
  64		return;
  65	}
  66
  67	#############################################
  68	#############################################
  69
  70	function podSafeDigit($digit = 0) {
  71		if (is_numeric($digit) && ($digit < 10000)) {
  72			$digit = abs((int)$digit);
  73		} else {
  74			$digit = 0;
  75		}
  76		return $digit;
  77	}
  78
  79	#############################################
  80	#############################################
  81
  82	function paging($start, $limit, $total, $text = null) {
  83		$pages = ceil($total / $limit);
  84		$actualpage = ceil($start / $limit);
  85
  86		if ($pages > 0) {
  87			if ($start > 0) {
  88				$start_new = ($start - $limit < 0) ? 0 : ($start - $limit);
  89				$right = '<a href="'.$this->path.'&amp;start='.$start_new.'">'.__('Next Entries &raquo;').'</a>';
  90			}
  91
  92			if ($start + $limit < $total) {
  93				$start_new = ($start + $limit);
  94				$left = '<a href="'.$this->path.'&amp;start='.$start_new.'">'.__('&laquo; Previous Entries').'</a>';
  95			}
  96
  97			echo '<div id="podPress_paging">'."\n";
  98			echo '	<div id="podPress_pagingLeft">'."\n";
  99			if ($pages > 1) {
 100				if (!is_null($text)) {
 101					echo $text;
 102				}
 103				echo '    <select name="podPress_pageSelect" onchange="javascript: window.location = \''.$this->path.'&start=\'+this.value;">';
 104				$i = 0;
 105				while ($i < $total) {
 106					$selected = ($i == $start) ? ' selected="selected"': null;
 107					$newi = ($i + $limit);
 108					if ($newi > $total) {
 109						$newi = $total;
 110					}
 111					echo '    	<option value="'.$i.'"'.$selected.'>'.ceil($total - ($newi - 1)).' - '.ceil($total - ($i)).'</option>';
 112					#$i = ($newi + 1);
 113					$i = $newi;
 114				}
 115				echo '	</select>';
 116
 117				echo '	'.__('of', 'podpress').' '.$total;
 118			}
 119			echo '	</div>'."\n";
 120
 121			echo '	<div id="podPress_pagingRight">';
 122				if ($start + $limit < $total) {
 123					echo $left;
 124				}
 125				if (($start + $limit < $total) AND ($start > 0)) {
 126					echo '&nbsp;&nbsp;|&nbsp;&nbsp;';
 127				}
 128				if ($start > 0) {
 129					echo $right;
 130				}
 131			echo "	</div>\n";
 132			echo "</div>\n";
 133		}
 134	}
 135	
 136	// ntm: paging() revised for v8.8.5 beta 3
 137	// -'previous/next entries' string swaped
 138	// - '$text from x to y' - select box revised
 139	function paging2($start, $limit, $total, $text = null) {
 140		$pages = ceil($total / $limit);
 141		if ($pages > 0) {
 142			echo '<div id="podPress_paging">'."\n";
 143			echo '	<div id="podPress_pagingLeft">'."\n";
 144			if ($pages > 1) {
 145				if (!is_null($text)) {
 146					echo $text;
 147				}
 148				echo '    <select name="podPress_pageSelect" onchange="javascript: window.location = \''.$this->path.'&start=\'+this.value;">';
 149				$low = (1);
 150				for ($i=$low; $i <= $total; $i++) {
 151					$selected = (($i-1) == $start) ? ' selected="selected"': '';
 152					if ( ($i % $limit) == 1 ) {
 153						if ((($low-1)+$limit) < $total) {
 154							$high = ($low-1)+$limit;
 155						} else {
 156							$high = $total;
 157						}
 158						if ($low != $high) {
 159							echo '    		<option value="'.($i-1).'"'.$selected.'>'.$low.' - '.$high.'</option>';
 160						} else {
 161							echo '    		<option value="'.($i-1).'"'.$selected.'>'.$high.'</option>';
 162						}
 163						$low += $limit;
 164					} 
 165				}
 166				echo '	</select>';
 167
 168				echo '	'.__('of', 'podpress').' '.$total;
 169			}
 170			//echo '<p>'.$start.' | '.$limit.' | '.$total.' | '.$text.'</p>';
 171			echo '	</div>'."\n";
 172
 173			if ($start + $limit < $total) {
 174				$right = '<a href="'.$this->path.'&amp;start='.($start+$limit).'">'.__('Next Entries &raquo;').'</a>';
 175			}
 176			if ($start > 0) {
 177				$left = '<a href="'.$this->path.'&amp;start='.($start-$limit).'">'.__('&laquo; Previous Entries').'</a>';
 178			}
 179
 180			echo '	<div id="podPress_pagingRight">';
 181				if ($start > 0) {
 182					echo $left;
 183				}
 184				if (($start + $limit < $total) AND ($start > 0)) {
 185					echo '&nbsp;|&nbsp;';
 186				}
 187				if ($start + $limit < $total) {
 188					echo $right;
 189				}
 190			echo "	</div>\n";
 191			echo "</div>\n";
 192		}
 193	}
 194
 195	#############################################
 196	#############################################
 197
 198	function podGetHighest($data) {
 199		$highest = 0;
 200		foreach ($data AS $key => $idata) {
 201			if ($idata->value > $highest) {
 202				$highest = $idata->value;
 203			}
 204		}
 205		return $highest;
 206	}
 207
 208	#############################################
 209	#############################################
 210
 211	function podGraph($data, $splitter = null) {
 212		$cnt_data   = count($data);
 213
 214		if ($cnt_data > 0) {
 215    		$box_width  = 600;
 216    		$box_height = 400;
 217    		$bar_margin = 2;
 218    		$bar_width  = floor(($box_width - ($cnt_data * $bar_margin)) / $cnt_data);
 219    		$bar_width  = ($bar_width < 2) ? 2: $bar_width;
 220    		$highest    = $this->podGetHighest($data);
 221    		$factor     = ($highest / $box_height);
 222
 223    		$output     = '<div id="podGraph" style="height: '.$box_height.'px; width: '.$box_width.'px; float: left; border: 1px solid #ccc; padding: 0.5em;">';
 224    		foreach ($data AS $key => $idata) {
 225    			$image_height  = floor($idata->value / $factor);
 226    			$margin  = ($box_height - $image_height);
 227    			$bgcolor = (is_array($splitter) && ($idata->$splitter[0] == $splitter[1])) ? '#aaa': '#ccc';
 228    			$bgcolor = ($image_height == $box_height) ? '#d00': $bgcolor;
 229    			$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";
 230    		}
 231    		$output .= "</div>\n";
 232		} else {
 233            $output = '<p>'.__('We\'re sorry. At the moment we don\'t have enough data collected to display the graph.', 'podpress')."</p>\n";
 234		}
 235
 236		return $output;
 237	}
 238
 239	#############################################
 240	#############################################
 241
 242	function settings_stats_edit() {
 243		GLOBAL $wpdb, $wp_version;
 244		podPress_isAuthorized();
 245		$baseurl = get_option('siteurl') . '/wp-admin/admin.php?page=podpress/podpress_stats.php&display=';
 246		echo '<div class="wrap">'."\n";
 247		
 248		if ( TRUE == version_compare($wp_version, '2.7', '>=') ) {
 249			echo '<div id="podpress-icon" class="icon32"><br /></div>';
 250		} 
 251		if ( TRUE == version_compare($wp_version, '2.8', '>=') ) {
 252			echo '	<h2>'.__('Download Statistics', 'podpress').'</h2>'."\n";
 253			// get the plugins version information via the WP plugins version check
 254			if ( TRUE == version_compare($wp_version, '2.9', '>=') ) {
 255				$versioninfo = get_site_transient( 'update_plugins' );
 256			} else {
 257				$versioninfo = get_transient( 'update_plugins' );
 258			}
 259			// If there is a new version then there is a 'response'. This is the method from the plugins page. 
 260			if ( FALSE !== isset($versioninfo->response[plugin_basename(dirname(__FILE__).'/podpress.php')]->new_version) ) {
 261				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>';
 262			}
 263		} else {
 264			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";
 265		}
 266		
 267		if($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus') {
 268			// Show all statistics which are based on wp_stats [stat logging: Full and Full+]
 269			$navi = array(
 270				'downloads_per_media_file' => __('Downloads Per Media File', 'podpress'),
 271				'downloads_per_post' => __('Downloads Per Post', 'podpress'),
 272				'topips' => __('Downloads Per IP Address', 'podpress'),
 273				'graphbydate' => __('Graph by Date', 'podpress'),
 274				'rawstats' => __('Raw Stats', 'podpress'),
 275			);
 276			echo '	<ul id="podPress_navi">'."\n";
 277			foreach ($navi AS $key => $value) {
 278				$active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'downloads_per_media_file'))) ? ' class="current"': null;
 279				echo '        	<li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a>';
 280				if($this->checkGD()) {
 281					if ($value == __('Graph by Date', 'podpress')) {
 282						echo ' (<a href="'.$baseurl.'graphbydatealt" title="'.sprintf(__('An alternative view of the %1$s', 'podpress'), __('Graph by Date', 'podpress')).'">'. __('alt', 'podpress').'</a>)';
 283					}
 284				}
 285				echo '</li>'."\n";
 286			}
 287			echo '	</ul>'."\n";
 288			
 289			// bot management menu (since 8.8.5 beta 3)
 290			$navi2 = array(
 291				'botdb_mark_bots' => __('Select / Deselect Bots', 'podpress'),
 292				'botdb_list' => __('List of Bots', 'podpress'),
 293			);
 294			echo '	<ul id="podPress_navi">'."\n";
 295			foreach ($navi2 AS $key => $value) {
 296				$active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'quickcounts'))) ? ' class="current"': null;
 297				echo '        	<li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a></li>'."\n";
 298			}
 299			echo '	</ul>'."\n";
 300			
 301		} else {
 302		
 303			// Show all statistics which are based on wp_statcounts	[stat logging: Counts Only]
 304			// old: $_GET['display'] = 'downloads_per_media_file';
 305			$navi = array(
 306				'quickcounts' => __('Quick Counts', 'podpress'),
 307				'graphbypost' => __('Graph by Post', 'podpress'),
 308			);
 309			echo '	<ul id="podPress_navi">'."\n";
 310			foreach ($navi AS $key => $value) {
 311				$active = (($_GET['display'] == $key) OR (!$_GET['display'] AND ($key == 'quickcounts'))) ? ' class="current"': null;
 312				echo '        	<li class="podpress_stats_sub_menu_item"><a href="'.$baseurl.$key.'"'.$active.'>'.$value.'</a>';
 313				if($this->checkGD()) {
 314					if($value == __('Graph by Post', 'podpress')) {
 315						echo ' (<a href="'.$baseurl.'graphbypostalt" title="'.sprintf(__('An alternative view of the %1$s', 'podpress'), __('Graph by Post', 'podpress')).'">'. __('alt', 'podpress').'</a>)';
 316					}
 317				}
 318				echo '</li>'."\n";
 319			}
 320			echo '	</ul>'."\n";
 321
 322		}
 323
 324		// Set Paging-Settings
 325		$start = (isset($_GET['start'])) ? $this->podSafeDigit($_GET['start']): 0;
 326		
 327		//~ ####################
 328		//~ Limit is limits the number of rows of the statistic tables
 329		$limit = 25;
 330		//~ ####################
 331		
 332		// 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)
 333		if (FALSE == isset($_GET['display']) OR FALSE !== empty($_GET['display'])) {
 334			if ($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus') {
 335				$show_this_page = 'downloads_per_media_file';
 336			} else {
 337				$show_this_page = 'quickcounts';
 338			}
 339		} else {
 340			$show_this_page = $_GET['display'];
 341		}
 342		Switch($show_this_page) {
 343			case 'botdb_list':
 344				// ntm: stat logging: Full and Full+
 345				podPress_isAuthorized();
 346				$botdb = get_option('podpress_botdb');
 347				if ( 'botdb' == $_POST['podPress_submitted'] ) {
 348					if ( function_exists('check_admin_referer') ) {
 349						check_admin_referer('podPress_botdb_nonce');
 350					}
 351					$IPs = $_POST['podpress_remote_ips'];
 352					$fullbotnames = stripslashes_deep($_POST['podpress_user_agents']);
 353					if ( is_array($botdb) ) {
 354						$something_removed=FALSE;
 355						if ( is_array($IPs) and is_array($botdb['IP'])) {
 356							$botdb['IP'] = array_diff($botdb['IP'], $IPs);
 357							sort($botdb['IP']);
 358						}
 359						if ( is_array($fullbotnames) and is_array($botdb['fullbotnames'])) {
 360							$botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $fullbotnames);
 361							sort($botdb['fullbotnames']);
 362						}
 363					}
 364					$updated=update_option('podpress_botdb', $botdb);
 365					if (isset($updated) AND $updated == TRUE) {
 366						echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
 367					}
 368				}
 369				
 370				echo '	<div class="wrap">'."\n";
 371				echo '		<fieldset class="options">'."\n";
 372				echo '			<legend>'.__('The list of IP addresses and names of bots', 'podpress').'</legend>'."\n";
 373				echo '			<form method="post">'."\n";
 374				if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
 375					wp_nonce_field('podPress_botdb_nonce');
 376				}
 377				echo '			<table class="the-list-x widefat">'."\n";
 378				echo '				<thead>'."\n";
 379				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";
 380				echo '				</thead>'."\n";
 381				echo '				<tbody>'."\n";
 382				$nobots = FALSE;
 383				if (is_array($botdb) and (is_array($botdb['fullbotnames']) OR is_array($botdb['IP'])) ) {
 384					$botnames_len = count($botdb['fullbotnames']);
 385					$IPs_len = count($botdb['IP']);
 386					$rows_total = max($botnames_len, $IPs_len);
 387					if ( $rows_total > ($start+$limit) ) {
 388						$high = $start+$limit;
 389					} else {
 390						$high = $rows_total;
 391					}
 392					$low = ($start+1);
 393					for ($i=$low; $i <= $high; $i++) {
 394						$style = ($i % 2) ? '' : ' class="alternate"';
 395						echo '				<tr'.$style.'>'."\n";
 396							echo '                  			<td>'.($start +$i).'.</td>'."\n";
 397						if ($i <= ($IPs_len-$start)) {
 398							$col_ip = '                  			<td>'.stripslashes($botdb['IP'][($i-1)]).'</td>'."\n";
 399							$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";
 400						} else {
 401							$col_ip = $col_ip_chb = '                  			<td></td>'."\n";
 402						}
 403						if ($i <= ($botnames_len-$start)) {
 404							$col_botname = '                  			<td>'.stripslashes($botdb['fullbotnames'][($i-1)]).'</td>'."\n";
 405							$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";
 406						} else {
 407							$col_botname = $col_botname_chb = '                  			<td></td>'."\n";
 408						}
 409						echo $col_ip.$col_botname.$col_ip_chb.$col_botname_chb;
 410						echo '              			</tr>'."\n";
 411					}
 412					if ( 0 == $botnames_len AND 0 == $IPs_len ) {
 413						$nobots = TRUE;
 414					}
 415				}  else {
 416					$nobots = TRUE;
 417				}				
 418				if (TRUE == $nobots) {
 419					echo '				<td colspan="5">'.__('Currently are no IP addresses or user agents marked as bots.', 'podpress').'</td>'."\n";
 420				}
 421				echo '				</tbody>'."\n";
 422				echo '				<tfood>'."\n";
 423				echo '				<tr>'."\n";
 424				echo '				<th colspan="5">'."\n";
 425					// Show paging
 426					echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
 427				echo '				</th>'."\n";
 428				echo '              			</tr>'."\n";
 429				echo '				</tfood>'."\n";
 430				echo '			</table>'."\n";				
 431				echo '			<p class="submit"> '."\n";
 432				echo '				<input class="button-primary" type="submit" name="Submit" value="'.__('Remove elements', 'podpress').' &raquo;" /><br />'."\n";
 433				echo '			</p> '."\n";
 434				echo '			<input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
 435				echo '			</form>'."\n";
 436				echo '		</fieldset>'."\n";
 437				echo '	</div>';
 438				break;
 439			case 'botdb_mark_bots':
 440				// ntm: stat logging: Full and Full+
 441				podPress_isAuthorized();
 442				$blog_charset = get_bloginfo('charset');
 443				$botdb = get_option('podpress_botdb');
 444				if ( 'botdb' == $_POST['podPress_submitted'] ) {
 445					if ( function_exists('check_admin_referer') ) {
 446						check_admin_referer('podPress_botdb_nonce');
 447					}
 448					$IPs = $_POST['podpress_remote_ips'];
 449					$fullbotnames = stripslashes_deep($_POST['podpress_user_agents']);
 450					
 451					if (is_array($botdb)) {
 452						$current_IP_set = $_POST['podpress_current_IP_set'];
 453						$unique_current_data_IPs = array_unique($_POST['podpress_current_IP_set']);
 454						
 455						//add new bots
 456						if (is_array($IPs)) {
 457							$unique_IPs = array_unique($IPs);
 458							foreach ($unique_IPs as $IP) {
 459								if (is_array($botdb['IP'])) {
 460									if ( FALSE === array_search($IP, $botdb['IP']) )  {
 461										$botdb['IP'][] = $IP;
 462									}
 463								} else {
 464									$botdb['IP'][] = $IP;
 465								}
 466							}
 467							
 468							// eventually remove bots
 469							$unmarked_IPs = array_diff($unique_current_data_IPs, $unique_IPs);
 470							$botdb['IP'] = array_diff($botdb['IP'], $unmarked_IPs);
 471							sort($botdb['IP']);
 472						} else {
 473							if (is_array($botdb['IP'])) {
 474								$botdb['IP'] = array_diff($botdb['IP'], $unique_current_data_IPs);
 475								sort($botdb['IP']);
 476							}
 477						}
 478						
 479						$current_user_agent_set = $_POST['podpress_current_user_agent_set'];
 480						$unique_current_data_fbnames = array_unique($_POST['podpress_current_user_agent_set']);
 481						if (is_array($fullbotnames)) {
 482							$unique_fullbotnames = array_unique($fullbotnames);
 483							foreach ($unique_fullbotnames as $fullbotname) {
 484								if (is_array($botdb['fullbotnames'])) {
 485									if ( FALSE === array_search($fullbotname, $botdb['fullbotnames']) ) {
 486										$botdb['fullbotnames'][] = $fullbotname;
 487									}
 488								} else {
 489									$botdb['fullbotnames'][] = $fullbotname;
 490								}
 491							}
 492							
 493							// eventually remove bots
 494							$unmarked_fullbotnames = array_diff($unique_current_data_fbnames, $unique_fullbotnames);
 495							$botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unmarked_fullbotnames);
 496							sort($botdb['fullbotnames']);
 497						} else {
 498							// eventually remove bots
 499							if (is_array($botdb['fullbotnames'])) {
 500								$botdb['fullbotnames'] = array_diff($botdb['fullbotnames'], $unique_current_data_fbnames);
 501								sort($botdb['fullbotnames']);
 502							}
 503						}
 504					} else {
 505						//add new bots (first time)
 506						if (is_array($IPs)) {
 507							$unique_IPs = array_unique($IPs);
 508							foreach ($unique_IPs as $IP) {
 509								$botdb['IP'][] = $IP;
 510							}
 511						}
 512						if (is_array($fullbotnames)) {
 513							$unique_fullbotnames = array_unique($fullbotnames);
 514							foreach ($unique_fullbotnames as $fullbotname) {
 515								$botdb['fullbotnames'][] = $fullbotname;
 516							}
 517						}
 518					}
 519					
 520					$updated=update_option('podpress_botdb', $botdb);
 521					if (isset($updated) AND $updated == TRUE) {
 522						echo '<div id="message" class="updated fade"><p>'. __('Settings Saved', 'podpress').'</p></div>';
 523					}
 524				}
 525				$where='';
 526				$rows_total = intval($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip, user_agent) AS total FROM '.$wpdb->prefix.'podpress_stats '.$where));
 527				$query_string = 'SELECT DISTINCT remote_ip, user_agent FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY dt DESC LIMIT '.$start.', '.$limit;
 528				$stats = $wpdb->get_results($query_string);
 529	
 530				echo '	<div class="wrap">'."\n";
 531				echo '		<fieldset class="options">'."\n";
 532				echo '			<legend>'.__('Which IP address or user agent name is from a web bot?', 'podpress').'</legend>'."\n";
 533				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";				
 534				echo '			<form method="post">'."\n";
 535				if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
 536					wp_nonce_field('podPress_botdb_nonce');
 537				}
 538				echo "\n".'			<table class="the-list-x widefat">'."\n";
 539				echo '				<thead>'."\n";
 540				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";
 541				echo '				</thead>'."\n";
 542				echo '				<tbody>'."\n";
 543				if(0 < count($stats)) {
 544					$i = 0;
 545					foreach ($stats as $stat) {
 546						++$i;
 547						$alternate = ($i % 2) ? '' : 'alternate';
 548						$bot_style = '';
 549						$ip_chb_checked = '';
 550						$name_chb_checked = '';
 551						if (TRUE == is_array($botdb)) {
 552							if (TRUE == is_array($botdb['IP']) AND FALSE !== array_search($stat->remote_ip, $botdb['IP'])) {
 553								$bot_style = ' podpress_is_bot';
 554								$ip_chb_checked = ' checked="checked"';
 555							}
 556							if (TRUE == is_array($botdb['fullbotnames']) AND FALSE !== array_search($stat->user_agent, $botdb['fullbotnames'])) {
 557								$bot_style = ' podpress_is_bot';
 558								$name_chb_checked = ' checked="checked"';
 559							}
 560						}
 561						echo '				<tr id ="podpress_ip_user_agent_row_'.($i).'" class="'.$alternate.$bot_style.'">'."\n";
 562						echo '                  			<td>'.($start+$i).'</td>'."\n";
 563						echo '                  			<td>'.$stat->remote_ip.'<input type="hidden" name="podpress_current_IP_set[]" value="'.$stat->remote_ip.'" /></td>'."\n";
 564						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";
 565						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";
 566						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";
 567						echo '              			</tr>'."\n";
 568					}
 569				} else {
 570					echo '<td colspan="5">'.__('No downloads yet.','podpress')."</td>\n";
 571				}
 572
 573				echo '				</tbody>'."\n";
 574				echo '				<tfood>'."\n";
 575				echo '				<tr>'."\n";
 576				echo '				<th colspan="5">'."\n";
 577					// Show paging
 578					echo $this->paging2($start, $limit, $rows_total, __('names and IPs','podpress'));
 579				echo '				</th>'."\n";
 580				echo '              			</tr>'."\n";
 581				echo '				</tfood>'."\n";
 582				echo '			</table>'."\n";				
 583				
 584				echo '				<p class="submit"> '."\n";
 585				echo '					<input class="button-primary" type="submit" name="Submit" value="'.__('Update Options', 'podpress').' &raquo;" /><br />'."\n";
 586				echo '				</p> '."\n";
 587				echo '				<input type="hidden" name="podPress_submitted" value="botdb" />'."\n";
 588				echo '			</form>'."\n";
 589				echo '		</fieldset>'."\n";
 590				echo '	</div>';
 591				break;
 592			case 'downloads_per_media_file':
 593				// ntm: stat logging: Full and Full+
 594				$where = $this->wherestr_to_exclude_bots('pod');
 595				
 596				$query_string = "SELECT COUNT(DISTINCT pod.media) as total_rows FROM ".$wpdb->prefix."podpress_stats as pod ".$where;
 597				$rows_total = intval($wpdb->get_var($query_string));
 598
 599				$query_string = "SELECT DISTINCT (pod.media) FROM ".$wpdb->prefix."podpress_stats as pod ".$where." LIMIT ".$start.", ".$limit;
 600				$posts_with_podpressmedia = $wpdb->get_results($query_string);
 601				$nr_postswpm = count($posts_with_podpressmedia);
 602				if ( 0 < $nr_postswpm) {
 603					$i=1;
 604					if (FALSE == empty($where)) {
 605						$where_posts = "AND pod.media IN (";
 606					} else {
 607						$where_posts = "WHERE pod.media IN (";
 608					}
 609					foreach ($posts_with_podpressmedia as $post) {
 610						if ($i == $nr_postswpm) {
 611							$where_posts .= "'".$post->media."'";
 612						} else {
 613							$where_posts .= "'".$post->media."', ";
 614						}
 615						$i++;
 616					}
 617					$where_posts .= ") ";
 618				} else {
 619					$where_posts = '';
 620				}
 621
 622				$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";
 623				$stat_data_sets = $wpdb->get_results($query_string);
 624				
 625				if (FALSE == empty($where)) {
 626					$where_or_and = "AND";
 627				} else {
 628					$where_or_and = "WHERE";
 629				}				
 630				$methods = Array('feed', 'web', 'play');
 631				foreach ($methods as $method) {
 632					$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";
 633					$downloads_col = $wpdb->get_col($query_string);
 634					switch ($method) {
 635						case 'feed' :
 636							$feed_max = intval($downloads_col[0]);
 637						break;
 638						case 'web' :
 639							$web_max = intval($downloads_col[0]);
 640						break;
 641						case 'play' :
 642							$play_max = intval($downloads_col[0]);
 643						break;
 644					}		
 645				}
 646				$query_string="SELECT COUNT(*) as downloads, pod.media FROM ".$wpdb->prefix."podpress_stats AS pod ".$where." GROUP BY pod.media ORDER BY downloads DESC";
 647				$downloads_col = $wpdb->get_col($query_string);
 648				$total_max = intval($downloads_col[0]);
 649				
 650				// prepare the query result for the output:
 651				// - if a media file was not downloaded  by one or more method then add this method  and a int(0) to the media file 		
 652				foreach ($stat_data_sets as $stat_data_set) {
 653					$feed = $web = $play = 0;
 654					switch ($stat_data_set->method) {
 655						case 'feed' :
 656							$feed = intval($stat_data_set->downloads);
 657						break;
 658						case 'web' :
 659							$web = intval($stat_data_set->downloads);
 660						break;
 661						case 'play' :
 662							$play = intval($stat_data_set->downloads);
 663						break;
 664					}
 665					$total_sum = $feed+$web+$play;
 666					$stats[$stat_data_set->media]['feed'] += $feed;
 667					$stats[$stat_data_set->media]['web'] += $web;
 668					$stats[$stat_data_set->media]['play'] += $play;
 669					$stats[$stat_data_set->media]['total'] += $total_sum;
 670				}
 671				
 672				// sort the media files by their 'total' value
 673				if (is_array($stats)) {
 674					uasort($stats, array(self, 'sort_downloads_per_media_desc'));
 675				}
 676				echo '	<div class="wrap">'."\n";
 677				echo '		<fieldset class="options">'."\n";
 678				echo '			<legend>'.__('Downloads Per Media File', 'podpress').'</legend>'."\n";
 679				echo '			<table class="the-list-x widefat">'."\n";
 680				echo '				<thead>';
 681				echo "				<tr>\n";
 682				echo '                  			<th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
 683				echo '                  			<th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
 684				echo '                  			<th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
 685				echo '                  			<th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
 686				echo '                  			<th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
 687				echo '                  			<th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
 688				echo '              			</tr>'."\n";
 689				echo '				<tr>'."\n";
 690				echo '                  			<th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
 691				echo '                  			<th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
 692				echo '                  			<th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
 693				echo '                  			<th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
 694				echo '                  			<th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
 695				echo '                  			<th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
 696				echo '              			</tr>'."\n";
 697				echo '				</thead>';
 698				echo '				<tbody>';
 699				if (0 < count($stat_data_sets)) {
 700					$i = 0;
 701					foreach ( $stats as $media => $downloads_per_method ) {
 702						$i++;
 703						$style = ($i % 2 != 0) ? '' : ' class="alternate"';
 704						$highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
 705						$highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
 706						$highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
 707						$highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
 708						$perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
 709						$perc_web = number_format(($downloads_per_method['web']  * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
 710						$perc_play = number_format(($downloads_per_method['play'] * 100 / $downloads_per_method['total']), 1, $this->local_settings['numbers'][0], $this->local_settings['numbers'][1]);
 711						echo '		<tr'.$style.'>'."\n";
 712						echo '                  	<td>'.($start +$i).'.</td>'."\n";
 713						echo '                  	<td>'.podPress_strlimiter2(urldecode($media), 50, TRUE).'</td>'."\n";
 714						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";
 715						echo '                  	<td class="podpress_stats_numbers_percent'.$highest_feed.'">'.$perc_feed."</td>\n";
 716						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";
 717						echo '                  	<td class="podpress_stats_numbers_percent'.$highest_web.'">'.$perc_web."</td>\n";
 718						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";
 719						echo '                  	<td class="podpress_stats_numbers_percent'.$highest_play.'">'.$perc_play."</td>\n";
 720						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";
 721						echo '		</tr>'."\n";
 722					}
 723				} else {
 724					if (FALSE == empty($where)) {
 725						echo '<td colspan="9">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
 726					} else {
 727						echo '<td colspan="9">'.__('No downloads yet.','podpress')."</td>\n";
 728					}
 729				}
 730				echo '				</tbody>';
 731				echo '				<tfood>'."\n";
 732				echo '				<tr>'."\n";
 733				echo '				<th colspan="9">'."\n";
 734					// Show paging
 735					echo $this->paging2($start, $limit, $rows_total, __('Ranks','podpress'));
 736				echo '				</th>'."\n";
 737				echo '              			</tr>'."\n";
 738				echo '				</tfood>'."\n";
 739				echo '			</table>'."\n";
 740				echo '		</fieldset>'."\n";
 741				echo '	</div>';
 742				break;
 743			case 'rawstats':
 744				// ntm: stat logging: Full and Full+
 745				$date_format = get_option('date_format');
 746				$time_format = get_option('time_format');
 747				$botdb = get_option('podpress_botdb');
 748				$where = '';
 749				$rows_total = $wpdb->get_var('SELECT COUNT(*) FROM '.$wpdb->prefix.'podpress_stats '.$where);
 750				$stats = $wpdb->get_results('SELECT * FROM '.$wpdb->prefix.'podpress_stats '.$where.'ORDER BY id DESC LIMIT '.$start.', '.$limit);
 751				echo '	<div class="wrap">'."\n";
 752				echo '		<fieldset class="options">'."\n";
 753				echo '			<legend>'.__('The raw list', 'podpress').'</legend>'."\n";
 754				echo '			<table class="the-list-x widefat">'."\n"; //width="100%" cellpadding="1" cellspacing="1"
 755				echo '				<thead>';
 756				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";
 757				echo '				</thead>';
 758				echo '				<tbody>';
 759				if(0 < count($stats)) {
 760					if ( TRUE === is_array($botdb['IP']) OR TRUE === is_array($botdb['fullbotnames']) ) {
 761						$i = 0;
 762						foreach ($stats as $stat) {
 763							++$i;
 764							$style = ($i % 2) ? '' : 'alternate';
 765							
 766							if ( (FALSE !== empty($botdb['fullbotnames']) OR FALSE === array_search($stat->user_agent, $botdb['fullbotnames']))) {
 767								if ( (FALSE !== empty($botdb['IP']) OR FALSE === array_search($stat->remote_ip, $botdb['IP']))) {
 768									$bot_style = '';
 769								} else {
 770									$bot_style = ' podpress_is_bot';
 771								}
 772							} else {
 773								$bot_style = ' podpress_is_bot';
 774							}
 775							echo '		<tr class="'.$style.$bot_style.'">'."\n";
 776							echo '                  	<td>'.($start +$i).'.</td>'."\n";
 777							echo '                  	<td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
 778							echo '                  	<td>'.$stat->method.'</td>'."\n";
 779							// iscifi : mod of stats output to create a link to domaintools.com whois lookup
 780							// domaintools seems faster and provides more concise infomation, url can not have trailing /
 781
 782							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";
 783							// OLD code where this .echo '                  <td>'.$stat->remote_ip.'</td>'."\n";
 784							echo '                  	<td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
 785							echo '                  	<td>'.date($date_format.' - '.$time_format,  intval($stat->dt)).'</td>'."\n";
 786							echo '		</tr>'."\n";
 787						}
 788					} else {
 789						$i = 0;
 790						foreach ($stats as $stat) {
 791							++$i;
 792							$style = ($i % 2) ? '' : 'alternate';
 793							echo '				<tr class="'.$style.'">'."\n";
 794							echo '                  <td>'.($start +$i).'.</td>'."\n";
 795							echo '                  <td>'.podPress_strlimiter2(urldecode($stat->media), 20, TRUE).'</td>'."\n";
 796							echo '                  <td>'.$stat->method.'</td>'."\n";
 797							// iscifi : mod of stats output to create a link to domaintools.com whois lookup
 798							// domaintools seems faster and provides more concise infomation, url can not have trailing /
 799
 800							echo '                  <td><a href="http://whois.domaintools.com/'.$stat->remote_ip.'" target="_blank">'.$stat->remote_ip.'</a></td>'."\n";
 801							// OLD code where this .echo '                  <td>'.$stat->remote_ip.'</td>'."\n";
 802							echo '                  <td>'.podPress_strlimiter2($stat->user_agent, 50, TRUE).'</td>'."\n";
 803							echo '                  <td>'.date($date_format.' - '.$time_format,  intval($stat->dt)).'</td>'."\n";
 804							echo '              </tr>'."\n";
 805						}
 806					}
 807				} else {
 808					echo '<td colspan="6">'.__('No downloads yet.','podpress').'</td>'."\n";
 809				}
 810				echo '				</tbody>';
 811				echo '				<tfood>'."\n";
 812				echo '				<tr>'."\n";
 813				echo '				<th colspan="6">'."\n";
 814					// Show paging
 815					echo $this->paging2($start, $limit, $rows_total, __('Hit','podpress'));
 816				echo '				</th>'."\n";
 817				echo '              			</tr>'."\n";
 818				echo '				</tfood>'."\n";
 819				echo '			</table>'."\n";
 820				echo '		</fieldset>'."\n";
 821				echo '	</div>';
 822				break;
 823			case 'topips':
 824				// ntm: stat logging: Full and Full+
 825				$where = $this->wherestr_to_exclude_bots();
 826				$rows_total = ($wpdb->get_var('SELECT COUNT(DISTINCT remote_ip) as uniq FROM '.$wpdb->prefix.'podpress_stats '.$where));
 827				
 828				$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;
 829				$stats = $wpdb->get_results($sql);
 830				
 831				echo '	<div class="wrap">'."\n";
 832				echo '		<fieldset class="options">'."\n";
 833				echo '			<legend>'.__('Top IP Addresses', 'podpress').'</legend>'."\n";
 834				echo '			<table class="the-list-x widefat">'."\n";
 835				echo '				<thead>';
 836				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";
 837				echo '				</thead>';
 838				echo '				<tbody>';
 839				if(0<count($stats)) {
 840					$i = 0;
 841					foreach ($stats as $stat) {
 842						++$i;
 843						$style = ($i % 2) ? '' : ' class="alternate"';
 844						echo '		<tr'.$style.'>'."\n";
 845						echo '                  	<td>'.($start +$i).'.</td>'."\n";
 846						echo '                  	<td>'.$stat->IPAddress.'</td>'."\n";
 847						echo '                  	<td>'.$stat->uniq.'</td>'."\n";
 848						echo '                  	<td>'.$stat->total.'</td>'."\n";
 849						echo '             	</tr>'."\n";
 850					}
 851				} else {
 852					if (FALSE == empty($where)) {
 853						echo '<td colspan="4">'.__('No downloads yet. (Bots have been filtered.)','podpress')."</td>\n";
 854					} else {
 855						echo '<td colspan="4">'.__('No downloads yet.','podpress')."</td>\n";
 856					}
 857				}
 858				echo '				</tbody>';
 859				echo '				<tfood>'."\n";
 860				echo '				<tr>'."\n";
 861				echo '				<th colspan="4">'."\n";
 862					// Show paging
 863					echo $this->paging2($start, $limit, $rows_total, __('IP Address','podpress'));
 864				echo '				</th>'."\n";
 865				echo '              			</tr>'."\n";
 866				echo '				</tfood>'."\n";
 867				echo '			</table>'."\n";
 868				echo '		</fieldset>'."\n";
 869				echo '	</div>';
 870				break;
 871			case 'graphbydate':
 872				// ntm: stat logging: Full and Full+
 873				if ($this->checkGD() ) {//&& ($this->settings['statLogging'] == 'Full' || $this->settings['statLogging'] == 'FullPlus')
 874					$this->graphByDate();
 875				} else {
 876					$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.');
 877				}
 878				break;
 879			case 'graphbydatealt':
 880				// ntm: stat logging: Full and Full+
 881				$this->graphByDateAlt();
 882				break;
 883			case 'graphbypost':
 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				if ($this->checkGD()) {
 887					$this->graphByPost();
 888				} else {
 889					$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.');
 890				}
 891				break;
 892			case 'graphbypostalt':
 893				// ntm: stat logging: Counts Only
 894				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>';
 895				$this->graphByPostAlt();
 896				break;
 897			case 'downloads_per_post' :
 898				// ntm: stat logging: Full and Full+
 899				$where = $this->wherestr_to_exclude_bots('pod');
 900				
 901				// get the number of all post with podPress podcasts
 902				$query_string = "SELECT COUNT(DISTINCT postID) as posts FROM ".$wpdb->prefix."podpress_stats ".$where;
 903				// get all post with podPress podcasts
 904				$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";
 905				$posts_with_podpressmedia = $wpdb->get_results($query_string);
 906				
 907				echo '	<div class="wrap">'."\n";
 908				echo '		<fieldset class="options">'."\n";
 909				echo '			<legend>'.__('Downloads Per Post', 'podpress').'</legend>'."\n";
 910				echo '			<form method="post">'."\n";
 911				if ( function_exists('wp_nonce_field') ) { // since WP 2.0.4
 912					wp_nonce_field('podPress_downloads_per_post_nonce');
 913				}
 914				echo '				<label>'.__('Select a post with a media file (attached with podPress):', 'podpress').'</label><br />'."\n";
 915				echo '				<select id="post_with_podpressmedia" name="post_with_podpressmedia" size="5">'."\n";
 916				foreach ($posts_with_podpressmedia as $post) {
 917					if ($post->postID == $_POST['post_with_podpressmedia']) {
 918						$selected = ' selected="selected"';
 919					} else {
 920						$selected = '';
 921					}
 922					echo '				<option value="'.$post->postID.'"'.$selected.'>'.$post->post_title.'</option>'."\n";
 923					$post_titles[$post->postID] = $post->post_title;
 924				}
 925				echo '				</select>'."\n";
 926				echo '				<p class="submit"> '."\n";
 927				echo '					<input type="submit" name="Submit" value="'.__('Show the stats for this post', 'podpress').' &raquo;" /><br />'."\n";
 928				echo '				</p> '."\n";
 929				echo '				<input type="hidden" name="podPress_submitted" value="downloadsperpost" />'."\n";
 930				echo '			</form>'."\n";
 931				echo '		</fieldset>'."\n";
 932				echo '	</div><!-- .wrap -->'."\n";
 933				
 934				// show the statistics of the media files of the submitted post
 935				if ( 'downloadsperpost' == $_POST['podPress_submitted'] ) {
 936					if ( function_exists('check_admin_referer') ) {
 937						check_admin_referer('podPress_downloads_per_post_nonce');
 938					}
 939
 940					if (FALSE == empty($where)) {
 941						$where_postID = "AND pod.postID = '".$_POST['post_with_podpressmedia']."' ";
 942					} else {
 943						$where_postID = "WHERE pod.postID = '".$_POST['post_with_podpressmedia']."' ";
 944					}
 945					$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";
 946					$stat_data_sets = $wpdb->get_results($query_string);
 947					
 948					// prepare the query result for the output:
 949					// - find the maximal downloads value for each download method
 950					// - if a media file was not downloaded  by one or more method then add this method  and a int(0) to the media file 		
 951					$feed_max = 0;
 952					$web_max = 0;
 953					$play_max = 0;
 954					$total_max = 0;
 955					foreach ($stat_data_sets as $stat_data_set) {
 956						$feed = 0;
 957						$web = 0;
 958						$play = 0;
 959						switch ($stat_data_set->method) {
 960							case 'feed' :
 961								$feed = intval($stat_data_set->downloads);
 962								$feed_max = max($feed_max, $feed);
 963							break;
 964							case 'web' :
 965								$web = intval($stat_data_set->downloads);
 966								$web_max = max($web_max, $web);
 967							break;
 968							case 'play' :
 969								$play = intval($stat_data_set->downloads);
 970								$play_max = max($play_max, $play);
 971							break;
 972						}
 973						$stats[$stat_data_set->media]['feed'] += $feed;
 974						$stats[$stat_data_set->media]['web'] += $web;
 975						$stats[$stat_data_set->media]['play'] += $play;
 976						$stats[$stat_data_set->media]['total'] += ($feed + $web + $play);
 977						$total_max = max($total_max, $stats[$stat_data_set->media]['total']);
 978					}
 979				
 980					// sort the media files by their 'total' value
 981					uasort($stats, array(self, 'sort_downloads_per_media_desc'));
 982
 983					echo '	<div class="wrap">'."\n";
 984					echo '		<fieldset class="options">'."\n";
 985					echo '			<legend>'.__('Post:', 'podpress')." ".$post_titles[$_POST['post_with_podpressmedia']]." - ".__('Downloads Per Media File', 'podpress').'</legend>'."\n";
 986					echo '			<table class="the-list-x widefat">'."\n";
 987					echo '				<thead>';
 988					echo "				<tr>\n";
 989					echo '                  			<th rowspan="2">'.__('Nr.', 'podpress')."</th>\n";
 990					echo '                  			<th rowspan="2">'.__('Media File', 'podpress')."</th>\n";
 991					echo '                  			<th class="podpress_stats_nr_head" colspan="2">'.__('Feed', 'podpress')."</th>\n";
 992					echo '                  			<th class="podpress_stats_nr_head" colspan="2">'.__('Web', 'podpress')."</th>\n";
 993					echo '                  			<th class="podpress_stats_nr_head" colspan="2">'.__('Play', 'podpress')."</th>\n";
 994					echo '                  			<th class="podpress_stats_nr_head" rowspan="2">'.__('Total', 'podpress')."</th>\n";
 995					echo '              			</tr>'."\n";
 996					echo '				<tr>'."\n";
 997					echo '                  			<th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
 998					echo '                  			<th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
 999					echo '                  			<th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
1000					echo '                  			<th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
1001					echo '                  			<th class="podpress_stats_nr_head">'.__('Files', 'podpress')."</th>\n";
1002					echo '                  			<th class="podpress_stats_nr_head">'.__('%', 'podpress')."</th>\n";
1003					echo '              			</tr>'."\n";
1004					echo '				</thead>';
1005					echo '				<tbody>';
1006					$mark_highest = FALSE;
1007					$nr_stat_data_sets = count($stat_data_sets);
1008					if (0 < $nr_stat_data_sets) {
1009						if ( 1 < $nr_stat_data_sets ) {
1010							$mark_highest = TRUE;
1011						}
1012						$i = 0;
1013						foreach ( $stats as $media => $downloads_per_method ) {
1014							$i++;
1015							$style = ($i % 2 != 0) ? '' : ' class="alternate"';
1016							if (TRUE === $mark_highest) {
1017								$highest_feed = ($downloads_per_method['feed'] == $feed_max AND 0 < $feed_max) ? ' podpress_stats_highest': '';
1018								$highest_web = ($downloads_per_method['web'] == $web_max AND 0 < $web_max) ? ' podpress_stats_highest': '';
1019								$highest_play = ($downloads_per_method['play'] == $play_max AND 0 < $play_max) ? ' podpress_stats_highest': '';
1020								$highest_total = ($downloads_per_method['total'] == $total_max AND 0 < $total_max) ? ' podpress_stats_highest': '';
1021							}
1022							$perc_feed = number_format(($downloads_per_method['feed'] * 100 / $downlo…

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