TeamSpeak 3 PHP Framework  1.1.23
Copyright © Planet TeamSpeak. All rights reserved.
 All Classes Namespaces Files Functions Variables Pages
ServerQuery.php
Go to the documentation of this file.
1 <?php
2 
3 /**
4  * @file
5  * TeamSpeak 3 PHP Framework
6  *
7  * $Id: ServerQuery.php 10/11/2013 11:35:21 scp@orilla $
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @package TeamSpeak3
23  * @version 1.1.23
24  * @author Sven 'ScP' Paulsen
25  * @copyright Copyright (c) 2010 by Planet TeamSpeak. All rights reserved.
26  */
27 
28 /**
29  * @class TeamSpeak3_Adapter_ServerQuery
30  * @brief Provides low-level methods for ServerQuery communication with a TeamSpeak 3 Server.
31  */
33 {
34  /**
35  * Stores a singleton instance of the active TeamSpeak3_Node_Host object.
36  *
37  * @var TeamSpeak3_Node_Host
38  */
39  protected $host = null;
40 
41  /**
42  * Stores the timestamp of the last command.
43  *
44  * @var integer
45  */
46  protected $timer = null;
47 
48  /**
49  * Number of queries executed on the server.
50  *
51  * @var integer
52  */
53  protected $count = 0;
54 
55  /**
56  * Stores an array with unsupported commands.
57  *
58  * @var array
59  */
60  protected $block = array("help");
61 
62  /**
63  * Connects the TeamSpeak3_Transport_Abstract object and performs initial actions on the remote
64  * server.
65  *
66  * @throws TeamSpeak3_Adapter_Exception
67  * @return void
68  */
69  protected function syn()
70  {
71  $this->initTransport($this->options);
72  $this->transport->setAdapter($this);
73 
74  TeamSpeak3_Helper_Profiler::init(spl_object_hash($this));
75 
76  if(!$this->getTransport()->readLine()->startsWith(TeamSpeak3::READY))
77  {
78  throw new TeamSpeak3_Adapter_Exception("invalid reply from the server");
79  }
80 
81  TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryConnected", $this);
82  }
83 
84  /**
85  * The TeamSpeak3_Adapter_ServerQuery destructor.
86  *
87  * @return void
88  */
89  public function __destruct()
90  {
91  if($this->getTransport() instanceof TeamSpeak3_Transport_Abstract && $this->transport->isConnected())
92  {
93  try
94  {
95  $this->request("quit");
96  }
97  catch(Exception $e)
98  {
99  return;
100  }
101  }
102  }
103 
104  /**
105  * Sends a prepared command to the server and returns the result.
106  *
107  * @param string $cmd
108  * @param boolean $throw
109  * @throws TeamSpeak3_Adapter_Exception
110  * @return TeamSpeak3_Adapter_ServerQuery_Reply
111  */
112  public function request($cmd, $throw = TRUE)
113  {
115 
116  if(strstr($cmd, "\r") || strstr($cmd, "\n"))
117  {
118  throw new TeamSpeak3_Adapter_Exception("illegal characters in command '" . $query . "'");
119  }
120  elseif(in_array($query, $this->block))
121  {
122  throw new TeamSpeak3_Adapter_ServerQuery_Exception("command not found", 0x100);
123  }
124 
125  TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandStarted", $cmd);
126 
127  $this->getProfiler()->start();
128  $this->getTransport()->sendLine($cmd);
129  $this->timer = time();
130  $this->count++;
131 
132  $rpl = array();
133 
134  do {
135  $str = $this->getTransport()->readLine();
136  $rpl[] = $str;
138 
139  $this->getProfiler()->stop();
140 
141  $reply = new TeamSpeak3_Adapter_ServerQuery_Reply($rpl, $cmd, $this->getHost(), $throw);
142 
143  TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandFinished", $cmd, $reply);
144 
145  return $reply;
146  }
147 
148  /**
149  * Waits for the server to send a notification message and returns the result.
150  *
151  * @throws TeamSpeak3_Adapter_Exception
152  * @return TeamSpeak3_Adapter_ServerQuery_Event
153  */
154  public function wait()
155  {
156  if($this->getTransport()->getConfig("blocking"))
157  {
158  throw new TeamSpeak3_Adapter_Exception("only available in non-blocking mode");
159  }
160 
161  do {
162  $evt = $this->getTransport()->readLine();
163  } while($evt instanceof TeamSpeak3_Helper_String && !$evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT));
164 
165  return new TeamSpeak3_Adapter_ServerQuery_Event($evt, $this->getHost());
166  }
167 
168  /**
169  * Uses given parameters and returns a prepared ServerQuery command.
170  *
171  * @param string $cmd
172  * @param array $params
173  * @return string
174  */
175  public function prepare($cmd, array $params = array())
176  {
177  $args = array();
178  $cells = array();
179 
180  foreach($params as $ident => $value)
181  {
182  $ident = is_numeric($ident) ? "" : strtolower($ident) . TeamSpeak3::SEPARATOR_PAIR;
183 
184  if(is_array($value))
185  {
186  $value = array_values($value);
187 
188  for($i = 0; $i < count($value); $i++)
189  {
190  if($value[$i] === null) continue;
191  elseif($value[$i] === FALSE) $value[$i] = 0x00;
192  elseif($value[$i] === TRUE) $value[$i] = 0x01;
193  elseif($value[$i] instanceof TeamSpeak3_Node_Abstract) $value[$i] = $value[$i]->getId();
194 
195  $cells[$i][] = $ident . TeamSpeak3_Helper_String::factory($value[$i])->escape()->toUtf8();
196  }
197  }
198  else
199  {
200  if($value === null) continue;
201  elseif($value === FALSE) $value = 0x00;
202  elseif($value === TRUE) $value = 0x01;
203  elseif($value instanceof TeamSpeak3_Node_Abstract) $value = $value->getId();
204 
205  $args[] = $ident . TeamSpeak3_Helper_String::factory($value)->escape()->toUtf8();
206  }
207  }
208 
209  foreach(array_keys($cells) as $ident) $cells[$ident] = implode(TeamSpeak3::SEPARATOR_CELL, $cells[$ident]);
210 
211  if(count($args)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_CELL, $args);
212  if(count($cells)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_LIST, $cells);
213 
214  return trim($cmd);
215  }
216 
217  /**
218  * Returns the timestamp of the last command.
219  *
220  * @return integer
221  */
222  public function getQueryLastTimestamp()
223  {
224  return $this->timer;
225  }
226 
227  /**
228  * Returns the number of queries executed on the server.
229  *
230  * @return integer
231  */
232  public function getQueryCount()
233  {
234  return $this->count;
235  }
236 
237  /**
238  * Returns the total runtime of all queries.
239  *
240  * @return mixed
241  */
242  public function getQueryRuntime()
243  {
244  return $this->getProfiler()->getRuntime();
245  }
246 
247  /**
248  * Returns the TeamSpeak3_Node_Host object of the current connection.
249  *
250  * @return TeamSpeak3_Node_Host
251  */
252  public function getHost()
253  {
254  if($this->host === null)
255  {
256  $this->host = new TeamSpeak3_Node_Host($this);
257  }
258 
259  return $this->host;
260  }
261 }