Location: PHPKode > projects > PHP VoiceViewer > library/channel.class.php
<?php
/**
 * PHP VoiceViewer - Channel Class
 *
 * Channel Entity
 *
 * 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');

final class vvChannel extends avvEntity implements ivvChannel
{

	const ELEMENT_CHANNELS	= 'channels';
	const ELEMENT_USERS		= 'users';
	
	private static $_proplist = array(	'id'					=> self::PROP_INIT_NOCDATA,
										'name'					=> self::PROP_INIT,
										'default'				=> self::PROP_NOCDATA,
										'sortorder'				=> self::PROP_NOCDATA,
										'temporary'				=> self::PROP_NOCDATA,
										'private'				=> self::PROP_NOCDATA,
										'moderated'				=> self::PROP_NOCDATA,
										'url'					=> self::PROP_VALUE,
										'description'			=> self::PROP_VALUE,
										self::ELEMENT_CHANNELS	=> self::PROP_IGNORE,
										self::ELEMENT_USERS		=> self::PROP_IGNORE
										);

	private static $_xpath_channels	= null;
	private static $_xpath_users	= null;

	private $_regchannels = array();
	private $_regusers = array();

	private $_channels = array();
	private $_users = array();
	
	private $_parent = null;
	
	public function __construct( &$data )
	{
		// Call parent constructor;
		parent::__construct(self::$_proplist, $data);

		if ( self::$_xpath_channels === null )
		{
			self::$_xpath_channels	= './' . self::ELEMENT_CHANNELS . '/' . self::ELEMENT_NAME;
			self::$_xpath_users		= './' . self::ELEMENT_USERS . '/' . ivvUser::ELEMENT_NAME;
		}
		
		if ( $root =& vv::transformToDOMElement($data) !== null )
		{
			$xpath = new DOMXPath($root->ownerDocument);
			foreach( $xpath->query(self::$_xpath_channels, $root) as $channel )
			{
				$this->appendChannel(new vvChannel($channel));
			}
			foreach( $xpath->query(self::$_xpath_users, $root) as $user )
			{
				$this->appendUser(new vvUser($user));
			}			
		}
		
		$this->registerChannel($this);
	}

	public function getElementName()
	{
		return self::ELEMENT_NAME;
	}
	
	public function &createDOMElement( DOMDocument &$doc )
	{
		$element =& parent::createDOMElement($doc);

		if ( $this->hasChannels() )
		{			
			$channels = $element->appendChild($doc->createElement(self::ELEMENT_CHANNELS));
			foreach( $this->_channels as &$sub )
			{
				$channels->appendChild($sub->createDOMElement($doc));
			}
		}

		if ( $this->hasUsers() )
		{			
			$users = $element->appendChild($doc->createElement(self::ELEMENT_USERS));
			foreach( $this->_users as &$user )
			{
				$users->appendChild($user->createDOMElement($doc));
			}
		}
		return $element;
	}
	
	private function setParent( ivvChannel &$parent = null )
	{
		// First set reference to parent
		$this->_parent =& $parent;
		
		if ( $this->_parent !== null )
		{
			$regto =& $this->_parent;
			// In case this was a filled base channel remove regdata
			if ( count($this->_regchannels) > 0 )
			{
				$this->_regchannels = array();
			}
			if ( count($this->_regusers) > 0 )
			{
				$this->_regusers = array();
			}
		}
		else
		{
			$regto =& $this;
		}
		
		// NOTE: Channel/Users can only be added once -> To move unregister frist
		$regto->registerChannel($this);
		foreach( $this->_users as &$user )
		{
			$regto->registerUser($user);
		}
		foreach( $this->_channels as &$channel )
		{
			$channel->setParent($this);
		}
	}
	
	public function &getParent()
	{
		return $this->_parent;
	}
	
	public function &appendChannel( &$input )
	{
		if ( is_array($input) )
		{
			$channel =& new vvChannel($input);
		}
		else if ( $input instanceof ivvChannel )
		{
			$channel =& $input;
		}
		else
		{
			throw new vvException('CHANNEL_APPENDCHANNEL_INVALID_ARG');
		}			
		$channel->setParent($this);
		return $this->_channels[$channel->getID()] =& $channel;
	}
	
	public function &appendUser( &$input )
	{
		if ( is_array($input) )
		{
			$user =& new vvUser($input);
		}
		else if ( $input instanceof ivvUser )
		{
			$user =& $input;
		}
		else
		{
			throw new vvException('CHANNEL_APPENDUSER_INVALID_ARG');
		}
		$this->registerUser($user);
		$user->setParent($this);
		return $this->_users[$user->getID()] =& $user;
	}
	
	public function hasChannels()
	{
		if ( count($this->_channels) > 0 )
		{
			return true;
		}
		return false;
	}
	
	public function hasUsers( $recursive = false )
	{
		if ( count($this->_users) > 0 )
		{
			return true;
		}
		if ( $recursive && (count($this->_channels) > 0) )
		{
			foreach( $this->_channels as &$channel )
			{
				if ( $channel->hasUsers(true) )
				{
					return true;
				}
			}
		}
		return false;
	}
	
	public function channelExists( $id, $local = true )
	{
		if ( $local === true )
		{
			return array_key_exists($id, $this->_channels);
		}
		else if ( $local === false )
		{
			if ( $this->_parent !== null )
			{
				return $this->_parent->channelExists($id, false);
			}
			return array_key_exists($id, $this->_regchannels);
		}
		else
		{
			throw new vvException('CHANNEL_CHANNELEXISTS_INVALID_ARG');
		}
	}

	public function userExists( $id, $local = true )
	{
		if ( $local === true )
		{
			return array_key_exists($id, $this->_users);
		}
		else if ( $local === false )
		{
			if ( $this->_parent !== null )
			{
				return $this->_parent->userExists($id, false);
			}
			return array_key_exists($id, $this->_regusers);
		}
		else
		{
			throw new vvException('CHANNEL_USEREXISTS_INVALID_ARG');
		}
	}

	public function &getChannel( $id )
	{
		$result = null;
		if ( $this->_parent !== null )
		{
			$result = $this->_parent->getChannel($id);
		}
		if ( !array_key_exists($id, $this->_regchannels) )
		{
			if ( vv::isDebug() )
			{
				throw new vvException('CHANNEL_GET_UNKNOWN_CHANNEL', 0, $id);
			}
		}
		else
		{
			$result = $this->_regchannels[$id];
		}
		return $result;
	}
	
	public function &getChannels()
	{
		return $this->_channels;
	}
	
	public function &getUser( $id )
	{
		$result = null;
		if ( $this->_parent !== null )
		{
			$result = $this->_parent->getUser($id);
		}
		if ( !array_key_exists($id, $this->_regusers) )
		{
			if ( vv::isDebug() )
			{
				throw new vvException('CHANNEL_GET_UNKNOWN_USER', 0, $id);
			}
		}
		else
		{
			$result = $this->_regusers[$id];
		}
		return $result;
	}

	public function &getUsers()
	{
		return $this->_users;
	}

	public function &removeChannel( $id, $remove = true )
	{
		if ( !array_key_exists($id, $this->_channels) )
		{
			throw new vvException('CHANNEL_REMOVE_UNKNOWN_CHANNEL', 0, $id, $thid->id);
		}
		$remchannel =& $this->_channels[$id];
		foreach( $remchannel->_channels as &$channel )
		{
			$remchannel->removeChannel($channel->getID(), false);
		}
		$this->unregisterChannel($id);
		foreach( $remchannel->_users as &$user )
		{
			$this->unregisterUser($user->getID(), false);
		}
		if ( $remove )
		{
			unset($this->_channels[$id]);
			$remchannel->setParent();
		}
		return $remchannel;
	}

	public function &removeUser( $id, $remove = true )
	{
		if ( !array_key_exists($id, $this->_users) )
		{
			throw new vvException('CHANNEL_REMOVE_UNKNOWN_USER', 0, $id, $this->id);
		}
		$remuser =& $this->_users[$id];
		$this->unregisterUser($id);
		if ( $remove )
		{
			unset($this->_users[$id]);
			$remuser->setParent();
		}
		return $remuser;
	}

	private function registerChannel( ivvChannel &$channel )
	{
		if ( $this->_parent !== null )
		{
			$this->_parent->registerChannel($channel);
		}
		else
		{
			$id = $channel->getID();
			if ( $this->channelExists($id, false) )
			{
				throw new vvException('CHANNEL_REGISTER_CHANNEL_DUPLICATE', 0, $id);
			}
			$this->_regchannels[$id] =& $channel;
		}
	}
	
	private function unregisterChannel( $id )
	{
		if ( $this->_parent !== null )
		{
			$this->_parent->unregisterChannel($id);
		}
		else
		{
			unset($this->_regchannels[$id]);
		}
	}
	
	private function registerUser( ivvUser &$user )
	{
		if ( $this->_parent !== null )
		{
			$this->_parent->registerUser($user);
		}
		else
		{
			$id = $user->getID();
			if ( $this->userExists($id, false) )
			{
				throw new vvException('CHANNEL_REGISTER_USER_DUPLICATE', 0, $id);
			}
			$this->_regusers[$id] =& $user;
		}
	}
	
	/** Removes user from root channel's user list. Internal method only.
	 */
	private function unregisterUser( $id )
	{
		if ( $this->_parent !== null )
		{
			$this->_parent->unregisterUser($id);
		}
		else
		{
			unset($this->_regusers[$id]);
		}
	}
	
	public function getID()
	{
		return ($this->id == '-1') ? 'vv:' . spl_object_hash($this) : $this->id;
	}
	
}
 
?>
Return current item: PHP VoiceViewer