7dc12f1d21b115bfb90626c4371c043d4f6f004c
1 <?php
2 /*
4 This code is part of GOsa (https://gosa.gonicus.de)
5 Copyright (C) 2008 Fabian Hickert
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 Function overview:
24 __construct - Create a new deamon handle.
25 connect - Connect to deamon socket.
26 disconnect - Disconnect from socket.
27 set_error - Sets a new error.
28 is_error - Returns TRUE if there was an error.
29 get_error - Returns the last error or "".
30 get_queued_entries - Returns all queued entries, with limitations.
31 ids_exist - Checks if the given id exists.
32 get_entries_by_id - Returns a set of entries.
33 id_exists - Checks if a set entries exists.
34 get_entry_by_id - Returns a single entry.
35 remove_entries - Remove a set of entries.
36 remove_entry - Removes a single entry.
37 update_entries - Updates a set of entries.
38 xml_to_array - XML to Array.
39 number_of_queued_entries - Returns the number of currently queued entries.
40 */
42 class gosaSupportDaemon
43 {
44 private $s_host = "";
45 private $i_port = 0;
46 private $s_encryption_key = "";
48 private $o_sock = NULL;
49 private $f_timeout = 2;
50 private $s_error = "";
51 private $b_error = FALSE;
53 private $is_connected = FALSE;
56 /*! \brief Creates a new gosaSupportDaemon object.
57 @param string Host The Host where the deamon is running on.
58 @param integer Port The port which the deamon use.
59 @param string Key The encryption string.
60 @param boolean Connect Directly connect to deamon socket.
61 @param float Timeout The timelimit for all socket actions.
62 */
63 public function __construct($connect=TRUE,$timeout=0.2)
64 {
65 #FIXME: bad idea about referencing global variables from within classes
66 global $config;
68 # load from config, store statically
69 if (isset($config->current['GOSA_SI'])){
71 if ($this->s_host == ""){
72 $this->s_host= preg_replace("/^.*@([^:]+):.*$/", "$1", $config->current['GOSA_SI']);
73 $this->i_port= preg_replace("/^.*@[^:]+:(.*)$/", "$1", $config->current['GOSA_SI']);
74 $this->s_encryption_key = preg_replace("/^(.*)@[^:]+:.*$/", "$1", $config->current['GOSA_SI']);
75 }
77 $this->f_timeout = $timeout;
78 if($connect){
79 $this->connect();
80 }
81 }
82 }
85 /*! \brief Establish deamon connection.
86 @return boolean Returns true if the connection was succesfully established.
87 */
88 public function connect()
89 {
90 $this->o_sock = new Socket_Client($this->s_host,$this->i_port,TRUE,$this->f_timeout);
91 if($this->o_sock->connected()){
92 $this->o_sock->setEncryptionKey($this->s_encryption_key);
93 $this->is_connected = TRUE;
94 }else{
95 $this->error = $this->o_sock->get_error();
96 $this->disconnect();
97 }
98 return($this->is_connected);
99 }
102 /*! \brief Disconnect from gosa deamon.
103 */
104 public function disconnect()
105 {
106 $this->o_sock->close();
107 $this->is_connected = FALSE;
108 }
111 /*! \brief Sets an error message, which can be returned with get_error().
112 @param string The Error message,
113 */
114 private function set_error($str)
115 {
116 $this->b_error = TRUE;
117 $this->s_error = $str;
118 }
121 /*! \brief Checks if an error occured.
122 @return boolean returns TRUE or FALSE, whether there is an error or not.
123 */
124 public function is_error()
125 {
126 return($this->b_error);
127 }
130 /*! \brief Returns the last error.
131 @return Returns the last error.
132 */
133 public function get_error()
134 {
135 return($this->s_error);
136 }
139 /*! \brief Returns an array containing all queued entries.
140 @return Array All queued entries as an array.
141 */
142 public function get_queued_entries($from=0,$to=10,$sort="timestamp DESC")
143 {
144 $this->b_error = FALSE;
145 $this->s_error = "";
146 $ret = array();
148 $xml_msg = "<xml>
149 <header>gosa_query_jobdb</header>
150 <where>
151 <clause>
152 <phrase>
153 <operator>ne</operator>
154 <HEADERTAG>*</HEADERTAG>
155 </phrase>
156 </clause>
157 </where>
158 <orderby>".$sort."</orderby>
159 <limit>
160 <from>".$from."</from>
161 <to>".$to."</to>
162 </limit>
163 </xml>";
165 if($this->connect()){
166 $this->o_sock->write($xml_msg);
167 $str = trim($this->o_sock->read());
168 $entries = $this->xml_to_array($str);
169 if(isset($entries['XML']) && is_array($entries['XML'])){
170 $ret = $entries;
171 }
172 }
174 return($ret);
175 }
178 /*! \brief Checks if the given ids are used queue ids.
179 @param Array The ids we want to check..
180 @return Array An array containing all ids as index and TRUE/FALSE as value.
181 */
182 public function ids_exist($ids)
183 {
184 if(!is_array($ids)){
185 trigger_error("Requires an array as parameter.");
186 return;
187 }
188 $this->b_error = FALSE;
189 $this->s_error = "";
191 $ret = array();
193 $xml_msg = "<xml>
194 <header>gosa_query_jobdb</header>
195 <where>
196 <clause>
197 <connector>or</connector>";
198 foreach($ids as $id){
199 $xml_msg .= "<phrase>
200 <operator>eq</operator>
201 <id>".$id."</id>
202 </phrase>";
203 }
204 $xml_msg .= "</clause>
205 </where>
206 </xml>";
208 if($this->connect()){
209 $this->o_sock->write($xml_msg);
210 $str = trim($this->o_sock->read());
211 $entries = $this->xml_to_array($str);
212 if(isset($entries['XML']) && is_array($entries['XML'])){
213 foreach($entries['XML'] as $entry){
214 $ret[] = $entry['ID'];
215 }
216 }
217 }
218 return($ret);
219 }
222 /*! \brief Returns an entry containing all requested ids.
223 @param Array The IDs of the entries we want to return.
224 @return Array Of the requested entries.
225 */
226 public function get_entries_by_id($ids)
227 {
228 if(!is_array($ids)){
229 trigger_error("Requires an array as parameter.");
230 return;
231 }
232 $this->b_error = FALSE;
233 $this->s_error = "";
235 $ret = array();
237 $xml_msg = "<xml>
238 <header>gosa_query_jobdb</header>
239 <where>
240 <clause>
241 <connector>or</connector>";
242 foreach($ids as $id){
243 $xml_msg .= "<phrase>
244 <operator>eq</operator>
245 <id>".$id."</id>
246 </phrase>";
247 $ret[$id] = FALSE;
248 }
249 $xml_msg .= "</clause>
250 </where>
251 </xml>";
253 if($this->connect()){
254 $this->o_sock->write($xml_msg);
255 $str = trim($this->o_sock->read());
256 $entries = $this->xml_to_array($str);
257 if(isset($entries['XML'])){
258 $ret = $entries['XML'];
259 }
260 }
261 return($ret);
262 }
265 /*! \brief Checks if the given id is in use.
266 @param Integer The ID of the entry.
267 @return Boolean TRUE if entry exists.
268 */
269 public function id_exists($id)
270 {
271 if(!is_numeric($id)){
272 trigger_error("Requires an integer as parameter.");
273 return;
274 }
276 $this->b_error = FALSE;
277 $this->s_error = "";
278 $xml_msg = "<xml>
279 <header>gosa_query_jobdb</header>
280 <where>
281 <clause>
282 <phrase>
283 <operator>eq</operator>
284 <id>".$id."</id>
285 </phrase>
286 </clause>
287 </where>
288 </xml>";
290 if($this->connect()){
291 $this->o_sock->write($xml_msg);
292 $str = trim($this->o_sock->read());
293 $entries = $this->xml_to_array($str);
294 if(isset($entries['XML']['ANSWER1'])){
295 return(TRUE);
296 }
297 }
298 return(FALSE);
299 }
302 /*! \brief Returns an entry from the gosaSupportQueue
303 @param Integer The ID of the entry we want to return.
304 @return Array Of the requested entry.
305 */
306 public function get_entry_by_id($id)
307 {
308 if(!is_numeric($id)){
309 trigger_error("Requires an integer as parameter.");
310 return;
311 }
313 $this->b_error = FALSE;
314 $this->s_error = "";
315 $ret = array();
316 $xml_msg = "<xml>
317 <header>gosa_query_jobdb</header>
318 <where>
319 <clause>
320 <phrase>
321 <operator>eq</operator>
322 <id>".$id."</id>
323 </phrase>
324 </clause>
325 </where>
326 </xml>";
327 if($this->connect()){
328 $this->o_sock->write($xml_msg);
329 $str = trim($this->o_sock->read());
330 $entries = $this->xml_to_array($str);
331 if(isset($entries['XML']['ANSWER1'])){
332 $ret = $entries['XML']['ANSWER1'];
333 }
334 }
335 return($ret);
336 }
339 /*! \brief Removes a set of entries from the GOsa support queue.
340 @param Array The IDs to remove.
341 @return Boolean True on success.
342 */
343 public function remove_entries($ids)
344 {
345 if(!is_array($ids)){
346 trigger_error("Requires an array as parameter.");
347 return;
348 }
349 $this->b_error = FALSE;
350 $this->s_error = "";
352 $ret = array();
354 $xml_msg = "<xml>
355 <header>gosa_delete_jobdb_entry</header>
356 <where>
357 <clause>
358 <connector>or</connector>";
359 foreach($ids as $id){
360 $xml_msg .= "<phrase>
361 <operator>eq</operator>
362 <id>".$id."</id>
363 </phrase>";
364 }
365 $xml_msg .= "</clause>
366 </where>
367 </xml>";
368 $this->b_error = FALSE;
369 $this->s_error = "";
371 if($this->connect()){
372 $this->o_sock->write($xml_msg);
373 $str = $this->o_sock->read();
374 $entries = $this->xml_to_array($str);
375 if(isset($entries['XML'])){
376 return(TRUE);
377 }
378 }
379 return(FALSE);
380 }
384 /*! \brief Removes an entry from the GOsa support queue.
385 @param Integer The ID of the entry we want to remove.
386 @return Boolean True on success.
387 */
388 public function remove_entry($id)
389 {
390 $this->b_error = FALSE;
391 $this->s_error = "";
393 $xml_msg = "<xml>
394 <header>gosa_delete_jobdb_entry</header>
395 <where>
396 <clause>
397 <phrase>
398 <operator>eq</operator>
399 <id>".$id."</id>
400 </phrase>
401 </clause>
402 </where>
403 </xml>";
404 if($this->connect()){
405 $this->o_sock->write($xml_msg);
406 $str = $this->o_sock->read();
407 $entries = $this->xml_to_array($str);
408 if(isset($entries['XML'])){
409 return(TRUE);
410 }
411 }
412 return(FALSE);
413 }
416 /*! \brief Parses the given xml string into an array
417 @param String XML string
418 @return Array Returns an array containing the xml structure.
419 */
420 private function xml_to_array($xml)
421 {
422 $params = array();
423 $level = array();
424 $parser = xml_parser_create_ns();
425 xml_parse_into_struct($parser, $xml, $vals, $index);
427 $err_id = xml_get_error_code($parser);
428 if($err_id){
429 xml_parser_free($parser);
430 }else{
431 xml_parser_free($parser);
433 foreach ($vals as $xml_elem) {
434 if ($xml_elem['type'] == 'open') {
435 if (array_key_exists('attributes',$xml_elem)) {
436 list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
437 } else {
438 $level[$xml_elem['level']] = $xml_elem['tag'];
439 }
440 }
441 if ($xml_elem['type'] == 'complete') {
442 $start_level = 1;
443 $php_stmt = '$params';
444 while($start_level < $xml_elem['level']) {
445 $php_stmt .= '[$level['.$start_level.']]';
446 $start_level++;
447 }
448 $php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
449 @eval($php_stmt);
450 }
451 }
452 }
454 if(!isset($params['XML'])){
455 if (!array_key_exists('XML', $params)){
456 $this->set_error(_("Could not parse XML."));
457 }
458 $params = array("COUNT" => 0);
459 }
461 return($params);
462 }
465 /*! \brief Updates an entry with a set of new values,
466 @param Integer The ID of the entry, we want to update.
467 @param Array The variables to update.
468 @return Boolean Returns TRUE on success.
469 */
470 public function update_entries($ids,$entry)
471 {
472 $this->b_error = FALSE;
473 $this->s_error = "";
474 if(!is_array($ids)){
475 trigger_error("Requires an array as first parameter.");
476 return;
477 }
479 if(!is_array($entry)){
480 trigger_error("Requires an array as second parameter.");
481 return;
482 }
484 $attr = "";
485 foreach($entry as $name => $entry){
486 $attr.="<".strtolower($name).">".$entry."</".strtolower($name).">\n";
487 }
488 $xml_msg = "<xml>
489 <header>gosa_update_status_jobdb_entry</header>
490 <where>
491 <clause>
492 <connector>or</connector>";
493 foreach($ids as $id){
494 $xml_msg .= "<phrase>
495 <operator>eq</operator>
496 <id>".$id."</id>
497 </phrase>";
498 }
499 $xml_msg .= "</clause>
500 </where>
501 <update>
502 ".$attr."
503 </update>
504 </xml>";
505 if($this->connect()){
506 $this->o_sock->write($xml_msg);
507 $str = trim($this->o_sock->read());
508 $entries = $this->xml_to_array($str);
509 if(isset($entries['XML'])){
510 return(TRUE);
511 }
512 }
513 return(FALSE);
514 }
517 /*! \brief Returns the number of currently queued objects.
518 @return Integer
519 */
520 public function number_of_queued_entries()
521 {
522 $xml_msg ="<xml><header>gosa_count_jobdb</header></xml>";
523 $this->connect();
524 if($this->connect()){
525 $this->o_sock->write($xml_msg);
526 $str = trim($this->o_sock->read());
527 $entries = $this->xml_to_array($str);
528 if(isset($entries['XML'])){
529 return($entries['XML']['COUNT']);
530 }
531 }
532 return(-1);
533 }
536 /*! \brief Returns an array containing all queued entries.
537 @return Array All queued entries as an array.
538 */
539 public function _send($data, $answer_expected= FALSE)
540 {
541 $this->b_error = FALSE;
542 $this->s_error = "";
543 $ret = array();
545 if($this->connect()){
546 $this->o_sock->write($data);
547 if ($answer_expected){
548 $str = trim($this->o_sock->read());
549 $entries = $this->xml_to_array($str);
550 if(isset($entries['XML']) && is_array($entries['XML'])){
551 $ret = $entries;
552 }
553 }
554 }
555 return($ret);
556 }
559 static function send($header, $to, $data= array())
560 {
561 $xml_message= "";
563 /* Get communication object */
564 $d= new gosaSupportDaemon(TRUE,10);
566 /* Prepare data */
567 foreach ($data as $key => $value){
568 $xml_message.= "<$key>$value</$key>";
569 }
571 return $d->_send("<xml><header>$header</header><source>GOSA</source><target>$to</target>".$xml_message."</xml>");
572 }
575 }
577 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
578 ?>