PHP Classes
Icontem

File: core/classes/Attributes.class.php


  Search   All class groups All class groups   Latest entries Latest entries   Top 10 charts Top 10 charts   Newsletter Newsletter   Blog Blog   Forums Forums   Help FAQ Help FAQ  
  Login   Register  
Recommend this page to a friend! ReTweet ReTweet Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Marius Zadara  >  PAX  >  core/classes/Attributes.class.php  
File: core/classes/Attributes.class.php
Role: Auxiliary script
Content type: text/plain
Description: Attributes classes
Class: PAX
Interpret XML command scripts with PHP classes
 

Contents

Class file image Download
<?php


/**
 * Page DocBlock definition
 * @package org.zadara.marius.pax
 */


/**
 * Attributes class definition.
 * This class is responsible with all the work done on tag's attributes
 * 
 * @author Marius Zadara <marius@zadara.org>
 * @category Classes
 * @copyright (C) 2008-2009 Marius Zadara
 * @license Free for non-comercial use
 * @package org.zadara.marius.pax
 * @final 
 * @see File
 * @see IAttributes
 * @version 6.0
 * @since 5.0
 */
final class Attributes extends File implements IAttributes
{
	/**
	 * The atributes file definition content.
	 *
	 * @access private
	 * @var string
	 */
	private $attributesFileContent;
	
	/**
	 * Array with all the attributes for a tag.
	 *
	 * @access private
	 * @var array
	 */
	private $tagAttributes;
	
	/**
	 * Array with the namespaces.
	 *
	 * @access private
	 * @var array
	 */
	private $registeredNamespaces;
	
	
	/**
	 * Class constructor.
	 * 
	 * @access public
	 * @see PAXObject::__construct()
	 */
	public function __construct()
	{
		// init the parent
		parent::__construct();
		
		// init the class members
		$this->tagAttributes = null;
		$this->attributesFileContent = null;
		$this->registeredNamespaces = null;
	}
	
