1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id$$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
23 define("SCHEDULED_EVENT",1);
24 define("TRIGGERED_EVENT",2);
26 define("HIDDEN_EVENT",1);
27 define("SYSTEM_EVENT",2);
28 define("USER_EVENT" ,4);
31 /*! \brief This is the event base class
32 \author Fabian Hickert <hickert@gonicus.de>
33 \version 1.00
34 \date 26.02.2008
36 This is the base class for all new daemon events.
37 It implements most of the required functionality.
38 */
39 class DaemonEvent
40 {
41 /* Menu Strings */
42 protected $s_Menu_Name = "s_Menu_Name not set"; // Diplayed in the ActionsMenu->CreateNew
43 protected $s_Event_Name = "s_Event_Name not set"; // Will be displayed in the Management list.
44 protected $s_Menu_Image = "images/empty.png"; // Image displayed in Actions->New
45 protected $s_List_Image = ""; // Image displayed in event listing
47 public $config; // GOsa configuration object
48 protected $data; // The event data, when edited
50 protected $a_targets = array(); // The list of assigned Targets (When newly created)
51 protected $s_Schedule_Action = ""; // The deamon command name when newly created. (e.g. job_trigger_action_halt)
52 protected $s_Trigger_Action= ""; // The deamon command name when edited. (e.g. trigger_action_halt)
53 protected $s_Queued_Action= ""; // The deamon command name when edited. (e.g. trigger_action_halt)
54 public $timestamp = 0; // Event execution time;
55 public $time_offset = 0; // An offset when an event should start (normally not used)
56 public $concurrent_operations = 1; // Number of concurrent operations when a timestamp offset is used
57 protected $id = -1; // The Table ID
58 protected $status = "unknown";// The current event status
59 protected $is_new = TRUE; // Is TRUE if this is a new event
61 protected $mode = SCHEDULED_EVENT; // Default action is sheduled.
63 /* Sub dialog hanlding */
64 protected $target_divlist = NULL; // The divlist used by the target add dialog
65 protected $target_add_list_used = FALSE; // Indicates that the target add list was used.
66 protected $time_select_used = FALSE; // Indicates that we have used the timestamp select boxes.
67 protected $target_list_used = FALSE; // Target list was diaplayed?
68 protected $_target_list = array(); // Object Cache of those objects displayed in the target add dialog
69 protected $workstation_list = array(); // Used as cache in the target list.
70 protected $server_list = array(); // Used as cache in the target list.
72 protected $visible_for = HIDDEN_EVENT;
74 protected $attributes = array("timestamp");
76 protected $time_offset_used = FALSE;
78 /* Indicate that multiple events have to be created from this event */
79 public $multiple_events = FALSE;
82 function set_type($type)
83 {
84 $this->mode = $type;
85 }
88 function get_type()
89 {
90 return($this->mode);
91 }
93 /*! \brief Class contructor.
94 @param Array GOsa configuration object.
95 @param Array Event data, only given when edited.
96 */
97 public function __construct($config,$data = array())
98 {
99 $this->data = $data;
100 $this->config = $config;
101 timezone::get_default_timezone();
102 $this->timestamp = time();
104 /* Load values from given data */
105 if(count($data)){
106 $this->is_new = FALSE;
108 $attrs = array("id" => "ID");
109 foreach($attrs as $to => $from){
110 $this->$to = $data[$from];
111 }
112 if(isset($data['TIMESTAMP'])){
113 $this->timestamp = $this->_event_to_timestamp($data['TIMESTAMP']);
114 }
115 }
116 }
119 /*! \brief Create the HTML output for the plugin.
120 @return String The generated HTML output.
121 */
122 public function execute()
123 {
124 $this->time_select_used = FALSE;
125 $this->target_list_used = FALSE;
127 $str = "<h2>"._("This job has no template!")."</h2>";
128 $str.= "<p class='seperator'></p>";
129 $str.= "<div style='text-align:right;width:100%;padding:3px;'>
130 <input type='submit' name='abort_event_dialog' value='".msgPool::cancelButton()."'>
131 </div>";
132 return($str);
133 }
135 /*! \brief Returns the plugin header, displayed in the template.
136 @return String HTML header part.
137 */
138 public function get_header()
139 {
140 if($this->target_add_list_used){
141 return("");
142 }
143 $str = "<h2>".sprintf(_("Create '%s' job"),$this->s_Event_Name)."</h2>";
144 return($str);
145 }
148 /*! \brief Returns the plugin footer (save cancel), displayed in the template.
149 @return String HTML footer part.
150 */
151 public function get_footer()
152 {
153 if($this->target_add_list_used){
154 return("");
155 }
156 $str = "<p class='seperator'></p>";
157 $str.= "<div style='text-align:right;width:99%;padding:5px;'>
158 <input type='submit' name='save_event_dialog' value='".msgPool::saveButton()."'>
159 <input type='submit' name='abort_event_dialog' value='".msgPool::cancelButton()."'>
160 </div>";
161 return($str);
162 }
165 public function get_time_offset_select()
166 {
167 $this->time_offset_used = TRUE;
168 $smarty = get_smarty();
170 $opts_minutes = array();
171 $opts_operations = array();
172 foreach(range(0,120) as $i) {
173 $opts_minutes[$i] = $i;
174 }
175 foreach(range(1,100) as $i) {
176 $opts_operations[$i] = $i;
177 }
179 $smarty->assign('offset_minutes', $opts_minutes);
180 $smarty->assign('offset_operations', $opts_operations);
181 $smarty->assign('time_offset', $this->time_offset);
182 $smarty->assign('concurrent_operations', $this->concurrent_operations);
183 return($smarty->fetch(get_template_path('time_offset.tpl', TRUE, dirname(__FILE__))));
184 }
186 /*! \brief Returns HTML representation of a timestamp using <select> boxes.
187 @return Returns HTML content.
188 */
189 public function get_time_select()
190 {
191 timezone::get_default_timezone();
192 $this->time_select_used = TRUE;
194 $smarty = get_smarty();
196 $year = date("Y",$this->timestamp);
197 $month = date("m",$this->timestamp);
198 $day = date("d",$this->timestamp);
200 $hour = date("H",$this->timestamp);
201 $minute = date("i",$this->timestamp);
202 $second = date("s",$this->timestamp);
204 $years = array();
205 for($i = date("Y",time()); $i <= 2037 ;$i ++){
206 $years[$i] = $i;
207 }
208 $months = array();
209 for($i = 1; $i <= 12; $i ++){
210 $e = str_pad($i,2,"0",STR_PAD_LEFT);
211 $months[$e] = $e;
212 }
213 $days = array();
214 for($i = 1; $i <= cal_days_in_month(CAL_GREGORIAN,$month,$year); $i ++){
215 $e = str_pad($i,2,"0",STR_PAD_LEFT);
216 $days[$e] = $e;
217 }
218 $hours = array();
219 for($i = 0; $i < 24; $i ++){
220 $e = str_pad($i,2,"0",STR_PAD_LEFT);
221 $hours[$e] = $e;
222 }
223 $minutes = array();
224 for($i = 0; $i < 60; $i ++){
225 $e = str_pad($i,2,"0",STR_PAD_LEFT);
226 $minutes[$e] = $e;
227 }
228 $seconds = array();
229 for($i = 0; $i < 60; $i ++){
230 $e = str_pad($i,2,"0",STR_PAD_LEFT);
231 $seconds[$e] = $e;
232 }
234 $smarty->assign("years", $years);
235 $smarty->assign("months", $months);
236 $smarty->assign("days", $days);
237 $smarty->assign("hours", $hours);
238 $smarty->assign("minutes", $minutes);
239 $smarty->assign("seconds", $seconds);
240 $smarty->assign("time_year",$year);
241 $smarty->assign("time_month",$month);
242 $smarty->assign("time_day",$day);
243 $smarty->assign("time_hour",$hour);
244 $smarty->assign("time_minute",$minute);
245 $smarty->assign("time_second",$second);
246 return($smarty->fetch(get_template_path('timestamp_select.tpl', TRUE, dirname(__FILE__))));
247 }
250 /*! \brief HTML representation of all currently assigned targets using (divSelectBox).
251 @return String Returns a listbox with all used targets.
252 */
253 public function get_target_list()
254 {
255 $this->target_list_used = TRUE;
256 $divlist = new divSelectBox("EventTargets");
257 foreach($this->a_targets as $key => $target){
258 $string = "";
259 if (is_array($target) && isset($target['cn'])) {
260 $string = $target['cn'];
261 }
262 if (is_array($target) && isset($target['ogroup'])) {
263 $title = sprintf(_("Added via object group '%s'"), $target['ogroup']);
264 $string .= sprintf("<img src='plugins/ogroups/images/select_ogroup.png' title=\"%s\">", $title);
265 }
266 if (is_array($target) && isset($target['mac'])) {
267 $string .= " - " . $target['mac'];
268 }else {
269 $string = $target;
270 }
272 $divlist->AddEntry(array(
273 array("string" => $string),
274 array("string" => "<input type='image' src='images/lists/trash.png' title='"._("Remove")."' name='del_target_".$key."'>",
275 "attach" => "style='width:20px; border-right:0px;'")
276 ));
277 }
278 $list_footer = "<input type='submit' name='open_target_list' value='"._("Add")."'>";
279 return($divlist->DrawList().$list_footer);
280 }
283 /*! \brief Returns HTML content, displaying a dialog which allows to add new targets.
284 @return String HTML content. (EventTargetAddList)
285 */
286 public function get_target_add_list()
287 {
288 $this->target_add_list_used = TRUE;
290 if($this->target_divlist == NULL){
291 $this->target_divlist = new EventTargetAddList($this->config,$this);
292 }
293 $this->target_divlist->execute();
295 $smarty = get_smarty();
296 $smarty->assign("divlist",$this->target_divlist->Draw());
297 return($smarty->fetch(get_template_path('target_list.tpl', TRUE, dirname(__FILE__))));
298 }
301 /*! \brief Handles all posted HTML data, including target add,remove...
302 */
303 public function save_object()
304 {
305 if(isset($_POST['open_target_list'])){
306 $this->target_add_list_used =TRUE;
307 }
308 if($this->target_divlist != NULL){
309 $this->target_divlist->save_object();
310 }
311 if($this->target_add_list_used){
312 if(isset($_POST['abort_target_dialog'])){
313 $this->target_add_list_used =FALSE;
314 $this->target_divlist = NULL;
315 }
316 if(isset($_POST['save_target_dialog'])){
317 $this->target_add_list_used =FALSE;
318 $this->add_targets($this->target_divlist->get_selected_targets());
319 $this->target_divlist = NULL;
320 }
321 }
323 if (isset($_POST['concurrent_operations'])) {
324 $this->concurrent_operations = $_POST['concurrent_operations'];
325 }
326 if (isset($_POST['time_offset'])) {
327 $this->time_offset = $_POST['time_offset'];
328 }
330 if ($this->time_offset_used){
331 /* Check that multiple events makes sense at all (e.g. there are more targets
332 * then allowed concurrent operations */
333 if ($this->concurrent_operations != 0 && count($this->a_targets) > $this->concurrent_operations) {
334 if ($this->time_offset > 0) {
335 $this->multiple_events = TRUE;
336 }
337 }
338 }
340 if($this->time_select_used){
341 $time_stamp_values_found = TRUE;
342 foreach(array("time_year","time_month","time_day","time_hour","time_minute","time_second") as $attr){
343 $time_stamp_values_found &= isset($_POST[$attr]);
344 }
345 if($time_stamp_values_found){
346 /* Make sure the following conversion happens with the right timezone */
347 timezone::get_default_timezone();
349 $this->timestamp = mktime(
350 $_POST['time_hour'],
351 $_POST['time_minute'],
352 $_POST['time_second'],
353 $_POST['time_month'],
354 $_POST['time_day'],
355 $_POST['time_year']);
356 }
358 }
360 if($this->target_list_used){
361 foreach($_POST as $name => $value){
362 if(preg_match("/^del_target_/",$name)){
363 $id = preg_replace("/^del_target_([0-9]*)_.*/","\\1",$name);
364 if(isset($this->a_targets[$id])){
365 unset($this->a_targets[$id]);
366 }
367 break;
368 }
369 }
370 }
371 }
374 /*! \brief Converts a daemon timestamp into an unix timestamp. \
375 e.g. 20080101125959 -> 1199188799
376 @param A daemon timestamp YYYYddmmHHiiss
377 @return Integer A unix timestamp.
378 */
379 public function _event_to_timestamp($str)
380 {
381 return(strtotime($str));
382 }
385 /*! \brief Converts a unix timestamp in to a gosa-si timestamp. \
386 e.g. 1199188799 -> 20080101125959
387 @param A unix timestamp (e.g. 1199188799)
388 @return Integer A daemon timestamp (e.g. 20080101125959).
389 */
390 public function _timestamp_to_event($stamp)
391 {
392 return(date("YmdHis",$stamp));
393 }
396 /*! \brief Returns event information, like menu strings, images ...
397 @return Array Event informations.
398 */
399 public function get_event_info()
400 {
401 $data =array();
402 $data['CLASS_NAME'] = get_class($this);
403 $data['s_Menu_Name'] = $this->s_Menu_Name;
404 $data['s_Event_Name'] = $this->s_Event_Name;
405 foreach(array("s_Queued_Action","s_Schedule_Action","s_Trigger_Action") as $attr){
406 if(!empty($this->$attr)){
407 $data[$attr] = $this->$attr;
408 }
409 }
410 $data['MenuImage'] = "<img src='".$this->s_Menu_Image."' alt='".$this->s_Menu_Name."' border='0' class='center'>";
411 $data['ListImage'] = "<img src='".$this->s_List_Image."' title='".$this->s_Event_Name."'
412 alt='".$this->s_Event_Name."' border='0' class='center'>";
413 return($data);
414 }
417 /*! \brief Check if we have opened the target add dialog.
418 @return Boolean TRUE if we have opened the target add dialog else FALSE.
419 */
420 protected function is_target_list_open()
421 {
422 return($this->target_add_list_used);
423 }
426 /*! \brief Save an event dialog and check if multiple events needs to be created */
427 static function save_event_dialog($dialog, $current, $o_queue, $config)
428 {
429 if(is_object($dialog)){
430 $dialog->save_object();
431 if($dialog->multiple_events) {
432 $event_type = get_class($dialog);
433 $targets = $dialog->get_targets();
434 $timestamp = $dialog->timestamp;
436 $i = 1;
437 $count = count($targets);
438 while($i <= $count) {
439 $operations = $dialog->concurrent_operations;
440 $event = new $event_type($config);
441 $event->set_timestamp($timestamp);
442 $event->set_type(SCHEDULED_EVENT);
444 while($operations > 0) {
445 $i++;
446 $target = array_shift($targets);
447 $event->add_targets(array($target));
448 $operations--;
449 }
451 $event->save_object();
452 $event->get_targets();
453 if(!$o_queue->append($event)){
454 msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
455 }
457 # Calculate start time for the next run
458 $timestamp = $timestamp + ($dialog->time_offset*60);
459 }
461 return(array(FALSE, -1));
462 } else {
463 $dialog->save_object();
464 if(!$o_queue->append($dialog)){
465 msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
466 return(array($dialog, $current));
467 }else{
468 return(array(FALSE, -1));
469 }
470 }
471 }
472 }
474 /*! \brief Returns a complete list of all available events.
475 @return Array Containing $this->get_event_info() for all available events.
476 */
477 static function get_event_types($type)
478 {
479 global $class_mapping,$config;
480 $list = array();
481 $list['BY_CLASS'] = array();
482 $list['TRIGGERED'] = array();
483 $list['SCHEDULED'] = array();
484 $list['QUEUED'] = array();
486 foreach($class_mapping as $name => $path){
487 if(preg_match("/^DaemonEvent_/",$name)){
488 $tmp = new $name($config);
489 if($tmp->visible_for & $type){
490 $evt = $tmp->get_event_info();
491 $list['BY_CLASS'][$name] = $evt;
492 if(isset($evt['s_Trigger_Action'])){
493 $list['TRIGGERED'][$name] = $evt;
494 $list['QUEUED'][$evt['s_Trigger_Action']] = $name;
495 }
496 if(isset($evt['s_Schedule_Action'])){
497 $list['SCHEDULED'][$name] = $evt;
498 $list['QUEUED'][$evt['s_Schedule_Action']] = $name;
499 }
500 if(isset($evt['s_Queued_Action'])){
501 $list['QUEUED'][$evt['s_Queued_Action']] = $name;
502 }
503 }
504 }
505 }
506 return($list);
507 }
510 /*! \brief Returns TRUE if this event is new. (Not edited)
511 @return Boolean TRUE if new, else FALSE.
512 */
513 public function is_new()
514 {
515 return($this->is_new);
516 }
519 /*! \brief Returns the event tag to schedule a new action
520 @param Returns the event e.g. 'job_trigger_action_wake'
521 */
522 public function get_schedule_action()
523 {
524 return($this->s_Schedule_Action);
525 }
528 /*! \brief Returns the event tag to schedule a new action
529 @param Returns the event e.g. 'trigger_action_wake'
530 */
531 public function get_trigger_action()
532 {
533 return($this->s_Trigger_Action);
534 }
537 /*! brief Returns an array containig all attributes \
538 That should be written.
539 @return Array e.g. 'status' => 'bla blub'
540 */
541 public function save()
542 {
543 $ret = array();
544 foreach($this->attributes as $attr){
545 $ret[$attr] = $this->$attr;
546 }
548 if(!isset($ret['timestamp'])){
549 $ret['timestamp'] = time();
550 }
552 # Check if timestamp is in gosa-si-time-format
553 if(!tests::is_gosa_si_time($ret['timestamp'])){
554 $ret['timestamp'] = $this->_timestamp_to_event($this->timestamp);
555 }
557 return($ret);
558 }
561 /*! \brief Returns the event targets
562 @return Array All selected targets.
563 */
564 public function get_targets()
565 {
566 return($this->a_targets);
567 }
570 /*! \brief Returns the event timestamp in GOsa daemon format.
571 @return Returns the event timestamp (20081231120000)
572 */
573 public function get_timestamp($si_type = TRUE)
574 {
575 if($si_type){
576 return($this->_timestamp_to_event($this->timestamp));
577 }else{
578 return($this->timestamp);
579 }
580 }
583 /*! \brief Returns the event ID
584 @return Returns the event ID
585 */
586 public function get_id()
587 {
588 if($this->is_new){
589 return(-1);
590 }else{
591 return($this->data['ID']);
592 }
593 }
596 /*! \brief Add a target MAC address
597 @param Array A List of all target that should be added.
598 */
599 public function set_timestamp($stamp)
600 {
601 $this->timestamp = $stamp;
602 }
605 /*! \brief Add a target MAC address
606 @param Array A List of all target that should be added.
607 */
608 public function add_targets($targets)
609 {
610 foreach($targets as $target){
611 $this->a_targets[] = $target;
612 }
613 }
615 public function check()
616 {
617 return(array());
618 }
621 /*! \brief Update a class variable from outside
622 */
623 public function set_value($name,$value)
624 {
625 $name = strtolower($name);
626 if(isset($this->$name) && in_array($name,$this->attributes)){
627 $this->$name = $value;
628 }
629 }
630 }
632 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
633 ?>