<?php
/**
* PmWiki module to embed a dynamic content using the TinyButStrong template Engine.
* Version 1.00 , on 2007-02-16, by Skrol29
* Version 1.02 , on 2007-03-21, by Skrol29 : Bug when a Javascript is placed inside the BODY tags.
* Version 1.03 , on 2007-03-26, by Skrol29 : Better management of <pre> tags and allows several arguments in the pmWiki makrup.
* Version 2.00 , on 2008-05-10, by Skrol29 : The content is insterted in the pmWiki page, but it is not processed by pmWiki Makups |+| Compatibility with TBS 3.3.0. |+| [var..pmwiki_url] |+| compatibility with $EnablePathInfo=1
* Version 2.01 , on 2010-02-02, by Skrol29 : works with TBS >= 3.5.0
* Version 2.02 , on 2010-02-04, by Skrol29 : optimize the time for inserting the content in the pmWiki page
* Works with TBS version 3.2.0 or higher. TinyButStrong site : www.tinybutstrong.com
* In your PmWiki page add (:tbscontent example1:) to insert the dynamic content made by TBS.
*/

// ----------------------
// --- PmWiki Cookbook --
// ----------------------

$RecipeInfo['TbsDynamicContent']['Version'] = '2.02';

if (defined('PmWiki')) {
	
	// Put a tag like this into your pmWiki page: (:TbsContent action:) action is a keywork transmeted by pmWiki to your script.
	Markup('tbscontent', 'directives', '/\\(:tbscontent (.*?):\\)/e', "TbsContent('$1')");
	$MarkupTable['tbscontent']['seq'] = 'C'; // Change the order of execution, this markup will be processed as the last one, but before the markups for adding skins.
	unset($MarkupRules); // it seems to not be done correctly in DisableMarkup() because the varibale is not declared as global. 

	function TbsContent($ArgLst='') {
		
		// Split arguments
		$ArgLst = explode(' ',$ArgLst);
		$iMax = count($ArgLst)-1;
		for ($i=0;$i<=$iMax;$i++) {$ArgLst[$i]=trim($ArgLst[$i]);}

		$TbsAction = $ArgLst[0];
		if ($TbsAction=='') return '(TBS for pmWiki) Error : no parameter defined.';

		global $TbsScriptToCall, $TbsScriptArgs;
		if (!isset($TbsScriptToCall)) return '(TBS for pmWiki) Error : no script defined.';
		$TbsScriptArgs = $ArgLst;

		if (is_array($TbsScriptToCall)) {
			// Allowed scripts are defined ins a PHP array
			if (isset($TbsScriptToCall['path'])) {
				$path = $TbsScriptToCall['path'];
			} else {
				$path = '';
			}
			if (isset($TbsScriptToCall[$TbsAction])) {
		  	include_once($path.$TbsScriptToCall[$TbsAction]);
			} else {
				return '(TBS for pmWiki) Error : parameter \''.$TbsAction.'\' is not allowed.';
			}
		} else {
	  	include_once($TbsScriptToCall);
	  }

	  $x = $GLOBALS['_TbsContentForPmWiki'];
	  unset($GLOBALS['_TbsContentForPmWiki']);
	  return $x;

	}

}

// ---------------------
// --- TBS Plug-In    --
// ---------------------

// Name of the class is a keyword used for Plug-In authentication. So it's better to save it into a constant.
define('TBS_PMWIKI','clsTbsPmWiki');

// Put the name of the class into global variable array $_TBS_AutoInstallPlugIns to have it automatically installed for any new TBS instance.
$GLOBALS['_TBS_AutoInstallPlugIns'][] = TBS_PMWIKI;

class clsTbsPmWiki {

	function OnInstall() {

		global $RecipeInfo, $NoHTMLCache;
		$this->Version = $RecipeInfo['TbsDynamicContent']['Version'];

		$NoHTMLCache = 1; // Avoid pmWiki cache for next pages.

		return array('BeforeLoadTemplate','OnSpecialVar','AfterShow');

	}