	/**
	 * Method to get the tag attributes from the definition file.
	 * Throws exception if error encountered.
	 *
	 * @param string <b>$rootTag</b> The attributes definition root tag
	 * @param string <b>$tag</b> The searched tag
	 * @param string <b>$paxNsSeparator</b> The namespaces separator used in tag's name
	 * @param string <b>$namespaceURL</b> The name used in defining tags from other namespaces 
	 * @return Array if the tag has attributes or false if no attribute found
	 */
	public function getTagAttributes($rootTag, $tag, $paxNsSeparator, $namespaceURL)
	{
		// if already seached for the current tag's attributes
		// return them
		if (isset($this->tagAttributes[$tag]))
			return $this->tagAttributes[$tag];		
		
		// try to load the content for the first time
		if (!is_object($this->attributesFileContent))
		{
			try
			{
				// get the content as xml from the file
				$this->attributesFileContent = @simplexml_load_file($this->path);
				
				// if failed, throw exception
				if ($this->attributesFileContent === false)
					throw new PAXException(sprintf(Messages::$MSG_037, $this->path), 37);	
			}
			catch (PAXException $pe)
			{
				// if exception caught, send it further
				throw $pe;
			}
			catch (Exception $e)
			{
				// if exception caught, send it further				
				throw new PAXException($e->getMessage());
			}
		}
		
		// get the separator position inside the tag's name
		$paxNsSepPos = strpos($tag, $paxNsSeparator);
		
		if ($paxNsSepPos !== false)
		{
			// get the namespace
			$namespace = substr($tag, 0, $paxNsSepPos);
			
			// init the namespaces array the first time
			if (!is_array($this->registeredNamespaces))
				$this->registeredNamespaces = array();
			
			// register the namespace 
			if (!in_array($namespace, $this->registeredNamespaces))
			{
				if ($this->attributesFileContent->registerXPathNamespace($namespace, sprintf("%s%s", $namespaceURL, $namespace)))
					array_push($this->registeredNamespaces, $namespace);
				else
					throw new PAXException(sprintf(Messages::$MSG_041), 41);
			}
		}
		
		// search the tag's attributes using XPath expressions
		$result = @$this->attributesFileContent->xPath(sprintf("/%s/%s", $rootTag, $tag));		
		
		if ($result == false)
			return false;
			
		if (sizeof($result) == 0)
			return false;
		
		$result = $result[0];
		$tagAttributes = array();

		// get each attribute for the tag
		foreach ($result as $attribute)
		{
			$attributeName = $attribute->getName();
			
			// skip duplicate attributes
			if (isset($tagAttributes[$attributeName]))
				continue;
				
			// get also each attribute for the current tag's attribute
			$defs = $attribute->attributes();
				
			$tagAttributes[$attributeName] = array();
			
			foreach ($defs as $def => $val)
			{
				// cast to string
				$def = (string) $def;
				$val = (string) $val;
				
				// skip duplicate attribute definition
				if (!isset($tagAttributes[$attributeName][$def]))
					$tagAttributes[$attributeName][$def] = $val;
			}
			
			if (sizeof($tagAttributes[$attributeName]) == 0)
				$tagAttributes[$attributeName] = true;
		}

		// init the array with all the tags attributes
		// only the first time
		if (!is_array($this->tagAttributes))
			$this->tagAttributes = array();
		
		// save the attributes definitions
		$this->tagAttributes[$tag] = $tagAttributes;
		
		// return the attributes definitions
		return $tagAttributes;
	}	
	
	
	
	
	/**
	 * Method to filter the tag's attributes according to its definition. 
	 * Throws exception if error encountered.
	 *
	 * @access public
	 * @static 
	 * @param config <b>$config</b> The PAX config object
	 * @param config <b>$elements</b> The PAX elements object
	 * @param config <b>$directories</b> The PAX directories object
	 * @param config <b>$filenames</b> The PAX filenames object
	 * @param array <b>$nodes</b> The nodes array
	 * @param array <b>$attributesDefinitions</b> The attributes definitions array
	 * @return void
	 */
	public static function filterTagAttributes(&$config, $elements, $directories, $filenames, &$nodes, &$attributesDefinitions)
	{
		// catch any exception
		try 
		{
			// get the filtering status from the config
			$filterAttributes = $config->get("filterTagAttributes", true);
			
			// get the filtering attribute name 
			$filterAttributesName = $config->get("filterAttributesAttributeName", "filterAttributes");

			// if the attribute has been found in the root,
			// update the filtering status using the 'true texts' dictionary
			if (isset($nodes[0]['attributes'][$filterAttributesName]))
				$filterAttributes = Model::isInList($nodes[0]['attributes'][$filterAttributesName], $elements->get("trueTexts")); 

			// continue with the filtering?
			if ($filterAttributes)
			{
				// allow no attributes definition?
				$allowNoAttributes = $config->get("allowNoAttributes", false);
				
				// if not ...
				if (!$allowNoAttributes)
				{
					// validate the attributes definition file
					// using the configuration
					
					$attributes = new Attributes();
					
					$attributesPath = $directories->get("definitions", "definitions");
					$attributesPath .= $filenames->get("attributes", "attributes.xml");
					
					$attributes->setPath($attributesPath);
					
					if (!$attributes->exists())
						throw new PAXException(sprintf(Messages::$MSG_034, $tagsPath), 34);

					if (!$attributes->isOrdinary())
						throw new PAXException(sprintf(Messages::$MSG_035, $tagsPath), 35);
						
					if (!$attributes->isReadable())
						throw new PAXException(sprintf(Messages::$MSG_036, $tagsPath), 36);
						
					// get extra informations
					// usefull in attribute parsing
					$rootTagAttributes = $config->get("attributesRoot", "attributes");
					$mandatoryText = $elements->get("mandatoryText", "mandatory");
					$defaultValueText = $elements->get("defaultValueText", "defaultValue");
					$namespaceURL = $elements->get("namespaceURL", "http://pax.org/");
					
					// parse the nodes list
					foreach ($nodes as $index => $nodeData)
					{
						// if invalid node, skip
						if ($nodeData === false)
							continue;
						
						// if the node type is close, skip
						// (the closed nodes don't have attributes)
						if ($nodeData['type'] == "close")
							continue;
						
						if (!isset($nodes[$index]['attributes']))
							$nodes[$index]['attributes'] = array();
							
							
						$paxNsSeparator = $elements->get("paxNsSeparator", ":");	
						
						// get the tag attributes according to the definition
						$tagAttributes = $attributes->getTagAttributes($rootTagAttributes, $nodeData['tag'], $paxNsSeparator, $namespaceURL);

						// if no attributes were defined, 
						// update the values and continue
						if ($tagAttributes === false)
						{
							$nodes[$index]['attributes'] = false;							
							continue;
						}
								
						$attributesCount = sizeof($tagAttributes);

						// if no attributes were defined, 
						// update the values and continue						
						if ($attributesCount == 0)
						{
							$nodes[$index]['attributes'] = false;							
							continue;
						}
							
						if (isset($nodeData['attributes']) && is_array($nodeData['attributes']))
						{
							// validate each attribute from the file according to the definition
							foreach ($nodeData['attributes'] as $attributeName => $attributeValue)
							{								
								if (stripos($attributeName, $paxNsSeparator) !== false)
								{
									unset($nodes[$index]['attributes'][$attributeName]);
									continue;
								}
								
								// if not found in the definition, unset it
								if (!isset($tagAttributes[$attributeName]))
									unset($nodes[$index]['attributes'][$attributeName]);								
							}
						}
						
						
						// add the mandatory attributes with their's default values
						foreach ($tagAttributes as $attributeName => $attributeData)
						{
							if (isset($nodes[$index]['attributes'][$attributeName]))
								continue;
								
							if (isset($attributeData[$mandatoryText]))
							{
								$isMandatory = Model::isInList($attributeData[$mandatoryText], $elements->get('trueTexts'));
								
								if (!$isMandatory)
									continue;

								if (!isset($attributeData[$defaultValueText]))
									continue;
								
								if (!isset($nodes[$index]['attributes']))
									$nodes[$index]['attributes'] = array();
									 	
								$nodes[$index]['attributes'][$attributeName] = $attributeData[$defaultValueText]; 
							}
						}
						
						// if at the end the attributes list is empty, set it to false
						if ((isset($nodes[$index]['attributes'])) && (sizeof($nodes[$index]['attributes']) == 0))
							$nodes[$index]['attributes'] = false;
							
						if ($nodes[$index]['attributes'] === false)
							continue;
							
						if ($attributesDefinitions == null)
							$attributesDefinitions = array();

							
						$attributesDefinitions[$index] = array();
						
						// clear the 'mandatory' and 'defaultValue' attributes from the definition
						// and save the new attributes list for the current index
						foreach ($nodes[$index]['attributes'] as $attributeName => $attributeValue)
						{
							$attributesDefinitions[$index][$attributeName] = $tagAttributes[$attributeName];
							
							if (isset($attributesDefinitions[$index][$attributeName][$mandatoryText]))
								unset($attributesDefinitions[$index][$attributeName][$mandatoryText]);

							if (isset($attributesDefinitions[$index][$attributeName][$defaultValueText]))
								unset($attributesDefinitions[$index][$attributeName][$defaultValueText]);	

							if (sizeof($attributesDefinitions[$index][$attributeName]) == 0)
								unset($attributesDefinitions[$index][$attributeName]);
						}

						if (sizeof($attributesDefinitions[$index]) == 0)
							unset($attributesDefinitions[$index]);
					}
				}
			}
		}
		catch (PAXException $pe)
		{
			// in case of exception, send it further
			throw $pe;
		}
		catch (Exception $e)
		{
			// in case of exception, send it further
			throw $e;						
		}
	}
	
