3namespace PlanetTeamSpeak\TeamSpeak3Framework\Node;
7use PlanetTeamSpeak\TeamSpeak3Framework\Adapter\ServerQuery;
8use PlanetTeamSpeak\TeamSpeak3Framework\Adapter\ServerQuery\Reply;
9use PlanetTeamSpeak\TeamSpeak3Framework\Exception\AdapterException;
10use PlanetTeamSpeak\TeamSpeak3Framework\Exception\NodeException;
11use PlanetTeamSpeak\TeamSpeak3Framework\Exception\ServerQueryException;
12use PlanetTeamSpeak\TeamSpeak3Framework\Helper\Convert;
13use PlanetTeamSpeak\TeamSpeak3Framework\Helper\StringHelper;
14use PlanetTeamSpeak\TeamSpeak3Framework\Viewer\ViewerInterface;
16use RecursiveIteratorIterator;
24abstract class Node implements RecursiveIterator, ArrayAccess, Countable
66 return $this->
getParent()->request($cmd, $throw);
123 $iconid = $this[$key];
124 if (!is_int($iconid)) {
125 $iconid = $iconid->toInt();
128 return $iconid > 0 && $iconid < 1000;
139 $iconid = $this[$key];
140 if (!is_int($iconid)) {
141 $iconid = $iconid->toInt();
144 $iconid = ($iconid < 0) ? (pow(2, 32)) - ($iconid * -1) : $iconid;
155 public function getClass(
string $prefix =
"ts3_"): string
157 if ($this instanceof
Channel && $this->isSpacer()) {
158 return $prefix .
"spacer";
159 } elseif ($this instanceof
Client && $this[
"client_type"]) {
160 return $prefix .
"query";
163 return $prefix . StringHelper::factory(get_class($this))->section(
"_", 2)->toLower();
197 $iterator =
new RecursiveIteratorIterator($this, RecursiveIteratorIterator::SELF_FIRST);
199 foreach ($iterator as $node) {
202 for ($level = 0; $level < $iterator->getDepth(); $level++) {
203 $siblings[] = ($iterator->getSubIterator($level)->
hasNext()) ? 1 : 0;
206 $siblings[] = (!$iterator->getSubIterator($level)->
hasNext()) ? 1 : 0;
211 if (empty($html) && method_exists($viewer,
"toString")) {
212 return $viewer->toString();
225 protected function filterList(array $nodes = [], array $rules = []): array
227 if (!empty($rules)) {
228 foreach ($nodes as $node) {
229 if (!$node instanceof
Node) {
233 $props = $node->getInfo(
false);
234 $props = array_intersect_key($props, $rules);
236 foreach ($props as $key => $val) {
238 $match = $val->contains($rules[$key],
true);
240 $match = $val == $rules[$key];
243 if ($match ===
false) {
244 unset($nodes[$node->getId()]);
261 public function getInfo(
bool $extend =
true,
bool $convert =
false): array
270 foreach ($info as $key => $val) {
271 $key = StringHelper::factory($key);
273 if ($key->contains(
"_bytes_")) {
274 $info[$key->toString()] = Convert::bytes($val);
275 } elseif ($key->contains(
"_bandwidth_")) {
276 $info[$key->toString()] = Convert::bytes($val) .
"/s";
277 } elseif ($key->contains(
"_packets_")) {
278 $info[$key->toString()] = number_format($val, 0,
null,
".");
279 } elseif ($key->contains(
"_packetloss_")) {
280 $info[$key->toString()] = sprintf(
"%01.2f", floatval($val instanceof
StringHelper ? $val->
toString() : strval($val)) * 100) .
"%";
281 } elseif ($key->endsWith(
"_uptime")) {
282 $info[$key->toString()] = Convert::seconds($val);
283 } elseif ($key->endsWith(
"_version")) {
284 $info[$key->toString()] = Convert::version($val);
285 } elseif ($key->endsWith(
"_icon_id")) {
286 $info[$key->toString()] = $this->
iconGetName($key)->filterDigits();
303 public function getProperty(
string $property, mixed $default =
null): mixed
313 return $this->nodeInfo[$property];
323 return get_class($this);
354 public function __call(
string $name, array $args)
357 return call_user_func_array([$this->
getParent(), $name], $args);
360 throw new NodeException(
"node method '" . $name .
"()' does not exist");
372 $this->storage[$key] = $val;
382 protected function getStorage(
string $key, mixed $default =
null): mixed
384 return !empty($this->storage[$key]) ? $this->storage[$key] : $default;
395 unset($this->storage[$key]);
405 return [
"parent",
"storage",
"nodeId"];
413 $this->nodeList = [];
428 $this->nodeInfo = [];
436 if ($this->nodeList ===
null) {
446 $this->nodeList =
null;
456 return count($this->nodeList);
466 return current($this->nodeList);
486 return $this->
current()->count() > 0;
496 return $this->
key() + 1 < $this->
count();
502 public function key(): string|int|null
506 return key($this->nodeList);
516 return $this->
key() !==
null;
526 next($this->nodeList);
536 reset($this->nodeList);
544 return array_key_exists((
string)$offset, $this->nodeInfo);
558 throw new NodeException(
"node '" . get_class($this) .
"' has no property named '" . $offset .
"'");
561 return $this->nodeInfo[(string)$offset];
570 if (method_exists($this,
"modify")) {
571 $this->modify([(
string)$offset => $value]);
575 throw new NodeException(
"node '" . get_class($this) .
"' is read only");
583 unset($this->nodeInfo[(
string)$offset]);
599 public function __set($offset, $value)
Provides methods to analyze and format a ServerQuery reply.
Enhanced exception class for PlanetTeamSpeak\TeamSpeak3Framework\Node\Node objects.
Helper class for string handling.
Class describing a TeamSpeak 3 channel and all it's parameters.
Class describing a TeamSpeak 3 client and all it's parameters.
Node null ServerQuery $parent
__call(string $name, array $args)
offsetSet($offset, $value)
filterList(array $nodes=[], array $rules=[])
execute($cmd, array $params=[])
request(string $cmd, bool $throw=true)
getClass(string $prefix="ts3_")
getViewer(ViewerInterface $viewer)
getStorage(string $key, mixed $default=null)
setStorage(string $key, mixed $val)
getInfo(bool $extend=true, bool $convert=false)
getProperty(string $property, mixed $default=null)
prepare(string $cmd, array $params=[])
fetchObject(Node $node, array $siblings=[])