Drupal で、カウンタを作ってみた。

なぜか Drupal にありそうでないのがカウンタ。いまどきカウンタなんて・・・などという声が聞こえてきそうだが、Google Analytics でアクセスログ取っていてもカウンタは欲しかったんですよ。自分のブログ継続モチベーション維持のために(苦笑)。なさそうなのでなので作ってみた。 モジュールを作っていて、データベースにテーブルをわざわざ作ってそれを利用するまでもないことに気づいた。カウンタって状態保持の変数だから、variable_set / variable_get で十分だろう(私も最初はテーブルに記録していましたが、たかだが1レコードしか使わないことが判明。variable_set / variable_get に変えました。もしそれがイヤなら、改造してください)。 このモジュールを有効にすると、counter_display() という関数を提供するので、テンプレートやブロックなど、Drupal でコードが書けるところなら好きなところで呼び出すことができる。
  1. ファイルをダウンロード、または、以下の3つのファイルをモジュールの counter ディレクトリに保存。
  2. まずは以下のコードを counter.info として保存。
    ; $Id: counter.info,v 5.x-0.6 2008/04/30 00:00:00 yas Exp $
    name = Counter
    description = "Simple Counter."
    package =
    version = VERSION

    ; Information added by drupal.org packaging script on 2008-04-30
    version = "5.x-0.6"
    project = "Counter"
  3. 次のコードを counter.install として保存。
    <?php
    // $Id: counter.install,v 5.x-0.6 2008/04/30 00:00:00 yas Exp $

    /**
    * Implementation of hook_install().
    */
    function counter_install() {

      switch (
    $GLOBALS['db_type']) {
        case
    'mysql':
        case
    'mysqli':
          break;

        case
    'pgsql':
          break;
      }
    }

    /**
    * Implementation of hook_uninstall().
    */
    function counter_uninstall() {
     
    variable_del('counter_deny');
     
    variable_del('counter_check');
     
    variable_del('counter_interval');
     
    variable_del('counter_lastip');
     
    variable_del('counter_lasttime');
     
    variable_del('counter_checkpoint');
     
    variable_del('counter_checkpoint_interval');
     
    variable_del('counter_checkpoint_time');
    }
    ?>
  4. 次のコードを counter.module として保存。
    <?php
    // $Id: counter.module,v 5.x-0.6 2008/04/30 00:00:00 yas Exp $

    // updated by yas 2008/04/30
    // updated by yas 2008/04/23
    // updated by yas 2008/04/22
    // updated by yas 2008/04/06
    // updated by yas 2008/04/05
    // updated by yas 2007/12/15
    // updated by yas 2007/12/03
    // created by yas 2007/12/03

    /**
    * Implementation of hook_help()
    * Display help text for the zone module
    */
    define('MODULE_NAME', 'Counter');
    define('DENY_IP', "64.233.*.*\n66.249.*.*");
    define('PRIVILEGE_ADMIN' , 'administer settings');
    // define('PRIVILEGE_VIEW'  , 'view counter');

    function counter_help($section) {
      switch (
    $section) {
        case
    'admin/help#counter':
         
    $o .= '<p>' . t('Simple counter') . '</p>';
          return
    $o;
        case
    'admin/modules#description':
          return
    t('Simple counter.');
      }
    }

    /**
    * Implementation of hook_perm().
    * Define the permissions this module uses
    */
    function counter_perm() {
      return array(
    PRIVILEGE_ADMIN);
    }

    /**
    * Implementation of hook_access().
    */
    function counter_access($op, $node) {
    //  global $user;
    //
    //  if ($op == 'view') {
    //    return user_access(PRIVILEGE_VIEW);
    //  }
    }

    /**
    * Implementation of hook_menu().
    */
    function counter_menu($may_cache) {

     
    $items = array();

      if (
    $may_cache) {

       
    $items[] = array(
         
    'type'               => MENU_NORMAL_ITEM,
         
    'path'               => 'admin/settings/counter',
         
    'title'              => t(MODULE_NAME),
         
    'access'             => user_access(PRIVILEGE_ADMIN),
         
    'callback'           => 'drupal_get_form',
         
    'callback arguments' => 'counter_admin',
         
    'description'        => 'Configure counter settings'
       
    );
      }

      return
    $items;
    }

    /**
    * Implementation of hook_admin().
    */
    function counter_admin() {

     
    // Robot IP Addresses
     
    $form['counter_deny'] = array(
       
    '#type'          => 'textarea',
       
    '#title'         => t('Robot IP Addresses'),
       
    '#default_value' => variable_get('counter_deny', DENY_IP),
       
    '#cols'          =>  20,
       
    '#rows'          =>   5,
       
    '#weight'        => -10,
       
    '#required'      => TRUE
     
    );

     
    // IP check
     
    $form['counter_check'] = array(
       
    '#type'          => 'checkbox',
       
    '#title'         => t('Check by a sequential IP Address'),
       
    '#default_value' => variable_get('counter_check', 1),
       
    '#required'      => FALSE
     
    );

     
    // Current total
     
    $form['counter_total'] = array(
       
    '#type'          => 'textfield',
       
    '#title'         => t('Set a counter'),
       
    '#default_value' => variable_get('counter_total', 0),
       
    '#size'          => 10,
       
    '#maxlength'     => 10,
       
    '#required'      => TRUE
     
    );

     
    // sequential access check interval
     
    global $user;
     
    $timezone = $user->timezone;
     
    $form['counter_checkpoint'] = array(
       
    '#type' => 'item',
       
    '#title' => t('Last Checkpoint Count') . ' (' . gmdate('Y/m/d H:i', (variable_get('counter_checkpoint_time', time()) + $timezone)) . ')',
       
    '#value' => number_format(variable_get('counter_checkpoint', 0)),
      );

     
    // Last IP address
     
    $form['counter_lastip'] = array(
       
    '#type'          => 'textfield',
       
    '#title'         => t('Last IP address'),
       
    '#default_value' => variable_get('counter_lastip', ''),
       
    '#size'          => 20,
       
    '#maxlength'     => 15,
       
    '#required'      => FALSE
     
    );

     
    // sequential access check interval
     
    $form['counter_interval'] = array(
       
    '#type'          => 'textfield',
       
    '#title'         => t('Minimum interval (min) with the same IP address'),
       
    '#default_value' => variable_get('counter_interval', 5),
       
    '#size'          => 3,
       
    '#maxlength'     => 3,
       
    '#required'      => FALSE
     
    );

     
    $checkpoint_intervals = drupal_map_assoc(array(600, 900, 1800, 3600, 10800, 21600, 43200, 86400, 172800, 259200, 604800), 'format_interval');

     
    // sequential access check interval
     
    $form['counter_checkpoint_interval'] = array(
       
    '#type'          => 'select',
       
    '#options'       => $checkpoint_intervals,
       
    '#title'         => t('Interval for the checkpoint'),
       
    '#default_value' => variable_get('counter_checkpoint_interval', 86400),
       
    '#required'      => TRUE
     
    );

      return
    system_settings_form($form);
    }

    function
    counter_init() {

     
    $total     = variable_get('counter_total'   , 0);
     
    $is_check  = variable_get('counter_check'   , 1);
     
    $lastip    = variable_get('counter_lastip'  , '');
     
    $interval  = variable_get('counter_interval', 5);
     
    $lasttime  = variable_get('counter_lasttime', 0);
     
    $lastchecktime       = variable_get('counter_checkpoint_time', 0);
     
    $lastcheckpoint      = variable_get('counter_checkpoint'     , 0);
     
    $checkpoint_interval = variable_get('counter_checkpoint_interval', 86400);
     
    $now       = time();

     
    $deny     = split("[\n\|,]", variable_get('counter_deny', DENY_IP));
     
    $deny     = implode(')|(', $deny);
     
    $deny     = str_replace('*', '\d+', $deny);
     
    $deny     = str_replace('.', '\.' , $deny);
     
    $ip       = $_SERVER['REMOTE_ADDR'];
      if(!
    preg_match ("/($deny)/i", $ip)) {
        if((
    $is_check && $lastip != $ip)
        || (
    $is_check && $lastip == $ip && (($now - $lasttime) > $interval * 60))
        || !
    $is_check) {
         
    $total =   $total >= $lastcheckpoint
                
    ? ++$total
                
    : ++$total + $lastcheckpoint;
         
    variable_set('counter_total'   , $total);
         
    variable_set('counter_lasttime', $now);
         
    variable_set('counter_lastip'  , $ip);

          if((
    $now - $lastchecktime) > $checkpoint_interval
         
    && $total > $lastcheckpoint) {
           
    variable_set('counter_checkpoint'     , $total);
           
    variable_set('counter_checkpoint_time', $now);
          }
        }
      }
    }

    function
    counter_display() {

      return
    number_format(variable_get('counter_total', 0));
    }
    ?>
  5. 上のコードは、template.php で、page.tpl.php その他テンプレートから $counter という変数で、カウンタの数字が呼び出せる。テンプレートで
    <?php
    print $counter;
    ?>
    というコードを入れれば、カウンタが表示される。
  6. また、ブロックでは、以下の1行を書いたブロックを追加すれば、カウンタがブロックに表示される。
    <?php if(module_exists('counter')) { return counter_display(); } ?>
  7. ちなみに、https://yourdomain.com/admin/settings/counter でカウンタの設定ができるようになってます。Google のロボットからのアクセスは予めはじくようにしています。
トラックバック URL: https://perltips.twinkle.cc/trackback/278