WP Statistics - Version 8.1

Version Description

  • Added: Detected browser information to the optimization page.
  • Updated: Re-organized new browscap code to avoid PHP 5.2 or below throwing a parse error.
  • Fixed: If the client sent no user agent string a fatal error would be generated, added additional logic to handle this case.
  • Removed: Unused code in various log displays.
Download this release

Release Info

Developer GregRoss
Plugin Icon 128x128 WP Statistics
Version 8.1
Comparing to
See all releases

Code changes from version 8.0 to 8.1

includes/classes/statistics.class.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- This is the primary class for WP Statisticsrecording hits on the WordPress site. It is extended by the Hits class and the GeoIPHits class.
4
 
5
  This class handles; visits, visitors and pages.
6
  */
@@ -267,7 +267,14 @@
267
  public function get_UserAgent() {
268
 
269
  // Parse the agent stirng.
270
- $agent = parse_user_agent();
 
 
 
 
 
 
 
271
 
272
  // null isn't a very good default, so set it to Unknown instead.
273
  if( $agent['browser'] == null ) { $agent['browser'] = "Unknown"; }
1
  <?php
2
  /*
3
+ This is the primary class for WP Statistics recording hits on the WordPress site. It is extended by the Hits class and the GeoIPHits class.
4
 
5
  This class handles; visits, visitors and pages.
6
  */
267
  public function get_UserAgent() {
268
 
269
  // Parse the agent stirng.
270
+ try
271
+ {
272
+ $agent = parse_user_agent();
273
+ }
274
+ catch( Exception $e )
275
+ {
276
+ $agent = array( 'browser' => 'Unknown', 'platform' => 'Unknown', 'version' => 'Unknown' );
277
+ }
278
 
279
  // null isn't a very good default, so set it to Unknown instead.
280
  if( $agent['browser'] == null ) { $agent['browser'] = "Unknown"; }
includes/log/all-browsers.php CHANGED
@@ -3,15 +3,6 @@
3
  postboxes.add_postbox_toggles(pagenow);
4
  });
5
  </script>
6
- <?php
7
- $search_engines = wp_statistics_searchengine_list();
8
-
9
- $search_result['All'] = wp_statistics_searchengine('all','total');
10
-
11
- foreach( $search_engines as $key => $se ) {
12
- $search_result[$key] = wp_statistics_searchengine($key,'total');
13
- }
14
- ?>
15
  <div class="wrap">
16
  <?php screen_icon('options-general'); ?>
17
  <h2><?php _e('Browser Statistics', 'wp_statistics'); ?></h2>
3
  postboxes.add_postbox_toggles(pagenow);
4
  });
5
  </script>
 
 
 
 
 
 
 
 
 
6
  <div class="wrap">
7
  <?php screen_icon('options-general'); ?>
8
  <h2><?php _e('Browser Statistics', 'wp_statistics'); ?></h2>
includes/log/hit-statistics.php CHANGED
@@ -3,15 +3,6 @@
3
  postboxes.add_postbox_toggles(pagenow);
4
  });
5
  </script>
6
- <?php
7
- $search_engines = wp_statistics_searchengine_list();
8
-
9
- $search_result['All'] = wp_statistics_searchengine('all','total');
10
-
11
- foreach( $search_engines as $key => $se ) {
12
- $search_result[$key] = wp_statistics_searchengine($key,'total');
13
- }
14
- ?>
15
  <div class="wrap">
16
  <?php screen_icon('options-general'); ?>
17
  <h2><?php _e('Hit Statistics', 'wp_statistics'); ?></h2>
3
  postboxes.add_postbox_toggles(pagenow);
4
  });
5
  </script>
 
 
 
 
 
 
 
 
 
6
  <div class="wrap">
7
  <?php screen_icon('options-general'); ?>
8
  <h2><?php _e('Hit Statistics', 'wp_statistics'); ?></h2>
includes/log/search-statistics.php CHANGED
@@ -5,12 +5,6 @@
5
  </script>
6
  <?php
7
  $search_engines = wp_statistics_searchengine_list();
8
-
9
- $search_result['All'] = wp_statistics_searchengine('all','total');
10
-
11
- foreach( $search_engines as $key => $se ) {
12
- $search_result[$key] = wp_statistics_searchengine($key,'total');
13
- }
14
  ?>
15
  <div class="wrap">
16
  <?php screen_icon('options-general'); ?>
5
  </script>
6
  <?php
7
  $search_engines = wp_statistics_searchengine_list();
 
 
 
 
 
 
8
  ?>
9
  <div class="wrap">
10
  <?php screen_icon('options-general'); ?>
includes/log/top-countries.php CHANGED
@@ -4,14 +4,6 @@
4
  });
5
  </script>
6
  <?php
7
- $search_engines = wp_statistics_searchengine_list();
8
-
9
- $search_result['All'] = wp_statistics_searchengine('all','total');
10
-
11
- foreach( $search_engines as $key => $se ) {
12
- $search_result[$key] = wp_statistics_searchengine($key,'total');
13
- }
14
-
15
  include_once( dirname( __FILE__ ) . "/../functions/country-codes.php" );
