$replace)
{
$str = preg_replace("/$rule/",$replace,$str);
}
}
// 見出しに固有IDを付与する
if ($fixed_heading_anchor and
preg_match('/^(\*{1,3}(.(?!\[#[A-Za-z][\w-]+\]))+)$/',$str,$matches))
{
// 固有IDを生成する
// ランダムな英字(1文字)+md5ハッシュのランダムな部分文字列(7文字)
$anchor = chr(mt_rand(ord('a'),ord('z'))).
substr(md5(uniqid(substr($matches[1],0,100),1)),mt_rand(0,24),7);
$str = rtrim($matches[1])." [#$anchor]";
}
$retvars[] = $str;
}
return join("\n",$retvars);
}
// ファイルへの出力
function file_write($dir,$page,$str,$notimestamp=FALSE)
{
global $post,$update_exec;
global $_msg_invalidiwn;
global $notify,$notify_diff_only,$notify_to,$notify_from,$notify_subject,$notify_header;
global $smtp_server,$smtp_auth;
if (!is_pagename($page))
{
die_message(
str_replace('$1',htmlspecialchars($page),
str_replace('$2','WikiName',$_msg_invalidiwn)
)
);
}
$page = strip_bracket($page);
$timestamp = FALSE;
$file = $dir.encode($page).'.txt';
if ($dir == DATA_DIR and $str == '' and file_exists($file))
{
unlink($file);
}
if ($str != '')
{
$str = preg_replace("/\r/",'',$str);
$str = rtrim($str)."\n";
if ($notimestamp and file_exists($file))
{
$timestamp = filemtime($file) - LOCALZONE;
}
$fp = fopen($file,'w')
or die_message('cannot write page file or diff file or other'.htmlspecialchars($page).'
maybe permission is not writable or filename is too long');
flock($fp,LOCK_EX);
fputs($fp,$str);
flock($fp,LOCK_UN);
fclose($fp);
if ($timestamp)
{
touch($file,$timestamp + LOCALZONE);
}
}
// is_pageのキャッシュをクリアする。
is_page($page,TRUE);
if (!$timestamp and $dir == DATA_DIR)
{
put_lastmodified();
}
if ($update_exec and $dir == DATA_DIR)
{
system($update_exec.' > /dev/null &');
}
if ($notify and $dir == DIFF_DIR)
{
if ($notify_diff_only)
{
// 差分だけを送信する
$str = preg_replace('/^[^-+].*\n/m','',$str);
}
if ($smtp_auth)
{
pop_before_smtp();
}
$subject = str_replace('$page',$page,$notify_subject);
ini_set('SMTP',$smtp_server);
mb_language(LANG);
mb_send_mail($notify_to,$subject,$str,$notify_header);
}
}
// 最終更新ページの更新
function put_lastmodified()
{
global $maxshow,$whatsnew,$non_list,$autolink;
$pages = get_existpages();
$recent_pages = array();
foreach($pages as $page)
{
if ($page != $whatsnew and !preg_match("/$non_list/",$page))
{
$recent_pages[$page] = get_filetime($page);
}
}
//時刻降順でソート
arsort($recent_pages,SORT_NUMERIC);
// create recent.dat (for recent.inc.php)
$fp = fopen(CACHE_DIR.'recent.dat','w')
or die_message('cannot write cache file '.CACHE_DIR.'recent.dat
maybe permission is not writable or filename is too long');
flock($fp,LOCK_EX);
foreach ($recent_pages as $page=>$time)
{
fputs($fp,"$time\t$page\n");
}
flock($fp,LOCK_UN);
fclose($fp);
// create RecentChanges
$fp = fopen(get_filename($whatsnew),'w')
or die_message('cannot write page file '.htmlspecialchars($whatsnew).'
maybe permission is not writable or filename is too long');
flock($fp,LOCK_EX);
foreach (array_splice($recent_pages,0,$maxshow) as $page=>$time)
{
$s_lastmod = htmlspecialchars(format_date($time));
$s_page = htmlspecialchars($page);
fputs($fp, "-$s_lastmod - [[$s_page]]\n");
}
fputs($fp,"#norelated\n"); // :)
flock($fp,LOCK_UN);
fclose($fp);
// for autolink
if ($autolink)
{
list($pattern,$pattern_a,$forceignorelist) = get_autolink_pattern($pages);
$fp = fopen(CACHE_DIR.'autolink.dat','w')
or die_message('cannot write autolink file '.CACHE_DIR.'/autolink.dat
maybe permission is not writable');
flock($fp,LOCK_EX);
fputs($fp,$pattern."\n");
fputs($fp,$pattern_a."\n");
fputs($fp,join("\t",$forceignorelist)."\n");
flock($fp,LOCK_UN);
fclose($fp);
}
}
// 指定されたページの経過時刻
function get_pg_passage($page,$sw=TRUE)
{
global $show_passage;
static $pg_passage = array();
if (!$show_passage)
{
return '';
}
if (!array_key_exists($page,$pg_passage))
{
$pg_passage[$page] = (is_page($page) and $time = get_filetime($page)) ?
get_passage($time) : '';
}
return $sw ? "{$pg_passage[$page]}" : " {$pg_passage[$page]}";
}
// Last-Modified ヘッダ
function header_lastmod($page=NULL)
{
global $lastmod;
if ($lastmod and is_page($page))
{
header('Last-Modified: '.date('D, d M Y H:i:s',get_filetime($page)).' GMT');
}
}
// 全ページ名を配列に
function get_existpages($dir=DATA_DIR,$ext='.txt')
{
$aryret = array();
$pattern = '^((?:[0-9A-F]{2})+)';
if ($ext != '')
{
$pattern .= preg_quote($ext,'/').'$';
}
$dp = @opendir($dir)
or die_message($dir. ' is not found or not readable.');
while ($file = readdir($dp))
{
if (preg_match("/$pattern/",$file,$matches))
{
$aryret[$file] = decode($matches[1]);
}
}
closedir($dp);
return $aryret;
}
// ページ名の読みを配列に
function get_readings()
{
global $pagereading_enable, $pagereading_kanji2kana_converter;
global $pagereading_kanji2kana_encoding, $pagereading_chasen_path;
global $pagereading_kakasi_path, $pagereading_config_page;
$pages = get_existpages();
$readings = array();
foreach ($pages as $page) {
$readings[$page] = '';
}
foreach (get_source($pagereading_config_page) as $line) {
$line = preg_replace('/[\s\r\n]+$/', '', $line);
if(preg_match('/^-\[\[([^]]+)\]\]\s(.+)$/', $line, $matches)
and isset($readings[$matches[1]])) {
$readings[$matches[1]] = $matches[2];
}
}
if($pagereading_enable) {
// ChaSen/KAKASI 呼び出しが有効に設定されている場合
$unknownPage = FALSE;
// 読みが不明のページがあるかチェック
foreach ($readings as $page => $reading) {
if($reading=='') {
$unknownPage = TRUE;
break;
}
}
if($unknownPage) {
// 読みが不明のページがある場合
// $tmpfname = tempnam(CACHE_DIR, 'PageReading');
$tmpfname = tempnam(CACHE_DIR, 'PageReading');
$fp = fopen($tmpfname, "w")
or die_message("cannot write temporary file '$tmpfname'.\n");
foreach ($readings as $page => $reading) {
if($reading=='') {
fputs($fp, mb_convert_encoding("$page\n", $pagereading_kanji2kana_encoding, SOURCE_ENCODING));
}
}
fclose($fp);
// ChaSen/KAKASI を実行
switch(strtolower($pagereading_kanji2kana_converter)) {
case 'chasen':
if(!file_exists($pagereading_chasen_path)) {
unlink($tmpfname);
die_message("CHASEN not found: $pagereading_chasen_path");
}
$fp = popen("$pagereading_chasen_path -F %y $tmpfname", "r");
if(!$fp) {
unlink($tmpfname);
die_message("ChaSen execution failed: $pagereading_chasen_path -F %y $tmpfname");
}
break;
case 'kakasi':
case 'kakashi':
if(!file_exists($pagereading_kakasi_path)) {
unlink($tmpfname);
die_message("KAKASI not found: $pagereading_kakasi_path");
}
$fp = popen("$pagereading_kakasi_path -kK -HK -JK <$tmpfname", "r");
if(!$fp) {
unlink($tmpfname);
die_message("KAKASI execution failed: $pagereading_kakasi_path -kK -HK -JK <$tmpfname");
}
break;
default:
die_message("unknown kanji-kana converter: $pagereading_kanji2kana_converter.");
break;
}
foreach ($readings as $page => $reading) {
if($reading=='') {
$line = fgets($fp);
$line = mb_convert_encoding($line, SOURCE_ENCODING, $pagereading_kanji2kana_encoding);
$line = preg_replace('/[\s\r\n]+$/', '', $line);
$readings[$page] = $line;
}
}
pclose($fp);
unlink($tmpfname) or die_message("temporary file can not be removed: $tmpfname");
// 読みでソート
asort($readings);
// ページを書き込み
$body = '';
foreach ($readings as $page => $reading) {
$body .= "-[[$page]] $reading\n";
}
page_write($pagereading_config_page, $body);
}
}
// 読み不明のページは、そのままページ名を返す (ChaSen/KAKASI 呼
// び出しが無効に設定されている場合や、ChaSen/KAKASI 呼び出しに
// 失敗した時の為)
foreach ($pages as $page) {
if($readings[$page]=='') {
$readings[$page] = $page;
}
}
return $readings;
}
//ファイル名の一覧を配列に(エンコード済み、拡張子を指定)
function get_existfiles($dir,$ext)
{
$aryret = array();
$pattern = '^(?:[0-9A-F]{2})+'.preg_quote($ext,'/').'$';
$dp = @opendir($dir)
or die_message($dir. ' is not found or not readable.');
while ($file = readdir($dp)) {
if (preg_match("/$pattern/",$file)) {
$aryret[] = $dir.$file;
}
}
closedir($dp);
return $aryret;
}
//あるページの関連ページを得る
function links_get_related($page)
{
global $vars,$related;
static $links = array();
if (array_key_exists($page,$links))
{
return $links[$page];
}
// 可能ならmake_link()で生成した関連ページを取り込む
$links[$page] = ($page == $vars['page']) ? $related : array();
// データベースから関連ページを得る
$links[$page] += links_get_related_db($vars['page']);
return $links[$page];
}
?>