Custom Search
A | A | A | Report content





<?php
/*
Plugin Name: WP-OnlineCounter
Version: 0.14
Plugin URI: http://faked.org/blog/wp-onlinecounter/'>http://faked.org/blog/wp-onlinecounter/
Description: Online and Total visitors counter.
Author: Jan Grewe
Author URI: http://faked.org
*/

/*

== Installation ==

add this to your template where you want the counter to show up:
---
<?php if(function_exists(wp_onlinecounter)) { wp_onlinecounter(); } ?>
---
if you want to include the counter on a page but DON'T want to show
the output put "hide" into the function's brackets.


== ChangeLog ==

v0.14: Removed Trackback option
       Output full widget structure
     Fixed saving/output of widget title

v0.13: Disabled Trackback by default

v0.12: uhm, i forgot...

v0.11: Added a page (Dashboard -> Manage) to show the last URIs visited by
       all online visitors, or all URIs in this session for a specific visitor.
       Moved the plugin's Settings page (Dashboard -> Options)
       Added a new column for URIs to the table (deactivate and re-activate
       the plugin to apply the changes!)

v0.10: Added sidebar-compatible structure (list and title) and more options
       to configure the output.
       Added a little script that allows WP-OnlineCounter to be used as a widget,
       make sure you activate it, too!

v0.9a: Fixed some typos which created unneeded option fields.
     Added some code to send a trackback to my site if you like the plugin.

v0.9:  Fixed the "Duplicate key" error, Primary key is now "timestamp" and "ip".
       Added an option to show currently online visitors only to registered users.
       Added options to set the labels from the dashboard.

v0.8:  Moved all configuration options to the "Plugins" page in the dashboard.

v0.7a: Fixed a bug which stopped the total count from increasing.

v0.7:  Added a settings page to the dashboard, you can now set the count
       of maximum concurrent and total visitors to any value.

v0.6:  Added automatic table creation on plugin activation.

v0.5:  Thanks to Arno Simon (http://www.arno-simon.de/) for replacing
       mysql-handling with $wpdb-handling.
       Thanks to Marcus Kimpenhaus (http://blog.marcus-kimpenhaus.de/) for
       adding detection of the user's IP if he uses a non-anon proxy.

v0.4:  Added a config option to change the table name ($wpoc_tablename).

v0.3a: Thanks to Lance (http://www.desire2design.com/) for pointing out an error
       in the documentation regarding hiding the counter.

v.03:  Thanks to Ara Pehlivanian (http://arapehlivanian.com/) for adding a
       parameter to hide the counter on certain pages.

v0.2:  Thanks to Tom Köhler (http://www.zappelfillip.de/) for adding the ability
       to exclude users with specific user-levels from being counted and keeping
       record of the highest concurrent visitor count so far.

v0.1:  initial release

*/

//set the table name for the counter in your wordpress database
//you normally should not have to use this, don't come crying if you mess up!
$wpoc_tablename = 'onlinecounter';