	function BeforeLoadTemplate(&$File,&$HtmlCharSet) {
		// Prepare data to found the template in the given path if any.
		if ( ($this->TBS->_LastFile=='') and (isset($GLOBALS['TbsScriptToCall']['path'])) ) {
			$this->TBS->_LastFile = $GLOBALS['TbsScriptToCall']['path'].'nofile.txt';
		}
	}

	function OnSpecialVar($Name,&$IsSupported,&$Value,&$PrmLst) {
		if ($Name=='pmwiki_url') {
			$IsSupported = true;
			$p = (isset($PrmLst['page'])) ? trim($PrmLst['page']) : '';
			if ($p=='') $p = $GLOBALS['pagename'];
			$Value = PageVar($p,'$PageUrl');
			return;
		}
		if ($Name=='pmwiki_page') {
			// Compatibility with plugin version 1.X: returns the full URL with all GET parameters
			$IsSupported = true;
			$Value = basename($_SERVER['PHP_SELF']);
			$q = trim(''.$_SERVER['QUERY_STRING']);
			if ($q!=='') $Value .= '?'.$q;
			return;
		}
	}

	function AfterShow(&$Render) {

		$Render = TBS_NOTHING;
		$Html = $this->TBS->Source;
		
		// Search if the merged content has a <body> part
		$body = $this->f_Html_GetPart($Html, 'body', true, true);
		
		if ($body===false) {
			// No <body> part => the content is added as is in the pmWiki page

			$GLOBALS['_TbsContentForPmWiki'] = $Html;
			
		} else {
			// There is a  <body> part => we keep only the <script> <style> and <body> parts in order to add them into the pmWiki page
		
			$script = '';
			do {
				$x = $this->f_Html_GetPart($Html, 'script', false);
				if ($x!==false) $script .= "\r\n".$x;
			} while ($x!==false);
	
			$style = '';
			do {
				$x = $this->f_Html_GetPart($Html, 'style', false);
			//echo $x; exit;
				if ($x!==false) $style .= "\r\n".$x;
			} while ($x!==false);
			
			$GLOBALS['_TbsContentForPmWiki'] = $script.$style."\r\n".$body;
		
		}
		
	}

	function f_Html_GetPart(&$Txt, $Tag, $Inner, $EraseEnd=true) {
	/* $Inner : true if the fct returns only the inner part of the tag
     EraseEnd : true if the fct erase all the content after the tag
	*/
	
		// Search the openning tag
		$p1 = $this->f_Html_FoundTag($Txt, $Tag, 0);
		if ($p1===false) return false;
		$p1e = strpos($Txt,'>', $p1);
		if ($p1e===false) return false;
		
		// Search the closing tag
		$p2 = $this->f_Html_FoundTag($Txt, '/'.$Tag, $p1e);
		if ($p2===false) return false;
		$p2e = strpos($Txt,'>', $p2);
		if ($p2e===false) return false;
		
		// Get the part
		if ($Inner) {
			$x = substr($Txt, $p1e+1, $p2 - $p1e -1);
		} else {
			$x = substr($Txt, $p1, $p2e - $p1 +1);
		}
		
		// Delete the part from the source text
		if ($EraseEnd) {
			$Txt = substr($Txt, 0, $p1);
		} else {
			$Txt = substr_replace($Txt, '', $p1, $p2e - $p1 +1);
		}
		
		return $x;
		
	}

	function f_Html_FoundTag($Txt, $Tag, $PosBeg) {

		$Tag = strtolower($Tag);
		$p = strpos($Txt,'<'.$Tag.' ', $PosBeg);
		if ($p===false) {
			$p = strpos($Txt,'<'.$Tag.'>', $PosBeg);
			if ($p===false) {
				$Tag = strtoupper($Tag);
				$p = strpos($Txt,'<'.$Tag.' ', $PosBeg);
				if ($p===false) {
					$p = strpos($Txt,'<'.$Tag.'>', $PosBeg);
				}				
			}
		}

		return $p;

	}

}

?>