最終更新:2011-02-28 (月) 12:04:05 (3449d)  

popular.inc.php
Top / popular.inc.php

カウンタをキャッシュして高速化

<?php
// PukiWiki - Yet another WikiWikiWeb clone
// $Id: popular.inc.php,v 1.16 2005/12/18 15:28:01 henoheno Exp $
//
// Popular pages plugin: Show an access ranking of this wiki
// -- like recent plugin, using counter plugin's count --

/*
 * (C) 2003-2005 PukiWiki Developers Team
 * (C) 2002 Kazunori Mizushima <kazunori@uc.netyou.jp>
 *
 * 通算および今日に別けて一覧を作ることができます。
 *
 * [Usage]
 *   #popular
 *   #popular(20)
 *   #popular(20,FrontPage|MenuBar)
 *   #popular(20,FrontPage|MenuBar,true)
 *
 * [Arguments]
 *   1 - 表示する件数                             default 10
 *   2 - 表示させないページの正規表現             default なし
 *   3 - 通算(true)か今日(false)の一覧かのフラグ  default false
 */

define('PLUGIN_POPULAR_DEFAULT', 10);

/**
 * キャッシュからカウンタ情報をロード
 **/
function load_cached_counters(){
	$fileName=COUNTER_DIR."counter.cache";
	$expire=60*60*1;//1時間
	if(file_exists($fileName)){
		//now-create>expire
		if((time()-filemtime($fileName))>$expire){
			//refresh
			return false;
		}else{
			return unserialize(file_get_contents($fileName));
		}
	}else{
		//refresh
		return false;
	}
}
/**
 * キャッシュに保存
 **/
function save_cached_counters($counters){
	file_put_contents(COUNTER_DIR."counter.cache",serialize($counters),LOCK_EX);
}

function plugin_popular_convert()
{
	global $vars, $whatsnew,$script;
	global $_popular_plugin_frame, $_popular_plugin_today_frame;

	$max    = PLUGIN_POPULAR_DEFAULT;
	$except = '';

	$array = func_get_args();
	$today = FALSE;
	switch (func_num_args()) {
	case 3: if ($array[2]) $today = get_date('Y/m/d');
	case 2: $except = $array[1];
	case 1: $max    = $array[0];
	}

	$counters = array();

	//キャッシュからカウンタ情報を読み込むようにする
	if($counters=load_cached_counters()){
		//読み込み成功
	}else{

		foreach (get_existpages(COUNTER_DIR, '.count') as $file=>$page) {
			if (($except != '' && ereg($except, $page)) ||
			    $page == $whatsnew || check_non_list($page) ||
			    ! is_page($page))
				continue;

			$array = file(COUNTER_DIR . $file);
			$count = rtrim($array[0]);
			$date  = rtrim($array[1]);
			$today_count = rtrim($array[2]);

			if ($today) {
				// $pageが数値に見える(たとえばencode('BBS')=424253)とき、
				// array_splice()によってキー値が変更されてしまうのを防ぐ
				// ため、キーに '_' を連結する
				if ($today == $date) $counters['_' . $page] = $today_count;
			} else {
				$counters['_' . $page] = $count;
			}
		}

		asort($counters, SORT_NUMERIC);
		//カウンタ情報をキャッシュに保存する
		save_cached_counters($counters);
	}

	// BugTrack2/106: Only variables can be passed by reference from PHP 5.0.5
	$counters = array_reverse($counters, TRUE); // with array_splice()
	$counters = array_splice($counters, 0, $max);

	$items = '';
	if (! empty($counters)) {
		$items = '<ul class="popular_list">' . "\n";

		foreach ($counters as $page=>$count) {
			$page = substr($page, 1);


				$r_page  = $script."?".rawurlencode($page);
				$hatena_link=<<<EOD
<A HREF="javascript:window.location='http://b.hatena.ne.jp/entry/'+escape(location.href);" class="hatena-bookmark"><img url="{$r_page}"></A>
EOD;
			$s_page = htmlspecialchars($page);
			if ($page == $vars['page']) {
				// No need to link itself, notifies where you just read
				$pg_passage = get_pg_passage($page,FALSE);
				$items .= ' <li><span title="' . $s_page . ' ' . $pg_passage . '">' .
					$s_page . '<span class="counter">(' . $count .
					')</span></span>'.$hatena_link.'</li>' . "\n";
			} else {
				$items .= ' <li>' . make_pagelink($page,
					$s_page . '<span class="counter">(' . $count . ')</span>') .$hatena_link.
					'</li>' . "\n";
			}
		}
		$items .= '</ul>' . "\n";
	}

	return sprintf($today ? $_popular_plugin_today_frame : $_popular_plugin_frame, count($counters), $items);
}
?>