function wp_onlinecounter($visibility = "show") {
    
  global $wpdb;
  global $table_prefix;
  global $wpoc_tablename;
  global $user_level;
  
  $ignore_level = get_option('wpoc_ignore_level');
  $timeout = get_option('wpoc_timeout');

  if(!isset($wpdb->wp_onlinecounter)){
    $wpdb->wp_onlinecounter = $table_prefix.$wpoc_tablename; }
    
    //get user's IP if he uses a non-anon proxy
    function get_user_ipaddr() {
    if(empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
      $ip_address = $_SERVER["REMOTE_ADDR"];
    }else{
      $ip_address = $_SERVER["HTTP_X_FORWARDED_FOR"];
    }
    if(strpos($ip_address, ',') !== false) {
      $ip_address = explode(',', $ip_address);
      $ip_address = $ip_address[0];
    }
    return $ip_address;
    }
    $user_ip = get_user_ipaddr();

    //get the time
    $timestamp = time();
    $timeout = $timestamp-$timeout;

    //grab current total count
    $count = $wpdb->get_var("SELECT count FROM $wpdb->wp_onlinecounter ORDER BY count DESC LIMIT 1");

  //get timestamp from last visit
    $visitor = $wpdb->get_var("SELECT timestamp FROM $wpdb->wp_onlinecounter WHERE ip = '$user_ip' ORDER BY timestamp DESC LIMIT 1");
    if(empty($visitor)) $visitor = 0;
    
    //get max. online visitors
    $maxon = $wpdb->get_var("SELECT maxon FROM $wpdb->wp_onlinecounter ORDER BY maxon DESC LIMIT 1");
  $maxontime = $wpdb->get_var("SELECT maxontime FROM $wpdb->wp_onlinecounter ORDER BY maxon DESC LIMIT 1");

  //increase count only if visitor is under $ignore_level
  //get_currentuserinfo();
  if(($visitor < $timeout) && ($user_level < $ignore_level)) {
    //increase count
    $count++;
  }

     //insert the values
    $insert = $wpdb->query("INSERT INTO $wpdb->wp_onlinecounter VALUES ('$timestamp', '$user_ip', '$count', '0', '0', '$_SERVER[REQUEST_URI]')");
  
  //delete values when they leave
  $delete = $wpdb->query("DELETE FROM $wpdb->wp_onlinecounter WHERE timestamp < $timeout");

    //grab the results
    $online = $wpdb->query("SELECT DISTINCT ip FROM $wpdb->wp_onlinecounter");
    
    //decrease displayed online-count if user-level is not lower then $ignore_level
    if ($user_level >= $ignore_level) --$online;

    if ($online > $maxon) {
      $maxon = $online;
      $maxontime = $timestamp;
    }
        
    $update = $wpdb->query("UPDATE $wpdb->wp_onlinecounter SET maxon='$maxon', maxontime='$maxontime' WHERE timestamp='$timestamp'");

    //output the results
    if($visibility == 'show') {
      $wpoc_header = get_option('wpoc_header');
    $wpoc_footer = get_option('wpoc_footer');
      $wpoc_show_current = get_option('wpoc_show_current');
      $wpoc_show_current_users_only = get_option('wpoc_show_current_users_only');
    $wpoc_show_maxon = get_option('wpoc_show_maxon');
    $wpoc_show_total = get_option('wpoc_show_total');
    $wpoc_label_current = get_option('wpoc_label_current');
    $wpoc_label_maxon = get_option('wpoc_label_maxon');
    $wpoc_label_total = get_option('wpoc_label_total');
    echo $wpoc_header;
      if ($wpoc_show_current == 'on')
        if ($wpoc_show_current_users_only !== 'on' || $user_level > 0)
          echo "<li>$online $wpoc_label_current</li>";
      if ($wpoc_show_maxon == 'on')
        echo "<li>$maxon $wpoc_label_maxon</li>";
      if ($wpoc_show_total == 'on')
        echo "<li>$count $wpoc_label_total</li>";
       echo $wpoc_footer;
    }
}

//functions to add a page to the options in the dashboard
add_action('admin_menu', 'wpoc_add_page');
function wpoc_add_page() {
  add_submenu_page('options-general.php', 'WP-OnlineCounter', 'WP-OnlineCounter', 10, __FILE__, 'wpoc_options_page');
  add_submenu_page('edit.php', 'WP-OnlineCounter', 'WP-OnlineCounter', 10, __FILE__, 'wpoc_counter_page');
}

