Location: PHPKode > projects > PHP VoiceViewer > library/entity.iface.php
<?php
/**
 * PHP VoiceViewer - XML Entity Interface
 *
 * Interface enabling appending DOM XML children to DOMNodes.
 *
 * Project   : PHP VoiceViewer
 * Copyright : Christopher Cooper © 2010
 * License   : FreeBSD
 * Author    : Christopher Cooper (PaNtHaLooN), hide@address.com
 * Date      : March 2010
 * Version   : 1.0.0
 *
 * Copyright 2010 Christopher Cooper. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are
 * permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright notice, this list of
 *       conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list
 *       of conditions and the following disclaimer in the documentation and/or other materials
 *       provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY CHRISTOPHER COOPER ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CHRISTOPHER COOPER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are those of the
 * authors and should not be interpreted as representing official policies, either expressed
 * or implied, of Christopher Cooper.
 */
 
// Define acronyms
defined('DS') || define('DS', DIRECTORY_SEPARATOR);

// Main include
@require_once(dirname(__FILE__) . DS . '..' . DS . 'main.inc.php');

interface ivvEntity
{

	// DOM default values
	const DOM_VERSION		= '1.0';
	const DOM_ENCODING		= 'UTF-8';

	// DOM error tag name
	const TAG_ERROR				= 'error';
	const TAG_ERROR_CODE		= 'code';
	const TAG_ERROR_MESSAGE		= 'message';
	const TAG_ERROR_FILE		= 'file';
	const TAG_ERROR_LINE		= 'line';

	// Property flags
	const PROP_VALUE			= 0;	// Every property is a property -> 0
	const PROP_INIT				= 1;
	const PROP_NOCDATA			= 2;
	const PROP_INIT_NOCDATA		= 3;	// INIT & NOCDATA
	const PROP_IGNORE			= 4;	// Ignores these child nodes while parsing xml

	public function getElementName();
	public function &createDOMElement( DOMDocument &$doc );

}

abstract class avvEntity implements ivvEntity
{

	private $_props = array();
	private static $_proplist = array();
	
	public function __construct( array $proplist, &$data )
	{
		array_key_exists(get_class($this), self::$_proplist) || self::$_proplist[get_class($this)] = $proplist;
		if ( is_array($data) )
		{
			$props =& $data;
		}
		else if ( $root =& vv::transformToDOMElement($data) !== null )
		{
			if( $root->nodeName === $this->getElementName() )
			{
				$props =& $this->DOMElementToArray($root);
			}
			else if ( $root->nodeName === self::TAG_ERROR )
			{
				if ( vv::$config['error_forward'] === true )
				{
					$message	= '';
					$code		= 1024;
					$file		= '';
					$line		= 0;

					$xpath = new DOMXPath($root->ownerDocument);
					foreach( $xpath->query(self::TAG_ERROR_MESSAGE, $root) as $node )
					{
						$message = $node->nodeValue;
						break;
					}
					if ( $message === '' )
					{
						throw new vvException('ENTITY_MISSING_ERROR_MESSAGE');
					}
					foreach( $xpath->query('@' . self::TAG_ERROR_CODE, $root) as $node )
					{
						$code = (int)$node->nodeValue;
						break;
					}
					foreach( $xpath->query(self::TAG_ERROR_FILE, $root) as $node )
					{
						$file = $node->nodeValue;
						break;
					}
					foreach( $xpath->query(self::TAG_ERROR_FILE . '/' . self::TAG_ERROR_LINE, $root) as $node )
					{
						$line = (int)$node->nodeValue;
						break;
					}

					throw new ErrorException($message, $code, 0, $file, $line);
				}
				else
				{
					throw new vvException('ENTITY_XML_IS_ERROR');
				}
			}
			else
			{
				throw new vvException('ENTITY_XML_PARSING_FAILED', 0, $root->nodeName);
			}
		}
		else
		{
			throw new vvException('ENTITY_UNKNOWN_SOURCE');
		}
		foreach( self::$_proplist[get_class($this)] as $name => $flags )
		{
			if ( ($flags & self::PROP_INIT) && !array_key_exists($name, $props) )
			{
				throw new vvException('ENTITY_MISSING_REQUIRED_PROPERTY', 0, $name, $this->getElementName());
			}
		}

		if ( $props !== null )
		{
			foreach( array_keys($props) as $name )
			{
				if ( !array_key_exists($name, self::$_proplist[get_class($this)]) )
				{
					throw new vvException('ENTITY_SET_INVALID_PROPERTY', 0, $name);
				}
				else if ( self::$_proplist[get_class($this)][$name] & self::PROP_IGNORE )
				{
					throw new vvException('ENTITY_SET_IGNORED_PROPERTY', 0, $name);
				}
			}
			$this->_props = $props;
		}
	}
	