	/**
	 * Method to filter tag attribute's value.
	 * Throws exception if error encountered.
	 *
	 * @param config <b>$config</b> The PAX config
	 * @param config <b>$elements</b> The PAX elements
	 * @param config <b>$directories</b> The PAX directories
	 * @param config <b>$filenames</b> The PAX filenames
	 * @param array <b>$nodes</b> The list of nodes
	 * @param array <b>$attributesDefinitions</b> Attributes definitions
	 * @return void
	 */
	public static function filterTagAttributesValue(&$config, $elements, $directories, $filenames, &$nodes, &$attributesDefinitions)
	{
		// catch any exception
		try 
		{	
			// get the filtering status from the config
			$filterAttributesValue = $config->get("filterTagAttributesValues", true);

			// get the filtering attribute name
			$filterAttributesValueTagName = $config->get("filterAttributesValueAttributeName", "filterAttributesValue");

			// update the filtering value if the attribute has been found
			if (isset($nodes[0]['attributes'][$filterAttributesValueTagName]))
				$filterAttributesValue = Model::isInList($nodes[0]['attributes'][$filterAttributesValueTagName], $elements->get("trueTexts")); 
			
			// continue with the filtering? 
			if ($filterAttributesValue)
			{
				// there are some attributes definitions?
				if (is_array($attributesDefinitions) && (sizeof($attributesDefinitions) > 0))
				{
					// get the attribute value validation name
					$attributeValueValidationMethodName = $elements->get("attrbuteValueValidationMethodName", "validateAttributeValue_[ATTRIBUTE]");					
					$paxNsSeparator = $elements->get("paxNsSeparator", ":");
					
					// parse the nodes list
					foreach ($nodes as $index => $nodeData)
					{
						// skip the invalid nodes
						if ($nodeData === false)
							continue;
						
						// skip the closed nodes
						if ($nodeData['type'] == 'close')
							continue;

						if (!isset($nodeData['attributes']))
							continue;	
							
						// skip the nodes without any attributes
						if ($nodeData['attributes'] === false)
							continue;
							
						// skip the nodes without any attributes definitions
						if (!isset($attributesDefinitions[$index]))
							continue;
						
						$paxNsSepPos = strpos($nodeData['tag'], $paxNsSeparator);
						
						// get the node name either from the a namespace or local
						if ($paxNsSepPos !== false)
							$currentNodeName = substr($nodeData['tag'], $paxNsSepPos + 1);
						else
							$currentNodeName = $nodeData['tag']; 
							
						// beautify the node name
						$currentNodeName = ucfirst($currentNodeName);

						// at this point, the class should already exists
						// (loaded at the moment of filtering tags)
						if (!class_exists($currentNodeName))
							throw new PAXException(sprintf(Messages::$MSG_038, $currentNodeName), 38);

						// validate each attribute 
						foreach ($nodeData['attributes'] as $attributeName => $attributeValue)
						{
							// skip the attributes without any definitions
							if (!isset($attributesDefinitions[$index][$attributeName]))
								continue;
							
							// update the validation method name
							$validationMethodName = str_ireplace("[ATTRIBUTE]", strtoupper($attributeName), $attributeValueValidationMethodName);	

							// seach the method inside the current class
							// if not found, skip filtering for the current attribute
							if (!method_exists($currentNodeName, $validationMethodName))
								continue;
							
								
							// create the evaluation string
							$evalString = sprintf("\$newAttributeValue = %s::%s('%s', \$attributesDefinitions[\$index][\$attributeName]);", $currentNodeName, $validationMethodName, $attributeValue);	

							// try to evaluate the string
							// if failed, thow exception
							if (@eval($evalString) === false)
								throw new PAXException(sprintf(Messages::$MSG_039, $currentNodeName, $attributeName, $nodeData['value']), 39);	

							if (is_null($newAttributeValue))
							{
								// if the result of validation method is null,
								// unset the attribute							
								unset($nodes[$index]['attributes'][$attributeName]);
							}
							else
							{
								// update the attribute value with the new one 
								$nodes[$index]['attributes'][$attributeName] = $newAttributeValue;
							}
						}
						
						// if at the end, the node has no attributes, 
						// update the record
						if (sizeof($nodes[$index]['attributes']) == 0)
							$nodes[$index]['attributes'] = false;
					}
				}
			}
		}
		catch (PAXException  $pe)
		{
			// in case of exception, throw it further
			throw $pe;
		}				
		catch (Exception $e)
		{
			// in case of exception, throw it further			
			throw $e;
		}
	}
	
	
	