16
  ?>
17
  <div class="wrap">
4
  });
5
  </script>
6
  <?php
 
 
 
 
 
 
 
 
7
  include_once( dirname( __FILE__ ) . "/../functions/country-codes.php" );
8
  ?>
9
  <div class="wrap">
includes/log/top-referring.php CHANGED
@@ -8,14 +8,6 @@
8
  });
9
  </script>
10
  <?php
11
- $search_engines = wp_statistics_searchengine_list();
12
-
13
- $search_result['All'] = wp_statistics_searchengine('all','total');
14
-
15
- foreach( $search_engines as $key => $se ) {
16
- $search_result[$key] = wp_statistics_searchengine($key,'total');
17
- }
18
-
19
  if( array_key_exists('referr',$_GET) ) {
20
  $referr = esc_sql( $_GET['referr'] );
21
  }
8
  });
9
  </script>
10
  <?php
 
 
 
 
 
 
 
 
11
  if( array_key_exists('referr',$_GET) ) {
12
  $referr = esc_sql( $_GET['referr'] );
13
  }
includes/optimization/tabs/wps-optimization-resources.php CHANGED
@@ -250,6 +250,42 @@
250
  <p class="description"><?php _e('The client user agent string.', 'wp_statistics'); ?></p>
251
  </td>
252
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  </tbody>
254
  </table>
255
  </div>
250
  <p class="description"><?php _e('The client user agent string.', 'wp_statistics'); ?></p>
251
  </td>
252
  </tr>
253
+
254
+ <tr valign="top">
255
+ <th scope="row">
256
+ <?php _e('Browser', 'wp_statistics'); ?>:
257
+ </th>
258
+
259
+ <td>
260
+ <strong><?php $agent = $WP_Statistics->get_UserAgent();
261
+ echo $agent['browser'];
262
+ ?></strong>
263
+ <p class="description"><?php _e('The detected client browser.', 'wp_statistics'); ?></p>
264
+ </td>
265
+ </tr>
266
+
267
+ <tr valign="top">
268
+ <th scope="row">
269
+ <?php _e('Version', 'wp_statistics'); ?>:
270
+ </th>
271
+
272
+ <td>
273
+ <strong><?php echo $agent['version'];?></strong>
274
+ <p class="description"><?php _e('The detected client browser version.', 'wp_statistics'); ?></p>
275
+ </td>
276
+ </tr>
277
+
278
+ <tr valign="top">
279
+ <th scope="row">
280
+ <?php _e('Platform', 'wp_statistics'); ?>:
281
+ </th>
282
+
283
+ <td>
284
+ <strong><?php echo $agent['platform'];?></strong>
285
+ <p class="description"><?php _e('The detected client platform.', 'wp_statistics'); ?></p>
286
+ </td>
287
+ </tr>
288
+
289
  </tbody>
290
  </table>
291
  </div>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: http://mostafa-soufi.ir/donate/
4
  Tags: statistics, stats, visit, visitors, chart, browser, blog, today, yesterday, week, month, year, total, post, page, sidebar, summary, feedburner, hits, pagerank, google, alexa, live visit
5
  Requires at least: 3.0
6
  Tested up to: 4.0
7
- Stable tag: 8.0
8
  License: GPL2
9
 
10
  Complete statistics for your WordPress site.
@@ -165,6 +165,29 @@ Pretty much every plugin/service is going to give you different results for visi
165
 
166
  Services that use centralized databases, like Google Analytics, for spam and robot detection have better detection than WP Statistics can. The trade off of course is relaying on an external service.
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  == Screenshots ==
169
  1. View stats page.
170
  2. View latest search words.
@@ -184,6 +207,12 @@ Services that use centralized databases, like Google Analytics, for spam and rob
184
  * Support for old format substitution codes in the statistics reports has been removed, the upgrade now converts them to short codes but you should verify the report content after upgrading.
185
 
186
  == Changelog ==
 
 
 
 
 
 
187
  = 8.0 =
188
  * Added: browscap.ini support for robot detection.
189
  * Added: Statistics->Optimization->Database tab now how an option to re-run the install routine in case you have had to delete tables from the database.
4
  Tags: statistics, stats, visit, visitors, chart, browser, blog, today, yesterday, week, month, year, total, post, page, sidebar, summary, feedburner, hits, pagerank, google, alexa, live visit
5
  Requires at least: 3.0
6
  Tested up to: 4.0
7
+ Stable tag: 8.1
8
  License: GPL2
9
 
10
  Complete statistics for your WordPress site.
165
 
166
  Services that use centralized databases, like Google Analytics, for spam and robot detection have better detection than WP Statistics can. The trade off of course is relaying on an external service.
167
 
