TeamSpeak 3 PHP Framework  1.1.16
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 8/31/2012 11:06:09 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.16
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  * @throws TeamSpeak3_Adapter_Exception
109  * @return TeamSpeak3_Adapter_ServerQuery_Reply
110  */
111  public function request($cmd)
112  {
114 
115  if(strstr($cmd, "\r") || strstr($cmd, "\n"))
116  {
117  throw new TeamSpeak3_Adapter_Exception("illegal characters in command '" . $query . "'");
118  }
119  elseif(in_array($query, $this->block))
120  {
121  throw new TeamSpeak3_Adapter_ServerQuery_Exception("command not found", 0x100);
122  }
123 
124  TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandStarted", $cmd);
125 
126  $this->getProfiler()->start();
127  $this->getTransport()->sendLine($cmd);
128  $this->timer = time();
129  $this->count++;
130 
131  $rpl = array();
132 
133  do {
134  $str = $this->getTransport()->readLine();
135  $rpl[] = $str;
137 
138  $this->getProfiler()->stop();
139 
140  $reply = new TeamSpeak3_Adapter_ServerQuery_Reply($rpl, $cmd, $this->getHost());
141 
142  TeamSpeak3_Helper_Signal::getInstance()->emit("serverqueryCommandFinished", $cmd, $reply);
143 
144  return $reply;
145  }
146 
147  /**
148  * Waits for the server to send a notification message and returns the result.
149  *
150  * @throws TeamSpeak3_Adapter_Exception
151  * @return TeamSpeak3_Adapter_ServerQuery_Event
152  */
153  public function wait()
154  {
155  if($this->getTransport()->getConfig("blocking"))
156  {
157  throw new TeamSpeak3_Adapter_Exception("only available in non-blocking mode");
158  }
159 
160  do {
161  $evt = $this->getTransport()->readLine();
162  } while($evt instanceof TeamSpeak3_Helper_String && !$evt->section(TeamSpeak3::SEPARATOR_CELL)->startsWith(TeamSpeak3::EVENT));
163 
164  return new TeamSpeak3_Adapter_ServerQuery_Event($evt, $this->getHost());
165  }
166 
167  /**
168  * Uses given parameters and returns a prepared ServerQuery command.
169  *
170  * @param string $cmd
171  * @param array $params
172  * @return string
173  */
174  public function prepare($cmd, array $params = array())
175  {
176  $args = array();
177  $cells = array();
178 
179  foreach($params as $ident => $value)
180  {
181  $ident = is_numeric($ident) ? "" : strtolower($ident) . TeamSpeak3::SEPARATOR_PAIR;
182 
183  if(is_array($value))
184  {
185  $value = array_values($value);
186 
187  for($i = 0; $i < count($value); $i++)
188  {
189  if($value[$i] === null) continue;
190  elseif($value[$i] === FALSE) $value[$i] = 0x00;
191  elseif($value[$i] === TRUE) $value[$i] = 0x01;
192  elseif($value[$i] instanceof TeamSpeak3_Node_Abstract) $value[$i] = $value[$i]->getId();
193 
194  $cells[$i][] = $ident . TeamSpeak3_Helper_String::factory($value[$i])->escape()->toUtf8();
195  }
196  }
197  else
198  {
199  if($value === null) continue;
200  elseif($value === FALSE) $value = 0x00;
201  elseif($value === TRUE) $value = 0x01;
202  elseif($value instanceof TeamSpeak3_Node_Abstract) $value = $value->getId();
203 
204  $args[] = $ident . TeamSpeak3_Helper_String::factory($value)->escape()->toUtf8();
205  }
206  }
207 
208  foreach(array_keys($cells) as $ident) $cells[$ident] = implode(TeamSpeak3::SEPARATOR_CELL, $cells[$ident]);
209 
210  if(count($args)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_CELL, $args);
211  if(count($cells)) $cmd .= " " . implode(TeamSpeak3::SEPARATOR_LIST, $cells);
212 
213  return trim($cmd);
214  }
215 
216  /**
217  * Returns the timestamp of the last command.
218  *
219  * @return integer
220  */
221  public function getQueryLastTimestamp()
222  {
223  return $this->timer;
224  }
225 
226  /**
227  * Returns the number of queries executed on the server.
228  *
229  * @return integer
230  */
231  public function getQueryCount()
232  {
233  return $this->count;
234  }
235 
236  /**
237  * Returns the total runtime of all queries.
238  *
239  * @return mixed
240  */
241  public function getQueryRuntime()
242  {
243  return $this->getProfiler()->getRuntime();
244  }
245 
246  /**
247  * Returns the TeamSpeak3_Node_Host object of the current connection.
248  *
249  * @return TeamSpeak3_Node_Host
250  */
251  public function getHost()
252  {
253  if($this->host === null)
254  {
255  $this->host = new TeamSpeak3_Node_Host($this);
256  }
257 
258  return $this->host;
259  }
260 }