mirror of
				https://github.com/gtbu/Typesetter-5.3-p8.git
				synced 2025-11-04 06:48:27 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			508 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			508 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
namespace gp\tool{
 | 
						|
 | 
						|
	defined('is_running') or die('Not an entry point...');
 | 
						|
 | 
						|
 | 
						|
	class Plugins{
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Holds the configuration values of the current plugin if there is an active plugin
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static $current = false;
 | 
						|
 | 
						|
		private static $stack = [];
 | 
						|
 | 
						|
		public static $curr_page_calls = [];
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Aliases of gpPlugin_incl()
 | 
						|
		 * @deprecated 3.5.3
 | 
						|
		 */
 | 
						|
		public static function incl($file){
 | 
						|
			return gpPlugin_incl($file);
 | 
						|
		}
 | 
						|
 | 
						|
		public static function inc($file){
 | 
						|
			return gpPlugin_incl($file);
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Add a css file to the page
 | 
						|
		 * @since 4.0
 | 
						|
		 * @param string $file The path of the css file relative to the addon folder
 | 
						|
		 * @param bool $combine Set to false to keep the file from being combined with other css files
 | 
						|
		 */
 | 
						|
		public static function css($file, $combine=true){
 | 
						|
			global $page;
 | 
						|
 | 
						|
			$file 					= \gp\tool::WinPath($file);
 | 
						|
 | 
						|
			if( $combine ){
 | 
						|
				$page->css_admin[] 	= self::$current['code_folder_part'] . '/' . ltrim($file, '/');
 | 
						|
				return self::$current['code_folder_part'] . '/' . ltrim($file, '/');
 | 
						|
			}
 | 
						|
 | 
						|
			//less or scss file
 | 
						|
			$ext = \gp\tool::Ext($file);
 | 
						|
			if( $ext === 'less' || $ext === 'scss' ){
 | 
						|
				$full_path			= self::$current['code_folder_full'] . '/' . ltrim($file, '/');
 | 
						|
				$path				= \gp\tool\Output\Css::Cache($full_path, $ext);
 | 
						|
			}else{
 | 
						|
				$file				= self::AddCacheBuster($file);
 | 
						|
				$path				= self::$current['code_folder_part'] . '/' . ltrim($file, '/');
 | 
						|
			}
 | 
						|
 | 
						|
			if( $path !== false ){
 | 
						|
				$page->head			.= "\n" . '<link rel="stylesheet" type="text/css" href="' . \gp\tool::GetDir($path) . '"/>';
 | 
						|
			}
 | 
						|
 | 
						|
			return $path;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Add a js file to the page
 | 
						|
		 * @since 4.0
 | 
						|
		 * @param string $file The path of the js file relative to the addon folder
 | 
						|
		 * @param bool $combine Set to false to keep the file from being combined with other js files
 | 
						|
		 */
 | 
						|
		public static function js($file, $combine=true){
 | 
						|
			global $page;
 | 
						|
 | 
						|
			$file = \gp\tool::WinPath($file);
 | 
						|
 | 
						|
			if( $combine ){
 | 
						|
				$page->head_js[]	= self::$current['code_folder_part'] . '/' . ltrim($file, '/');
 | 
						|
			}else{
 | 
						|
				$file				= self::AddCacheBuster($file);
 | 
						|
				$url				= self::$current['code_folder_rel'].'/'.ltrim($file,'/');
 | 
						|
				$page->head			.= "\n" . '<script type="text/javascript" src="' . $url . '"></script>';
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Add a cache-busting query string to the end of the file if it doesn't already have a query string
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function AddCacheBuster($file){
 | 
						|
			if( strpos('?', $file) == false ){
 | 
						|
				$full = self::$current['code_folder_full'] . '/' . ltrim($file, '/');
 | 
						|
				if( file_exists($full) ){
 | 
						|
					$file .= '?' . filemtime($full);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return $file;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		public static function GetDir($path='', $ampersands=false){
 | 
						|
			$path = self::$current['code_folder_part'] . '/' . ltrim($path, '/');
 | 
						|
			return \gp\tool::GetDir($path, $ampersands);
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Similar to php's register_shutdown_function()
 | 
						|
		 * Will keep track of the active plugin and make sure global path variables are set properly before callting $function
 | 
						|
		 * Example: \gp\tool\Plugins::RegisterShutdown(array('class_name','method_name'));  or  \gp\tool\Plugins::RegisterShutdown(array('class_name','method_name'),'argument1'....);
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function RegisterShutdown(){
 | 
						|
			global $addonFolderName;
 | 
						|
			if( gp_safe_mode ){
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			$args = func_get_args();
 | 
						|
			register_shutdown_function(['\\gp\\tool\\Plugins','ShutdownFunction'], $addonFolderName, $args);
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Handle functions passed to \gp\tool\Plugins::RegisterShutdown()
 | 
						|
		 * This function should not be called directly.
 | 
						|
		 */
 | 
						|
		public static function ShutdownFunction($addonFolderName,$args){
 | 
						|
 | 
						|
			if( gp_safe_mode ){
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			if( !is_array($args) || count($args) < 1 ){
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
 | 
						|
			self::SetDataFolder($addonFolderName);
 | 
						|
 | 
						|
			$function = array_shift($args);
 | 
						|
 | 
						|
			if( count($args) > 0 ){
 | 
						|
				call_user_func_array($function, $args);
 | 
						|
			}else{
 | 
						|
				call_user_func($function);
 | 
						|
			}
 | 
						|
 | 
						|
			self::ClearDataFolder();
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Similar to wordpress apply_filters_ref_array()
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function Filter($hook, $args=[]){
 | 
						|
			global $gp_hooks;
 | 
						|
 | 
						|
			self::$curr_page_calls[] = 'Filter:' . $hook;
 | 
						|
 | 
						|
			if( !self::HasHook($hook) ){
 | 
						|
				if( isset($args[0]) ){
 | 
						|
					return $args[0];
 | 
						|
				}
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
 | 
						|
			foreach($gp_hooks[$hook] as $hook_info){
 | 
						|
				$args[0] = self::ExecHook($hook, $hook_info, $args);
 | 
						|
			}
 | 
						|
 | 
						|
			if( isset($args[0]) ){
 | 
						|
				return $args[0];
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		public static function OneFilter($hook, $args=[], $addon=false){
 | 
						|
			global $gp_hooks;
 | 
						|
 | 
						|
			self::$curr_page_calls[] = 'OneFilter:' . $hook;
 | 
						|
 | 
						|
			if( !self::HasHook($hook) ){
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
 | 
						|
			if( $addon === false ){
 | 
						|
				$hook_info = end($gp_hooks[$hook]);
 | 
						|
				return self::ExecHook($hook, $hook_info, $args);
 | 
						|
			}
 | 
						|
 | 
						|
			foreach($gp_hooks[$hook] as $addon_key => $hook_info){
 | 
						|
				if( $addon_key === $addon ){
 | 
						|
					return self::ExecHook($hook, $hook_info, $args);
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		public static function Action($hook, $args=[]){
 | 
						|
			global $gp_hooks;
 | 
						|
 | 
						|
			self::$curr_page_calls[] = 'Action:' . $hook;
 | 
						|
 | 
						|
			if( !self::HasHook($hook) ){
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			foreach($gp_hooks[$hook] as $hook_info){
 | 
						|
				self::ExecHook($hook, $hook_info, $args);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Check to see if there area any hooks matching $hook
 | 
						|
		 * @param string $hook The name of the hook
 | 
						|
		 * @return bool
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function HasHook($hook){
 | 
						|
			global $gp_hooks;
 | 
						|
			if( empty($gp_hooks) || empty($gp_hooks[$hook]) ){
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
			return true;
 | 
						|
		}
 | 
						|
 | 
						|
		public static function ArgReturn($args){
 | 
						|
			if( is_array($args) && isset($args[0]) ){
 | 
						|
				return $args[0];
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Execute the php code associated with a $hook
 | 
						|
		 * @param string $hook
 | 
						|
		 * @param array $hook_info
 | 
						|
		 * @param array $args
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function ExecHook($hook, $info, $args=[]){
 | 
						|
			global $dataDir, $gp_current_hook;
 | 
						|
 | 
						|
			if( gp_safe_mode ){
 | 
						|
				if( isset($args[0]) ){
 | 
						|
					return $args[0];
 | 
						|
				}
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			if( !is_array($args) ){
 | 
						|
				$args = [$args];
 | 
						|
			}
 | 
						|
			$gp_current_hook[] = $hook;
 | 
						|
 | 
						|
			//value
 | 
						|
			if( !empty($info['value']) ){
 | 
						|
				$args[0] = $info['value'];
 | 
						|
			}
 | 
						|
 | 
						|
			$args = \gp\tool\Output::ExecInfo($info, $args);
 | 
						|
 | 
						|
			array_pop( $gp_current_hook );
 | 
						|
			if( isset($args[0]) ){
 | 
						|
				return $args[0];
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Set global path variables for the current addon
 | 
						|
		 * @param string $addon_key Key used to identify a plugin uniquely in the configuration
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function SetDataFolder($addon_key){
 | 
						|
			global $dataDir, $config;
 | 
						|
			global $addonDataFolder, $addonCodeFolder; //deprecated
 | 
						|
			global $addonRelativeCode, $addonRelativeData, $addonPathData, $addonPathCode;
 | 
						|
			global $addonFolderName, $addon_current_id, $addon_current_version;
 | 
						|
 | 
						|
			if( !isset($config['addons'][$addon_key]) ){
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			self::StackPush();
 | 
						|
			self::$current = self::GetAddonConfig($addon_key);
 | 
						|
 | 
						|
			$addonFolderName					= $addon_key;
 | 
						|
			$addon_current_id					= self::$current['id'];
 | 
						|
			$addon_current_version				= self::$current['version'];
 | 
						|
			$addonPathCode = $addonCodeFolder 	= self::$current['code_folder_full'];
 | 
						|
			$addonPathData = $addonDataFolder	= self::$current['data_folder_full'];
 | 
						|
			$addonRelativeCode					= self::$current['code_folder_rel'];
 | 
						|
			$addonRelativeData					= self::$current['data_folder_rel'];
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Return settings of addon defined by $addon_key
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function GetAddonConfig($addon_key){
 | 
						|
			global $config, $dataDir;
 | 
						|
 | 
						|
			if( !array_key_exists($addon_key, $config['addons']) ){
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
 | 
						|
			$addon_config = $config['addons'][$addon_key];
 | 
						|
			if( !is_array($addon_config) ){
 | 
						|
				trigger_error('Corrupted configuration for addon: ' . $addon_key); //.pre($config['addons']));
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
 | 
						|
			$addon_config += [
 | 
						|
				'version'			=>	false,
 | 
						|
				'id'				=>	false,
 | 
						|
				'data_folder'		=>	$addon_key,
 | 
						|
				'order'				=>	false,
 | 
						|
				'code_folder_part'	=>	'/data/_addoncode/' . $addon_key,
 | 
						|
				'name'				=>	$addon_key
 | 
						|
			];
 | 
						|
 | 
						|
			//data folder
 | 
						|
			$addon_config['data_folder_part']	= '/data/_addondata/' . $addon_config['data_folder'];
 | 
						|
			$addon_config['data_folder_full']	= $dataDir . $addon_config['data_folder_part'];
 | 
						|
			$addon_config['data_folder_rel']	= \gp\tool::GetDir($addon_config['data_folder_part']);
 | 
						|
 | 
						|
 | 
						|
			// Code folder
 | 
						|
			//$addon_config['code_folder_part']	= $addon_config['code_folder'].'/'.$addon_key;
 | 
						|
			$addon_config['code_folder_full']	= $dataDir.$addon_config['code_folder_part'];
 | 
						|
			$addon_config['code_folder_rel']	= \gp\tool::GetDir($addon_config['code_folder_part']);
 | 
						|
 | 
						|
			return $addon_config;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * If there's a current addon folder or addon id, push it onto the stack
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function StackPush(){
 | 
						|
			global $addonFolderName, $addon_current_id;
 | 
						|
 | 
						|
			if( !$addon_current_id && !$addonFolderName ){
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			self::$stack[] = ['folder' => $addonFolderName, 'id' => $addon_current_id];
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Reset global path variables
 | 
						|
		 */
 | 
						|
		public static function ClearDataFolder(){
 | 
						|
			global $addonDataFolder, $addonCodeFolder; //deprecated
 | 
						|
			global $addonRelativeCode, $addonRelativeData, $addonPathData, $addonPathCode;
 | 
						|
			global $addonFolderName, $addon_current_id, $addon_current_version;
 | 
						|
 | 
						|
			self::$current			= [];
 | 
						|
			$addonFolderName		= false;
 | 
						|
			$addonDataFolder		= false;
 | 
						|
			$addonCodeFolder		= false;
 | 
						|
			$addonRelativeCode		= false;
 | 
						|
			$addonRelativeData		= false;
 | 
						|
			$addonPathData			= false;
 | 
						|
			$addon_current_id		= false;
 | 
						|
			$addon_current_version	= false;
 | 
						|
 | 
						|
			//Make the most recent addon folder or addon id in the stack the current addon
 | 
						|
			if( count(self::$stack) > 0 ){
 | 
						|
				$info = array_pop(self::$stack);
 | 
						|
				if( $info['folder'] ){
 | 
						|
					self::SetDataFolder($info['folder']);
 | 
						|
				}elseif( $info['id'] ){
 | 
						|
					$addon_current_id = $info['id'];
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Get the addon_key of an addon by its id
 | 
						|
		 * @static
 | 
						|
		 * @param int $addon_id
 | 
						|
		 * @return mixed Returns addon_key string if found, false otherwise
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function AddonFromId($addon_id){
 | 
						|
			global $config;
 | 
						|
			if( empty($config['addons']) ){
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
			foreach($config['addons'] as $addon_key => $addon_info){
 | 
						|
				if( isset($addon_info['id']) && $addon_info['id'] == $addon_id ){
 | 
						|
					return $addon_key;
 | 
						|
				}
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Checks if an addon is installed
 | 
						|
		 * @since 5.2
 | 
						|
		 * @param string $name - the addon name, very forgiving in terms of case, blanks, underscores and dashes
 | 
						|
		 * @param mixed (string | number) $min_ver, optional minimum addon version
 | 
						|
		 * @param mixed (string | number) $max_ver, optional maximum addon version
 | 
						|
		 * @return mixed (array | boolean ) returns an array with name and version if the addon is installed, false otherwise
 | 
						|
		 */
 | 
						|
		public static function AddonInstalled($name, $min_ver=false, $max_ver=false){
 | 
						|
			global $config;
 | 
						|
 | 
						|
			if( empty($config['addons']) ){
 | 
						|
				return false;
 | 
						|
			}
 | 
						|
 | 
						|
			$requested = preg_replace('/[ _-]+/', '', strtolower($name));
 | 
						|
 | 
						|
			foreach( $config['addons'] as $key => $data ){
 | 
						|
				$found = $data['name'];
 | 
						|
				$current = preg_replace('/[ _-]+/', '', strtolower($found));
 | 
						|
 | 
						|
				if( $current != $requested ){
 | 
						|
					continue;
 | 
						|
				}
 | 
						|
 | 
						|
				$current_ver = $data['version'];
 | 
						|
 | 
						|
				$in_range = true;
 | 
						|
				if( !empty($min_ver) ){
 | 
						|
					$in_range = version_compare($current_ver, $min_ver, '>=');
 | 
						|
				}
 | 
						|
				if( !empty($max_ver) ){
 | 
						|
					$in_range = $in_range && version_compare($current_ver, $max_ver, '<=');
 | 
						|
				}
 | 
						|
 | 
						|
				if( $in_range ){
 | 
						|
					return [ 'name' => $found, 'version' => $current_ver ];
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Get plugin configuration values
 | 
						|
		 * @since 3.6
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function GetConfig(){
 | 
						|
 | 
						|
			$file = self::$current['data_folder_full'] . '/_config.php';
 | 
						|
			return \gp\tool\Files::Get($file, 'config');
 | 
						|
		}
 | 
						|
 | 
						|
 | 
						|
		/**
 | 
						|
		 * Get plugin configuration values
 | 
						|
		 * @since 3.6
 | 
						|
		 *
 | 
						|
		 */
 | 
						|
		public static function SaveConfig($config){
 | 
						|
 | 
						|
			$file = self::$current['data_folder_full'] . '/_config.php';
 | 
						|
 | 
						|
			if( \gp\tool\Files::SaveData($file, 'config', $config) ){
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
namespace{
 | 
						|
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Include a file in the current plugin directory
 | 
						|
	 * @param string $file File to include relative to the current plugin directory
 | 
						|
	 * @since 3.5.3
 | 
						|
	 */
 | 
						|
	function gpPlugin_incl($file){
 | 
						|
		global $addonPathCode, $dataDir;
 | 
						|
		if( gp_safe_mode ){
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		return IncludeScript($addonPathCode.'/'.$file);  // return added in 5.0b3
 | 
						|
	}
 | 
						|
 | 
						|
 | 
						|
	class gpPlugin extends \gp\tool\Plugins{}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 |