Code

Bugfix for #4721
[gosa.git] / trunk / gosa-plugins / goto / addons / goto / events / class_DaemonEvent.inc
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;
81  
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()."'>&nbsp;
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();
169     
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     }
329     
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         $tmp_array[0] = $targets[0];
435         foreach ($targets as $current) {
436           $add_flag = 1;
437           foreach ($tmp_array as $tmp) {
438             if ($current["mac"]==$tmp["mac"]) {
439               $add_flag = 0; break;
440             }
441           }
442           if ($add_flag) $tmp_array[] = $current;
443         }
444         $targets = $tmp_array;
445         $timestamp = $dialog->timestamp;
447         $i = 1;
448         $count = count($targets);
449         while($i <= $count) {
450           $operations = $dialog->concurrent_operations;
451           $event = new $event_type($config);
452           $event->set_timestamp($timestamp);
453           $event->set_type(SCHEDULED_EVENT);
455           while($operations > 0) {
456             $i++;
457             $target = array_shift($targets);
458             $event->add_targets(array($target));
459             $operations--;
460           }
462           $event->save_object();
463           $event->get_targets();
464           if(!$o_queue->append($event)){
465             msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
466           }
468           # Calculate start time for the next run
469           $timestamp = $timestamp + ($dialog->time_offset*60);
470        }
472        return(array(FALSE, -1));
473      } else {
474        $dialog->save_object();
475        if(!$o_queue->append($dialog)){
476         msg_dialog::display(_("Service infrastructure"),msgPool::siError($o_queue->get_error()),ERROR_DIALOG);
477         return(array($dialog, $current));
478        }else{
479         return(array(FALSE, -1));
480        } 
481      }
482    }
485   /*! \brief  Returns a complete list of all available events.
486     @return   Array   Containing $this->get_event_info() for all available events.
487    */
488   static function get_event_types($type)
489   {
490     global $class_mapping,$config;
491     $list = array();
492     $list['BY_CLASS']  = array();
493     $list['TRIGGERED'] = array();
494     $list['SCHEDULED'] = array();
495     $list['QUEUED']    = array();
497     foreach($class_mapping as $name => $path){
498       if(preg_match("/^DaemonEvent_/",$name)){
499         $tmp  = new $name($config);
500         if($tmp->visible_for & $type){
501           $evt  = $tmp->get_event_info();
502           $list['BY_CLASS'][$name]                      = $evt;
503           if(isset($evt['s_Trigger_Action'])){
504             $list['TRIGGERED'][$name] = $evt;
505             $list['QUEUED'][$evt['s_Trigger_Action']] = $name;
506           }
507           if(isset($evt['s_Schedule_Action'])){
508             $list['SCHEDULED'][$name] = $evt;
509             $list['QUEUED'][$evt['s_Schedule_Action']] = $name;
510           }
511           if(isset($evt['s_Queued_Action'])){
512             $list['QUEUED'][$evt['s_Queued_Action']] = $name;
513           }
514         }
515       }
516     }
517     return($list);
518   }
521   /*! \brief  Returns TRUE if this event is new. (Not edited)
522     @return Boolean TRUE if new, else FALSE.
523    */
524   public function is_new()
525   {
526     return($this->is_new);
527   }
530   /*! \brief  Returns the event tag to schedule a new action 
531     @param    Returns the event e.g. 'job_trigger_action_wake'
532    */
533   public function get_schedule_action()
534   {
535     return($this->s_Schedule_Action);
536   }
539   /*! \brief  Returns the event tag to schedule a new action 
540     @param    Returns the event e.g. 'trigger_action_wake'
541    */
542   public function get_trigger_action()
543   {
544     return($this->s_Trigger_Action);
545   }
548   /*! brief  Returns an array containig all attributes \
549     That should be written.
550     @return Array e.g. 'status' => 'bla blub'  
551    */ 
552   public function save()
553   {
554     $ret = array();
555     foreach($this->attributes as $attr){
556       $ret[$attr] = $this->$attr;
557     }
559     if(!isset($ret['timestamp'])){
560       $ret['timestamp'] = time();
561     }
563     # Check if timestamp is in gosa-si-time-format 
564     if(!tests::is_gosa_si_time($ret['timestamp'])){ 
565       $ret['timestamp'] = $this->_timestamp_to_event($this->timestamp); 
566     }
568     return($ret);
569   }
572   /*! \brief  Returns the event targets
573     @return Array  All selected targets.
574    */ 
575   public function get_targets()
576   {
577     return($this->a_targets);
578   }
581   /*! \brief  Returns the event timestamp in GOsa daemon format. 
582     @return Returns the event timestamp (20081231120000)
583    */
584   public function get_timestamp($si_type = TRUE)
585   {
586     if($si_type){
587       return($this->_timestamp_to_event($this->timestamp));
588     }else{
589       return($this->timestamp);
590     }
591   }
594   /*! \brief  Returns the event ID
595     @return Returns the event ID
596    */
597   public function get_id()
598   {
599     if($this->is_new){
600       return(-1);
601     }else{
602       return($this->data['ID']);
603     }
604   }
607   /*! \brief Add a target MAC address 
608       @param Array A List of all target that should be added.
609    */
610   public function set_timestamp($stamp) 
611   {
612     $this->timestamp = $stamp;
613   }
616   /*! \brief Add a target MAC address 
617       @param Array A List of all target that should be added.
618    */
619   public function add_targets($targets) 
620   {
621     foreach($targets as $target){
622       $this->a_targets[] = $target;
623     }
624   }
626   public function check()
627   {
628     return(array());
629   }
632   /*! \brief Update a class variable from outside 
633    */
634   public function set_value($name,$value)
635   {
636     $name = strtolower($name);
637     if(isset($this->$name) && in_array($name,$this->attributes)){
638       $this->$name = $value;
639     }
640   }
643 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
644 ?>