⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reader.php

📁 Joomla15 - 最新开源CMS
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?PHP
/**
 * Base class for patTemplate readers
 *
 * $Id: Reader.php 8287 2007-08-01 08:38:59Z eddieajau $
 *
 * This class is able to parse patTemplate tags from any string you hand it over
 * It will emulate some kind of SAX parsing by calling start-, end- and CData-handlers.
 *
 * @package		patTemplate
 * @subpackage	Readers
 * @author		Stephan Schmidt <schst@php.net>
 */
// Check to ensure this file is within the rest of the frameworkdefined('JPATH_BASE') or die();
/**
 * No input
 */
define( 'PATTEMPLATE_READER_ERROR_NO_INPUT', 6000 );

/**
 * Unknown tag
 */
define( 'PATTEMPLATE_READER_ERROR_UNKNOWN_TAG', 6001 );

/**
 * Invalid tag (missing attribute)
 */
define( 'PATTEMPLATE_READER_ERROR_INVALID_TAG', 6002 );

/**
 * Closing tag is missing
 */
define( 'PATTEMPLATE_READER_ERROR_NO_CLOSING_TAG', 6003 );

/**
 * Invalid closing tag
 */
define( 'PATTEMPLATE_READER_ERROR_INVALID_CLOSING_TAG', 6004 );

/**
 * Invalid condition specified
 */
define( 'PATTEMPLATE_READER_ERROR_INVALID_CONDITION', 6005 );

/**
 * No name has been specified
 */
define( 'PATTEMPLATE_READER_ERROR_NO_NAME_SPECIFIED', 6010 );

/**
 * CData in a conditional template
 */
define( 'PATTEMPLATE_READER_NOTICE_INVALID_CDATA_SECTION', 6050 );

/**
 * template already exists
 */
define( 'PATTEMPLATE_READER_NOTICE_TEMPLATE_EXISTS', 6051 );

/**
 * Base class for patTemplate readers
 *
 * This class is able to parse patTemplate tags from any string you hand it over
 * It will emulate some kind of SAX parsing by calling start-, end- and CData-handlers.
 *
 * @abstract
 * @package		patTemplate
 * @subpackage	Readers
 * @author		Stephan Schmidt <schst@php.net>
 */
class patTemplate_Reader extends patTemplate_Module
{
	/**
	* reference to the patTemplate object that instantiated the module
	*
	* @access	protected
	* @var	object
	*/
	var	$_tmpl;

	/**
	* stack for all open elements
	* @access	private
	* @var	array
	*/
	var	$_elStack;

	/**
	* stack for all open templates
	* @access	private
	* @var	array
	*/
	var	$_tmplStack;

	/**
	* character data
	* @access	private
	* @var	array
	*/
	var	$_data;

	/**
	* tag depth
	* @access	private
	* @var	integer
	*/
	var	$_depth;

	/**
   	* templates that have been found
	* @access	protected
	* @var		array
	*/
	var $_templates	=	array();

	/**
   	* path to the template
	* @access	protected
	* @var		array
	*/
	var $_path	=	array();

	/**
	* start tag for variables
	* @access	private
	* @var		string
	*/
	var	$_startTag;

	/**
	* end tag for variables
	* @access	private
	* @var		string
	*/
	var	$_endTag;

	/**
	* default attributes
	*
	* @access	private
	* @var		array
	*/
	var	$_defaultAtts	=	array();

	/**
	* root attributes
	*
	* This is used when reading the template content
	* from an external file.
	*
	* @access	private
	* @var		array
	*/
	var	$_rootAtts	=	array();

	/**
	* inherit attributes
	*
	* @access	private
	* @var		array
	*/
	var	$_inheritAtts	=	array();

	/**
	* name of the first template that has been found
	*
	* @access	private
	* @var		string
	*/
	var	$_root = null;

	/**
	* all data that has been processed
	*
	* @access	private
	* @var		string
	*/
	var	$_processedData = null;

	/**
	* current input
	*
	* @access	private
	* @var		string
	*/
	var	$_currentInput = null;