	/**
	 * Method to compile the instructions
	 *
	 * @access public
	 * @static 
	 * @param config <b>$instructions</b> The PAX config
	 * @param array </b>$nodes</b> The nodes list
	 * @return void
	 */
	public static function compileInstructions(&$instructions, &$nodes)
	{
		// validate the instructions
		if (is_null($instructions))
			return;
		
		// create the pattern
		$pattern = new Pattern();
		$instructionExtractor = new InstructionExtractor();
		$instructionEvaluator = new InstructionEvaluator();
		$currentInstructions = array();	
			
		$startDelimiter = $instructions->get("startDelimiter", "!#");
		$endDelimiter = $instructions->get("endDelimiter", "#!");
		
		// parse each node
		foreach ($nodes as $nodeIndex => $nodeData)
		{
			if ($nodeData === false)
				continue;
				
			if (!isset($nodeData['attributes']))
				continue;
				
			if ($nodeData['attributes'] === false)
				continue;

			foreach ($nodeData['attributes'] as $attributeName => $attributeValue)
			{
				try
				{
					// try to extract instructions from the value of the current attribute
					$currentInstructions = $instructionExtractor->extract($attributeValue, $startDelimiter, $endDelimiter);
				}
				catch (PAXException $pe)
				{
					// if exception, throw it further
					throw $pe;
				}
				catch (Exception $e)
				{
					// if exception, throw it further
					throw $e;
				}
				
				// validate the instructions
				if ($currentInstructions === false)
					continue;

				// compile each instruction
				// and replace it by its value
				foreach ($currentInstructions as $instruction)
				{
					$replacePattern = $pattern->makeInstructionReplacePattern($instruction, $startDelimiter, $endDelimiter);
					$nodes[$nodeIndex]['attributes'][$attributeName] = InstructionReplacer::replace($replacePattern, $instructionEvaluator->evaluate($instruction), $nodes[$nodeIndex]['attributes'][$attributeName]);
				}
			}
		}
	}
	
	
	
	/**
	 * Class destructor.
	 * 
	 * @access public
	 */
	function __destruct()
	{
		
	}
}

?>

 
  Advertise on this site Advertise on this site   Site map Site map   Statistics Statistics   Site tips Site tips   Privacy policy Privacy policy   Contact Contact  

For more information send a message to :
info at phpclasses dot org.
Copyright (c) Icontem 1999-2009 PHP Classes - PHP Class Scripts
  PHP Book Reviews - Reviews of books and other products