<?php if (!defined('PmWiki')) exit();

/*	=== Bloge ===
 *	Copyright 2009 Eemeli Aro <eemeli@gmail.com>
 *
 *	A bundle of blogging
 *
 *	Developed and tested using PmWiki 2.2.x
 *
 *	To use, add the following to a configuration file:

  		include_once("$FarmD/cookbook/bloge.php");

 *	This is a configuration file for not one, but a bundle of recipes.
 *	For more information, please see the online documentation at
 *		http://www.pmwiki.org/wiki/Cookbook/Bloge
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 */

$RecipeInfo['Bloge']['Version'] = '2009-08-31';


## Bloge-ShortUrl
if (IsEnabled($EnableBlogeShortUrl,0)) {
	SDV($ShortUrlFilter, array('!^Comments\.!', '!-Draft$!'));
	include_once("$FarmD/cookbook/bloge-shorturl.php");
}

## Bloge-LinkbackServer
if (IsEnabled($EnableBlogeLinkbackServer,0)) {
	SDV($EnableLinkbackBlocklist, 10);
	include_once("$FarmD/cookbook/bloge-linkback-server.php");
}


SDVA($Bloge, array(
	'group' => 'Blog',
	'comment-group' => 'Comments',
	'comment-edittime' => 30*60, ## seconds
	'comment-blocklist' => 10,
	'comment-feeds' => array('atom','rss'),
	'email-to' => '',
	'email-from' => "Bloge comment [{\$Author}] <pmwiki-noreply@{$_SERVER['SERVER_NAME']}>",
	'email-subject' => '{$Title}',
	'editformpage' => 'Blog.EditForm',
	'templatepage' => 'Blog.Templates',
	'newpostpage' => 'Blog.NewPost',
	'css-url' => "$PubDirUrl/bloge.css",
	'javascript-url' => "$PubDirUrl/bloge.js"
));
SDV($Bloge['feeds'], array(
	'atom' => PageVar("{$Bloge['group']}.{$Bloge['group']}",'$PageUrl').'?action=atom',
	'rss' => PageVar("{$Bloge['group']}.{$Bloge['group']}",'$PageUrl').'?action=rss'
));

$FmtPV['$BlogMonth'] = 'substr($name,0,7)'; # for Blog.Templates#months (:template first:)
$FmtPV['$BlogFuture'] = 'NoCache($GLOBALS["Now"] < $page["ctime"])'; # for Blog.SideBar future/past posts pagelist
$FmtPV['$BlogRoot'] = 'PUE(($EnablePathInfo)
         ? "$ScriptUrl/{$GLOBALS[\'Bloge\'][\'group\']}"
         : "$ScriptUrl?n={$GLOBALS[\'Bloge\'][\'group\']}")'; # for links to archive pages
$FmtPV['$CommentNumber'] = 'intval(substr($name,-3))'; # could also use {(math (substr {=$Name} -3))}
$FmtPV['$PageCreatedTime'] = '@$page["ctime"]';


## {(math 2.0*010 + 9/[2+[0<1]])} => '23'
## Perform mathematic operations in base 10. Putting quotes around the
## expression is optional, but without them you need to use [ ] instead of ( ).
## Boolean expressions return '1' for true and '' for false.
## NOTE: May conflict with Cookbook.MarkupExpressionsExtensions, which also
## includes {(math)} with fewer features
SDV($MarkupExpr['math'], 'ME_math(preg_replace($rpat, $rrep, $params))');
function ME_math($expr) {
	$expr = preg_replace(
		array('/[A-Za-z]\w*/', '/[^0-9.+-\/*%!()<>=]/', '/(^|[^0-9.])0+([1-9.])/', '/(?<![!<>=])=/'),
		array('0',             '',                      '$1$2',                    '=='),
		str_replace(
			array('[', ']', '&lt;', '&gt;'),
			array('(', ')', '<',    '>'),
			$expr ));
	return eval("return ($expr);");
}

## {(atomic one 'two ' "{$Title}" )} => 'onetwo MarkupExpressionSamples'
## Glues the parameters together unless at least one of them in blank, in which
## case returns an empty string. Remember to quote variables!
SDV($MarkupExpr['atomic'], 'ME_atomic($args)');
function ME_atomic($args) {
	if (empty($args)) return '';
	foreach($args as $a) if (empty($a)) return '';
	return implode('', $args);
}