function wpoc_options_page() {
  global $wpdb;
  global $wpoc_tablename;
  global $table_prefix;
  global $max;
  global $total;
  
  if(!isset($wpdb->wp_onlinecounter)){
    $wpdb->wp_onlinecounter = $table_prefix.$wpoc_tablename; }
    
  if(isset($_POST['submitted'])){
    $wpdb->query("UPDATE $wpdb->wp_onlinecounter SET maxon='$_POST[wpoc_maxon]'");
    $wpdb->query("UPDATE $wpdb->wp_onlinecounter SET count='$_POST[wpoc_total]'");
    update_option('wpoc_header', $_POST['wpoc_header']);
    update_option('wpoc_footer', $_POST['wpoc_footer']);
    update_option('wpoc_show_current', $_POST['wpoc_show_current']);
    update_option('wpoc_show_current_users_only', $_POST['wpoc_show_current_users_only']);
    update_option('wpoc_show_maxon', $_POST['wpoc_show_maxon']);
    update_option('wpoc_show_total', $_POST['wpoc_show_total']);
    update_option('wpoc_ignore_level', $_POST['wpoc_ignore_level']);
    update_option('wpoc_timeout', $_POST['wpoc_timeout']);
    update_option('wpoc_label_current', $_POST['wpoc_label_current']);
    update_option('wpoc_label_maxon', $_POST['wpoc_label_maxon']);
    update_option('wpoc_label_total', $_POST['wpoc_label_total']);
    
    /*
    if ($_POST['wpoc_trackback'] == "sent") {
      $trackback_body = "at my site \"".get_option(blogname)."\"";
      $last_post = $wpdb->get_var("SELECT ID FROM $wpdb->posts ORDER BY ID DESC LIMIT 1");
      trackback("http://faked.org/blog/wp-onlinecounter/'>http://faked.org/blog/wp-onlinecounter/trackback/", "I installed your plugin", $trackback_body, $last_post);
      update_option('wpoc_trackback', $_POST['wpoc_trackback']);
    }
    */
    ?>
    <div id="message" class="updated fade"><p><?php _e('Settings <strong>updated</strong>.') ?></p>
    </div>
    <?
  }

  $wpoc_max = $wpdb->get_var("SELECT maxon FROM $wpdb->wp_onlinecounter ORDER BY maxon DESC LIMIT 1");
  $wpoc_total = $wpdb->get_var("SELECT count FROM $wpdb->wp_onlinecounter ORDER BY count DESC LIMIT 1");
  $wpoc_header = get_option('wpoc_header');
  $wpoc_footer = get_option('wpoc_footer');
  $wpoc_show_current = get_option('wpoc_show_current');
  $wpoc_show_current_users_only = get_option('wpoc_show_current_users_only');
  $wpoc_show_maxon = get_option('wpoc_show_maxon');
  $wpoc_show_total = get_option('wpoc_show_total');
  $wpoc_ignore_level = get_option('wpoc_ignore_level');
  $wpoc_timeout = get_option('wpoc_timeout');
  $wpoc_label_current = get_option('wpoc_label_current');
  $wpoc_label_maxon = get_option('wpoc_label_maxon');
  $wpoc_label_total = get_option('wpoc_label_total');
  //$wpoc_trackback = get_option('wpoc_trackback');
  
?>

  <div class="wrap">
    <h2>WP-OnlineCounter Settings</h2>
    <form name="wpoc-settings" action="" method="post">
    <table width="100%" cellspacing="2" cellpadding="5" class="editform" summary="WP-OnlineCounter Settings">
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_structure">Structure:</label></th>
        <td>
          <input name="wpoc_header" type="text" size="25" value="<?php echo $wpoc_header; ?>"/> as Header (default: &lt;ul&gt;)<br />
          <input name="wpoc_footer" type="text" size="25" value="<?php echo $wpoc_footer; ?>"/> as Footer (default: &lt;/ul&gt;)<br />
          (the lines of the counter output are put into &lt;li&gt;&lt;/li&gt;)<br />
          (<b>K2:</b> Header = &lt;ul&gt;, Footer = &lt;/ul&gt;)<br />
          (<b>Widget:</b> Header = &lt;li&gt;&lt;h2&gt;Counter&lt;/h2&gt;&lt;ul&gt;, Footer = &lt;/ul&gt;&lt;li&gt;)
        </td>
      </tr>
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_labels">Labels:</label></th>
        <td>
          <input name="wpoc_label_current" type="text" size="20" value="<?php echo $wpoc_label_current; ?>"/> (default: currently online)<br />
          <input name="wpoc_label_maxon" type="text" size="20" value="<?php echo $wpoc_label_maxon; ?>"/> (default: maximum concurrent)<br />
          <input name="wpoc_label_total" type="text" size="20" value="<?php echo $wpoc_label_total; ?>"/> (default: total visitors)
        </td>
      </tr>
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_show_current">Show:</label></th>
        <td>
          <input name="wpoc_show_current" type="checkbox" value="on" <?php if($wpoc_show_current == 'on') { echo "checked=\"checked\""; } ?> /> Line "<?php echo $wpoc_label_current; ?>"<br />
          <input name="wpoc_show_maxon" type="checkbox" value="on" <?php if($wpoc_show_maxon == 'on') { echo "checked=\"checked\""; } ?> /> Line "<?php echo $wpoc_label_maxon; ?>"<br />
          <input name="wpoc_show_total" type="checkbox" value="on" <?php if($wpoc_show_total == 'on') { echo "checked=\"checked\""; } ?> /> Line "<?php echo $wpoc_label_total; ?>"<br />
          <input name="wpoc_show_current_users_only" type="checkbox" value="on" <?php if($wpoc_show_current_users_only == 'on') { echo "checked=\"checked\""; } ?> /> show "<?php echo $wpoc_label_current; ?>" only to registered users
        </td>
      </tr>
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_timeout">Timeout:</label></th>
        <td><input name="wpoc_timeout" type="text" size="10" value="<?php echo $wpoc_timeout; ?>"/> seconds
        <br />Set the timeout after which a user's visit expires.<br />(default: 600 = 10 minutes)
        </td>
      </tr>
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_ignore_level">Ignore Level:</label></th>
        <td><input name="wpoc_ignore_level" type="text" size="10" value="<?php echo $wpoc_ignore_level; ?>"/>
        <br />Set user level for visitors who should not be counted.<br />
        Set to anything above 10 to count everyone.<br />(default: 10 = Administrator)
        </td>
      </tr>
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_total">Total Count:</label></th>
        <td><input name="wpoc_total" type="text" size="10" value="<?php echo $wpoc_total; ?>"/>
        <br />Set the total count of visitors.
        </td>
      </tr>
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_maxon">Maximum Concurrent Count:</label></th>
        <td><input name="wpoc_maxon" type="text" size="10" value="<?php echo $wpoc_max; ?>"/>
        <br />Set the count of maximum concurrent visitors.
        </td>
      </tr>
      <? // if ($wpoc_trackback !== 'sent') { ?>
      <!---
      <tr valign="top">
        <th scope="row" width="33%"><label for="wpoc_trackback">Send trackback:</label></th>
        <td><input name="wpoc_trackback" type="checkbox" value="sent" <?php if($wpoc_trackback == 'sent') { echo "disabled=\"disabled\""; } ?> />
        <br />Send a trackback <strong>once</strong> to <a href="http://faked.org/blog/">the author</a> of this plugin<br />to notify him that you installed it.
        </td>
      </tr>
      //--->
      <? // } ?>
    </table>
    <p class="submit"><input type="hidden" name="submitted" /><input type="submit" name="Submit" value="Update Settings &raquo;" /></p>
    </form>
  </div>
<?
}