168
+ = When I upgrade or install WP Statistics I get an error message like "Parse error: syntax error, unexpected T_STRING, expecting T_CONSTANT_ENCAPSED_STRING or '('" =
169
+
170
+ Since WP Statistics 8.0, PHP 5.3 or above has been required. If you are using an older version of PHP it cannot understand the new syntax included in WP Statistics 8.0 and generates a parse error.
171
+
172
+ You have two choices:
173
+
174
+ 1. Upgrade your PHP to 5.3 or above (recommended)
175
+ 2. Downgrade WP Statistics to 7.4
176
+
177
+ Your hosting provider should have a newer version of PHP available, sometimes you must activate it through your hosting control panel.
178
+
179
+ Since the last release of PHP 5.2 is over 3 years ago (Jan 2011) and is no longer supported or receiving security fixes, if your provider does not support a newer version you should probably be moving hosting providers.
180
+
181
+ Having said that if you cannot move to PHP 5.3 or above you can still use WP Statistics 7.4, which you can download (here)[https://downloads.wordpress.org/plugin/wp-statistics.7.4.zip] and install manually through the WordPress plugin installer.
182
+
183
+ If you have done an upgrade and you can no longer access your site due to the parse error you will have to manually delete the wp-statistics directory from your wordpress/wp-content/plugins directory, either through your hosting providers control panel or FTP.
184
+
185
+ = I've decided to stay with WP Statistics 7.4 even though its a bad idea but now WordPress continuously reports there are updates available, how can I stop that? =
186
+
187
+ If you are staying on WP Statistics 7.4 WordPress will, through the Dashboard and Admin bar, let you know that a newer version is available. However that can be annoying, there are some plugins in the WordPress directory to help though.
188
+
189
+ (Disable Updates Manager)[https://wordpress.org/plugins/stops-core-theme-and-plugin-updates/] is one I found doing a quick search and lets you disable individual plugins from the update process.
190
+
191
  == Screenshots ==
192
  1. View stats page.
193
  2. View latest search words.
207
  * Support for old format substitution codes in the statistics reports has been removed, the upgrade now converts them to short codes but you should verify the report content after upgrading.
208
 
209
  == Changelog ==
210
+ = 8.1 =
211
+ * Added: Detected browser information to the optimization page.
212
+ * Updated: Re-organized new browscap code to avoid PHP 5.2 or below throwing a parse error.
213
+ * Fixed: If the client sent no user agent string a fatal error would be generated, added additional logic to handle this case.
214
+ * Removed: Unused code in various log displays.
215
+
216
  = 8.0 =
217
  * Added: browscap.ini support for robot detection.
218
  * Added: Statistics->Optimization->Database tab now how an option to re-run the install routine in case you have had to delete tables from the database.
wp-statistics.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP Statistics
4
  Plugin URI: http://wp-statistics.com/
5
  Description: Complete statistics for your WordPress site.
6
- Version: 8.0
7
  Author: Mostafa Soufi & Greg Ross
8
  Author URI: http://wp-statistics.com/
9
  Text Domain: wp_statistics
@@ -17,7 +17,7 @@ License: GPL2
17
  }
18
 
19
  // These defines are used later for various reasons.
20
- define('WP_STATISTICS_VERSION', '8.0');
21
  define('WP_STATISTICS_MANUAL', 'manual/WP Statistics Admin Manual.');
22
  define('WP_STATISTICS_REQUIRED_PHP_VERSION', '5.3.0');
23
  define('WP_STATISTICS_REQUIRED_GEOIP_PHP_VERSION', WP_STATISTICS_REQUIRED_PHP_VERSION);
@@ -41,9 +41,6 @@ License: GPL2
41
  // Load the user agent parsing code first, the WP_Statistics class depends on it. Then load the WP_Statistics class.
42
  include_once dirname( __FILE__ ) . '/includes/functions/parse-user-agent.php';
43
  include_once dirname( __FILE__ ) . '/includes/classes/statistics.class.php';
44
- include_once dirname( __FILE__ ) . '/includes/classes/Browscap.php';
45
-
46
- use phpbrowscap\Browscap;
47
 
48
  // This is our global WP_Statitsics class that is used throughout the plugin.
49
  $WP_Statistics = new WP_Statistics();
@@ -53,6 +50,9 @@ License: GPL2
53
  if( $WPS_Installed != WP_STATISTICS_VERSION ) {
54
  include_once( dirname( __FILE__ ) . '/wps-install.php' );
55
  }
 
 
 
56
 
57
  // Load the rest of the required files for our global functions, online user tracking and hit tracking.
58
  include_once dirname( __FILE__ ) . '/includes/functions/functions.php';
@@ -569,244 +569,6 @@ License: GPL2
569
  include_once dirname( __FILE__ ) . "/includes/optimization/wps-optimization.php";
570
  }
571
 