## list of AuthUser users; used to reserve comment author names and highligh
## authenticated commenters
function BlogeAuthUserList($pagename) {
	global $EnableAuthUser, $AuthUserPageFmt;

	static $users = NULL;
	if (!is_null($users)) return $users;

	SDV($AuthUserPageFmt, '$SiteAdminGroup.AuthUser');
	$pn = FmtPageName($AuthUserPageFmt, $pagename);
	if (empty($EnableAuthUser) || empty($pn)) return $users = FALSE;

	$apage = ReadPage($pn, READPAGE_CURRENT);
	if (!$apage) return $users = FALSE;
	preg_match_all("/^\\s*(\\w[^\\s:]*):/m", $apage['text'], $matches);
	if (empty($matches)) return $users = FALSE;
	return $users = $matches[1];
}

$FmtPV['$BlogeAuthUser'] = 'BlogeAuthUser($pn, @$page["author"])';
function BlogeAuthUser($pagename, $author) {
	$users = BlogeAuthUserList($pagename);
	if (empty($users)) return '';

	$key = array_search($author, $users);
	if ($key === FALSE) return '';

	return $users[$key];
}

## wrap authentication:
##   * editing comments requires only read access if using PmForm or if edited
##     recently from the same IP address
##   * reading draft or pre-dated pages requires edit access
SDV($AuthFunction,'PmWikiAuth');
SDV($DraftSuffix, '-Draft');
$BlogeAuthFunction = $AuthFunction;
$AuthFunction = 'BlogeAuth';
function BlogeAuth($pagename, $level, $authprompt=true, $since=0) {
	global $action, $Now, $DraftSuffix, $BlogeAuthFunction, $Bloge, $EnableBlogeComments;
	if ( (($level=='edit') || ($level=='publish')) && IsEnabled($EnableBlogeComments,1) && preg_match("/^{$Bloge['comment-group']}\./", $pagename) ) {
		if ($action=='pmform') $level = 'read';
		else {
			$page = $BlogeAuthFunction($pagename, 'read', FALSE, READPAGE_CURRENT);
			if ( !empty($page)
				&& !empty($page['=auth'])
				&& ( $Now < $page['time']+$Bloge['comment-edittime'] )
				&& ( @$page['host'] == $_SERVER['REMOTE_ADDR'] )
			) $level = 'read';
		}
	}

	$page = $BlogeAuthFunction($pagename, $level, $authprompt, $since);
	if ( !empty($page)
		&& !empty($page['=auth']['read'])
		&&  empty($page['=auth']['edit'])
		&& preg_match("/^{$Bloge['group']}\./", $pagename)
		&& ( ( @$page['ctime'] > $Now ) || ( $DraftSuffix && preg_match("/$DraftSuffix$/", $pagename) ) )
	) {
		if ($level=='read') {
			if (!$authprompt) return FALSE;
			else $page = $BlogeAuthFunction($pagename, 'edit', $authprompt, $since);
		}
		$page['=auth']['read'] = 0;
		$page['=passwd']['read'] = $page['=passwd']['edit'];
	}
	return $page;
}

## keep draft and future blog posts from getting cached by pagelist
$PageListFilters['BlogePageListProtect'] = 95;
function BlogePageListProtect(&$list, &$opt, $pn, &$page) {
	global $EnablePageListProtect, $Now, $DraftSuffix;

	if ($opt['=phase'] == PAGELIST_PRE)
		return IsEnabled($EnablePageListProtect, 1) ? PAGELIST_ITEM : 0;

	if ( !empty($opt['=protectexclude'][$pn]) || empty($opt['=protectsafe'][$pn]) ) return 1;

	if ( $DraftSuffix && preg_match("/$DraftSuffix$/", $pn) ) {
		unset($opt['=protectsafe'][$pn]);
		NoCache();
	} else {
		if (!$page) {
			$page = ReadPage($pn, READPAGE_CURRENT);
			$opt['=readc']++;
		}
		if ( @$page['ctime'] > $Now ) {
			unset($opt['=protectsafe'][$pn]);
			NoCache();
		}
	}
	return 1;
}