| 1 | <?php
|
|---|
| 2 | /*
|
|---|
| 3 | Plugin Name: WordPress.com Stats
|
|---|
| 4 | Plugin URI: http://wordpress.org/extend/plugins/stats/
|
|---|
| 5 | Description: Tracks views, post/page views, referrers, and clicks. Requires a WordPress.com API key.
|
|---|
| 6 | Author: Andy Skelton
|
|---|
| 7 | Javascript fixes by: gonchuki
|
|---|
| 8 | Version: 1.2.0
|
|---|
| 9 |
|
|---|
| 10 | Requires WordPress 2.1 or later. Not for use with WPMU.
|
|---|
| 11 |
|
|---|
| 12 | Looking for a way to hide the gif? Don't use "display:none"! Put this in your stylesheet:
|
|---|
| 13 | img#wpstats{width:0px;height:0px;overflow:hidden;}
|
|---|
| 14 |
|
|---|
| 15 | */
|
|---|
| 16 |
|
|---|
| 17 | // If you hardcode a WP.com API key here, all key config screens will be hidden.
|
|---|
| 18 | $stats_wpcom_api_key = '';
|
|---|
| 19 |
|
|---|
| 20 | function stats_get_api_key() {
|
|---|
| 21 | if ( !empty( $GLOBALS['stats_wpcom_api_key'] ) )
|
|---|
| 22 | return $GLOBALS['stats_wpcom_api_key'];
|
|---|
| 23 |
|
|---|
| 24 | return stats_get_option('api_key');
|
|---|
| 25 | }
|
|---|
| 26 |
|
|---|
| 27 | function stats_set_api_key($api_key) {
|
|---|
| 28 | stats_set_option('api_key', $api_key);
|
|---|
| 29 | }
|
|---|
| 30 |
|
|---|
| 31 | function stats_get_options() {
|
|---|
| 32 | $options = get_option( 'stats_options' );
|
|---|
| 33 |
|
|---|
| 34 | if ( !isset( $options['version'] ) || $options['version'] < STATS_VERSION ) {
|
|---|
| 35 | $options = stats_upgrade_options( $options );
|
|---|
| 36 |
|
|---|
| 37 | stats_set_options( $options );
|
|---|
| 38 | }
|
|---|
| 39 |
|
|---|
| 40 | return $options;
|
|---|
| 41 | }
|
|---|
| 42 |
|
|---|
| 43 | function stats_get_option( $option ) {
|
|---|
| 44 | $options = stats_get_options();
|
|---|
| 45 |
|
|---|
| 46 | if ( isset( $options[$option] ) )
|
|---|
| 47 | return $options[$option];
|
|---|
| 48 |
|
|---|
| 49 | return null;
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | function stats_set_option( $option, $value ) {
|
|---|
| 53 | $options = stats_get_options();
|
|---|
| 54 |
|
|---|
| 55 | $options[$option] = $value;
|
|---|
| 56 |
|
|---|
| 57 | stats_set_options($options);
|
|---|
| 58 | }
|
|---|
| 59 |
|
|---|
| 60 | function stats_set_options($options) {
|
|---|
| 61 | update_option( 'stats_options', $options );
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | function stats_upgrade_options( $options ) {
|
|---|
| 65 | $defaults = array(
|
|---|
| 66 | 'host' => '',
|
|---|
| 67 | 'path' => '',
|
|---|
| 68 | 'blog_id' => false,
|
|---|
| 69 | );
|
|---|
| 70 |
|
|---|
| 71 | if ( is_array( $options ) && !empty( $options ) )
|
|---|
| 72 | $options = array_merge( $defaults, $options );
|
|---|
| 73 | else
|
|---|
| 74 | $options = $defaults;
|
|---|
| 75 |
|
|---|
| 76 | $options['version'] = STATS_VERSION;
|
|---|
| 77 |
|
|---|
| 78 | return $options;
|
|---|
| 79 | }
|
|---|
| 80 |
|
|---|
| 81 | function stats_footer() {
|
|---|
| 82 | global $wp_the_query, $current_user;
|
|---|
| 83 |
|
|---|
| 84 | $options = stats_get_options();
|
|---|
| 85 |
|
|---|
| 86 | if ( !empty($current_user->ID) || empty($options['blog_id']) )
|
|---|
| 87 | return;
|
|---|
| 88 |
|
|---|
| 89 | $a['blog'] = $options['blog_id'];
|
|---|
| 90 | $a['v'] = 'ext';
|
|---|
| 91 | if ( ( $wp_the_query->is_single || $wp_the_query->is_page ) && !$wp_the_query->is_attachment )
|
|---|
| 92 | $a['post'] = $wp_the_query->get_queried_object_id();
|
|---|
| 93 | else
|
|---|
| 94 | $a['post'] = '0';
|
|---|
| 95 |
|
|---|
| 96 | ?>
|
|---|
| 97 | <script src="http://stats.wordpress.com/e-<?php echo gmdate('YW'); ?>.js" type="text/javascript"></script>
|
|---|
| 98 | <script type="text/javascript">
|
|---|
| 99 | wpcom_stats.st_go({<?php echo stats_array($a); ?>});
|
|---|
| 100 | wpcom_stats.addEvent(
|
|---|
| 101 | window, 'load',
|
|---|
| 102 | function(){ wpcom_stats.linktracker_init(<?php echo "{$a['blog']},{$a['post']},2"; ?>);}
|
|---|
| 103 | );
|
|---|
| 104 | </script>
|
|---|
| 105 | <?php
|
|---|
| 106 | }
|
|---|
| 107 |
|
|---|
| 108 | function stats_array($kvs) {
|
|---|
| 109 | $kvs = apply_filters('stats_array', $kvs);
|
|---|
| 110 | $kvs = array_map('addslashes', $kvs);
|
|---|
| 111 | foreach ( $kvs as $k => $v )
|
|---|
| 112 | $jskvs[] = "$k:'$v'";
|
|---|
| 113 | return join(',', $jskvs);
|
|---|
| 114 | }
|
|---|
| 115 |
|
|---|
| 116 | function stats_admin_menu() {
|
|---|
| 117 | if ( stats_get_option('blog_id') ) {
|
|---|
| 118 | $hook = add_submenu_page('index.php', __('Blog Stats'), __('Blog Stats'), 'manage_options', 'stats', 'stats_reports_page');
|
|---|
| 119 | add_action("load-$hook", 'stats_reports_load');
|
|---|
| 120 | }
|
|---|
| 121 | $hook = add_submenu_page('plugins.php', __('WordPress.com Stats Plugin'), __('WordPress.com Stats'), 'manage_options', 'wpstats', 'stats_admin_page');
|
|---|
| 122 | add_action("load-$hook", 'stats_admin_load');
|
|---|
| 123 | add_action("admin_head-$hook", 'stats_admin_head');
|
|---|
| 124 | add_action('admin_notices', 'stats_admin_notices');
|
|---|
| 125 | }
|
|---|
| 126 |
|
|---|
| 127 | function stats_reports_load() {
|
|---|
| 128 | add_action('admin_head', 'stats_reports_head');
|
|---|
| 129 | }
|
|---|
| 130 |
|
|---|
| 131 | function stats_reports_head() {
|
|---|
| 132 | ?>
|
|---|
| 133 | <style type="text/css">
|
|---|
| 134 | body { height: 100%; }
|
|---|
| 135 | #statsreport { height: 2500px; width: 100%; }
|
|---|
| 136 | </style>
|
|---|
| 137 | <?php
|
|---|
| 138 | }
|
|---|
| 139 |
|
|---|
| 140 | function stats_reports_page() {
|
|---|
| 141 | $blog_id = stats_get_option('blog_id');
|
|---|
| 142 | echo "<iframe id='statsreport' frameborder='0' src='http://dashboard.wordpress.com/wp-admin/index.php?page=estats&blog=$blog_id&noheader=true'></iframe>";
|
|---|
| 143 | }
|
|---|
| 144 |
|
|---|
| 145 | function stats_admin_load() {
|
|---|
| 146 | global $plugin_page;
|
|---|
| 147 |
|
|---|
| 148 | if ( ! empty( $_POST['action'] ) ) {
|
|---|
| 149 | switch( $_POST['action'] ) {
|
|---|
| 150 | case 'get_blog_id' :
|
|---|
| 151 | if ( isset( $_POST['usesavedkey'] ) )
|
|---|
| 152 | $key = get_option('wordpress_api_key');
|
|---|
| 153 | else $key = $_POST['api_key'];
|
|---|
| 154 | $blog_id = stats_get_blog_id( $key );
|
|---|
| 155 | wp_redirect( "plugins.php?page=$plugin_page" );
|
|---|
| 156 | exit;
|
|---|
| 157 | }
|
|---|
| 158 | }
|
|---|
| 159 |
|
|---|
| 160 | $options = stats_get_options();
|
|---|
| 161 | $api_key = stats_get_api_key();
|
|---|
| 162 | if ( empty( $options['blog_id'] ) && !empty( $api_key ) )
|
|---|
| 163 | stats_get_blog_id( $api_key );
|
|---|
| 164 | }
|
|---|
| 165 |
|
|---|
| 166 | function stats_admin_notices() {
|
|---|
| 167 | if ( stats_get_api_key() )
|
|---|
| 168 | return;
|
|---|
| 169 | echo "<div class='updated' style='background-color:#f66;'><p>" . sprintf(__('<a href="%s">WordPress.com Stats</a> needs attention: please enter an API key or disable the plugin.'), "plugins.php?page=wpstats") . "</p></div>";
|
|---|
| 170 | }
|
|---|
| 171 |
|
|---|
| 172 | function stats_admin_head() {
|
|---|
| 173 | ?>
|
|---|
| 174 | <style type="text/css">
|
|---|
| 175 | #statserror {
|
|---|
| 176 | border: 1px solid #766;
|
|---|
| 177 | background-color: #d22;
|
|---|
| 178 | padding: 1em 3em;
|
|---|
| 179 | }
|
|---|
| 180 | </style>
|
|---|
| 181 | <?php
|
|---|
| 182 | }
|
|---|
| 183 |
|
|---|
| 184 | function stats_admin_page() {
|
|---|
| 185 | global $plugin_page;
|
|---|
| 186 |
|
|---|
| 187 | $options = stats_get_options();
|
|---|
| 188 | ?>
|
|---|
| 189 | <div class="wrap">
|
|---|
| 190 | <h2><?php _e('WordPress.com Stats'); ?></h2>
|
|---|
| 191 | <div class="narrow">
|
|---|
| 192 | <?php if ( !empty($options['error']) ) : ?>
|
|---|
| 193 | <div id='statserror'>
|
|---|
| 194 | <h3><?php _e('Error from last API Key attempt:'); ?></h3>
|
|---|
| 195 | <p><?php echo $options['error']; ?></p>
|
|---|
| 196 | </div>
|
|---|
| 197 | <?php $options['error'] = false; stats_set_options($options); endif; ?>
|
|---|
| 198 |
|
|---|
| 199 | <?php if ( empty( $options['blog_id'] ) ) : ?>
|
|---|
| 200 | <p><?php _e('The WordPress.com Stats Plugin is not working because it needs to be linked to a WordPress.com account.'); ?></p>
|
|---|
| 201 |
|
|---|
| 202 | <?php if ( empty( $GLOBALS['stats_wpcom_api_key'] ) ) : ?>
|
|---|
| 203 | <form action="plugins.php?page=<?php echo $plugin_page; ?>" method="post">
|
|---|
| 204 | <p><?php _e('Enter your WordPress.com API key to link this blog to your WordPress.com account. Be sure to use your own API key! Using any other key will lock you out of your stats. (<a href="http://wordpress.com/profile/">Get your key here.</a>)'); ?></p>
|
|---|
| 205 | <label for="api_key"><?php _e('API Key:'); ?> <input type="text" name="api_key" id="api_key" value="<?php echo $api_key; ?>" /></label>
|
|---|
| 206 | <input type="hidden" name="action" value="get_blog_id" />
|
|---|
| 207 | <p class="submit"><input type="submit" value="<?php _e('Save »'); ?>" /></p>
|
|---|
| 208 | </form>
|
|---|
| 209 | <?php else : ?>
|
|---|
| 210 | <p><?php _e('An API Key is present in the source code but it did not work.') ?></p>
|
|---|
| 211 | <?php endif; ?>
|
|---|
| 212 |
|
|---|
| 213 | <?php else : ?>
|
|---|
| 214 | <p><?php _e('The WordPress.com Stats Plugin is configured and working.'); ?></p>
|
|---|
| 215 | <p><?php _e('Visitors who are logged in are not counted. (This means you.)'); ?></p>
|
|---|
| 216 | <p><?php printf(__('Visit <a href="%s">your Dashboard</a> to see your blog stats.'), 'index.php?page=stats'); ?></p>
|
|---|
| 217 | <?php endif; ?>
|
|---|
| 218 |
|
|---|
| 219 | </div>
|
|---|
| 220 | </div>
|
|---|
| 221 |
|
|---|
| 222 | <?php
|
|---|
| 223 | stats_set_options( $options );
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 | function stats_xmlrpc_methods( $methods ) {
|
|---|
| 227 | $my_methods = array(
|
|---|
| 228 | 'wpStats.get_posts' => 'stats_get_posts',
|
|---|
| 229 | 'wpStats.get_blog' => 'stats_get_blog'
|
|---|
| 230 | );
|
|---|
| 231 |
|
|---|
| 232 | return array_merge( $methods, $my_methods );
|
|---|
| 233 | }
|
|---|
| 234 |
|
|---|
| 235 | function stats_get_posts( $args ) {
|
|---|
| 236 | list( $post_ids ) = $args;
|
|---|
| 237 |
|
|---|
| 238 | $post_ids = array_map( 'intval', (array) $post_ids );
|
|---|
| 239 | $r = 'include=' . join(',', $post_ids);
|
|---|
| 240 | $posts = get_posts( $r );
|
|---|
| 241 | $_posts = array();
|
|---|
| 242 |
|
|---|
| 243 | foreach ( $post_ids as $post_id )
|
|---|
| 244 | $_posts[$post_id] = stats_get_post($post_id);
|
|---|
| 245 |
|
|---|
| 246 | return $_posts;
|
|---|
| 247 | }
|
|---|
| 248 |
|
|---|
| 249 | function stats_get_blog( ) {
|
|---|
| 250 | $home = parse_url( get_option('home') );
|
|---|
| 251 | return array(
|
|---|
| 252 | 'host' => $home['host'],
|
|---|
| 253 | 'path' => $home['path'],
|
|---|
| 254 | 'name' => get_option('blogname'),
|
|---|
| 255 | 'description' => get_option('blogdescription'),
|
|---|
| 256 | 'siteurl' => get_option('siteurl'),
|
|---|
| 257 | 'version' => STATS_VERSION
|
|---|
| 258 | );
|
|---|
| 259 | }
|
|---|
| 260 |
|
|---|
| 261 | function stats_get_post( $post_id ) {
|
|---|
| 262 | $post = get_post( $post_id );
|
|---|
| 263 | if ( empty( $post ) )
|
|---|
| 264 | $post = get_page( $post_id );
|
|---|
| 265 | return array(
|
|---|
| 266 | 'id' => $post->ID,
|
|---|
| 267 | 'permalink' => get_permalink($post->ID),
|
|---|
| 268 | 'title' => $post->post_title,
|
|---|
| 269 | 'type' => $post->post_type
|
|---|
| 270 | );
|
|---|
| 271 | }
|
|---|
| 272 |
|
|---|
| 273 | function stats_client() {
|
|---|
| 274 | require_once( ABSPATH . WPINC . '/class-IXR.php' );
|
|---|
| 275 | $client = new IXR_ClientMulticall( STATS_XMLRPC_SERVER );
|
|---|
| 276 | return $client;
|
|---|
| 277 | }
|
|---|
| 278 |
|
|---|
| 279 | function stats_add_call() {
|
|---|
| 280 | global $stats_xmlrpc_client;
|
|---|
| 281 | if ( empty($stats_xmlrpc_client) ) {
|
|---|
| 282 | $stats_xmlrpc_client = stats_client();
|
|---|
| 283 | ignore_user_abort(true);
|
|---|
| 284 | add_action('shutdown', 'stats_multicall_query');
|
|---|
| 285 | }
|
|---|
| 286 |
|
|---|
| 287 | $args = func_get_args();
|
|---|
| 288 |
|
|---|
| 289 | call_user_method_array( 'addCall', $stats_xmlrpc_client, $args );
|
|---|
| 290 | }
|
|---|
| 291 |
|
|---|
| 292 | function stats_multicall_query() {
|
|---|
| 293 | global $stats_xmlrpc_client;
|
|---|
| 294 |
|
|---|
| 295 | $stats_xmlrpc_client->query();
|
|---|
| 296 | }
|
|---|
| 297 |
|
|---|
| 298 | function stats_update_bloginfo() {
|
|---|
| 299 | stats_add_call(
|
|---|
| 300 | 'wpStats.update_bloginfo',
|
|---|
| 301 | stats_get_api_key(),
|
|---|
| 302 | stats_get_option('blog_id'),
|
|---|
| 303 | stats_get_blog()
|
|---|
| 304 | );
|
|---|
| 305 | }
|
|---|
| 306 |
|
|---|
| 307 | function stats_update_post( $post_id ) {
|
|---|
| 308 | stats_add_call(
|
|---|
| 309 | 'wpStats.update_postinfo',
|
|---|
| 310 | stats_get_api_key(),
|
|---|
| 311 | stats_get_option('blog_id'),
|
|---|
| 312 | stats_get_post($post_id)
|
|---|
| 313 | );
|
|---|
| 314 | }
|
|---|
| 315 |
|
|---|
| 316 | function stats_flush_posts() {
|
|---|
| 317 | stats_add_call(
|
|---|
| 318 | 'wpStats.flush_posts',
|
|---|
| 319 | stats_get_api_key(),
|
|---|
| 320 | stats_get_option('blog_id')
|
|---|
| 321 | );
|
|---|
| 322 | }
|
|---|
| 323 |
|
|---|
| 324 | function stats_activity() {
|
|---|
| 325 | $options = stats_get_options();
|
|---|
| 326 |
|
|---|
| 327 | if ( $options['blog_id'] ) {
|
|---|
| 328 | ?>
|
|---|
| 329 | <h3><?php _e('WordPress.com Blog Stats'); ?></h3>
|
|---|
| 330 | <p><?php printf(__('Visit %s to see your blog stats.'), '<a href="http://dashboard.wordpress.com/wp-admin/index.php?page=stats&blog=' . $options['blog_id'] . '">' . __('your Global Dashboard') . '</a>'); ?></p>
|
|---|
| 331 | <?php
|
|---|
| 332 | }
|
|---|
| 333 | }
|
|---|
| 334 |
|
|---|
| 335 | function stats_get_blog_id($api_key) {
|
|---|
| 336 | $options = stats_get_options();
|
|---|
| 337 |
|
|---|
| 338 | require_once( ABSPATH . WPINC . '/class-IXR.php' );
|
|---|
| 339 |
|
|---|
| 340 | $client = new IXR_Client( STATS_XMLRPC_SERVER );
|
|---|
| 341 |
|
|---|
| 342 | extract( parse_url( get_option( 'home' ) ) );
|
|---|
| 343 |
|
|---|
| 344 | $path = rtrim( $path, '/' );
|
|---|
| 345 |
|
|---|
| 346 | if ( empty( $path ) )
|
|---|
| 347 | $path = '/';
|
|---|
| 348 |
|
|---|
| 349 | $client->query( 'wpStats.get_blog_id', $api_key, stats_get_blog() );
|
|---|
| 350 |
|
|---|
| 351 | if ( $client->isError() ) {
|
|---|
| 352 | if ( $client->getErrorCode() == -32300 )
|
|---|
| 353 | $options['error'] = __('Your blog was unable to connect to WordPress.com. Please ask your host for help. (' . $client->getErrorMessage() . ')');
|
|---|
| 354 | else
|
|---|
| 355 | $options['error'] = $client->getErrorMessage();
|
|---|
| 356 | stats_set_options( $options );
|
|---|
| 357 | return false;
|
|---|
| 358 | } else {
|
|---|
| 359 | $options['error'] = false;
|
|---|
| 360 | }
|
|---|
| 361 |
|
|---|
| 362 | $response = $client->getResponse();
|
|---|
| 363 |
|
|---|
| 364 | $blog_id = isset($response['blog_id']) ? (int) $response['blog_id'] : false;
|
|---|
| 365 |
|
|---|
| 366 | $options[ 'host' ] = $host;
|
|---|
| 367 | $options[ 'path' ] = $path;
|
|---|
| 368 | $options[ 'blog_id' ] = $blog_id;
|
|---|
| 369 |
|
|---|
| 370 | stats_set_options( $options );
|
|---|
| 371 |
|
|---|
| 372 | stats_set_api_key( $api_key );
|
|---|
| 373 |
|
|---|
| 374 | return $blog_id;
|
|---|
| 375 | }
|
|---|
| 376 |
|
|---|
| 377 | function stats_activate() {
|
|---|
| 378 | $options = stats_get_options();
|
|---|
| 379 |
|
|---|
| 380 | if ( empty($options['blog_id']) && $api_key = stats_get_api_key() )
|
|---|
| 381 | stats_get_blog_id($api_key);
|
|---|
| 382 | }
|
|---|
| 383 |
|
|---|
| 384 | function stats_deactivate() {
|
|---|
| 385 | delete_option('stats_options');
|
|---|
| 386 | }
|
|---|
| 387 |
|
|---|
| 388 | // Boooooooooooring init stuff
|
|---|
| 389 | register_activation_hook(__FILE__, 'stats_activate');
|
|---|
| 390 | register_deactivation_hook(__FILE__, 'stats_deactivate');
|
|---|
| 391 | add_action( 'admin_menu', 'stats_admin_menu' );
|
|---|
| 392 | add_action( 'activity_box_end', 'stats_activity', 1 );
|
|---|
| 393 |
|
|---|
| 394 | // Plant the tracking code in the footer
|
|---|
| 395 | add_action( 'wp_footer', 'stats_footer', 101 );
|
|---|
| 396 |
|
|---|
| 397 | // Tell HQ about changed settings
|
|---|
| 398 | add_action( 'update_option_home', 'stats_update_bloginfo' );
|
|---|
| 399 | add_action( 'update_option_siteurl', 'stats_update_bloginfo' );
|
|---|
| 400 | add_action( 'update_option_blogname', 'stats_update_bloginfo' );
|
|---|
| 401 | add_action( 'update_option_blogdescription', 'stats_update_bloginfo' );
|
|---|
| 402 |
|
|---|
| 403 | // Tell HQ about changed posts
|
|---|
| 404 | add_action( 'save_post', 'stats_update_post', 10, 1 );
|
|---|
| 405 |
|
|---|
| 406 | // Tell HQ to drop all post info for this blog
|
|---|
| 407 | add_action( 'update_option_permalink_structure', 'stats_flush_posts' );
|
|---|
| 408 |
|
|---|
| 409 | // Teach the XMLRPC server how to dance properly
|
|---|
| 410 | add_filter( 'xmlrpc_methods', 'stats_xmlrpc_methods' );
|
|---|
| 411 |
|
|---|
| 412 | define( 'STATS_VERSION', '1' );
|
|---|
| 413 | define( 'STATS_XMLRPC_SERVER', 'http://wordpress.com/xmlrpc.php' );
|
|---|
| 414 |
|
|---|
| 415 | ?>
|
|---|