572
- // This function downloads the GeoIP database from MaxMind.
573
- function wp_statistics_download_geoip() {
574
-
575
- GLOBAL $WP_Statistics;
576
-
577
- // We need the download_url() function, it should exists on virtually all installs of PHP, but if it doesn't for some reason, bail out.
578
- if( !function_exists( 'download_url' ) ) { return ''; }
579
-
580
- // If GeoIP is disabled, bail out.
581
- if( $WP_Statistics->get_option('geoip') == false ) { return '';}
582
-
583
- // This is the location of the file to download.
584
- $download_url = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz';
585
-
586
- // Get the upload directory from WordPRess.
587
- $upload_dir = wp_upload_dir();
588
-
589
- // Create a variable with the name of the database file to download.
590
- $DBFile = $upload_dir['basedir'] . '/wp-statistics/GeoLite2-Country.mmdb';
591
-
592
- // Check to see if the subdirectory we're going to upload to exists, if not create it.
593
- if( !file_exists($upload_dir['basedir'] . '/wp-statistics') ) { mkdir($upload_dir['basedir'] . '/wp-statistics'); }
594
-
595
- // Download the file from MaxMind, this places it in a temporary location.
596
- $TempFile = download_url( $download_url );
597
-
598
- // If we failed, through a message, otherwise proceed.
599
- if (is_wp_error( $TempFile ) ) {
600
- $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error downloading GeoIP database from: %s - %s', 'wp_statistics'), $download_url, $TempFile->get_error_message() ) . "</strong></p></div>";
601
- }
602
- else {
603
- // Open the downloaded file to unzip it.
604
- $ZipHandle = gzopen( $TempFile, 'rb' );
605
-
606
- // Create th new file to unzip to.
607
- $DBfh = fopen( $DBFile, 'wb' );
608
-
609
- // If we failed to open the downloaded file, through an error and remove the temporary file. Otherwise do the actual unzip.
610
- if( ! $ZipHandle ) {
611
- $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error could not open downloaded GeoIP database for reading: %s', 'wp_statistics'), $TempFile) . "</strong></p></div>";
612
-
613
- unlink( $TempFile );
614
- }
615
- else {
616
- // If we failed to open the new file, through and error and remove the temporary file. Otherwise actually do the unzip.
617
- if( !$DBfh ) {
618
- $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error could not open destination GeoIP database for writing %s', 'wp_statistics'), $DBFile) . "</strong></p></div>";
619
- unlink( $TempFile );
620
- }
621
- else {
622
- while( ( $data = gzread( $ZipHandle, 4096 ) ) != false ) {
623
- fwrite( $DBfh, $data );
624
- }
625
-
626
- // Close the files.
627
- gzclose( $ZipHandle );
628
- fclose( $DBfh );
629
-
630
- // Delete the temporary file.
631
- unlink( $TempFile );
632
-
633
- // Display the success message.
634
- $result = "<div class='updated settings-error'><p><strong>" . __('GeoIP Database updated successfully!', 'wp_statistics') . "</strong></p></div>";
635
-
636
- // Update the options to reflect the new download.
637
- $WP_Statistics->update_option('last_geoip_dl', time());
638
- $WP_Statistics->update_option('update_geoip', false);
639
-
640
- // Populate any missing GeoIP information if the user has selected the option.
641
- if( $WP_Statistics->get_option('geoip') && wp_statistics_geoip_supported() && $WP_Statistics->get_option('auto_pop')) {
642
- include_once dirname( __FILE__ ) . '/includes/functions/geoip-populate.php';
643
- $result .= wp_statistics_populate_geoip_info();
644
- }
645
- }
646
- }
647
- }
648
-
649
- // All of the messages displayed above are stored in a stirng, now it's time to actually output the messages.
650
- return $result;
651
- }
652
-
653
- // This function downloads the browscap database from browscap.org.
654
- function wp_statistics_download_browscap() {
655
-
656
- GLOBAL $WP_Statistics;
657
-
658
- // We need the download_url() function, it should exists on virtually all installs of PHP, but if it doesn't for some reason, bail out.
659
- if( !function_exists( 'download_url' ) ) { return ''; }
660
-
661
- // If browscap is disabled, bail out.
662
- if( $WP_Statistics->get_option('browscap') == false ) { return '';}
663
-
664
- // This is the location of the file to download.
665
- $download_url = 'http://browscap.org/stream?q=PHP_BrowsCapINI';
666
- $download_version = 'http://browscap.org/version-number';
667
-
668
- // Get the upload directory from WordPress.
669
- $upload_dir = wp_upload_dir();
670
-
671
- // Check to see if the subdirectory we're going to upload to exists, if not create it.
672
- if( !file_exists($upload_dir['basedir'] . '/wp-statistics') ) { mkdir($upload_dir['basedir'] . '/wp-statistics'); }
673
-
674
- $LocalVersion = 0;
675
-
676
- // Get the Browscap object, tell it NOT to autoupdate.
677
- $bc = new Browscap($upload_dir['basedir'] . '/wp-statistics');
678
- $bc->doAutoUpdate = false; // We don't want to auto update.
679
-
680
- // If we already have a browscap.ini file (aka we're already done a download in the past) we can get it's version number.
681
- // We can't execute this code if no browscap.ini exists as then the library will automatically download a full version, even
682
- // though we've told it not to autoupdate above.
683
- if( $WP_Statistics->get_option('last_browscap_dl') > 1 ) {
684
- // Get the current browser so that the version information is populated.
685
- $bc->getBrowser();
686
-
687
- $LocalVersion = $bc->getSourceVersion();
688
- }
689
-
690
- // Get the remote version info from browscap.org.
691
- $TempVersionFile = download_url( $download_version );
692
-
693
- // Read the version we just downloaded in to a string.
694
- $RemoteVersion = file_get_contents($TempVersionFile);
695
-
696
- // Get rid of the temporary file.
697
- unlink( $TempVersionFile );
698
-
699
- // If there is a new version, let's go get it.
700
- if( intval($RemoteVersion) > $LocalVersion ) {
701
-
702
- // Download the file from MaxMind, this places it in a temporary location.
703
- $TempFile = download_url( $download_url );
704
-
705
- // If we failed, through a message, otherwise proceed.
706
- if (is_wp_error( $TempFile ) ) {
707
- $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error downloading browscap database from: %s - %s', 'wp_statistics'), $download_url, $TempFile->get_error_message() ) . "</strong></p></div>";
708
- }
709
- else {
710
- // Setup our file handles.
711
- $infile = fopen($TempFile, 'r' );
712
- $outfile = fopen($upload_dir['basedir'] . '/wp-statistics/browscap.ini', 'w');
713
-
714
- // We're going to need some variables to use as we process the new browscap.ini.
715
- // $crawler has three possible settings:
716
- // 0 = no setting found
717
- // 1 = setting found but not a crawler
718
- // 2 = setting found and a crawler
719
- $parent = '';
720
- $title = '';
721
- $crawler = 0;
722
- $parents = array( '' => false );
723
-
724
- // Now read in the browscap.ini file we downloaded one line at a time.
725
- while( ( $buffer = fgets($infile) ) !== false)
726
- {
727
- // Let's get rid of the tailing carriage return extra spaces.
728
- $buffer = trim($buffer);
729
-
730
- // We're going to do some things based on the first charater on the line so let's just get it once.
731
- $firstchar = substr( $buffer, 0, 1 );
732
-
733
- // The first character will tell us what kind of line we're dealing with.
734
- switch( $firstchar )
735
- {
736
- // A square bracket means it's a section title.
737
- case '[':
738
-
739
- // We have three sections we need to copy verbatium so don't do the standard processing for them.
740
- if( $title != 'GJK_Browscap_Version' && $title != 'DefaultProperties' && $title != "*" )
741
- {
742
- // If we found the current section is a crawler or we didn't find a crawler setting but the parent is a crawler...
743
- if( $crawler == 2 || ( $crawler == 0 && array_key_exists( $parent, $parents ) ) )
744
- {
745
- // Write out the section with just the parent/crawler setting saved.
746
- fwrite( $outfile, "[" . $title . "]\n" );
747
- fwrite( $outfile, 'Parent="' . $parent . '"' . "\n");
748
- fwrite( $outfile, "Crawler=true\n" );
749
- }
750
- }
751
-
752
- // Reset our variables.
753
- $crawler = 0;
754
- $parent = '';
755
- $title = substr( $buffer, 1, strlen($buffer) - 2 );
756
-
757
- // We have three sections we need to copy verbatium so write out their headings immediatly instead of waiting to see if they are a crawler.
758
- if( $title == 'GJK_Browscap_Version' || $title == 'DefaultProperties' || $title == "*" ) { fwrite($outfile,"[" . $title . "]\n"); }
759
-
760
- break;
761
- // A space or semi-colan means it's a comment.
762
- case ' ':
763
- case ';':
764
- // Since we're hacking out lots of data the only comments we want to keep are the first few in the file before the first section is processed.
765
- if( $title == '' ) { fwrite( $outfile, $buffer . "\n" ); }
766
-
767
- break;
768
- // Otherwise its a real setting line.
769
- default:
770
- // If the setting is for the crawler let's inidicate we found it and it's true. We can also set the parents array.
771
- if( $buffer == 'Crawler=true' ) { $crawler = 2; $parents[$title] = true;}
772
-
773
- // If the setting for the parent then set it now.
774
- if( substr( $buffer, 0, 7 ) == 'Parent=' ) { $parent = substr( $buffer, 8, -1 ); }
775
-
776
- // We have three sections we need to copy verbatium so write out their settings.
777
- if( $title == 'GJK_Browscap_Version' || $title == 'DefaultProperties' || $title == "*" ) { fwrite( $outfile, $buffer . "\n" ); }
778
- }
779
- }
780
-
781
- // Close the files.
782
- fclose( $outfile );
783
- fclose( $infile );
784
-
785
- // Delete the temporary file.
786
- unlink( $TempFile );
787
-
788
- // Force the cache to be updated.
789
- $bc->updateCache();
790
-
791
- // Update the options to reflect the new download.
792
- $WP_Statistics->update_option('last_browscap_dl', time());
793
- $WP_Statistics->update_option('update_browscap', false);
794
-
795
- $result = "<div class='updated settings-error'><p><strong>" . __('browscap database updated successfully!', 'wp_statistics') . "</strong></p></div>";
796
- }
797
- }
798
- else {
799
- // Update the options to reflect the new download.
800
- $WP_Statistics->update_option('last_browscap_dl', time());
801
- $WP_Statistics->update_option('update_browscap', false);
802
-
803
- $result = "<div class='updated settings-error'><p><strong>" . __('browscap already at current version!', 'wp_statistics') . "</strong></p></div>";
804
- }
805
-
806
- // All of the messages displayed above are stored in a stirng, now it's time to actually output the messages.
807
- return $result;
808
- }
809
-
810
  // This function displays the HTML for the settings page.