	/**
	* all loaded functions
	*
	* @access	private
	* @var		array
	*/
	var	$_functions	=	array();

	/**
	* function aliases
	*
	* @access   private
	* @var	  array
	*/
	var $_funcAliases = array();

	/**
	* options
	*
	* @access   private
	* @var	  array
	*/
	var $_options = array();

	/**
	* reader is in use
	*
	* @access   private
	* @var	  boolean
	*/
	var $_inUse = false;

	/**
	* set a reference to the patTemplate object that instantiated the reader
	*
	* @access	public
	* @param	object		patTemplate object
	*/
	function setTemplateReference( &$tmpl )
	{
		$this->_tmpl = &$tmpl;
	}

	/**
	* read templates from any input
	*
	* @abstract	must be implemented in the template readers
	* @param	mixed	input to read from.
	*					This can be a string, a filename, a resource or whatever the derived class needs to read from
	* @param	array	options, not implemented in current versions, but future versions will allow passing of options
	* @return	array	template structure
	*/
	function readTemplates( $input, $options = array() )
	{
		return array();
	}

	/**
	* load template from any input
	*
	* If the a template is loaded, the content will not get
	* analyzed but the whole content is returned as a string.
	*
	* @abstract	must be implemented in the template readers
	* @param	mixed	input to load from.
	*					This can be a string, a filename, a resource or whatever the derived class needs to read from
	* @param	array	options, not implemented in current versions, but future versions will allow passing of options
	* @return	string  template content
	*/
	function loadTemplate( $input, $options = array() )
	{
		return $input;
	}

	/**
	* set options
	*
	* @access	public
	* @param	array	array containing options
	*/
	function setOptions( $options )
	{
		$this->_startTag = $options['startTag'];
		$this->_endTag   = $options['endTag'];

		$this->_options  = $options;

		if (isset($options['functionAliases'])) {
			$this->_funcAliases = $options['functionAliases'];
		}
		array_map('strtolower', $this->_funcAliases);
	}

	/**
	* add an alias for a function
	*
	* @access   public
	* @param	string  alias
	* @param	string  function name
	*/
	function addFunctionAlias($alias, $function)
	{
		$this->_funcAliases[strtolower($alias)] = $function;
	}

	/**
	* set the root attributes
	*
	* @access	public
	* @param	array	array containing options
	*/
	function setRootAttributes( $attributes )
	{
		$this->_rootAtts = $attributes;
	}