function wpoc_counter_page() {
  global $wpdb;
  global $wpoc_tablename;
  global $table_prefix;
  global $max;
  global $total;
  if(!isset($wpdb->wp_onlinecounter)){
    $wpdb->wp_onlinecounter = $table_prefix.$wpoc_tablename; }
  ?>  
  
  <div class="wrap" align="center">
    <h2>WP-OnlineCounter Stats</h2>
    <?php
      if(isset($_GET['ip'])) {
      ?>
      <table cellspacing="2" cellpadding="5" summary="WP-OnlineCounter Count Info">
        <tr valign="top">
          <th scope="row" colspan="2">URIs visited by <?=$_GET['ip']?></th>
        </tr>
        <tr valign="top">
          <th scope="row">Time</th>
          <th scope="row">URI</th>
        </tr>
        <?php
        $count_uris = $wpdb->get_results("SELECT uri,timestamp FROM ".$table_prefix.$wpoc_tablename." WHERE ip = '$_GET[ip]' ORDER BY timestamp ASC");
        if($count_uris)
          foreach ($count_uris as $count_uri) {
          ?>
          <tr valign="top">
            <td align="center"><?=date(" H:i:s", $count_uri->timestamp)?></td>
            <td><?=$count_uri->uri?></td>
          </tr>
        <?php } ?>
      </table>
      <br />
      <?php
      }
      ?>
    <table cellspacing="2" cellpadding="5" summary="WP-OnlineCounter Counts">
      <tr valign="top">
        <th scope="row">Time</th>
        <th scope="row">IP</th>
        <th scope="row">URI</th>
      </tr>
      <?php
      $counts = $wpdb->get_results("SELECT t1.ip,t1.uri,t1.timestamp FROM $wpdb->wp_onlinecounter t1 JOIN (SELECT ip, MAX(timestamp) timestamp  FROM wp_onlinecounter GROUP BY ip ) v1 ON t1.ip=v1.ip AND t1.timestamp=v1.timestamp");
      if($counts)
        foreach ($counts as $count) {
      ?>
      <tr valign="top">
        <td align="center"><?=date(" H:i:s", $count->timestamp)?></td>
        <?php $this_page = explode('&',$_SERVER['REQUEST_URI']); ?>
        <td><a href="<?=$this_page[0]?>&ip=<?=$count->ip?>"><?=$count->ip?></a></td>
        <td><?=$count->uri?></td>
      </tr>
      <?php } ?>
    </table>
  </div>
<?
}