811
  function wp_statistics_settings() {
812
  GLOBAL $WP_Statistics;
3
  Plugin Name: WP Statistics
4
  Plugin URI: http://wp-statistics.com/
5
  Description: Complete statistics for your WordPress site.
6
+ Version: 8.1
7
  Author: Mostafa Soufi & Greg Ross
8
  Author URI: http://wp-statistics.com/
9
  Text Domain: wp_statistics
17
  }
18
 
19
  // These defines are used later for various reasons.
20
+ define('WP_STATISTICS_VERSION', '8.1');
21
  define('WP_STATISTICS_MANUAL', 'manual/WP Statistics Admin Manual.');
22
  define('WP_STATISTICS_REQUIRED_PHP_VERSION', '5.3.0');
23
  define('WP_STATISTICS_REQUIRED_GEOIP_PHP_VERSION', WP_STATISTICS_REQUIRED_PHP_VERSION);
41
  // Load the user agent parsing code first, the WP_Statistics class depends on it. Then load the WP_Statistics class.
42
  include_once dirname( __FILE__ ) . '/includes/functions/parse-user-agent.php';
43
  include_once dirname( __FILE__ ) . '/includes/classes/statistics.class.php';
 
 
 
44
 
45
  // This is our global WP_Statitsics class that is used throughout the plugin.