	/**
	* parse templates from string
	*
	* @access	private
	* @param	string		string to parse
	* @return	array		templates
	*/
	function parseString( $string )
	{
		$this->_inUse = true;

		/**
		 * apply input filter before parsing
		 */
		$string = $this->_tmpl->applyInputFilters( $string );

		$this->_inheritAtts	  =	array();
		$this->_elStack		  =	array();
		$this->_data		  =	array( '' );
		$this->_tmplStack	  =	array();
		$this->_depth		  =	0;
		$this->_templates	  =	array();
		$this->_path		  =	array();
		$this->_processedData =	'';

		$this->_defaultAtts	= $this->_tmpl->getDefaultAttributes();

		if( !isset( $this->_defaultAtts['autoload'] ) ) {
			$this->_defaultAtts['autoload']	= 'on';
		}

		/**
		 * create a special root template
		 */
		$attributes			= $this->_rootAtts;
		$attributes['name']	= '__ptroot';

		$rootTemplate = $this->_initTemplate( $attributes );
		$this->_root  = null;
		unset( $rootTemplate['isRoot'] );

		array_push( $this->_tmplStack, $rootTemplate );

		$patNamespace = $this->_tmpl->getNamespace();
		if (is_array($patNamespace)) {
			$patNamespace = array_map('strtolower', $patNamespace);
		} else {
			$patNamespace = array(strtolower( $patNamespace ));
		}

		/**
		 *start parsing
		 */
		$regexp	=	'/(<(\/?)([[:alnum:]]+):([[:alnum:]]+)[[:space:]]*([^>]*)>)/im';

		$tokens	=	preg_split( $regexp, $string, -1, PREG_SPLIT_DELIM_CAPTURE );

		/**
		 * the first token is always character data
		 * Though it could just be empty
		 */
		if( $tokens[0] != '' ) {
			$this->_characterData( $tokens[0] );
		}

		$cnt	=	count( $tokens );
		$i		=	1;
		// process all tokens
		while( $i < $cnt ) {
			$fullTag	= $tokens[$i++];
			$closing	= $tokens[$i++];
			$namespace	= strtolower( $tokens[$i++] );
			$tagname	= strtolower( $tokens[$i++] );
			$attString	= $tokens[$i++];
			$empty		= substr( $attString, -1 );
			$data		= $tokens[$i++];

			/**
			 * check, whether it's a known namespace
			 * currently only the template namespace is possible
			 */
			 if( !in_array($namespace, $patNamespace) ) {
			 	$this->_characterData( $fullTag );
			 	$this->_characterData( $data );
				continue;
			 }

			/**
			 * is it a closing tag?
			 */
			if( $closing === '/' ) {
				$result	=	$this->_endElement( $namespace, $tagname );
				if( patErrorManager::isError( $result ) ) {
					return	$result;
				}
				$this->_characterData( $data );
				continue;
			}

			/**
			 * Is empty or opening tag!
			 */
			if( $empty === '/' ) {
				$attString	=	substr( $attString, 0, -1 );
			}

			$attributes	=	$this->_parseAttributes( $attString );
			$result 	=	$this->_startElement( $namespace, $tagname, $attributes );
			if( patErrorManager::isError( $result ) ) {
				return	$result;
			}

			/**
			 * check, if the tag is empty
			 */
			if( $empty === '/' ) {
				$result	=	$this->_endElement( $namespace, $tagname );
				if( patErrorManager::isError( $result ) ) {
					return	$result;
				}
			}

			$this->_characterData( $data );
		}

		$rootTemplate = array_pop( $this->_tmplStack );

		$this->_closeTemplate( $rootTemplate, $this->_data[0] );

		/**
		 * check for tags that are still open
		 */
		if( $this->_depth > 0 ) {
			$el	=	array_pop( $this->_elStack );
			return patErrorManager::raiseError(
				PATTEMPLATE_READER_ERROR_NO_CLOSING_TAG,
				$this->_createErrorMessage( "No closing tag for {$el['ns']}:{$el['name']} found" )
			);
		}

		$this->_inUse = false;

		return	$this->_templates;
	}

	/**
	* parse an attribute string and build an array
	*
	* @access	private
	* @param	string	attribute string
	* @param	array	attribute array
	*/
	function _parseAttributes( $string )
	{
	 	static $entities = array(
									'&lt;' => '<',
									'&gt;' => '>',
									'&amp;' => '&',
									'&quot;' => '"',
									'&apos;' => '\''
								);

		$attributes	=	array();
		$match = array();
		preg_match_all('/([a-zA-Z_0-9]+)="((?:\\\.|[^"\\\])*)"/U', $string, $match);
		for ($i = 0; $i < count($match[1]); $i++) {
			$attributes[strtolower( $match[1][$i] )] = strtr( (string)$match[2][$i], $entities );
		}
		return	$attributes;
	}

	/**
	* handle start element
	*
	* @access	private
	* @param	string		element name
	* @param	array		attributes
	*/
	function _startElement( $ns, $name, $attributes )
	{
		array_push( $this->_elStack, array(
											'ns'			=>  $ns,
											'name'			=>	$name,
											'attributes'	=>	$attributes,
										)
				 );

		$this->_depth++;

		$this->_data[$this->_depth]	=	'';

		/**
		 * handle tag
		 */
		switch( $name )
		{
			/**
			 * template
			 */
			case 'tmpl':
				$result	=	$this->_initTemplate( $attributes );
				break;

			/**
			 * sub-template
			 */
			case 'sub':
				$result	=	$this->_initSubTemplate( $attributes );
				break;

			/**
			 * link
			 */
			case 'link':
				$result	=	$this->_initLink( $attributes );
				break;

			/**
			 * variable

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -