<?php
/**
 * Wiki farm manager action plugin
 *
 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author   Etienne MELEARD <etienne.meleard@cru.fr>
 * @desc     Restrict animal usage and display messages depending on animal state.
 */

// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();

if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
if(!defined('DOKU_FARM_PLUGIN')) define('DOKU_FARM_PLUGIN', DOKU_PLUGIN.'farm/');

if(!defined('DOKU_FARM_WWW')) define('DOKU_FARM_WWW', 'lib/plugins/farm/');

if(!defined('DOKU_FARMPLUGINACTIONHANDLER')) define('DOKU_FARMPLUGINACTIONHANDLER', true);

require_once(DOKU_PLUGIN.'action.php');
require_once(DOKU_FARM_PLUGIN.'animal.class.php');

class action_plugin_farm extends DokuWiki_Action_Plugin {
	private $animal = null;
	
	/**
	 * Returns infos about the plugin
	 */
	function getInfo(){
		return array(
			'author' => 'Etienne Meleard',
			'email'  => 'etienne.meleard@cru.fr',
			'date'   => '2009-12-16',
			'name'   => 'Farm Manager Action Plugin',
			'desc'   => 'Manage Wiki farm'.($this->disabled ? ' (disabled)' : ''),
			'url'    => 'http://wiki.splitbrain.org/plugin:farm',
			);
	}
	
	/**
	 * Register plugin hooks
	 */
	function register(&$controller) {
		if(!defined('DOKU_IS_FARMER')) return; // don't register if farm not installed
		
		$controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'cleanACT');
		$controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'displayState');
		$controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'processHeaders');
	}
	
	/**
	 * Clean $ACT depending on lockstate
	 * @param &$event dokuwiki event object
	 * @param $args handler arguments
	 */
    function cleanACT(&$event, $args) {
		switch($this->getLockState()) {
			case 'all' :
				if(
					$event->data == 'register' ||
					$event->data == 'login' ||
					$event->data == 'profile'
				) $event->data = 'show';
			case 'admin' :
				if($event->data == 'admin') $event->data = 'show';
			case 'edits' :
				if(
					$event->data == 'edit' ||
					$event->data == 'preview' ||
					$event->data == 'save' ||
					$event->data == 'draft' ||
					$event->data == 'recover' ||
					$event->data == 'draftdel' ||
					$event->data == 'conflict'
				) $event->data = 'show';
		}
    }
	
	/**
	 * Display messages about lockstate / overflow at top of the page
	 * @param &$event dokuwiki event object
	 * @param $args handler arguments
	 */
    function displayState(&$event, $args) {
		$animal = new dokuwiki_farm_animal(DOKU_FARM_ANIMAL, null);
		
		$farmconf = dokuwiki_farm_animal::getConf();
		
		$toobig = false;
		if((int)$farmconf['animalmaxsize'] > 0) {
			if($animal->getInfos()->getSize() >= (int)$farmconf['animalmaxsize']) $toobig = true;
		}
		
		$farmtoobig = false;
		if((int)$farmconf['farmmaxsize'] > 0) {
			if(dokuwiki_farm_animal::farmSize() >= (int)$farmconf['farmmaxsize']) $farmtoobig = true;
		}
		
		$ls = $this->getLockState();
		
		if(isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) if($ls == 'edits' || $ls == 'admin' || $ls == 'all') echo '<div class="info">'.$this->getLang('animal_lockstate_'.$ls.'_message').'</div>';
		
		if(isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) if($toobig) echo '<div class="error">'.$this->getLang('animal_toobig_message').'</div>';
		//if($farmtoobig) echo '<div class="error">'.$this->getLang('animal_farmtoobig_message').'</div>';
    }
    
    /**
     * Process headers to change paths
     */
    function processHeaders(&$event, $args) {
		$animal = new dokuwiki_farm_animal(DOKU_FARM_ANIMAL, null);
		
		$farmconf = dokuwiki_farm_animal::getConf();
		
		if($farmconf['virtual'] && ($_SERVER['HTTP_HOST'] != $farmconf['farmerhost'])) {
			for($i=0; $i<count($event->data['link']); $i++) {
				if(!isset($event->data['link'][$i]['href'])) continue;
				$event->data['link'][$i]['href'] = preg_replace('`^/?'.$animal->getName().'`', '', $event->data['link'][$i]['href']);
			}
			
			for($i=0; $i<count($event->data['script']); $i++) {
				if(!isset($event->data['script'][$i]['src'])) continue;
				$event->data['script'][$i]['src'] = preg_replace('`^/?'.$animal->getName().'`', '', $event->data['script'][$i]['src']);
			}
		}elseif(!$farmconf['userewrite']) {
			for($i=0; $i<count($event->data['link']); $i++) {
				if(!isset($event->data['link'][$i]['href'])) continue;
				$event->data['link'][$i]['href'] = $farmconf['farmwebroot'].$farmconf['farmer'].substr($event->data['link'][$i]['href'], strlen(DOKU_BASE));
				if(!DOKU_IS_FARMER) $event->data['link'][$i]['href'] .= (strrpos($event->data['link'][$i]['href'], '?') !== false ? '&' : '?').'animal='.$animal->getName();
			}
			
			for($i=0; $i<count($event->data['script']); $i++) {
				if(!isset($event->data['script'][$i]['src'])) continue;
				$event->data['script'][$i]['src'] = $farmconf['farmwebroot'].$farmconf['farmer'].substr($event->data['script'][$i]['src'], strlen(DOKU_BASE));
				if(!DOKU_IS_FARMER) $event->data['script'][$i]['src'] .= (strrpos($event->data['script'][$i]['src'], '?') !== false ? '&' : '?').'animal='.$animal->getName();
			}
		}
	}
	
	/**
	 * Retreive lockstate from animal meta file
	 * @return string or false if no metafile entry
	 */
	function getLockState() {
		foreach(explode("\n", @file_get_contents(DOKU_CONF.'../animal.meta')) as $l) {
			list($k, $v) = preg_split('`\s+:\s+`', $l, 2);
			if(trim($k) == 'lockstate') return trim($v);
		}
		return false;
	}
	
	/**
	 * Localize a string
	 * Customize your lang strings by puting them in <farm_plugin_dir>/customlang/<lang_code>/lang.php
	 * @param $code lang string identifier
	 * @param $data string or array used to replace %s occurences in the localized string
	 * @return localized string
	 */
	function getLang($code, $data = null) {
		global $conf;
		$l = isset($conf['lang']) ? $conf['lang'] : 'en';
		$lang = array();
		
		@include DOKU_FARM_PLUGIN.'lang/en/lang.php';
		if($l != 'en') @include DOKU_FARM_PLUGIN.'lang/'.$l.'/lang.php';
		@include DOKU_FARM_PLUGIN.'customlang/en/lang.php';
		if($l != 'en') @include DOKU_FARM_PLUGIN.'customlang/'.$l.'/lang.php';
		
		if(!isset($lang[$code])) return '{'.strtoupper($code).'}';
		$str = $lang[$code];
		if(!is_null($data)) if(!is_array($data)) $data = array($data);
		if(is_array($data)) foreach($data as $d) $str = preg_replace('`%s`', $d, $str, 1);
		return $str;
	}
}
