From 1b9d2f3435f9d90443f68017cb0cd4abbe69ae52 Mon Sep 17 00:00:00 2001
From: Marius Burkard <m.burkard@pixcept.de>
Date: Mon, 14 Dec 2015 19:45:11 +0100
Subject: [PATCH] - Added template content hook feature

---
 interface/lib/classes/plugin.inc.php          | 33 +++++++++----
 interface/lib/classes/tpl.inc.php             | 47 +++++++++++++++----
 interface/lib/classes/tpl_cache.inc.php       |  9 ++--
 .../sites/templates/web_vhost_domain_edit.htm | 10 +++-
 4 files changed, 75 insertions(+), 24 deletions(-)

diff --git a/interface/lib/classes/plugin.inc.php b/interface/lib/classes/plugin.inc.php
index 199245756f..8abb77c324 100644
--- a/interface/lib/classes/plugin.inc.php
+++ b/interface/lib/classes/plugin.inc.php
@@ -107,28 +107,33 @@ class plugin {
 		This function is called when a certian action occurs, e.g. a form gets saved or a user is logged in.
 	*/
 
-	public function raiseEvent($event_name, $data) {
+	public function raiseEvent($event_name, $data, $return_data = false) {
 		global $app;
 
 		if(!isset($_SESSION['s']['plugin_cache'])) {
 			$this->loadPluginCache();
 			if($this->debug) $app->log('Loaded the plugin cache.', LOGLEVEL_DEBUG);
 		}
-
-
+		
+		$result = '';
 		$sub_events = explode(':', $event_name);
 
 		if(is_array($sub_events)) {
 			if(count($sub_events) == 3) {
-				$tmp_event = $sub_events[2];
+				$mp_event = $sub_events[2];
 				if($this->debug) $app->log("Called Event '$tmp_event'", LOGLEVEL_DEBUG);
-				$this->callPluginEvent($tmp_event, $data);
+				$tmpresult = $this->callPluginEvent($tmp_event, $data, $return_data);
+				if($return_data == true && $tmpresult) $result .= $tmpresult;
+				
 				$tmp_event = $sub_events[0].':'.$sub_events[2];
 				if($this->debug) $app->log("Called Event '$tmp_event'", LOGLEVEL_DEBUG);
-				$this->callPluginEvent($tmp_event, $data);
+				$tmpresult = $this->callPluginEvent($tmp_event, $data, $return_data);
+				if($return_data == true && $tmpresult) $result .= $tmpresult;
+				
 				$tmp_event = $sub_events[0].':'.$sub_events[1].':'.$sub_events[2];
 				if($this->debug) $app->log("Called Event '$tmp_event'", LOGLEVEL_DEBUG);
-				$this->callPluginEvent($tmp_event, $data);
+				$tmpresult = $this->callPluginEvent($tmp_event, $data, $return_data);
+				if($return_data == true && $tmpresult) $result .= $tmpresult;
 
 				/*$sub_events = array_reverse($sub_events);
 				$tmp_event = '';
@@ -140,16 +145,21 @@ class plugin {
 				*/
 			} else {
 				if($this->debug) $app->log("Called Event '$sub_events[0]'", LOGLEVEL_DEBUG);
-				$this->callPluginEvent($sub_events[0], $data);
+				$tmpresult = $this->callPluginEvent($sub_events[0], $data, $return_data);
+				if($return_data == true && $tmpresult) $result .= $tmpresult;
 			}
 		}
+		
+		if($return_data == true) return $result;
 
 	} // end function raiseEvent
 
 	//* Internal function to load the plugin and call the event function in the plugin.
-	private function callPluginEvent($event_name, $data) {
+	private function callPluginEvent($event_name, $data, $return_data = false) {
 		global $app;
 
+		$result = '';
+
 		//* execute the functions for the events
 		if(@is_array($_SESSION['s']['plugin_cache'][$event_name])) {
 			foreach($_SESSION['s']['plugin_cache'][$event_name] as $rec) {
@@ -175,12 +185,15 @@ class plugin {
 					if($this->debug) $app->log("Called method: '$function_name' in plugin '$plugin_name' for event '$event_name'", LOGLEVEL_DEBUG);
 					// call_user_method($function_name,$app->loaded_plugins[$plugin_name],$event_name,$data);
 
-					call_user_func(array($app->loaded_plugins[$plugin_name], $function_name), $event_name, $data);
+					$tmpresult = call_user_func(array($app->loaded_plugins[$plugin_name], $function_name), $event_name, $data);
+					if($return_data == true && $tmpresult) $result .= $tmpresult;
 
 				}
 			}
 
 		}
+		
+		if($return_data == true) return $result;
 
 	} // end functiom callPluginEvent
 
diff --git a/interface/lib/classes/tpl.inc.php b/interface/lib/classes/tpl.inc.php
index 34df2a9343..0c58bcaa44 100644
--- a/interface/lib/classes/tpl.inc.php
+++ b/interface/lib/classes/tpl.inc.php
@@ -839,28 +839,34 @@ if (!defined('vlibTemplateClassLoaded')) {
 		 * @access private
 		 * @return mixed data/string or boolean
 		 */
-		private function _getData ($tmplfile, $do_eval=false)
+		private function _getData ($tmplfile, $do_eval=false, $tmpl_from_string = false)
 		{
 			//* check the current file depth
 			if ($this->_includedepth > $this->OPTIONS['MAX_INCLUDES'] || $tmplfile == false) {
 				return;
 			} else {
 				if ($this->_debug){
-					array_push($this->_debugIncludedfiles, $tmplfile);
+					if($tmpl_from_string) array_push($this->_debugIncludedfiles, 'String: ' . substr($tmplfile, 0, 25) . '...');
+					else array_push($this->_debugIncludedfiles, $tmplfile);
 				}
 				if ($do_eval) {
-					array_push($this->_currentincludedir, dirname($tmplfile));
+					if($tmpl_from_string == true) array_push($this->_currentincludedir, end($this->_currentincludedir));
+					else array_push($this->_currentincludedir, dirname($tmplfile));
 					$this->_includedepth++;
 				}
 			}
 
 
-			if($this->_cache && $this->_checkCache($tmplfile)) { //* cache exists so lets use it
+			if($this->_cache && $this->_checkCache($tmplfile, $tmpl_from_string)) { //* cache exists so lets use it
 				$data = fread($fp = fopen($this->_cachefile, 'r'), filesize($this->_cachefile));
 				fclose($fp);
 			} else { //* no cache lets parse the file
-				$data = fread($fp = fopen($tmplfile, 'r'), filesize($tmplfile));
-				fclose($fp);
+				if($tmpl_from_string == true) {
+					$data = $tmplfile;
+				} else {
+					$data = fread($fp = fopen($tmplfile, 'r'), filesize($tmplfile));
+					fclose($fp);
+				}
 
 				$regex = '/(<|<\/|{|{\/|<!--|<!--\/){1}\s*';
 				$regex.= 'tmpl_([\w]+)\s*';
@@ -884,7 +890,7 @@ if (!defined('vlibTemplateClassLoaded')) {
 			}
 
 			//* now we must parse the $data and check for any <tmpl_include>'s
-			if ($this->_debug) $this->doDebugWarnings(file($tmplfile), $tmplfile);
+			if ($this->_debug && $tmpl_from_string == false) $this->doDebugWarnings(file($tmplfile), $tmplfile);
 
 			if ($do_eval) {
 				$success = @eval('?>'.$data.'<?php return 1;');
@@ -1061,6 +1067,28 @@ if (!defined('vlibTemplateClassLoaded')) {
 			}
 		}
 
+		/**
+		 * returns a string containing hook data
+		 * @param string $type
+		 * @param string $name
+		 * @return string hook data
+		 */
+		private function _parseHook ($type, $name)
+		{
+			global $app;
+			
+			$module_name = '';
+			if(strpos($name, ':') !== false) list($name, $module_name) = explode(':', $name, 2);
+			
+			$result = $app->plugin->raiseEvent('on_template_content_hook', array(
+				'type' => $type,
+				'name' => $name,
+				'module' => $module_name
+			), true);
+			if(!$result) $result = '';
+			
+			return $result;
+		}
 
 		/**
 		 * returns a string used for parsing in tmpl_loop statements.
@@ -1254,7 +1282,10 @@ if (!defined('vlibTemplateClassLoaded')) {
 				if ($this->OPTIONS['ENABLE_PHPINCLUDE']) {
 					return '<?php include(\''.$file.'\'); ?>';
 				}
-
+			
+			case 'hook':
+				return $this->_parseHook(@$var, @$value);
+			
 			case 'include':
 				return '<?php $this->_getData($this->_fileSearch(\''.$file.'\'), 1); ?>';
 
diff --git a/interface/lib/classes/tpl_cache.inc.php b/interface/lib/classes/tpl_cache.inc.php
index 4bf75faa8c..ce8a5b16ce 100644
--- a/interface/lib/classes/tpl_cache.inc.php
+++ b/interface/lib/classes/tpl_cache.inc.php
@@ -101,8 +101,8 @@ class tplc extends tpl {
 	 * FUNCTION: _checkCache
 	 * checks if there's a cache, if there is then it will read the cache file as the template.
 	 */
-	function _checkCache ($tmplfile) {
-		$this->_cachefile = $this->_getFilename($tmplfile);
+	function _checkCache ($tmplfile, $tmpl_from_string = false) {
+		$this->_cachefile = $this->_getFilename($tmplfile, $tmpl_from_string);
 		if ($this->_clearcache) {
 			if (file_exists($this->_cachefile)) unlink($this->_cachefile);
 			return false;
@@ -133,8 +133,9 @@ class tplc extends tpl {
 	 * gets the full pathname for the cached file
 	 *
 	 */
-	function _getFilename($tmplfile) {
-		return $this->OPTIONS['CACHE_DIRECTORY'].'/'.md5('vlibCachestaR'.realpath($tmplfile)).'.'.$this->OPTIONS['CACHE_EXTENSION'];
+	function _getFilename($tmplfile, $tmpl_from_string = false) {
+		if($tmpl_from_string == true) return $this->OPTIONS['CACHE_DIRECTORY'].'/'.md5('vlibCachestaRSTRING'.$tmplfile).'.'.$this->OPTIONS['CACHE_EXTENSION'];
+		else return $this->OPTIONS['CACHE_DIRECTORY'].'/'.md5('vlibCachestaR'.realpath($tmplfile)).'.'.$this->OPTIONS['CACHE_EXTENSION'];
 	}
 
 
diff --git a/interface/web/sites/templates/web_vhost_domain_edit.htm b/interface/web/sites/templates/web_vhost_domain_edit.htm
index 13702932ef..4a0fb4d9b8 100644
--- a/interface/web/sites/templates/web_vhost_domain_edit.htm
+++ b/interface/web/sites/templates/web_vhost_domain_edit.htm
@@ -13,7 +13,7 @@
 </tmpl_if>
 
 
-        
+        {tmpl_hook name="begin_form"}
 		<tmpl_if name="vhostdomain_type" value="domain">
             <tmpl_if name="is_admin">
                 <div class="form-group">
@@ -222,26 +222,32 @@
                     {tmpl_var name='php'}
                 </select></div>
             </div>
+            {tmpl_hook name="begin_field" value="fastcgi_php_version"}
             <div class="form-group fastcgi_php_version">
                 <label for="fastcgi_php_version" class="col-sm-3 control-label">{tmpl_var name='fastcgi_php_version_txt'}</label>
                 <div class="col-sm-9"><select name="fastcgi_php_version" id="fastcgi_php_version" class="form-control">
                     {tmpl_var name='fastcgi_php_version'}
                 </select></div>
             </div>
+            {tmpl_hook name="end_field" value="fastcgi_php_version"}
 			{tmpl_var name="directive_snippets_id"}
+			{tmpl_hook name="begin_field" value="enable_pagespeed"}
 			<div class="form-group nginx pagespeed">
 				<label class="col-sm-3 control-label">{tmpl_var name='enable_pagespeed_txt'}</label>
 				<div class="col-sm-9">
 					{tmpl_var name="enable_pagespeed"}
 				</div>
 			</div>
+			{tmpl_hook name="end_field" value="enable_pagespeed"}
+			{tmpl_hook name="begin_field" value="active"}
             <div class="form-group">
                 <label class="col-sm-3 control-label">{tmpl_var name='active_txt'}</label>
                 <div class="col-sm-9">
                     {tmpl_var name='active'}
                 </div>
             </div>
-        
+            {tmpl_hook name="end_field" value="active"}
+			{tmpl_hook name="end_form"}
 
         <input type="hidden" name="id" value="{tmpl_var name='id'}">
 
-- 
GitLab