	final public function __set( $name, $value )
	{
		if ( !array_key_exists($name, self::$_proplist[get_class($this)]) )
		{
			if ( vv::isDebug() )
			{
				throw new vvException('ENTITY_SET_INVALID_PROPERTY', 0, $name);
			}
		}
		else if ( self::$_proplist[get_class($this)][$name] & self::PROP_INIT )
		{
			if ( vv::isDebug() )
			{
				throw new vvException('ENTITY_SET_PROTECTED_PROPERTY', 0, $name);
			}
		}
		else if ( self::$_proplist[get_class($this)][$name] & self::PROP_IGNORE )
		{
			if ( vv::isDebug() )
			{
				throw new vvException('ENTITY_SET_IGNORED_PROPERTY', 0, $name);
			}
		}
		else
		{
			$this->_props[$name] = $value;
		}
	}
	
	final public function &__get( $name )
	{
		if ( array_key_exists($name, $this->_props) )
		{
/*			if ( vv::isDebug() && (self::$_proplist[get_class($this)][$name] & self::PROP_IGNORE) )
			{
				throw new vvException('ENTITY_GET_IGNORED_PROPERTY', 0, $name);
			}
*/			return $this->_props[$name];
		}
/*		if ( vv::isDebug() )
		{
			throw new vvException('ENTITY_GET_INVALID_PROPERTY', 0, $name);
		}
*/		return null;
	}	
	
	final public function __isset( $name )
	{
/*		if ( vv::isDebug() )
		{
			if ( !array_key_exists($name, self::$_proplist[get_class($this)]) )
			{
				throw new vvException('ENTITY_CHECK_INVALID_PROPERTY', 0, $name);
			}
			else if ( self::$_proplist[get_class($this)][$name] & self::PROP_IGNORE )
			{
				throw new vvException('ENTITY_CHECK_IGNORED_PROPERTY', 0, $name);
			}
		}
*/		return isset($this->_props[$name]);
	}
	
	final public function __unset( $name )
	{
		if ( vv::isDebug() )
		{
			if ( !array_key_exists($name, self::$_proplist[get_class($this)]) )
			{
				throw new vvException('ENTITY_UNSET_INVALID_PROPERTY', 0, $name);
			}
			else if ( self::$_proplist[get_class($this)][$name] & self::PROP_IGNORE )
			{
				throw new vvException('ENTITY_UNSET_IGNORED_PROPERTY', 0, $name);
			}
		}
		unset($this->_props[$name]);
	}

	public function getElementName()
	{
		throw new vvException('ENTITY_IMPLEMENT_GETELEMENTNAME', 0, get_class($this));
	}

	public function &createDOMElement( DOMDocument &$doc )
	{
		$element = $doc->createElement($this->getElementName());
		foreach ( $this->_props as $name => $value )
		{
			if ( array_key_exists($name, self::$_proplist[get_class($this)]) &&
				(self::$_proplist[get_class($this)][$name] & self::PROP_NOCDATA) )
			{
				$element->setAttribute($name, $value);
			}
			else if ( is_string($value) )
			{
				$child = $element->appendChild($doc->createElement($name));
				$child->appendChild($doc->createCDATASection($value));
			}
			else
			{
				$child = $element->appendChild($doc->createElement($name));
				$child->appendChild($doc->createCDATASection(serialize($value)));
			}
		}
		return $element;
	}
	
	private function &DOMElementToArray( DOMElement &$element )
	{
		$props = array();
		foreach( $element->attributes as $attribute )
		{
			$props[$attribute->nodeName] = $attribute->nodeValue;
		}
		foreach( $element->childNodes as $child )
		{
			if ( array_key_exists($child->nodeName, self::$_proplist[get_class($this)]) &&
				!(self::$_proplist[get_class($this)][$child->nodeName] & self::PROP_IGNORE) )
			{
				$props[$child->nodeName] = $child->nodeValue;
			}
		}
		return $props;
	}

}

?>
Return current item: PHP VoiceViewer