1 <?php
3 class gotomasses extends plugin
4 {
5 /* Definitions */
6 var $plHeadline = "System deployment";
7 var $plDescription = "This does something";
9 /* attribute list for save action */
10 var $attributes= array();
11 var $objectclasses= array();
13 /* Queue tasks */
14 var $current = FALSE;
15 var $dialog = FALSE;
16 var $ids_to_remove = array();
17 var $divlist = NULL;
19 var $events = array();
20 var $event_tags = array();
22 var $sort_by = "Schedule";
23 var $sort_dir = "down";
24 var $entries = array();
25 var $range = 25;
26 var $start = 0;
28 function gotomasses(&$config, $dn= NULL)
29 {
30 /* Include config object */
31 $this->config= &$config;
32 $this->o_queue = new gosaSupportDaemon(TRUE,10);
33 $this->events = DaemonEvent::get_event_types( USER_EVENT | SYSTEM_EVENT);
35 /* Get tags that will be used in queue searches */
36 $this->event_tags = array("none");
37 foreach($this->events['BY_CLASS'] as $evt){
38 if(isset($evt['s_Queued_Action'])){
39 $this->event_tags[] = $evt['s_Queued_Action'];
40 }
41 }
42 }
45 function execute()
46 {
47 $smarty = get_smarty();
49 /************
50 * Handle posts
51 ************/
53 $s_entry = $s_action = "";
54 $arr = array(
56 "/^pause_/" => "pause",
57 "/^resume_/" => "resume",
58 "/^execute_process_/" => "execute_process",
59 "/^abort_process_/" => "abort_process",
61 "/^prio_up_/" => "prio_up",
62 "/^prio_down_/" => "prio_down",
64 "/^edit_task_/" => "edit",
65 "/^remove_task_/" => "remove",
66 "/^new_task_/" => "new_task");;
69 foreach($arr as $regex => $action){
70 foreach($_POST as $name => $value){
71 if(preg_match($regex,$name)){
72 $s_action = $action;
73 $s_entry = preg_replace($regex,"",$name);
74 $s_entry = preg_replace("/_(x|y)$/","",$s_entry);
75 }
76 }
77 }
79 /* Menu actions */
80 if(isset($_POST['menu_action']) && !empty($_POST['menu_action'])){
81 $s_action = $_POST['menu_action'];
82 }
84 /* Edit posted from list link */
85 if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id']) && isset($this->tasks[$_GET['id']])){
86 $s_action = "edit";
87 $s_entry = $_GET['id'];
88 }
91 /************
92 * Handle Priority modifications
93 ************/
95 if(preg_match("/^prio_/",$s_action)){
96 switch($s_action){
97 case 'prio_down' : $this->update_priority($s_entry,"down");break;
98 case 'prio_up' : $this->update_priority($s_entry,"up");break;
99 }
100 }
102 /************
103 * Handle pause/resume/execute modifications
104 ************/
106 if(preg_match("/^resume/",$s_action) ||
107 preg_match("/^pause/",$s_action) ||
108 preg_match("/^abort_process/",$s_action) ||
109 preg_match("/^execute_process/",$s_action)){
111 switch($s_action){
112 case 'resume' : $this->resume_queue_entries (array($s_entry));break;
113 case 'pause' : $this->pause_queue_entries (array($s_entry));break;
114 case 'execute_process': $this->execute_queue_entries (array($s_entry));break;
115 case 'abort_process' : $this->abort_queue_entries (array($s_entry));break;
116 case 'resume_all' : $this->resume_queue_entries ($this->list_get_selected_items());break;
117 case 'pause_all' : $this->pause_queue_entries ($this->list_get_selected_items());break;
118 case 'execute_process_all': $this->execute_queue_entries ($this->list_get_selected_items());break;
119 case 'abort_process_all' : $this->abort_queue_entries ($this->list_get_selected_items());break;
121 default : trigger_error("Undefined action setting used (".$s_action.").");
122 }
123 if($this->o_queue->is_error()){
124 msg_dialog::display(_("Error"), $this->o_queue->get_error(), ERROR_DIALOG);
125 }
126 }
128 /************
129 * ADD
130 ************/
132 if(preg_match("/^add_event_/",$s_action)){
133 $type = preg_replace("/^add_event_/","",$s_action);
134 if(isset($this->events['BY_CLASS'][$type])){
135 $e_data = $this->events['BY_CLASS'][$type];
136 $this->dialog = new $e_data['CLASS_NAME']($this->config);
137 }
138 }
140 /************
141 * EDIT
142 ************/
144 if($s_action == "edit"){
145 $id = $s_entry;
146 $type = FALSE;
147 if(isset($this->entries[$id])){
148 $event = $this->entries[$s_entry];
151 if($event['STATUS'] == "waiting" && isset($this->events['BY_QUEUED_ACTION'][$event['HEADERTAG']])){
152 $type = $this->events['BY_QUEUED_ACTION'][$event['HEADERTAG']];
153 $this->dialog = new $type['CLASS_NAME']($this->config,$event);
154 }
155 }
156 }
158 /************
159 * REMOVE
160 ************/
162 /* Remove multiple */
163 if($s_action == "remove_multiple" || $s_action == "remove"){
165 if(!$this->acl_is_removeable()){
166 msg_dialog::display(_("Permission error"), _("You have no permission to delete this entry!"), ERROR_DIALOG);
167 }else{
169 if($s_action == "remove"){
170 $ids = array($s_entry);
171 }else{
172 $ids = $this->list_get_selected_items();
173 }
175 if(count($ids)){
176 $ret = $this->o_queue->ids_exist($ids);
177 $ret = $this->o_queue->get_entries_by_id($ret);
179 $tmp = "";
180 foreach($ret as $task){
182 /* Only remove WAITING or ERROR entries */
183 if(in_array($task['STATUS'],array("waiting","error"))){
184 $this->ids_to_remove[] = $task['ID'];
185 if(isset($this->events['BY_QUEUED_ACTION'][$task['HEADERTAG']])){
186 $evt = $this->events['BY_QUEUED_ACTION'][$task['HEADERTAG']];
187 $tmp.= "\n".$task['ID']." - ".$evt['s_Menu_Name']." ".$task['MACADDRESS'];
188 }else{
189 $tmp.= "\n".$task['ID']." - ".$task['HEADERTAG']." ".$task['MACADDRESS'];
190 }
191 }
192 }
193 $smarty->assign("multiple", TRUE);
194 $smarty->assign("info",sprintf(_("You are about to remove the following actions from the GOsa support Daemon: %s"),"<pre>".$tmp."</pre>"));
195 $this->current = $s_entry;
196 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
197 }
198 }
199 }
201 /* Remove specified tasks */
202 if(count($this->ids_to_remove) && isset($_POST['delete_multiple_confirm'])){
203 $this->o_queue->remove_entries($this->ids_to_remove);
204 $this->save();
205 }
207 /* Remove aborted */
208 if(isset($_POST['delete_cancel'])){
209 $this->ids_to_remove = array();;
210 }
213 /************
214 * EDIT
215 ************/
217 /* Close dialog */
218 if(isset($_POST['save_event_dialog'])){
219 if(is_object($this->dialog)){
220 $this->dialog->save_object();
221 if(!$this->o_queue->append($this->dialog)){
222 msg_dialog::display(_("Daemon"),sprintf(_("Something went wrong while talking to the daemon: %s."),
223 $this->o_queue->get_error()),ERROR_DIALOG);
224 }else{
225 $this->dialog = FALSE;
226 $this->current = -1;
227 }
228 }
229 }
232 /* Close dialog */
233 if(isset($_POST['abort_event_dialog'])){
234 $this->dialog = FALSE;
235 $this->current = -1;
236 }
238 /* Display dialogs if currently opened */
239 if(is_object($this->dialog)){
240 $this->dialog->save_object();
241 return($this->dialog->execute());
242 }
244 /************
245 * Handle Divlist
246 ************/
248 $divlist = new MultiSelectWindow($this->config,"gotoMasses",array("gotomasses"));
249 $divlist->SetInformation(_("This menu allows you to remove and change the properties of GOsa tasks."));
250 $divlist->SetSummary(_("List of queued jobs"));
251 $divlist->EnableCloseButton(FALSE);
252 $divlist->EnableSaveButton(FALSE);
253 $divlist->SetHeadpageMode();
254 $s = ".|"._("Actions")."|\n";
255 $s.= "..|<img src='images/list_new.png' alt='' border='0' class='center'> "._("Create")."\n";
256 foreach($this->events['BY_CLASS'] as $name => $event){
257 $s.= "...|".$event['MenuImage']." ".$event['s_Menu_Name']."|add_event_".$name."\n";
258 }
259 if($this->acl_is_removeable()){
260 $s.= "..|---|\n";
261 $s.= "..|<img src='images/edittrash.png' alt='' border='0' class='center'> "._("Remove")."|remove_multiple\n";
262 }
263 if(preg_match("/w/",$this->getacl(""))){
264 $s.= "..|---|\n";
265 $s.= "..|<img src='images/status_start.png' alt='' border='0' class='center'> "._("Resume all")."|resume_all\n";
266 $s.= "..|<img src='images/status_pause.png' alt='' border='0' class='center'> "._("Pause all")."|pause_all\n";
267 $s.= "..|<img src='images/small_error.png' alt='' border='0' class='center'> "._("Abort all")."|abort_process_all\n";
268 $s.= "..|<img src='images/rocket.png' alt='' border='0' class='center'> "._("Execute all")."|execute_process_all\n";
269 }
271 $divlist->SetDropDownHeaderMenu($s);
273 if($this->sort_dir == "up"){
274 $sort_img = "<img src='images/sort_up.png' alt='/\' border=0>";
275 }else{
276 $sort_img = "<img src='images/sort_down.png' alt='\/' border=0>";
277 }
279 if($this->sort_by == "TargetName"){ $sort_img_1 = $sort_img; } else { $sort_img_1 = "" ;}
280 if($this->sort_by == "TaskID"){ $sort_img_2 = $sort_img; } else { $sort_img_2 = "" ;}
281 if($this->sort_by == "Schedule"){ $sort_img_3 = $sort_img; } else { $sort_img_3 = "" ;}
282 if($this->sort_by == "Action"){ $sort_img_4 = $sort_img; } else { $sort_img_4 = "" ;}
284 /* Create divlist */
285 $divlist->SetListHeader("<input type='image' src='images/list_reload.png' title='"._("Reload")."'>");
287 $plug = $_GET['plug'];
288 $chk = "<input type='checkbox' id='select_all' name='select_all'
289 onClick='toggle_all_(\"^item_selected_[0-9]*$\",\"select_all\");' >";
291 /* set Page header */
292 $divlist->AddHeader(array("string"=> $chk, "attach"=>"style='width:20px;'"));
293 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=TargetName'>"._("Target").$sort_img_1."</a>"));
294 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=TaskID'>"._("Task").$sort_img_2."</a>",
295 "attach"=>"style='width:120px;'"));
296 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Schedule'>"._("Schedule").$sort_img_3."</a>",
297 "attach"=>"style='width:100px;'"));
298 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Action'>"._("Status").$sort_img_4."</a>",
299 "attach"=>"style='width:80px;'"));
300 $divlist->AddHeader(array("string"=>_("Action"),
301 "attach"=>"style='border-right:0px;width:120px;'"));
304 /* Reload the list of entries */
305 $this->reload();
307 foreach($this->entries as $key => $task){
309 $prio_actions="";
310 $action = "";
312 /* If WAITING add priority action
313 */
314 if(in_array($task['STATUS'],array("waiting"))){
315 $prio_actions.= "<input class='center' type='image' src='images/prio_increase.png'
316 title='"._("Move up in execution queue")."' name='prio_up_".$key."'> ";
317 $prio_actions.= "<input class='center' type='image' src='images/prio_decrease.png'
318 title='"._("Move down in execution queue")."' name='prio_down_".$key."'> ";
319 }
321 /* If WAITING add pause action
322 */
323 if(in_array($task['STATUS'],array("waiting"))){
324 $prio_actions.= "<input class='center' type='image' src='images/status_pause.png'
325 title='"._("Pause job")."' name='pause_".$key."'> ";
326 }
328 /* If PAUSED add resume action
329 */
330 if(in_array($task['STATUS'],array("paused"))){
331 $prio_actions.= "<input class='center' type='image' src='images/status_start.png'
332 title='"._("Resume job")."' name='resume_".$key."'> ";
333 }
335 /* If PROCESSING add abort action
336 */
337 if(in_array($task['STATUS'],array("processing"))){
338 $prio_actions.= "<input class='center' type='image' src='images/small_error.png'
339 title='"._("Abort execution")."' name='abort_process_".$key."'>";
340 }
342 /* If PAUSED or WAITING add execution action
343 */
344 if(in_array($task['STATUS'],array("paused","waiting"))){
345 $prio_actions.= "<input class='center' type='image' src='images/rocket.png'
346 title='"._("Force execution now!")."' name='execute_process_".$key."'> ";
347 }
349 /* If PAUSED or WAITING add edit action
350 */
351 if(in_array($task['STATUS'],array("waiting"))){
352 $action.= "<input type='image' src='images/edit.png' name='edit_task_".$key."'
353 class='center' alt='"._("Edit")."'>";
354 }
356 /* If WAITING or ERROR add remove action
357 */
358 if( $this->acl_is_removeable() && in_array($task['STATUS'],array("waiting","error"))){
359 $action.= "<input type='image' src='images/edittrash.png' name='remove_task_".$key."'
360 class='center' alt='"._("Remove")."'>";
361 }
363 $color = "";
364 $display = $task['MACADDRESS'];
365 $display2= $task['HEADERTAG'];
367 /* Check if this event exists as Daemon class
368 * In this case, display a more accurate entry.
369 */
370 if(isset($this->events['BY_QUEUED_ACTION'][$task['HEADERTAG']]['s_Menu_Name'])){
371 $event_type = $this->events['BY_QUEUED_ACTION'][$task['HEADERTAG']];
372 $display2= $event_type['s_Menu_Name'];
374 if(strlen($display2) > 20){
375 $display2 = substr($display2,0,18)."...";
376 }
378 if(isset($event_type['ListImage']) && !empty($event_type['ListImage'])){
379 $display2 = $event_type['ListImage']." ".$display2;
380 }
381 }
383 $status = $task['STATUS'];
385 if($status == "waiting"){
386 $status = "<img class='center' src='images/clock.png' alt=''> "._("Waiting");
387 }
388 if($status == "error"){
389 $status = "<img class='center' src='images/false.png' alt=''> "._("Error");
390 }
392 /* Special handling for all entries that have
393 STATUS == "processing" && PROGRESS == NUMERIC
394 */
395 if($status == "processing" && isset($task['PROGRESS'])){
396 $percent = $task['PROGRESS'];
397 $status = "<img src='progress.php?x=80&y=13&p=".$percent."' alt='".$percent." %'>";
398 }
401 /* Create each field */
402 $field0 = array("string" => "<input type='checkbox' id='item_selected_".$task['ID']."' name='item_selected_".$key."'>" ,
403 "attach" => "style='width:20px;".$color."'");
404 $field1 = array("string" => $display,
405 "attach" => "style='".$color."'");
406 $field1a= array("string" => $display2,
407 "attach" => "style='".$color.";width:120px;'");
408 $field2 = array("string" => date("d.m.Y H:i:s",strtotime($task['TIMESTAMP'])),"attach" => "style='".$color.";width:100px;'");
409 $field3 = array("string" => $status,"attach" => "style='".$color.";width:80px;'");
410 $field4 = array("string" => $prio_actions.$action,"attach" => "style='".$color.";text-align:right;width:120px;border-right:0px;'");
411 $divlist->AddElement(array($field0,$field1,$field1a,$field2,$field3,$field4));
412 }
414 $smarty = get_smarty();
415 $smarty->assign("events",$this->events);
416 $smarty->assign("start",$this->start);
417 $smarty->assign("start_real", ($this->start + 1));
418 $smarty->assign("ranges", array("10" => "10",
419 "20" => "20",
420 "25" => "25",
421 "50" => "50",
422 "100"=> "100",
423 "200"=> "200",
424 "9999" => "*"));
426 $count = $this->o_queue->number_of_queued_entries();
427 $smarty->assign("range_selector", range_selector($count, $this->start, $this->range,"range"));
428 $smarty->assign("range",$this->range);
429 $smarty->assign("div",$divlist->Draw());
430 return($smarty->fetch (get_template_path('gotomasses.tpl', TRUE, dirname(__FILE__))));
431 }
434 /*! \brief Move an entry up or down in the queue, by updating its execution timestamp
435 @param $id Integer The ID of the entry which should be updated.
436 @param $type String "up" / "down"
437 @return boolean TRUE in case of success else FALSE
438 */
439 public function update_priority($id,$type = "up")
440 {
441 if($type == "up"){
442 $tmp = $this->o_queue->get_queued_entries($this->event_tags,-1,-1,"timestamp DESC");
443 }else{
444 $tmp = $this->o_queue->get_queued_entries($this->event_tags,-1,-1,"timestamp ASC");
445 }
446 $last = array();
447 foreach($tmp as $entry){
448 if($entry['ID'] == $id){
449 if(count($last)){
450 $time = strtotime($last['TIMESTAMP']);
451 if($type == "up"){
452 $time ++;
453 }else{
454 $time --;
455 }
456 $time_str = date("YmdHis",$time);
457 return($this->o_queue->update_entries(array($id),array("timestamp" => $time_str)));
458 }else{
459 return(FALSE);
460 }
461 }
462 $last = $entry;
463 }
464 return(FALSE);
465 }
468 /*! \brief Resumes to status 'waiting'.
469 * @return Boolean TRUE in case of success, else FALSE.
470 */
471 private function resume_queue_entries($ids)
472 {
473 if(!count($ids)){
474 return;
475 }
477 /* Entries are resumed by setting the status to
478 * 'waiting'
479 */
480 $data = array("status" => "waiting");
482 /* Check if given ids are valid and check if the status
483 * allows resuming.
484 */
485 $update_ids = array();
486 foreach($this->o_queue->get_entries_by_id($ids) as $entry){
487 if(isset($entry['STATUS']) && preg_match("/paused/",$entry['STATUS'])){
488 $update_ids[] = $entry['ID'];
489 }
490 }
492 /* Tell the daemon that we have entries to update.
493 */
494 if(count($update_ids)){
495 if(!$this->o_queue->update_entries($update_ids,$data)){
496 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
497 return(FALSE);
498 }
499 }
500 return(TRUE);
501 }
504 /*! \brief Force queue job to be done as far as possible.
505 * @return Boolean TRUE in case of success, else FALSE.
506 */
507 private function execute_queue_entries($ids)
508 {
509 if(!count($ids)){
510 return;
511 }
513 /* Execution is forced by updating the status to
514 * waiting and setting the timestamp to current time.
515 */
516 $data = array( "timestamp" => date("YmdHis",time()),
517 "status" => "waiting");
519 /* Only allow execution of paused or waiting entries
520 */
521 $update_ids = array();
522 foreach($this->o_queue->get_entries_by_id($ids) as $entry){
523 if(in_array($entry['STATUS'],array("paused","waiting"))){
524 $update_ids[] = $entry['ID'];
525 }
526 }
528 /* Tell the daemon that we want to update some entries
529 */
530 if(count($update_ids)){
531 if(!$this->o_queue->update_entries($update_ids,$data)){
532 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entries.")) , ERROR_DIALOG);
533 return(FALSE);
534 }
535 }
536 return(TRUE);
537 }
540 /*! \brief Force queue job to be done as far as possible.
541 * @return Boolean TRUE in case of success, else FALSE.
542 */
543 private function abort_queue_entries($ids)
544 {
545 if(!count($ids)){
546 return;
547 }
549 /* Entries are paused by setting the status to
550 * something different from 'waiting'.
551 * We simply use 'paused'.
552 */
553 $data = array("status" => "paused");
555 /* Detect if the ids we got are valid and
556 * check if the status allows pausing.
557 */
558 $update_ids = array();
559 foreach($this->o_queue->get_entries_by_id($ids) as $entry){
560 if(isset($entry['STATUS']) && preg_match("/processing/",$entry['STATUS'])){
561 if(isset($entry['MACADDRESS'])){
562 $update_ids[] = $entry['MACADDRESS'];
563 }else{
564 trigger_error("No mac address found in event.");
565 }
566 }
567 }
569 if(class_available("DaemonEvent_faireboot")){
570 $tmp = new DaemonEvent_faireboot($this->config);
571 $tmp->add_targets($update_ids);
572 if(!$this->o_queue->append($tmp)){
573 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
574 return(FALSE);
575 }
576 }else{
577 msg_dialog::display(_("Error"),
578 sprintf(_("The Job could not be aborted, the '%s' event class was not found."),
579 "DaemonEvent_faireboot") , ERROR_DIALOG);
580 }
581 }
584 /*! \brief Pauses the specified queue entry from execution.
585 * @return Boolean TRUE in case of success, else FALSE.
586 */
587 private function pause_queue_entries($ids)
588 {
589 if(!count($ids)){
590 return;
591 }
593 /* Entries are paused by setting the status to
594 * something different from 'waiting'.
595 * We simply use 'paused'.
596 */
597 $data = array("status" => "paused");
599 /* Detect if the ids we got are valid and
600 * check if the status allows pausing.
601 */
602 $update_ids = array();
603 foreach($this->o_queue->get_entries_by_id($ids) as $entry){
604 if(isset($entry['STATUS']) && preg_match("/waiting/",$entry['STATUS'])){
605 $update_ids[] = $entry['ID'];
606 }
607 }
609 /* Tell the daemon that we want to update some entries
610 */
611 if(count($update_ids)){
612 if(!$this->o_queue->update_entries($update_ids,$data)){
613 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
614 return(FALSE);
615 }
616 }
617 return(TRUE);
618 }
621 /*! \brief Request list of queued jobs.
622 * @return Returns an array of all queued jobs.
623 */
624 function reload()
625 {
627 /* Sort map html-post-name => daemon-col-name
628 */
629 $map = array(
630 "QueuePosition" => "id",
631 "Action" => "status",
632 "TaskID" => "headertag",
633 "TargetName" => "macaddress",
634 "Schedule" => "timestamp");
636 /* Create sort header
637 */
638 if(!isset($map[$this->sort_by])){
639 $sort = "id DESC";
640 }else{
641 $sort = $map[$this->sort_by];
642 if($this->sort_dir == "up"){
643 $sort.= " ASC";
644 }else{
645 $sort.= " DESC";
646 }
647 }
649 /* Get entries. */
650 $start = $this->start;
651 $stop = $this->range;
652 $entries = $this->o_queue->get_queued_entries($this->event_tags,$start,$stop,$sort);
653 if ($this->o_queue->is_error()){
654 msg_dialog::display(_("Error"), sprintf(_("Cannot load queue entries: %s"), "<br><br>".$this->o_queue->get_error()), ERROR_DIALOG);
655 }
657 /* Assign entries by id.
658 */
659 $this->entries = array();
660 foreach($entries as $entry){
661 $this->entries[$entry['ID']]= $entry;
662 }
663 }
666 /*! \brief Handle post jobs, like sorting.
667 */
668 function save_object()
669 {
670 /* Check for sorting changes
671 */
672 $sort_vals = array("Action","QueuePosition","TargetName","Schedule","TaskID");
673 if(isset($_GET['sort']) && in_array($_GET['sort'],$sort_vals)){
674 $sort = $_GET['sort'];
675 if($this->sort_by == $sort){
676 if($this->sort_dir == "up"){
677 $this->sort_dir = "down";
678 }else{
679 $this->sort_dir = "up";
680 }
681 }
682 $this->sort_by = $sort;
683 }
685 /* Range selection used? */
686 if(isset($_POST['range']) && is_numeric($_POST['range'])){
687 $this->range = $_POST['range'];
688 }
690 /* Page changed. */
691 if(isset($_GET['start'])){
692 $start = $_GET['start'];
693 if(is_numeric($start) || $start == 0){
694 $this->start = $start;
695 }
696 }
698 /* Check start stop and reset if necessary */
699 $count = $this->o_queue->number_of_queued_entries();
700 if($this->start >= $count){
701 $this->start = $count -1;
702 }
703 if($this->start < 0){
704 $this->start = 0;
705 }
706 }
709 function save()
710 {
711 // We do not save anything here.
712 }
715 /*! \brief Return a list of all selected items.
716 @return Array Returns an array containing all selected item ids.
717 */
718 function list_get_selected_items()
719 {
720 $ids = array();
721 foreach($_POST as $name => $value){
722 if(preg_match("/^item_selected_[0-9]*$/",$name)){
723 $id = preg_replace("/^item_selected_/","",$name);
724 $ids[$id] = $id;
725 }
726 }
727 return($ids);
728 }
731 static function plInfo()
732 {
733 return (array(
734 "plShortName" => _("System mass deployment"),
735 "plDescription" => _("Provide a mechanism to automatically activate a set of systems"),
736 "plSelfModify" => FALSE,
737 "plDepends" => array(),
738 "plPriority" => 0,
739 "plSection" => array("addon"),
740 "plCategory" => array("gotomasses" => array("objectClass" => "none", "description" => _("System mass deployment"))),
741 "plProvidedAcls" => array("Comment" => _("Description"))
742 ));
743 }
744 }
745 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
746 ?>