46
  $WP_Statistics = new WP_Statistics();
50
  if( $WPS_Installed != WP_STATISTICS_VERSION ) {
51
  include_once( dirname( __FILE__ ) . '/wps-install.php' );
52
  }
53
+
54
+ // Load the update fuctions for GeoIP and browscap.ini (done in a seperate file to avoid a parse error in PHP 5.2 or below)
55
+ include_once dirname( __FILE__ ) . '/wps-updates.php';
56
 
57
  // Load the rest of the required files for our global functions, online user tracking and hit tracking.
58
  include_once dirname( __FILE__ ) . '/includes/functions/functions.php';
569
  include_once dirname( __FILE__ ) . "/includes/optimization/wps-optimization.php";
570
  }
571
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
  // This function displays the HTML for the settings page.
573
  function wp_statistics_settings() {
574
  GLOBAL $WP_Statistics;
wps-updates.php ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include_once dirname( __FILE__ ) . '/includes/classes/Browscap.php';
3
+
4
+ use phpbrowscap\Browscap;
5
+
6
+ // This function downloads the GeoIP database from MaxMind.
7
+ function wp_statistics_download_geoip() {
8
+
9
+ GLOBAL $WP_Statistics;
10
+
11
+ // We need the download_url() function, it should exists on virtually all installs of PHP, but if it doesn't for some reason, bail out.
12
+ if( !function_exists( 'download_url' ) ) { return ''; }
13
+
14
+ // If GeoIP is disabled, bail out.
15
+ if( $WP_Statistics->get_option('geoip') == false ) { return '';}
16
+
17
+ // This is the location of the file to download.
18
+ $download_url = 'http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz';
19
+
20
+ // Get the upload directory from WordPRess.
21
+ $upload_dir = wp_upload_dir();
22
+
23
+ // Create a variable with the name of the database file to download.
24
+ $DBFile = $upload_dir['basedir'] . '/wp-statistics/GeoLite2-Country.mmdb';
25
+
26
+ // Check to see if the subdirectory we're going to upload to exists, if not create it.
27
+ if( !file_exists($upload_dir['basedir'] . '/wp-statistics') ) { mkdir($upload_dir['basedir'] . '/wp-statistics'); }
28
+
29
+ // Download the file from MaxMind, this places it in a temporary location.
30
+ $TempFile = download_url( $download_url );
31
+
32
+ // If we failed, through a message, otherwise proceed.
33
+ if (is_wp_error( $TempFile ) ) {
34
+ $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error downloading GeoIP database from: %s - %s', 'wp_statistics'), $download_url, $TempFile->get_error_message() ) . "</strong></p></div>";
35
+ }
36
+ else {
37
+ // Open the downloaded file to unzip it.
38
+ $ZipHandle = gzopen( $TempFile, 'rb' );
39
+
40
+ // Create th new file to unzip to.
41
+ $DBfh = fopen( $DBFile, 'wb' );
42
+
43
+ // If we failed to open the downloaded file, through an error and remove the temporary file. Otherwise do the actual unzip.
44
+ if( ! $ZipHandle ) {
45
+ $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error could not open downloaded GeoIP database for reading: %s', 'wp_statistics'), $TempFile) . "</strong></p></div>";
46
+
47
+ unlink( $TempFile );
48
+ }
49
+ else {
50
+ // If we failed to open the new file, through and error and remove the temporary file. Otherwise actually do the unzip.
51
+ if( !$DBfh ) {
52
+ $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error could not open destination GeoIP database for writing %s', 'wp_statistics'), $DBFile) . "</strong></p></div>";
53
+ unlink( $TempFile );
54
+ }
55
+ else {
56
+ while( ( $data = gzread( $ZipHandle, 4096 ) ) != false ) {
57
+ fwrite( $DBfh, $data );
58
+ }
59
+
60
+ // Close the files.
61
+ gzclose( $ZipHandle );
62
+ fclose( $DBfh );
63
+
64
+ // Delete the temporary file.
65
+ unlink( $TempFile );
66
+
67
+ // Display the success message.
68
+ $result = "<div class='updated settings-error'><p><strong>" . __('GeoIP Database updated successfully!', 'wp_statistics') . "</strong></p></div>";
69
+
70
+ // Update the options to reflect the new download.
71
+ $WP_Statistics->update_option('last_geoip_dl', time());
72
+ $WP_Statistics->update_option('update_geoip', false);
73
+
74
+ // Populate any missing GeoIP information if the user has selected the option.
75
+ if( $WP_Statistics->get_option('geoip') && wp_statistics_geoip_supported() && $WP_Statistics->get_option('auto_pop')) {
76
+ include_once dirname( __FILE__ ) . '/includes/functions/geoip-populate.php';
77
+ $result .= wp_statistics_populate_geoip_info();
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ // All of the messages displayed above are stored in a stirng, now it's time to actually output the messages.
84
+ return $result;
85
+ }
86
+
87
+ // This function downloads the browscap database from browscap.org.
88
+ function wp_statistics_download_browscap() {
89
+
90
+ GLOBAL $WP_Statistics;
91
+
92
+ // We need the download_url() function, it should exists on virtually all installs of PHP, but if it doesn't for some reason, bail out.
93
+ if( !function_exists( 'download_url' ) ) { return ''; }
94
+
95
+ // If browscap is disabled, bail out.
96
+ if( $WP_Statistics->get_option('browscap') == false ) { return '';}
97
+
98
+ // This is the location of the file to download.
99
+ $download_url = 'http://browscap.org/stream?q=PHP_BrowsCapINI';
100
+ $download_version = 'http://browscap.org/version-number';
101
+
102
+ // Get the upload directory from WordPress.
103
+ $upload_dir = wp_upload_dir();
104
+
105
+ // Check to see if the subdirectory we're going to upload to exists, if not create it.
106
+ if( !file_exists($upload_dir['basedir'] . '/wp-statistics') ) { mkdir($upload_dir['basedir'] . '/wp-statistics'); }
107
+
108
+ $LocalVersion = 0;
109
+
110
+ // Get the Browscap object, tell it NOT to autoupdate.
111
+ $bc = new Browscap($upload_dir['basedir'] . '/wp-statistics');
112
+ $bc->doAutoUpdate = false; // We don't want to auto update.
113
+
114
+ // If we already have a browscap.ini file (aka we're already done a download in the past) we can get it's version number.
115
+ // We can't execute this code if no browscap.ini exists as then the library will automatically download a full version, even
116
+ // though we've told it not to autoupdate above.
117
+ if( $WP_Statistics->get_option('last_browscap_dl') > 1 ) {
118
+ // Get the current browser so that the version information is populated.
119
+ $bc->getBrowser();
120
+
121
+ $LocalVersion = $bc->getSourceVersion();
122
+ }
123
+
124
+ // Get the remote version info from browscap.org.
125
+ $TempVersionFile = download_url( $download_version );
126
+
127
+ // Read the version we just downloaded in to a string.
128
+ $RemoteVersion = file_get_contents($TempVersionFile);
129
+
130
+ // Get rid of the temporary file.
131
+ unlink( $TempVersionFile );
132
+
133
+ // If there is a new version, let's go get it.
134
+ if( intval($RemoteVersion) > $LocalVersion ) {
135
+
136
+ // Download the file from MaxMind, this places it in a temporary location.
137
+ $TempFile = download_url( $download_url );
138
+
139
+ // If we failed, through a message, otherwise proceed.
140
+ if (is_wp_error( $TempFile ) ) {
141
+ $result = "<div class='updated settings-error'><p><strong>" . sprintf(__('Error downloading browscap database from: %s - %s', 'wp_statistics'), $download_url, $TempFile->get_error_message() ) . "</strong></p></div>";
142
+ }
143
+ else {
144
+ // Setup our file handles.
145
+ $infile = fopen($TempFile, 'r' );
146
+ $outfile = fopen($upload_dir['basedir'] . '/wp-statistics/browscap.ini', 'w');
147
+
148
+ // We're going to need some variables to use as we process the new browscap.ini.
149
+ // $crawler has three possible settings:
150
+ // 0 = no setting found
151
+ // 1 = setting found but not a crawler
152
+ // 2 = setting found and a crawler
153
+ $parent = '';
154
+ $title = '';
155
+ $crawler = 0;
156
+ $parents = array( '' => false );
157
+
158
+ // Now read in the browscap.ini file we downloaded one line at a time.
159
+ while( ( $buffer = fgets($infile) ) !== false)
160
+ {
161
+ // Let's get rid of the tailing carriage return extra spaces.
162
+ $buffer = trim($buffer);
163
+
164
+ // We're going to do some things based on the first charater on the line so let's just get it once.
165
+ $firstchar = substr( $buffer, 0, 1 );
166
+
167
+ // The first character will tell us what kind of line we're dealing with.
168
+ switch( $firstchar )
169
+ {
170
+ // A square bracket means it's a section title.
171
+ case '[':
172
+
173
+ // We have three sections we need to copy verbatium so don't do the standard processing for them.
174
+ if( $title != 'GJK_Browscap_Version' && $title != 'DefaultProperties' && $title != "*" )
175
+ {
176
+ // If we found the current section is a crawler or we didn't find a crawler setting but the parent is a crawler...
177
+ if( $crawler == 2 || ( $crawler == 0 && array_key_exists( $parent, $parents ) ) )
178
+ {
179
+ // Write out the section with just the parent/crawler setting saved.
180
+ fwrite( $outfile, "[" . $title . "]\n" );
181
+ fwrite( $outfile, 'Parent="' . $parent . '"' . "\n");
182
+ fwrite( $outfile, "Crawler=true\n" );
183
+ }
184
+ }
185
+
186
+ // Reset our variables.
187
+ $crawler = 0;
188
+ $parent = '';
189
+ $title = substr( $buffer, 1, strlen($buffer) - 2 );
190
+
191
+ // We have three sections we need to copy verbatium so write out their headings immediatly instead of waiting to see if they are a crawler.
192
+ if( $title == 'GJK_Browscap_Version' || $title == 'DefaultProperties' || $title == "*" ) { fwrite($outfile,"[" . $title . "]\n"); }
193
+
194
+ break;
195
+ // A space or semi-colan means it's a comment.
196
+ case ' ':
197
+ case ';':
198
+ // Since we're hacking out lots of data the only comments we want to keep are the first few in the file before the first section is processed.
199
+ if( $title == '' ) { fwrite( $outfile, $buffer . "\n" ); }
200
+
201
+ break;
202
+ // Otherwise its a real setting line.
203
+ default:
204
+ // If the setting is for the crawler let's inidicate we found it and it's true. We can also set the parents array.
205
+ if( $buffer == 'Crawler=true' ) { $crawler = 2; $parents[$title] = true;}
206
+
207
+ // If the setting for the parent then set it now.
208
+ if( substr( $buffer, 0, 7 ) == 'Parent=' ) { $parent = substr( $buffer, 8, -1 ); }
209
+
210
+ // We have three sections we need to copy verbatium so write out their settings.
211
+ if( $title == 'GJK_Browscap_Version' || $title == 'DefaultProperties' || $title == "*" ) { fwrite( $outfile, $buffer . "\n" ); }
212
+ }
213
+ }
214
+
215
+ // Close the files.
216
+ fclose( $outfile );
217
+ fclose( $infile );
218
+
219
+ // Delete the temporary file.
220
+ unlink( $TempFile );
221
+
222
+ // Force the cache to be updated.
223
+ $bc->updateCache();
224
+
225
+ // Update the options to reflect the new download.
226
+ $WP_Statistics->update_option('last_browscap_dl', time());
227
+ $WP_Statistics->update_option('update_browscap', false);
228
+
229
+ $result = "<div class='updated settings-error'><p><strong>" . __('browscap database updated successfully!', 'wp_statistics') . "</strong></p></div>";
230
+ }
231
+ }
232
+ else {
233
+ // Update the options to reflect the new download.
234
+ $WP_Statistics->update_option('last_browscap_dl', time());
235
+ $WP_Statistics->update_option('update_browscap', false);
236
+
237
+ $result = "<div class='updated settings-error'><p><strong>" . __('browscap already at current version!', 'wp_statistics') . "</strong></p></div>";
238
+ }
239
+
240
+ // All of the messages displayed above are stored in a stirng, now it's time to actually output the messages.
241
+ return $result;
242
+ }