Code

Added abort action
[gosa.git] / gosa-plugins / goto / addons / goto / class_gotomasses.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 class gotomasses extends management
24 {
26   var $plHeadline     = "System deployment status";
27   var $plDescription  = "System deployment status";
28   var $plIcon  = "plugins/goto/images/goto.png";
30   var $current        = FALSE;
31   var $dialog         = FALSE;
32   var $ids_to_remove  = array();
34   var $events         = array();
35   var $event_tags     = array();
36   var $recently_removed = array();
38   var $read_only = FALSE;
39   var $acl_base;
40   var $acl_category;
42   function __construct(&$config, $ui)
43   {
44     /* Include config object */
45     $this->config= &$config;
46     $this->o_queue = new gosaSupportDaemon(TRUE,5);
47     $this->events  = DaemonEvent::get_event_types( SYSTEM_EVENT);
48     $this->acl_base = $config->current['BASE'];
49     $this->acl_category = "gotomasses/";
51     /* Get tags that will be used in queue searches */
52     $this->event_tags = array("none");
53     foreach($this->events['SCHEDULED'] as $evt){
54       $this->event_tags[] = $evt['s_Queued_Action'];
55     }
57     // Build filter
58    # if (session::global_is_set(get_class($this)."_filter")){
59   #    $filter= session::global_get(get_class($this)."_filter");
60  #   } else {
61       $filter = new filter(get_template_path("deploy-filter.xml", true));
62       $filter->setObjectStorage($this->storagePoints);
63 #    }
64     $this->setFilter($filter);
66     // Build headpage
67     $headpage = new listing(get_template_path("deploy-list.xml", true));
68     $headpage->registerElementFilter("hostName",  "gotomasses::filterHostName");
69     $headpage->registerElementFilter("filterTask","gotomasses::filterTask");
70     $headpage->registerElementFilter("filterPeriod","gotomasses::filterPeriod");
71     $headpage->registerElementFilter("filterSchedule","gotomasses::filterSchedule");
72     $headpage->registerElementFilter("filterStatus","gotomasses::filterStatus");
73     $headpage->setFilter($filter);
75     parent::__construct($config, $ui, "Events", $headpage);
77     $this->registerAction('prioDown',   "prioDown");
78     $this->registerAction('prioUp',     "prioUp");
79     $this->registerAction('prioPause',  "prioPause");
80     $this->registerAction('processNow', "processNow");
81     $this->registerAction('viewLogs',   "viewLogs");
82     $this->registerAction('abort',      "abortEvent");
83     $this->registerAction('saveEventDialog',   "saveEventDialog");
84   }
86   static function filterHostName($mac, $name ="")
87   {
88     if(isset($name[0]) && $name[0] != "none"){
89       return($name[0]);
90     }
91     return($mac[0]);
92   }
94   static function filterTask($tag)
95   {
96     $tag = $tag[0];
97     $str = $tag;
99     /* Check if this event exists as Daemon class
100      * In this case, display a more accurate entry.
101      */
102     $events  = DaemonEvent::get_event_types( SYSTEM_EVENT);
103     if(isset($events['QUEUED'][$tag])){
104       $evt_name   = $events['QUEUED'][$tag];
105       $event_type = $events['BY_CLASS'][$evt_name];
106       $str        = $event_type['s_Menu_Name'];
108       if(strlen($str) > 20){
109         $str = substr($str,0,18)."...";
110       }
112       if(isset($event_type['ListImage']) && !empty($event_type['ListImage'])){
113         $str = $event_type['ListImage']."&nbsp;".$str;
114       }
115     }
116     return($str);
117   }
119   static function filterPeriod($periodic=array())
120   {
121     $period = "&nbsp;-";
122     if(isset($periodic[0]) && !preg_match("/none/i",$periodic[0])){
123       $tmp = explode("_", $periodic[0]);
124       if(count($tmp) == 2){
125         $period= $tmp[0]."&nbsp;"._($tmp[1]);
126       }
127     }
128     return($period);
129   }
131   static function filterSchedule($stamp)
132   {
133     if ($stamp['0'] == "19700101000000"){
134       return(_("immediately"));
135     } else {
136       return(date("d.m.Y H:i:s",strtotime($stamp[0])));
137     }
138   }
141   static function filterStatus($status, $mac,$headertag, $progress)
142   {
144     $mac = $mac[0];
145     $status = $status[0];
146     $progress = $progress[0];
147     $headertag = $headertag[0];
149     if($status == "waiting"){
150       $status = "<img class='center' src='plugins/goto/images/clock.png' alt=''>&nbsp;"._("Waiting");
151     }
152     if($status == "error"){
153       $status = "<img class='center' src='images/false.png' alt=''>&nbsp;"._("Error");
154     }
155     if($status == "processed"){
156       $status = "<img class='center' src='images/true.png' alt=''>&nbsp;"._("Processed");
157     }
159     /* Special handling for all entries that have
160        STATUS == "processing" && PROGRESS == NUMERIC
161      */
162     if($status == "processing" && $progress){
163       $percent = $progress;
165       /* Show activation? */
166       if ($percent == "goto-activation"){
167         $status = "<img class='center' src='images/lists/off.png' alt=''>&nbsp;"._("Locked");
169         /* Show hardware detect? */
170       } elseif ($percent == "goto-hardware-detection") {
171         $status = "<img class='center' src='plugins/goto/images/hardware.png' alt=''>&nbsp;"._("Detection");
173         /* Real percent */
174       } else {
175         if (preg_match('/install/', $headertag)){
176           $status = "<img src='progress.php?x=80&y=13&p=".$progress."' alt=''
177             id='progress_".preg_replace("/:/","_",$mac)."'>";
178         } else {
179           $status = preg_replace('/ /', '&nbsp;', _("in progress"));
180         }
181       }
182     }
183     return($status);
184   }
186   function editEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
187   {
188     if(count($target) == 1){
189       $headpage = $this->getHeadpage();
190       $entry = $headpage->getEntry($target[0]);
191       $event = $entry['EVENT'];
192       if($event['STATUS'] == "waiting" && isset($this->events['QUEUED'][$event['HEADERTAG']])){
193         $evt_name = $this->events['QUEUED'][$event['HEADERTAG']];
194         $type = $this->events['BY_CLASS'][$evt_name];
195         $this->dialogObject = new $type['CLASS_NAME']($this->config,$event);
196       }
197     }
198   }
200   function removeEntryRequested($action="",$target=array(),$all=array())
201   {
202     if(!$this->acl_is_removeable()){
203       msg_dialog::display(_("Permission"), msgPool::permDelete(), ERROR_DIALOG);
204     }else{
206       $deleteable_jobs = array();
207       $not_deleteable_jobs = array();
208       $headpage = $this->getHeadpage();
210       foreach($target as $dn){
212         $tmp = $headpage->getEntry($dn);
213         $task = $tmp['EVENT'];
215         /* Create a printable job name/description */
216         if(isset($this->events['QUEUED'][$task['HEADERTAG']])){
217           $evt_name = $this->events['QUEUED'][$task['HEADERTAG']];
218           $evt = $this->events['BY_CLASS'][$evt_name];
219           $j_name = $task['ID']." - ".$evt['s_Menu_Name']."&nbsp;".$task['MACADDRESS'];
220         }else{
221           $j_name = $task['ID']." - ".$task['HEADERTAG']."&nbsp;".$task['MACADDRESS'];
222         }
224         /* Only remove WAITING or ERROR entries */
225         if(in_array($task['STATUS'],array("waiting","error","processed")) ||
226             ($task['STATUS'] == "processing" && !preg_match("/install/",$task['HEADERTAG'])) ){
227           $this->ids_to_remove[] = $task['ID'];
228           $deleteable_jobs[] = $j_name;
229         }else{
230           $not_deleteable_jobs[] = $j_name;
231         }
232       }
233       if(count($not_deleteable_jobs)){
234         msg_dialog::display(_("Remove"),
235             sprintf(_("The following jobs couldn't be deleted, they have to be aborted: %s"),
236               "<br>".msgPool::buildList($not_deleteable_jobs)),INFO_DIALOG);
237       }
239       if(count($this->ids_to_remove)){
240         $smarty = get_smarty();
241         $smarty->assign("multiple", TRUE);
242         $smarty->assign("info",msgPool::deleteInfo($deleteable_jobs));
243         return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
244       }
245     }
246   }
248   function removeEntryConfirmed($action="",$target=array(),$all=array(),$altTabClass="",$altTabType="",$altAclCategory="")
249   {
250     if($this->acl_is_removeable("")){
251       timezone::get_default_timezone();
252       foreach($this->ids_to_remove as $id){
253         $entry = $this->o_queue->get_entries_by_id(array($id));
254         if(isset($entry['ANSWER1'])){
255           $entry = $entry['ANSWER1'];
256           if( $entry['STATUS'] == "waiting" && 
257               $entry['HEADERTAG'] == "trigger_action_reinstall"){
258             $evt = new DaemonEvent_reinstall($this->config,$entry);
259             if($evt->get_timestamp(FALSE)  < time()){
260               $r_evt = new DaemonEvent_localboot($this->config);
261               $r_evt->add_targets(array($entry['MACADDRESS']));
262               $r_evt->set_type(TRIGGERED_EVENT);
263               $this->o_queue->append($r_evt);
264             }
265           }
266         }
267       }
268       $this->o_queue->remove_entries($this->ids_to_remove);
269       $this->save();
270     }
271   }
272  
273  
274   /*! \brief  Force queue job to be aborted.
275    */
276   function abortEvent($action="",$target=array(),$all=array())
277   {
278     /* Entries are paused by setting the status to
279      *  something different from 'waiting'.
280      * We simply use 'paused'.
281      */
282     $data = array("status"    => "paused");
284     /* Detect if the ids we got are valid and
285      *  check if the status allows pausing.
286      */
287     $update_ids = array();
288     $headpage = $this->getHeadpage();
289     foreach($target as $id){
290       $tmp = $headpage->getEntry($id);
291       $update_ids[] = $tmp['MACADDRESS'][0];
292     }
294     if(class_available("DaemonEvent_faireboot")){
295       $tmp = new DaemonEvent_faireboot($this->config);
296       $tmp->add_targets($update_ids);
297       $tmp->set_type(TRIGGERED_EVENT);
298       $this->recently_removed = $update_ids;
299       if(!$this->o_queue->append($tmp)){
300         msg_dialog::display(_("Error"), sprintf(_("Cannot update queue entry: %s"),$id) , ERROR_DIALOG);
301         return(FALSE);
302       }
303     }else{
304       msg_dialog::display(_("Error"),
305           sprintf(_("Required class '%s' cannot be found: job not aborted!"),
306             "DaemonEvent_faireboot") , ERROR_DIALOG);
307     }
308   }
311   function prioDown($action="",$target=array(),$all=array())
312   {
313     if(count($target) == 1){
314       $this->update_priority($target[0], 'down');
315     }
316   }
318   function prioUp($action="",$target=array(),$all=array())
319   {
320     if(count($target) == 1){
321       $this->update_priority($target[0], 'up');
322     }
323   }
325   function prioPause($action="",$target=array(),$all=array())
326   {
327     $this->pause_queue_entries($target);
328 #    $this->resume_queue_entries($target);
329   }
331   function processNow($action="",$target=array(),$all=array())
332   {
333     $this->execute_queue_entries($target);
334 #    $this->abort_queue_entries($target);
335   }
337   function viewLogs($action="",$target=array(),$all=array())
338   {
339     print_a($all);
340   }
342   function saveEventDialog()
343   {
344     if(is_object($this->dialogObject)){
345       $this->dialogObject->save_object();
346       if(!$this->o_queue->append($this->dialogObject)){
347         msg_dialog::display(_("Service infrastructure"),msgPool::siError($this->o_queue->get_error()),ERROR_DIALOG);
348       }else{
349         $this->current = -1;
350       } 
351     }
352     $this->closeDialogs();
353   }
358   /*! \brief  Move an entry up or down in the queue, by updating its execution timestamp                             
359     @param  $id     Integer  The ID of the entry which should be updated.                                            
360     @param  $type   String   "up" / "down"                                                                           
361     @return boolean TRUE in case of success else FALSE                                                               
362    */                                                                                                                
363   public function update_priority($id,$type = "up")                                                                  
364   {                                          
365     $headpage = $this->getHeadpage();
366     $entries = $headpage->getEntries();
367     $entry = $headpage->getEntry($id);
369     $map = array();
370     $last = 0;
371     $next = 0;
372     foreach($entries as $pa){
373       $map[$pa['TIMESTAMP'][0]] = $pa['TIMESTAMP'][0];
374     }
375     krsort($map);
376     $found = 0;
377     $cur = 0;
378     foreach($map as $ts){
379       if($found){
380         $next = $ts;
381         break;
382       }
383       if($ts == $entry['TIMESTAMP'][0]){
384         $found = TRUE;  
385         $cur = $ts;
386       }else{
387         $last = $ts;
388       }
389     }
391     if($type == "up" && $next != 0){
392       return($this->o_queue->update_entries(array($id),array("timestamp" => $next)));
393     }elseif($type == "down" && $last != 0){
394       return($this->o_queue->update_entries(array($id),array("timestamp" => $last)));
395     }
396   }
399   function detectPostActions()
400   {
401     $action = management::detectPostActions();
402     if(isset($_POST['save_event_dialog'])) $action['action'] = "saveEventDialog";
403     if(isset($_POST['abort_event_dialog'])) $action['action'] = "cancel";
404     if(isset($_POST['delete_multiple_confirm'])) $action['action'] = "removeConfirmed";
405     if(isset($_POST['delete_cancel'])) $action['action'] = "cancel";
406     return($action);
407   }
410   function closeDialogs()
411   {
412     $this->current = FALSE;
413     management::closeDialogs();
414   }
416   function _execute()
417   {
419     /************
420      * Import CSV file  
421      ************/
423     if($s_action == "import_file" && $this->acl_is_writeable("")){
424       $this->dialog = new goto_import_file($this->config,$this);
425     }
427     if(isset($_POST['import_abort'])){
428       $this->dialog = FALSE;
429     }
432     /************
433      * ADD 
434      ************/
436     if(preg_match("/^add_event_/",$s_action) && $this->acl_is_writeable("")){
437       $type = preg_replace("/^add_event_/","",$s_action);
438       if(isset($this->events['BY_CLASS'][$type])){
439         $e_data = $this->events['BY_CLASS'][$type];
440         $this->dialog = new $e_data['CLASS_NAME']($this->config);
441       }
442     }
444     /************
445      * LOG VIEW
446      ************/
448     if($s_action == "logview"  && $this->acl_is_readable("")){  
449       $id =  $s_entry;
450       $type = FALSE;
451       if(isset($this->entries[$id])){
452         $event = $this->entries[$s_entry];
453         $this->dialog = new gotoLogView($this->config,"",$event,$this);
454       }
455     }
458     /************
459     /************
460      * EDIT 
461      ************/
463     /* Display dialogs if currently opened */
464     if(is_object($this->dialog)){
465       $this->dialog->save_object();
466       $display = $this->dialog->execute();
468       if($this->dialog instanceOf goto_import_file && $this->dialog->import_successful){
469         $this->dialog = FALSE;
470       }else{
471         return($display);
472       }
473     }
475    if($this->acl_is_writeable("")){
476      foreach($this->events['SCHEDULED'] as $name =>  $event){
477        $s.= "...|".$event['MenuImage']."&nbsp;".$event['s_Menu_Name']."|add_event_".$name."\n";
478      }
479    }
480    if($this->acl_is_removeable()){
481      $s.= "..|---|\n";
482      $s.= "..|<img src='images/lists/import.png' alt='' border='0' class='center'>&nbsp;"._("Import")."|import_file\n";
483      $s.= "..|<img src='images/lists/trash.png' alt='' border='0' class='center'>&nbsp;"._("Remove")."|remove_multiple\n";
484    }
485    if(preg_match("/w/",$this->getacl(""))){
486      $s.= "..|---|\n";
487      $s.= "..|<img alt='"._("Resume")."' src='images/status_start.png' border='0' class='center'>&nbsp;"._("Resume")."|resume_all\n";
488      $s.= "..|<img alt='"._("Pause")."' src='images/status_pause.png' border='0' class='center'>&nbsp;"._("Pause")."|pause_all\n";
489      $s.= "..|<img alt='"._("Abort")."' src='images/small_error.png'  border='0' class='center'>&nbsp;"._("Abort")."|abort_process_all\n";
490      $s.= "..|<img alt='"._("Execute")."' src='images/rocket.png'       border='0' class='center'>&nbsp;"._("Execute")."|execute_process_all\n";
491    }
493    $divlist->SetDropDownHeaderMenu($s);
495    if($this->sort_dir == "up"){
496      $sort_img = "<img src='images/lists/sort-up.png' alt='/\' border=0>";
497    }else{
498      $sort_img = "<img src='images/lists/sort-down.png' alt='\/' border=0>";
499    }
501    if($this->sort_by == "TargetName"){ $sort_img_1 = $sort_img; } else { $sort_img_1 = "" ;}
502    if($this->sort_by == "TaskID"){ $sort_img_2 = $sort_img; } else { $sort_img_2 = "" ;}
503    if($this->sort_by == "Schedule"){ $sort_img_3 = $sort_img; } else { $sort_img_3 = "" ;}
504    if($this->sort_by == "Action"){ $sort_img_4 = $sort_img; } else { $sort_img_4 = "" ;}
506    /* Create divlist */
507    $divlist->SetListHeader("<input type='image' src='images/lists/reload.png' title='"._("Reload")."'>");
509    $plug  = $_GET['plug'];
510    $chk = "<input type='checkbox' id='select_all' name='select_all'
511               onClick='toggle_all_(\"^item_selected_[0-9]*$\",\"select_all\");' >";
513    /* set Page header */
514    $divlist->AddHeader(array("string"=> $chk,          "attach"=>"style='width:20px;'"));
515    $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&amp;sort=TargetName'>"._("Target").$sort_img_1."</a>"));
516    $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&amp;sort=TaskID'>"._("Task").$sort_img_2."</a>",
517                                      "attach"=>"style='width:120px;'"));
518    $divlist->AddHeader(array("string"=>_("Period"),
519                                      "attach"=>"style='width:60px;'"));
520    $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&amp;sort=Schedule'>"._("Schedule").$sort_img_3."</a>",
521                                      "attach"=>"style='width:140px;'"));
522    $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&amp;sort=Action'>"._("Status").$sort_img_4."</a>",
523                                      "attach"=>"style='width:80px;'"));
524    $divlist->AddHeader(array("string"=>_("Action"),
525                                       "attach"=>"style='border-right:0px;width:140px;'"));
528     /* Reload the list of entries */
529     $this->reload();
531     foreach($this->entries as $key => $task){
533       $prio_actions="";
534       $action = "";
537       /* If WAITING add priority action
538        */  
539       if(in_array($task['STATUS'],array("waiting")) && $this->acl_is_writeable("")){
540         $prio_actions.= "<input class='center' type='image' src='plugins/goto/images/prio_increase.png' 
541           title='"._("Move up")."' name='prio_up_".$key."'>&nbsp;";
542         $prio_actions.= "<input class='center' type='image' src='plugins/goto/images/prio_decrease.png' 
543           title='"._("Move down")."' name='prio_down_".$key."'>&nbsp;";
544       }
546       /* If WAITING add pause action
547        */  
548       if(in_array($task['STATUS'],array("waiting")) && $this->acl_is_writeable("")){
549         $prio_actions.= "<input class='center' type='image' src='images/status_pause.png' 
550           title='"._("Pause job")."' name='pause_".$key."'>&nbsp;";
551       }
553       /* If PAUSED add resume action
554        */  
555       if(in_array($task['STATUS'],array("paused")) && $this->acl_is_writeable("")){
556         $prio_actions.= "<input class='center' type='image' src='images/status_start.png' 
557           title='"._("Resume job")."' name='resume_".$key."'>&nbsp;";
558       }
560       /* If PAUSED or WAITING add execution action
561        */  
562       if(in_array($task['STATUS'],array("paused","waiting")) && $this->acl_is_writeable("")){
563         $prio_actions.= "<input class='center' type='image' src='images/rocket.png' 
564           title='"._("Execute now")."' name='execute_process_".$key."'>&nbsp;";
565       }
567       /* Add logview button, currently ever.
568        */  
569       if($this->acl_is_readable("")){
570         $action .= "<input type='image' src='plugins/goto/images/view_logs.png' name='log_view_".$key."' 
571           class='center' title='"._("View logs")."' alt='"._("View logs")."'>&nbsp;";
572       }
574       /* If PAUSED or WAITING add edit action
575        */  
576       if(in_array($task['STATUS'],array("waiting")) && $this->acl_is_writeable("")){
577         $action.= "<input type='image' src='images/lists/edit.png' name='edit_task_".$key."' 
578           class='center' title='"._("Edit")."' alt='"._("Edit")."'>";
579       }
581       /* If PROCESSING add abort action
582        */  
583       if(in_array($task['STATUS'],array("processing")) && preg_match("/install/",$task['HEADERTAG']) && $this->acl_is_writeable("")){
584         $action.= "<img src='images/empty.png' alt=''>";
585         $action.= "<input class='center' type='image' src='images/small_error.png' 
586           title='"._("Abort job")."' name='abort_process_".$key."'>";
587       }
589       /* If WAITING or ERROR add remove action
590        */  
591       if( $this->acl_is_removeable() && in_array($task['STATUS'],array("waiting","error","processed"))){
592         $action.= "<input type='image' src='images/lists/trash.png' name='remove_task_".$key."' 
593           class='center' title='"._("Remove")."' alt='"._("Remove")."'>";
594       }
595       if($this->acl_is_writeable("") && in_array($task['STATUS'],array("processing")) && !preg_match("/install/",$task['HEADERTAG'])){
596         $action.= "<input type='image' src='images/lists/trash.png' name='remove_task_".$key."' 
597           class='center' title='"._("Remove")."' alt='"._("Remove")."'>";
598       }
600       /* Create entry display name and tooltip */
601       $color = "";
602       $display = $task['MACADDRESS'];
603       $tooltip = "";
604       if(isset($task['PLAINNAME']) && !preg_match("/none/i",$task['PLAINNAME'])){
605         $display = $task['PLAINNAME'];
606         $tooltip = " title='".$task['MACADDRESS']."' ";
607       }
610       $display2= $task['HEADERTAG'];
612       /* Check if this event exists as Daemon class 
613        * In this case, display a more accurate entry.
614        */ 
615       if(isset($this->events['QUEUED'][$task['HEADERTAG']])){
616         $evt_name   = $this->events['QUEUED'][$task['HEADERTAG']];
617         $event_type = $this->events['BY_CLASS'][$evt_name];
618         $display2   = $event_type['s_Menu_Name'];
620         if(strlen($display2) > 20){
621           $display2 = substr($display2,0,18)."...";
622         }
624         if(isset($event_type['ListImage']) && !empty($event_type['ListImage'])){
625           $display2 = $event_type['ListImage']."&nbsp;".$display2;
626         }
627       } 
629       $status = $task['STATUS'];
631       if($status == "waiting"){
632         $status = "<img class='center' src='plugins/goto/images/clock.png' alt=''>&nbsp;"._("Waiting");
633       }
634       if($status == "error"){
635         $status = "<img class='center' src='images/false.png' alt=''>&nbsp;"._("Error");
636       }
637       if($status == "processed"){
638         $status = "<img class='center' src='images/true.png' alt=''>&nbsp;"._("Processed");
639       }
641       /* Special handling for all entries that have 
642          STATUS == "processing" && PROGRESS == NUMERIC
643        */
644       if($status == "processing" && isset($task['PROGRESS'])){
645         $percent = $task['PROGRESS'];
647         /* Show activation? */
648         if ($percent == "goto-activation"){
649           $status = "<img class='center' src='images/lists/off.png' alt=''>&nbsp;"._("Locked");
651           /* Show hardware detect? */
652         } elseif ($percent == "goto-hardware-detection") {
653           $status = "<img class='center' src='plugins/goto/images/hardware.png' alt=''>&nbsp;"._("Detection");
655           /* Real percent */
656         } else {
657           if (preg_match('/install/', $task['HEADERTAG'])){
658             $status = "<img src='progress.php?x=80&y=13&p=".$task['PROGRESS']."' alt=''
659               id='progress_".preg_replace("/:/","_",$task['MACADDRESS'])."'>";
660           } else {
661             $status = preg_replace('/ /', '&nbsp;', _("in progress"));
662           }
663         }
664       }
666       // Check whether this is a periodical job or not.
667       $period = "";
668       if(isset($task['PERIODIC']) && !preg_match("/none/i",$task['PERIODIC'])){
669         $tmp = explode("_", $task['PERIODIC']);
670         if(count($tmp) == 2){
671           $period= $tmp[0]."&nbsp;"._($tmp[1]);
672         }
673       }
675       /* Create each field */
676       $field0 = array("string" => "<input type='checkbox' id='item_selected_".$task['ID']."' name='item_selected_".$key."'>" ,
677           "attach" => "style='width:20px;".$color."'");
678       $field1 = array("string" => $display,
679           "attach" => $tooltip."style='".$color."'");
680       $field1a= array("string" => $display2,
681           "attach" => "style='".$color.";width:120px;'");
682       $field1b= array("string" => $period,
683           "attach" => "style='".$color.";width:60px;'");
684       if ($task['TIMESTAMP'] == "19700101000000"){
685         $field2 = array("string" => _("immediately"),"attach" => "style='".$color.";width:140px;'");
686       } else {
687         $field2 = array("string" => date("d.m.Y H:i:s",strtotime($task['TIMESTAMP'])),"attach" => "style='".$color.";width:140px;'");
688       }
689       $field3 = array("string" => $status,"attach" => "style='".$color.";width:80px;'");
690       $field4 = array("string" => $prio_actions.$action,"attach" => "style='".$color.";text-align:right;width:140px;border-right:0px;'");
691       $divlist->AddElement(array($field0,$field1,$field1a,$field1b,$field2,$field3,$field4));
692    }
694    $smarty = get_smarty();
695    $smarty->assign("events",$this->events);
696    $smarty->assign("start",$this->start);
697    $smarty->assign("start_real", ($this->start + 1));
698    $smarty->assign("ranges", array("10" => "10",
699          "20" => "20",
700          "25" => "25",
701          "50" => "50",
702          "100"=> "100",
703          "200"=> "200",
704          "9999" => "*"));
706    $count = $this->o_queue->number_of_queued_entries($this->event_tags);
707    if(!$count) $count = $this->range;
708     $divlist->SetListFooter(range_selector($count, $this->start, $this->range,"range"));
709    $smarty->assign("range",$this->range);
710     $smarty->assign("div",$divlist->Draw());
712     return(management::execute());
713     return($smarty->fetch (get_template_path('gotomasses.tpl', TRUE, dirname(__FILE__))));
714   }
717   /*! \brief  Resumes to status 'waiting'.
718    *  @return Boolean TRUE in case of success, else FALSE. 
719    */
720   private function resume_queue_entries($ids)
721   {
722     if(!count($ids)){
723       return;
724     }
726     /* Entries are resumed by setting the status to 
727      *  'waiting'
728      */
729     $data = array("status"    => "waiting");
731     /* Check if given ids are valid and check if the status
732      *  allows resuming.
733      */
734     $update_ids = array();
735     foreach($this->o_queue->get_entries_by_id($ids) as $entry){
736       if(isset($entry['STATUS']) && preg_match("/paused/",$entry['STATUS'])){
737         $update_ids[] = $entry['ID'];
738       }
739     }
741     /* Tell the daemon that we have entries to update.
742      */
743     if(count($update_ids)){
744       if(!$this->o_queue->update_entries($update_ids,$data)){
745         msg_dialog::display(_("Error"), sprintf(_("Cannot update queue entry: %s"),$id) , ERROR_DIALOG);
746         return(FALSE);
747       }
748     }
749     return(TRUE);
750   }
753   /*! \brief  Force queue job to be done as far as possible.
754    *  @return Boolean TRUE in case of success, else FALSE.
755    */
756   private function execute_queue_entries($ids)
757   {
758     if(!count($ids)){
759       return;
760     }
762     /* Execution is forced by updating the status to 
763      *  waiting and setting the timestamp to current time.
764      */
765     $data = array(  "timestamp" => date("YmdHis",time()), 
766         "status"    => "waiting");
768     /* Only allow execution of paused or waiting entries 
769      */
770     $update_ids = array();
771     foreach($this->o_queue->get_entries_by_id($ids) as $entry){
772       if(in_array($entry['STATUS'],array("paused","waiting"))){
773         $update_ids[] = $entry['ID'];
774       }
775     }
777     /* Tell the daemon that we want to update some entries
778      */
779     if(count($update_ids)){
780       if(!$this->o_queue->update_entries($update_ids,$data)){
781         msg_dialog::display(_("Error"), sprintf(_("Cannot update queue entries.")) , ERROR_DIALOG);
782         return(FALSE);
783       }
784     }
785     return(TRUE);
786   }
789   /*! \brief Pauses the specified queue entry from execution.
790    *  @return Boolean TRUE in case of success, else FALSE. 
791    */
792   private function pause_queue_entries($ids)
793   {
794     if(!count($ids)){
795       return;
796     }
798     /* Entries are paused by setting the status to 
799      *  something different from 'waiting'.
800      * We simply use 'paused'.
801      */   
802     $data = array("status"    => "paused");
804     /* Detect if the ids we got are valid and
805      *  check if the status allows pausing.
806      */ 
807     $update_ids = array();
808     foreach($this->o_queue->get_entries_by_id($ids) as $entry){
809       if(isset($entry['STATUS']) && preg_match("/waiting/",$entry['STATUS'])){
810         $update_ids[] = $entry['ID'];
811       }
812     }
814     /* Tell the daemon that we want to update some entries
815      */
816     if(count($update_ids)){
817       if(!$this->o_queue->update_entries($update_ids,$data)){
818         msg_dialog::display(_("Error"), sprintf(_("Cannot update queue entry: %s"),$id) , ERROR_DIALOG);
819         return(FALSE);
820       }
821     }
822     return(TRUE);
823   }
826   /*! \brief  Request list of queued jobs.
827    *  @return Returns an array of all queued jobs.
828    */
829   function reload()
830   {
832     /* Sort map   html-post-name => daemon-col-name
833      */
834     $map = array(
835         "QueuePosition" => "id",
836         "Action"        => "status",
837         "TaskID"        => "headertag",
838         "TargetName"    => "macaddress",
839         "Schedule"      => "timestamp");
841     /* Create sort header 
842      */
843     if(!isset($map[$this->sort_by])){
844       $sort = "id DESC";
845     }else{
846       $sort   = $map[$this->sort_by]; 
847       if($this->sort_dir == "up"){
848         $sort.= " ASC";
849       }else{
850         $sort.= " DESC";
851       }
852     }
854     /* Get entries. */ 
855     $start  = $this->start; 
856     $stop   = $this->range;
857     $entries = $this->o_queue->get_queued_entries($this->event_tags,$start,$stop,$sort);
858     if ($this->o_queue->is_error()){
859       msg_dialog::display(_("Error"), sprintf(_("Cannot load queue entries: %s"), "<br><br>".$this->o_queue->get_error()), ERROR_DIALOG);
860     }
862     /* Assign entries by id.
863      */
864     $this->entries = array();
866     foreach($entries as $entry){
868       /* Skip entries which will be removed within the next seconds */
869       if(isset($entry['MACADDRESS']) && in_array($entry['MACADDRESS'],$this->recently_removed)){
870         continue;
871       }
872       $this->entries[$entry['ID']]= $entry;
873     }
874     $this->recently_removed = array();
875   }
877   function save_object(){}
879   /*! \brief  Handle post jobs, like sorting.
880    */
881   function _save_object()
882   {
883     /* Check for sorting changes 
884      */
885     $sort_vals = array("Action","QueuePosition","TargetName","Schedule","TaskID");
886     if(isset($_GET['sort']) && in_array($_GET['sort'],$sort_vals)){
887       $sort = $_GET['sort'];
888       if($this->sort_by == $sort){
889         if($this->sort_dir == "up"){
890           $this->sort_dir = "down";
891         }else{
892           $this->sort_dir = "up";
893         }
894       }
895       $this->sort_by = $sort;
896     }
898     /* Range selection used? */
899     if(isset($_POST['range']) && is_numeric($_POST['range'])){
900       $this->range = $_POST['range'];
901     }
903     /* Save filter settings */ 
904     $gotomasses_filter = session::get("gotomasses_filter");
905     foreach(array("range","sort_by","sort_dir") as $attr){
906       $gotomasses_filter[$attr] = $this->$attr;
907     }
908     session::set("gotomasses_filter",$gotomasses_filter);
910     /* Page changed. */
911     if(isset($_GET['start'])){
912       $start = $_GET['start'];
913       if(is_numeric($start) || $start == 0){
914         $this->start = $start;
915       }
916     }
918     /* Check start stop and reset if necessary */
919     $count = $this->o_queue->number_of_queued_entries($this->event_tags);
920     if($this->start >= $count){
921       $this->start = $count -1;
922     }
923     if($this->start < 0){
924       $this->start = 0;
925     }
926   }
929   function save()
930   {
931     // We do not save anything here.
932   }
935   /*! \brief  Return a list of all selected items.
936     @return Array   Returns an array containing all selected item ids.
937    */
938   function list_get_selected_items()
939   {
940     $ids = array();
941     foreach($_POST as $name => $value){
942       if(preg_match("/^item_selected_[0-9]*$/",$name)){
943         $id   = preg_replace("/^item_selected_/","",$name);
944         $ids[$id] = $id;
945       }
946     }
947     return($ids);
948   }
951   static function plInfo()
952   {
953     return (array(
954           "plShortName"   => _("System deployment"),
955           "plDescription" => _("Provide a mechanism to automatically activate systems"),
956           "plSelfModify"  => FALSE,
957           "plDepends"     => array(),
958           "plPriority"    => 0,
959           "plSection"     => array("addon"),
960           "plCategory"    => array("gotomasses" => array("objectClass" => "none", "description" => _("System deployment"))),
961           "plProvidedAcls" => array("Comment"   => _("Description")) 
962           ));
963   }
966   function set_acl_base($base)
967   {
968     $this->acl_base= $base;
969   }
972   function set_acl_category($category)
973   {
974     $this->acl_category= "$category/";
975   }
978   function acl_is_writeable($attribute,$skip_write = FALSE)
979   {
980     if($this->read_only) return(FALSE);
981     $ui= get_userinfo();
982     return preg_match('/w/', $ui->get_permissions($this->acl_base, $this->acl_category.get_class($this), $attribute, $skip_write));
983   }
986   function acl_is_readable($attribute)
987   {
988     $ui= get_userinfo();
989     return preg_match('/r/', $ui->get_permissions($this->acl_base, $this->acl_category.get_class($this), $attribute));
990   }
993   function acl_is_createable($base ="")
994   {
995     if($this->read_only) return(FALSE);
996     $ui= get_userinfo();
997     if($base == "") $base = $this->acl_base;
998     return preg_match('/c/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
999   }
1002   function acl_is_removeable($base ="")
1003   {
1004     if($this->read_only) return(FALSE);
1005     $ui= get_userinfo();
1006     if($base == "") $base = $this->acl_base;
1007     return preg_match('/d/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
1008   }
1010   function acl_is_moveable($base = "")
1011   {
1012     if($this->read_only) return(FALSE);
1013     $ui= get_userinfo();
1014     if($base == "") $base = $this->acl_base;
1015     return preg_match('/m/', $ui->get_permissions($base, $this->acl_category.get_class($this), '0'));
1016   }
1019   function getacl($attribute,$skip_write= FALSE)
1020   {
1021     $ui= get_userinfo();
1022     $skip_write |= $this->read_only;
1023     return  $ui->get_permissions($this->acl_base, $this->acl_category.get_class($this), $attribute,$skip_write);
1024   }
1027 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1028 ?>