TeamSpeak 3 PHP Framework
1.1.12
|
00001 <?php 00002 00003 /** 00004 * @file 00005 * TeamSpeak 3 PHP Framework 00006 * 00007 * $Id: Abstract.php 2/18/2012 12:42:46 scp@orilla $ 00008 * 00009 * This program is free software: you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation, either version 3 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 * @package TeamSpeak3 00023 * @version 1.1.12 00024 * @author Sven 'ScP' Paulsen 00025 * @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved. 00026 */ 00027 00028 /** 00029 * @class TeamSpeak3_Node_Abstract 00030 * @brief Abstract class describing a TeamSpeak 3 node and all it's parameters. 00031 */ 00032 abstract class TeamSpeak3_Node_Abstract implements RecursiveIterator, ArrayAccess, Countable 00033 { 00034 /** 00035 * @ignore 00036 */ 00037 protected $parent = null; 00038 00039 /** 00040 * @ignore 00041 */ 00042 protected $server = null; 00043 00044 /** 00045 * @ignore 00046 */ 00047 protected $nodeId = 0x00; 00048 00049 /** 00050 * @ignore 00051 */ 00052 protected $nodeList = null; 00053 00054 /** 00055 * @ignore 00056 */ 00057 protected $nodeInfo = array(); 00058 00059 /** 00060 * @ignore 00061 */ 00062 protected $storage = array(); 00063 00064 /** 00065 * Sends a prepared command to the server and returns the result. 00066 * 00067 * @param string $cmd 00068 * @return TeamSpeak3_Adapter_ServerQuery_Reply 00069 */ 00070 public function request($cmd) 00071 { 00072 return $this->getParent()->request($cmd); 00073 } 00074 00075 /** 00076 * Uses given parameters and returns a prepared ServerQuery command. 00077 * 00078 * @param string $cmd 00079 * @param array $params 00080 * @return TeamSpeak3_Helper_String 00081 */ 00082 public function prepare($cmd, array $params = array()) 00083 { 00084 return $this->getParent()->prepare($cmd, $params); 00085 } 00086 00087 /** 00088 * Prepares and executes a ServerQuery command and returns the result. 00089 * 00090 * @param string $cmd 00091 * @param array $params 00092 * @return TeamSpeak3_Adapter_ServerQuery_Reply 00093 */ 00094 public function execute($cmd, array $params = array()) 00095 { 00096 return $this->request($this->prepare($cmd, $params)); 00097 } 00098 00099 /** 00100 * Returns the parent object of the current node. 00101 * 00102 * @return TeamSpeak3_Adapter_ServerQuery 00103 * @return TeamSpeak3_Node_Abstract 00104 */ 00105 public function getParent() 00106 { 00107 return $this->parent; 00108 } 00109 00110 /** 00111 * Returns the primary ID of the current node. 00112 * 00113 * @return integer 00114 */ 00115 public function getId() 00116 { 00117 return $this->nodeId; 00118 } 00119 00120 /** 00121 * Returns TRUE if the node icon has a local source. 00122 * 00123 * @return boolean 00124 */ 00125 public function iconIsLocal($key) 00126 { 00127 return ($this[$key] > 0 && $this[$key] < 1000) ? TRUE : FALSE; 00128 } 00129 00130 /** 00131 * Returns the internal path of the node icon. 00132 * 00133 * @return TeamSpeak3_Helper_String 00134 */ 00135 public function iconGetName($key) 00136 { 00137 $iconid = ($this[$key] < 0) ? (pow(2, 32))-($this[$key]*-1) : $this[$key]; 00138 00139 return new TeamSpeak3_Helper_String("/icon_" . $iconid); 00140 } 00141 00142 /** 00143 * Returns a possible classname for the node which can be used as a HTML property. 00144 * 00145 * @return string 00146 */ 00147 public function getClass($prefix = "ts3_") 00148 { 00149 if($this instanceof TeamSpeak3_Node_Channel && $this->isSpacer()) 00150 { 00151 return $prefix . "spacer"; 00152 } 00153 elseif($this instanceof TeamSpeak3_Node_Client && $this["client_type"]) 00154 { 00155 return $prefix . "query"; 00156 } 00157 00158 return $prefix . TeamSpeak3_Helper_String::factory(get_class($this))->section("_", 2)->toLower(); 00159 } 00160 00161 /** 00162 * Returns a unique identifier for the node which can be used as a HTML property. 00163 * 00164 * @return string 00165 */ 00166 abstract public function getUniqueId(); 00167 00168 /** 00169 * Returns the name of a possible icon to display the node object. 00170 * 00171 * @return string 00172 */ 00173 abstract public function getIcon(); 00174 00175 /** 00176 * Returns a symbol representing the node. 00177 * 00178 * @return string 00179 */ 00180 abstract public function getSymbol(); 00181 00182 /** 00183 * Returns the HTML code to display a TeamSpeak 3 viewer. 00184 * 00185 * @param TeamSpeak3_Viewer_Interface $viewer 00186 * @return string 00187 */ 00188 public function getViewer(TeamSpeak3_Viewer_Interface $viewer) 00189 { 00190 $html = $viewer->fetchObject($this); 00191 00192 $iterator = new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST); 00193 00194 foreach($iterator as $node) 00195 { 00196 $siblings = array(); 00197 00198 for($level = 0; $level < $iterator->getDepth(); $level++) 00199 { 00200 $siblings[] = ($iterator->getSubIterator($level)->hasNext()) ? 1 : 0; 00201 } 00202 00203 $siblings[] = (!$iterator->getSubIterator($level)->hasNext()) ? 1 : 0; 00204 00205 $html .= $viewer->fetchObject($node, $siblings); 00206 } 00207 00208 return $html; 00209 } 00210 00211 /** 00212 * Filters given node list array using specified filter rules. 00213 * 00214 * @param array $nodes 00215 * @param array $rules 00216 * @return array 00217 */ 00218 protected function filterList(array $nodes = array(), array $rules = array()) 00219 { 00220 if(!empty($rules)) 00221 { 00222 foreach($nodes as $node) 00223 { 00224 if(!$node instanceof TeamSpeak3_Node_Abstract) continue; 00225 00226 $props = $node->getInfo(FALSE); 00227 $props = array_intersect_key($props, $rules); 00228 $match = TRUE; 00229 00230 foreach($props as $key => $val) 00231 { 00232 if($val instanceof TeamSpeak3_Helper_String) 00233 { 00234 $match = $val->contains($rules[$key], TRUE); 00235 } 00236 else 00237 { 00238 $match = $val == $rules[$key]; 00239 } 00240 00241 if($match === FALSE) 00242 { 00243 unset($nodes[$node->getId()]); 00244 } 00245 } 00246 } 00247 } 00248 00249 return $nodes; 00250 } 00251 00252 /** 00253 * Returns all information available on this node. If $convert is enabled, some property 00254 * values will be converted to human-readable values. 00255 * 00256 * @param boolean $extend 00257 * @param boolean $convert 00258 * @return array 00259 */ 00260 public function getInfo($extend = TRUE, $convert = FALSE) 00261 { 00262 if($extend) 00263 { 00264 $this->fetchNodeInfo(); 00265 } 00266 00267 if($convert) 00268 { 00269 $info = $this->nodeInfo; 00270 00271 foreach($info as $key => $val) 00272 { 00273 $key = TeamSpeak3_Helper_String::factory($key); 00274 00275 if($key->contains("_bytes_")) 00276 { 00277 $info[$key->toString()] = TeamSpeak3_Helper_Convert::bytes($val); 00278 } 00279 elseif($key->contains("_bandwidth_")) 00280 { 00281 $info[$key->toString()] = TeamSpeak3_Helper_Convert::bytes($val) . "/s"; 00282 } 00283 elseif($key->contains("_packets_")) 00284 { 00285 $info[$key->toString()] = number_format($val, null, null, "."); 00286 } 00287 elseif($key->contains("_packetloss_")) 00288 { 00289 $info[$key->toString()] = sprintf("%01.2f", floatval($val->toString())*100) . "%"; 00290 } 00291 elseif($key->endsWith("_uptime")) 00292 { 00293 $info[$key->toString()] = TeamSpeak3_Helper_Convert::seconds($val); 00294 } 00295 elseif($key->endsWith("_version")) 00296 { 00297 $info[$key->toString()] = TeamSpeak3_Helper_Convert::version($val); 00298 } 00299 elseif($key->endsWith("_icon_id")) 00300 { 00301 $info[$key->toString()] = $this->iconGetName($key)->filterDigits(); 00302 } 00303 } 00304 00305 return $info; 00306 } 00307 00308 return $this->nodeInfo; 00309 } 00310 00311 /** 00312 * Returns the specified property or a pre-defined default value from the node info array. 00313 * 00314 * @param string $property 00315 * @param mixed $default 00316 * @return mixed 00317 */ 00318 public function getProperty($property, $default = null) 00319 { 00320 if(!$this->offsetExists($property)) 00321 { 00322 $this->fetchNodeInfo(); 00323 } 00324 00325 if(!$this->offsetExists($property)) 00326 { 00327 return $default; 00328 } 00329 00330 return $this->nodeInfo[(string) $property]; 00331 } 00332 00333 /** 00334 * Returns a string representation of this node. 00335 * 00336 * @return string 00337 */ 00338 public function __toString() 00339 { 00340 return get_class($this); 00341 } 00342 00343 /** 00344 * Returns a string representation of this node. 00345 * 00346 * @return string 00347 */ 00348 public function toString() 00349 { 00350 return $this->__toString(); 00351 } 00352 00353 /** 00354 * Returns an assoc array filled with current node info properties. 00355 * 00356 * @return array 00357 */ 00358 public function toArray() 00359 { 00360 return $this->nodeList; 00361 } 00362 00363 /** 00364 * Called whenever we're using an unknown method. 00365 * 00366 * @param string $name 00367 * @param array $args 00368 * @throws TeamSpeak3_Node_Exception 00369 * @return mixed 00370 */ 00371 public function __call($name, array $args) 00372 { 00373 if($this->getParent() instanceof TeamSpeak3_Node_Abstract) 00374 { 00375 return call_user_func_array(array($this->getParent(), $name), $args); 00376 } 00377 00378 throw new TeamSpeak3_Node_Exception("node method '" . $name . "()' does not exist"); 00379 } 00380 00381 /** 00382 * Writes data to the internal storage array. 00383 * 00384 * @param string $key 00385 * @param mixed $val 00386 * @return void 00387 */ 00388 protected function setStorage($key, $val) 00389 { 00390 $this->storage[$key] = $val; 00391 } 00392 00393 /** 00394 * Returns data from the internal storage array. 00395 * 00396 * @param string $key 00397 * @param mixed $default 00398 * @return mixed 00399 */ 00400 protected function getStorage($key, $default = null) 00401 { 00402 return (array_key_exists($key, $this->storage) && !empty($this->storage[$key])) ? $this->storage[$key] : $default; 00403 } 00404 00405 /** 00406 * Deletes data from the internal storage array. 00407 * 00408 * @param string $key 00409 * @return void 00410 */ 00411 protected function delStorage($key) 00412 { 00413 unset($this->storage[$key]); 00414 } 00415 00416 /** 00417 * Commit pending data. 00418 * 00419 * @return array 00420 */ 00421 public function __sleep() 00422 { 00423 return array("parent", "storage", "nodeId"); 00424 } 00425 00426 /** 00427 * @ignore 00428 */ 00429 protected function fetchNodeList() 00430 { 00431 $this->nodeList = array(); 00432 } 00433 00434 /** 00435 * @ignore 00436 */ 00437 protected function fetchNodeInfo() 00438 { 00439 return; 00440 } 00441 00442 /** 00443 * @ignore 00444 */ 00445 protected function resetNodeInfo() 00446 { 00447 $this->nodeInfo = array(); 00448 } 00449 00450 /** 00451 * @ignore 00452 */ 00453 protected function verifyNodeList() 00454 { 00455 if($this->nodeList === null) 00456 { 00457 $this->fetchNodeList(); 00458 } 00459 } 00460 00461 /** 00462 * @ignore 00463 */ 00464 protected function resetNodeList() 00465 { 00466 $this->nodeList = null; 00467 } 00468 00469 /** 00470 * @ignore 00471 */ 00472 public function count() 00473 { 00474 $this->verifyNodeList(); 00475 00476 return count($this->nodeList); 00477 } 00478 00479 /** 00480 * @ignore 00481 */ 00482 public function current() 00483 { 00484 $this->verifyNodeList(); 00485 00486 return current($this->nodeList); 00487 } 00488 00489 /** 00490 * @ignore 00491 */ 00492 public function getChildren() 00493 { 00494 $this->verifyNodeList(); 00495 00496 return $this->current(); 00497 } 00498 00499 /** 00500 * @ignore 00501 */ 00502 public function hasChildren() 00503 { 00504 $this->verifyNodeList(); 00505 00506 return $this->current()->count() > 0; 00507 } 00508 00509 /** 00510 * @ignore 00511 */ 00512 public function hasNext() 00513 { 00514 $this->verifyNodeList(); 00515 00516 return $this->key()+1 < $this->count(); 00517 } 00518 00519 /** 00520 * @ignore 00521 */ 00522 public function key() 00523 { 00524 $this->verifyNodeList(); 00525 00526 return key($this->nodeList); 00527 } 00528 00529 /** 00530 * @ignore 00531 */ 00532 public function valid() 00533 { 00534 $this->verifyNodeList(); 00535 00536 return $this->key() !== null; 00537 } 00538 00539 /** 00540 * @ignore 00541 */ 00542 public function next() 00543 { 00544 $this->verifyNodeList(); 00545 00546 return next($this->nodeList); 00547 } 00548 00549 /** 00550 * @ignore 00551 */ 00552 public function rewind() 00553 { 00554 $this->verifyNodeList(); 00555 00556 return reset($this->nodeList); 00557 } 00558 00559 /** 00560 * @ignore 00561 */ 00562 public function offsetExists($offset) 00563 { 00564 return array_key_exists((string) $offset, $this->nodeInfo) ? TRUE : FALSE; 00565 } 00566 00567 /** 00568 * @ignore 00569 */ 00570 public function offsetGet($offset) 00571 { 00572 if(!$this->offsetExists($offset)) 00573 { 00574 $this->fetchNodeInfo(); 00575 } 00576 00577 if(!$this->offsetExists($offset)) 00578 { 00579 echo $offset; 00580 00581 throw new TeamSpeak3_Adapter_ServerQuery_Exception("invalid parameter", 0x602); 00582 } 00583 00584 return $this->nodeInfo[(string) $offset]; 00585 } 00586 00587 /** 00588 * @ignore 00589 */ 00590 public function offsetSet($offset, $value) 00591 { 00592 if(method_exists($this, "modify")) 00593 { 00594 return $this->modify(array((string) $offset => $value)); 00595 } 00596 00597 throw new TeamSpeak3_Node_Exception("node '" . get_class($this) . "' is read only"); 00598 } 00599 00600 /** 00601 * @ignore 00602 */ 00603 public function offsetUnset($offset) 00604 { 00605 unset($this->nodeInfo[(string) $offset]); 00606 } 00607 00608 /** 00609 * @ignore 00610 */ 00611 public function __get($offset) 00612 { 00613 return $this->offsetGet($offset); 00614 } 00615 00616 /** 00617 * @ignore 00618 */ 00619 public function __set($offset, $value) 00620 { 00621 $this->offsetSet($offset, $value); 00622 } 00623 }