//function to create the table on plugin activation
add_action('activate_wp-onlinecounter.php','wpoc_install');
function wpoc_install () {
  global $table_prefix, $wpoc_tablename, $wpdb;

  $table = $table_prefix . $wpoc_tablename;
  if($wpdb->get_var("show tables like '$table'") != $table) {
      
    $sql = "CREATE TABLE IF NOT EXISTS `wp_onlinecounter` (
        `timestamp` int(15) NOT NULL default '0',
        `ip` varchar(15) NOT NULL default '',
        `count` int(15) NOT NULL default '0',
        `maxon` int(6) NOT NULL default '0',
        `maxontime` int(15) NOT NULL default '0',
        `uri` text NOT NULL default '',
        PRIMARY KEY  (timestamp, ip)
    );";

    require_once(ABSPATH . 'wp-admin/upgrade-functions.php');
    dbDelta($sql);
  }elseif($wpdb->get_var("SHOW COLUMNS FROM ".$table." LIKE 'uri'") != 'uri') {
      $wpdb->query("ALTER TABLE wp_onlinecounter ADD uri TEXT NOT NULL");
  }
  
  add_option('wpoc_header', '<ul>', 'WPOC: output before counter');
  add_option('wpoc_footer', '</ul>', 'WPOC: output after counter');
  add_option('wpoc_show_current', 'on', 'WPOC: show online count');
  add_option('wpoc_show_current_users_only', '', 'WPOC: show online count only to registered users');
  add_option('wpoc_show_maxon', 'on', 'WPOC: show max online count');
  add_option('wpoc_show_total', 'on', 'WPOC: show total count');
  add_option('wpoc_label_current', 'currently online', 'WPOC: label for currently online');
  add_option('wpoc_label_maxon', 'maximum concurrent', 'WPOC: label for maximum concurrent');
  add_option('wpoc_label_total', 'total visitors', 'WPOC: label for total visitors');
  add_option('wpoc_ignore_level', '10', 'WPOC: ignore users with or above this level');
  add_option('wpoc_timeout', '600', 'WPOC: how long until a visit timeouts');
  //add_option('wpoc_trackback', '', 'WPOC: did we send a trackback');
}

function widget_wpoc_init() {

  if ( !function_exists('register_sidebar_widget') )
    return;

  function widget_wpoc($args) {
    extract($args);
    $options = get_option('widget_wpoc');
    $title = $options['title'];
    if (empty($title)) {
    }
    echo $before_widget . $before_title . $title . $after_title;
    wp_onlinecounter();
    echo $after_widget;
  }
  register_sidebar_widget('WP OnlineCounter', 'widget_wpoc');

function widget_wpoc_control() {

    $options = get_option('widget_wpoc');
    if (!is_array($options)) {
      $options = array(
        'title' => __("OnlineCounter", 'widget_wpoc')
      );
    }

    $title = htmlspecialchars($options['title'], ENT_QUOTES);
        $options = get_option('widget_wpoc');
    
        if ( $_POST['widget_wpoc-submit'] ) {
            $newoptions['title'] = strip_tags(stripslashes($_POST['widget_wpoc-title']));
        }
    
        if ( $options != $newoptions ) {
            $options = $newoptions;
            update_option('widget_wpoc', $options);
        }

        $title = htmlspecialchars($options['title'], ENT_QUOTES);
        $text = htmlspecialchars($options['text'], ENT_QUOTES);

// The HTML below is the control form for editing options.
?>
        <div>
        <label for="widget_wpoc-title" style="line-height:35px;display:block;">Title: <input type="text" id="widget_wpoc-title" name="widget_wpoc-title" value="<?php echo $title; ?>" /></label>
        <input type="hidden" name="widget_wpoc-submit" id="widget_wpoc-submit" value="1" />
        </div>
    <?php
    }

    register_widget_control('WP OnlineCounter', 'widget_wpoc_control');

}
add_action('plugins_loaded', 'widget_wpoc_init');

?>