You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							625 lines
						
					
					
						
							12 KiB
						
					
					
				
			
		
		
	
	
							625 lines
						
					
					
						
							12 KiB
						
					
					
				| <?php
 | |
| 
 | |
| /**
 | |
|  * @file
 | |
|  * TeamSpeak 3 PHP Framework
 | |
|  *
 | |
|  * $Id: Abstract.php 06/06/2016 22:27:13 scp@Svens-iMac $
 | |
|  *
 | |
|  * This program is free software: you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License as published by
 | |
|  * the Free Software Foundation, either version 3 of the License, or
 | |
|  * (at your option) any later version.
 | |
|  *
 | |
|  * This program is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | |
|  * GNU General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU General Public License
 | |
|  * along with this program. If not, see <http://www.gnu.org/licenses/>.
 | |
|  *
 | |
|  * @package   TeamSpeak3
 | |
|  * @version   1.1.24
 | |
|  * @author    Sven 'ScP' Paulsen
 | |
|  * @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
 | |
|  */
 | |
| 
 | |
| /**
 | |
|  * @class TeamSpeak3_Node_Abstract
 | |
|  * @brief Abstract class describing a TeamSpeak 3 node and all it's parameters.
 | |
|  */
 | |
| abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAccess, Countable
 | |
| {
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected $parent = null;
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected $server = null;
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected $nodeId = 0x00;
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected $nodeList = null;
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected $nodeInfo = array();
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected $storage = array();
 | |
| 
 | |
|   /**
 | |
|    * Sends a prepared command to the server and returns the result.
 | |
|    *
 | |
|    * @param  string  $cmd
 | |
|    * @param  boolean $throw
 | |
|    * @return TeamSpeak3_Adapter_ServerQuery_Reply
 | |
|    */
 | |
|   public function request($cmd, $throw = TRUE)
 | |
|   {
 | |
|     return $this->getParent()->request($cmd, $throw);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Uses given parameters and returns a prepared ServerQuery command.
 | |
|    *
 | |
|    * @param  string $cmd
 | |
|    * @param  array  $params
 | |
|    * @return TeamSpeak3_Helper_String
 | |
|    */
 | |
|   public function prepare($cmd, array $params = array())
 | |
|   {
 | |
|     return $this->getParent()->prepare($cmd, $params);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Prepares and executes a ServerQuery command and returns the result.
 | |
|    *
 | |
|    * @param  string $cmd
 | |
|    * @param  array  $params
 | |
|    * @return TeamSpeak3_Adapter_ServerQuery_Reply
 | |
|    */
 | |
|   public function execute($cmd, array $params = array())
 | |
|   {
 | |
|     return $this->request($this->prepare($cmd, $params));
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the parent object of the current node.
 | |
|    *
 | |
|    * @return TeamSpeak3_Adapter_ServerQuery
 | |
|    * @return TeamSpeak3_Node_Abstract
 | |
|    */
 | |
|   public function getParent()
 | |
|   {
 | |
|     return $this->parent;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the primary ID of the current node.
 | |
|    *
 | |
|    * @return integer
 | |
|    */
 | |
|   public function getId()
 | |
|   {
 | |
|     return $this->nodeId;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns TRUE if the node icon has a local source.
 | |
|    *
 | |
|    * @param  string $key
 | |
|    * @return boolean
 | |
|    */
 | |
|   public function iconIsLocal($key)
 | |
|   {
 | |
|     return ($this[$key] > 0 && $this[$key] < 1000) ? TRUE : FALSE;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the internal path of the node icon.
 | |
|    *
 | |
|    * @param  string $key
 | |
|    * @return TeamSpeak3_Helper_String
 | |
|    */
 | |
|   public function iconGetName($key)
 | |
|   {
 | |
|     $iconid = ($this[$key] < 0) ? (pow(2, 32))-($this[$key]*-1) : $this[$key];
 | |
| 
 | |
|     return new TeamSpeak3_Helper_String("/icon_" . $iconid);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns a possible classname for the node which can be used as a HTML property.
 | |
|    *
 | |
|    * @param  string $prefix
 | |
|    * @return string
 | |
|    */
 | |
|   public function getClass($prefix = "ts3_")
 | |
|   {
 | |
|     if($this instanceof TeamSpeak3_Node_Channel && $this->isSpacer())
 | |
|     {
 | |
|       return $prefix . "spacer";
 | |
|     }
 | |
|     elseif($this instanceof TeamSpeak3_Node_Client && $this["client_type"])
 | |
|     {
 | |
|       return $prefix . "query";
 | |
|     }
 | |
| 
 | |
|     return $prefix . TeamSpeak3_Helper_String::factory(get_class($this))->section("_", 2)->toLower();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns a unique identifier for the node which can be used as a HTML property.
 | |
|    *
 | |
|    * @return string
 | |
|    */
 | |
|   abstract public function getUniqueId();
 | |
| 
 | |
|   /**
 | |
|    * Returns the name of a possible icon to display the node object.
 | |
|    *
 | |
|    * @return string
 | |
|    */
 | |
|   abstract public function getIcon();
 | |
| 
 | |
|   /**
 | |
|    * Returns a symbol representing the node.
 | |
|    *
 | |
|    * @return string
 | |
|    */
 | |
|   abstract public function getSymbol();
 | |
| 
 | |
|   /**
 | |
|    * Returns the HTML code to display a TeamSpeak 3 viewer.
 | |
|    *
 | |
|    * @param  TeamSpeak3_Viewer_Interface $viewer
 | |
|    * @return string
 | |
|    */
 | |
|   public function getViewer(TeamSpeak3_Viewer_Interface $viewer)
 | |
|   {
 | |
|     $html = $viewer->fetchObject($this);
 | |
| 
 | |
|     $iterator = new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST);
 | |
| 
 | |
|     foreach($iterator as $node)
 | |
|     {
 | |
|       $siblings = array();
 | |
| 
 | |
|       for($level = 0; $level < $iterator->getDepth(); $level++)
 | |
|       {
 | |
|         $siblings[] = ($iterator->getSubIterator($level)->hasNext()) ? 1 : 0;
 | |
|       }
 | |
| 
 | |
|       $siblings[] = (!$iterator->getSubIterator($level)->hasNext()) ? 1 : 0;
 | |
| 
 | |
|       $html .= $viewer->fetchObject($node, $siblings);
 | |
|     }
 | |
| 
 | |
|     return $html;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Filters given node list array using specified filter rules.
 | |
|    *
 | |
|    * @param  array $nodes
 | |
|    * @param  array $rules
 | |
|    * @return array
 | |
|    */
 | |
|   protected function filterList(array $nodes = array(), array $rules = array())
 | |
|   {
 | |
|     if(!empty($rules))
 | |
|     {
 | |
|       foreach($nodes as $node)
 | |
|       {
 | |
|         if(!$node instanceof TeamSpeak3_Node_Abstract) continue;
 | |
| 
 | |
|         $props = $node->getInfo(FALSE);
 | |
|         $props = array_intersect_key($props, $rules);
 | |
| 
 | |
|         foreach($props as $key => $val)
 | |
|         {
 | |
|           if($val instanceof TeamSpeak3_Helper_String)
 | |
|           {
 | |
|             $match = $val->contains($rules[$key], TRUE);
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             $match = $val == $rules[$key];
 | |
|           }
 | |
| 
 | |
|           if($match === FALSE)
 | |
|           {
 | |
|             unset($nodes[$node->getId()]);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return $nodes;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns all information available on this node. If $convert is enabled, some property
 | |
|    * values will be converted to human-readable values.
 | |
|    *
 | |
|    * @param  boolean $extend
 | |
|    * @param  boolean $convert
 | |
|    * @return array
 | |
|    */
 | |
|   public function getInfo($extend = TRUE, $convert = FALSE)
 | |
|   {
 | |
|     if($extend)
 | |
|     {
 | |
|       $this->fetchNodeInfo();
 | |
|     }
 | |
| 
 | |
|     if($convert)
 | |
|     {
 | |
|       $info = $this->nodeInfo;
 | |
| 
 | |
|       foreach($info as $key => $val)
 | |
|       {
 | |
|         $key = TeamSpeak3_Helper_String::factory($key);
 | |
| 
 | |
|         if($key->contains("_bytes_"))
 | |
|         {
 | |
|           $info[$key->toString()] = TeamSpeak3_Helper_Convert::bytes($val);
 | |
|         }
 | |
|         elseif($key->contains("_bandwidth_"))
 | |
|         {
 | |
|           $info[$key->toString()] = TeamSpeak3_Helper_Convert::bytes($val) . "/s";
 | |
|         }
 | |
|         elseif($key->contains("_packets_"))
 | |
|         {
 | |
|           $info[$key->toString()] = number_format($val, null, null, ".");
 | |
|         }
 | |
|         elseif($key->contains("_packetloss_"))
 | |
|         {
 | |
|           $info[$key->toString()] = sprintf("%01.2f", floatval($val->toString())*100) . "%";
 | |
|         }
 | |
|         elseif($key->endsWith("_uptime"))
 | |
|         {
 | |
|           $info[$key->toString()] = TeamSpeak3_Helper_Convert::seconds($val);
 | |
|         }
 | |
|         elseif($key->endsWith("_version"))
 | |
|         {
 | |
|           $info[$key->toString()] = TeamSpeak3_Helper_Convert::version($val);
 | |
|         }
 | |
|         elseif($key->endsWith("_icon_id"))
 | |
|         {
 | |
|           $info[$key->toString()] = $this->iconGetName($key)->filterDigits();
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       return $info;
 | |
|     }
 | |
| 
 | |
|     return $this->nodeInfo;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns the specified property or a pre-defined default value from the node info array.
 | |
|    *
 | |
|    * @param  string $property
 | |
|    * @param  mixed  $default
 | |
|    * @return mixed
 | |
|    */
 | |
|   public function getProperty($property, $default = null)
 | |
|   {
 | |
|     if(!$this->offsetExists($property))
 | |
|     {
 | |
|       $this->fetchNodeInfo();
 | |
|     }
 | |
| 
 | |
|     if(!$this->offsetExists($property))
 | |
|     {
 | |
|       return $default;
 | |
|     }
 | |
| 
 | |
|     return $this->nodeInfo[(string) $property];
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns a string representation of this node.
 | |
|    *
 | |
|    * @return string
 | |
|    */
 | |
|   public function __toString()
 | |
|   {
 | |
|     return get_class($this);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns a string representation of this node.
 | |
|    *
 | |
|    * @return string
 | |
|    */
 | |
|   public function toString()
 | |
|   {
 | |
|     return $this->__toString();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns an assoc array filled with current node info properties.
 | |
|    *
 | |
|    * @return array
 | |
|    */
 | |
|   public function toArray()
 | |
|   {
 | |
|     return $this->nodeList;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Called whenever we're using an unknown method.
 | |
|    *
 | |
|    * @param  string $name
 | |
|    * @param  array  $args
 | |
|    * @throws TeamSpeak3_Node_Exception
 | |
|    * @return mixed
 | |
|    */
 | |
|   public function __call($name, array $args)
 | |
|   {
 | |
|     if($this->getParent() instanceof TeamSpeak3_Node_Abstract)
 | |
|     {
 | |
|       return call_user_func_array(array($this->getParent(), $name), $args);
 | |
|     }
 | |
| 
 | |
|     throw new TeamSpeak3_Node_Exception("node method '" . $name . "()' does not exist");
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Writes data to the internal storage array.
 | |
|    *
 | |
|    * @param  string $key
 | |
|    * @param  mixed  $val
 | |
|    * @return void
 | |
|    */
 | |
|   protected function setStorage($key, $val)
 | |
|   {
 | |
|     $this->storage[$key] = $val;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Returns data from the internal storage array.
 | |
|    *
 | |
|    * @param  string $key
 | |
|    * @param  mixed  $default
 | |
|    * @return mixed
 | |
|    */
 | |
|   protected function getStorage($key, $default = null)
 | |
|   {
 | |
|     return !empty($this->storage[$key]) ? $this->storage[$key] : $default;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Deletes data from the internal storage array.
 | |
|    *
 | |
|    * @param  string $key
 | |
|    * @return void
 | |
|    */
 | |
|   protected function delStorage($key)
 | |
|   {
 | |
|     unset($this->storage[$key]);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Commit pending data.
 | |
|    *
 | |
|    * @return array
 | |
|    */
 | |
|   public function __sleep()
 | |
|   {
 | |
|     return array("parent", "storage", "nodeId");
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected function fetchNodeList()
 | |
|   {
 | |
|     $this->nodeList = array();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected function fetchNodeInfo()
 | |
|   {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected function resetNodeInfo()
 | |
|   {
 | |
|     $this->nodeInfo = array();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected function verifyNodeList()
 | |
|   {
 | |
|     if($this->nodeList === null)
 | |
|     {
 | |
|       $this->fetchNodeList();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   protected function resetNodeList()
 | |
|   {
 | |
|     $this->nodeList = null;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function count()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return count($this->nodeList);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function current()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return current($this->nodeList);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function getChildren()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return $this->current();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function hasChildren()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return $this->current()->count() > 0;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function hasNext()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return $this->key()+1 < $this->count();
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function key()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return key($this->nodeList);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function valid()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return $this->key() !== null;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function next()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return next($this->nodeList);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function rewind()
 | |
|   {
 | |
|     $this->verifyNodeList();
 | |
| 
 | |
|     return reset($this->nodeList);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function offsetExists($offset)
 | |
|   {
 | |
|     return array_key_exists((string) $offset, $this->nodeInfo) ? TRUE : FALSE;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function offsetGet($offset)
 | |
|   {
 | |
|     if(!$this->offsetExists($offset))
 | |
|     {
 | |
|       $this->fetchNodeInfo();
 | |
|     }
 | |
| 
 | |
|     if(!$this->offsetExists($offset))
 | |
|     {
 | |
|       throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid parameter", 0x602);
 | |
|     }
 | |
| 
 | |
|     return $this->nodeInfo[(string) $offset];
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function offsetSet($offset, $value)
 | |
|   {
 | |
|     if(method_exists($this, "modify"))
 | |
|     {
 | |
|       return $this->modify(array((string) $offset => $value));
 | |
|     }
 | |
| 
 | |
|     throw new TeamSpeak3_Node_Exception("node '" . get_class($this) . "' is read only");
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function offsetUnset($offset)
 | |
|   {
 | |
|     unset($this->nodeInfo[(string) $offset]);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function __get($offset)
 | |
|   {
 | |
|     return $this->offsetGet($offset);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * @ignore
 | |
|    */
 | |
|   public function __set($offset, $value)
 | |
|   {
 | |
|     $this->offsetSet($offset, $value);
 | |
|   }
 | |
| }
 |