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();
21 var $sort_by = "Schedule";
22 var $sort_dir = "down";
23 var $entries = array();
24 var $range = 25;
25 var $start = 0;
27 function gotomasses(&$config, $dn= NULL)
28 {
29 /* Include config object */
30 $this->config= &$config;
31 $this->o_queue = new gosaSupportDaemon(TRUE,10);
32 $this->events = DaemonEvent::get_event_types();
33 }
36 function execute()
37 {
38 $smarty = get_smarty();
40 /************
41 * Handle posts
42 ************/
44 $s_entry = $s_action = "";
45 $arr = array(
46 "/^stop_/" => "stop",
47 "/^stop_all/" => "stop_all",
48 "/^start_/" => "start",
49 "/^start_all/" => "start_all",
51 "/^prio_up_/" => "prio_up",
52 "/^prio_down_/" => "prio_down",
54 "/^edit_task_/" => "edit",
55 "/^remove_task_/" => "remove",
56 "/^new_task_/" => "new_task",
57 "/^remove_multiple_task_/" => "remove_multiple");
59 foreach($arr as $regex => $action){
60 foreach($_POST as $name => $value){
61 if(preg_match($regex,$name)){
62 $s_action = $action;
63 $s_entry = preg_replace($regex,"",$name);
64 $s_entry = preg_replace("/_(x|y)$/","",$s_entry);
65 }
66 }
67 }
69 /* Menu actions */
70 if(isset($_POST['menu_action']) && !empty($_POST['menu_action'])){
71 $s_action = $_POST['menu_action'];
72 }
74 /* Edit posted from list link */
75 if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id']) && isset($this->tasks[$_GET['id']])){
76 $s_action = "edit";
77 $s_entry = $_GET['id'];
78 }
81 /************
82 * Handle Priority modifications
83 ************/
85 if(preg_match("/^prio_/",$s_action)){
87 switch($s_action){
89 case 'prio_down' : $this->update_priority($s_entry,"down");break;
90 case 'prio_up' : $this->update_priority($s_entry,"up");break;
91 }
92 }
94 /************
95 * Handle start/stop modifications
96 ************/
98 if(preg_match("/^start/",$s_action) || preg_match("/^stop/",$s_action)){
100 switch($s_action){
101 case 'start_all' : $this->start_queue_entries($this->list_get_selected_items());break;
102 case 'start' : $this->start_queue_entries(array($s_entry));break;
103 case 'stop_all' : $this->stop_queue_entries ($this->list_get_selected_items());break;
104 case 'stop' : $this->stop_queue_entries (array($s_entry));break;
105 default : trigger_error("Undefined priority setting used.");
106 }
107 if($this->o_queue->is_error()){
108 msg_dialog::display(_("Error"), $this->o_queue->get_error(), ERROR_DIALOG);
109 }
110 }
112 /************
113 * ADD
114 ************/
116 if(preg_match("/^add_event_/",$s_action)){
117 $type = preg_replace("/^add_event_/","",$s_action);
118 if(isset($this->events[$type])){
119 $e_data = $this->events[$type];
120 $this->dialog = new $e_data['NAME']($this->config);
121 }
122 }
124 /************
125 * EDIT
126 ************/
128 if($s_action == "edit"){
129 $id = $s_entry;
130 $type = FALSE;
131 if(isset($this->entries[$id])){
132 $event = $this->entries[$s_entry];
133 if(isset($this->events['BY_EDIT_ACTION'][$event['HEADERTAG']])){
134 $type = $this->events['BY_EDIT_ACTION'][$event['HEADERTAG']];
135 $this->dialog = new $type['CLASS_NAME']($this->config,$event);
136 }
137 }
138 }
140 /************
141 * REMOVE
142 ************/
144 /* Remove multiple */
145 if($s_action == "remove_multiple" || $s_action == "remove"){
147 if(!$this->acl_is_removeable()){
148 msg_dialog::display(_("Permission error"), _("You have no permission to delete this entry!"), ERROR_DIALOG);
149 }else{
151 if($s_action == "remove"){
152 $ids = array($s_entry);
153 }else{
154 $ids = $this->list_get_selected_items();
155 }
156 if(count($ids)){
157 $this->ids_to_remove = $ids;
158 $ret = $this->o_queue->ids_exist($this->ids_to_remove);
159 $ret = $this->o_queue->get_entries_by_id($ret);
161 $tmp = "";
162 foreach($ret as $task){
163 $tmp.= "\n".$task['ID']." - ".$task['HEADERTAG']." ".$task['MACADDRESS'];
164 }
165 $smarty->assign("multiple", TRUE);
166 $smarty->assign("info",sprintf(_("Your are about to delete the following tasks: %s"),"<pre>".$tmp."</pre>"));
167 $this->current = $s_entry;
168 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
169 }
170 }
171 }
173 /* Remove specified tasks */
174 if(count($this->ids_to_remove) && isset($_POST['delete_multiple_confirm'])){
175 $this->o_queue->remove_entries($this->ids_to_remove);
176 $this->save();
177 }
179 /* Remove aborted */
180 if(isset($_POST['delete_cancel'])){
181 $this->ids_to_remove = array();;
182 }
185 /************
186 * EDIT
187 ************/
189 /* Close dialog */
190 if(isset($_POST['save_event_dialog'])){
192 if(is_object($this->dialog)){
194 if($this->dialog->is_new()){
195 $header = $this->dialog->get_header_tag();
196 $targets = $this->dialog->get_targets();
197 $data = $this->dialog->save();
198 $data['timestamp'] = $this->dialog->get_timestamp();
201 foreach($targets as $target){
202 $data['mac'] = $target;
203 if(!$this->o_queue->send($header,$target,$data,TRUE)){
204 msg_dialog::display(_("Daemon"),sprintf(_("Something went wrong while talking to the daemon: %s."),
205 $this->o_queue->get_error()),ERROR_DIALOG);
206 }
207 }
208 $this->dialog = FALSE;
209 $this->current = -1;
210 }else{
211 $id = $this->dialog->get_id();
212 $data = $this->dialog->save();
213 $data['timestamp'] = $this->dialog->get_timestamp();
214 if($this->o_queue->update_entries(array($id),$data)){
215 $this->dialog = FALSE;
216 $this->current = -1;
217 }
218 }
219 }
220 }
223 /* Close dialog */
224 if(isset($_POST['abort_event_dialog'])){
225 $this->dialog = FALSE;
226 $this->current = -1;
227 }
229 /* Display dialogs if currently opened */
230 if(is_object($this->dialog)){
231 $this->dialog->save_object();
232 return($this->dialog->execute());
233 }
235 /************
236 * Handle Divlist
237 ************/
239 $divlist = new MultiSelectWindow($this->config,"gotoMasses",array("gotomasses"));
240 $divlist->SetInformation(_("This menu allows you to remove and change the properties of GOsa deamon tasks."));
241 $divlist->SetSummary(_("List of queued deamon jobs."));
242 $divlist->EnableCloseButton(FALSE);
243 $divlist->EnableSaveButton(FALSE);
244 $divlist->SetHeadpageMode();
245 $s = ".|"._("Actions")."|\n";
246 $s.= "..|<img src='images/list_new.png' alt='' border='0' class='center'> "._("Create")."\n";
247 foreach($this->events['BY_CLASS'] as $name => $event){
248 $s.= "...|".$event['MenuImage']." ".$event['s_Menu_Name']."|add_event_".$name."\n";
249 }
251 $divlist->SetDropDownHeaderMenu($s);
253 if($this->sort_dir == "up"){
254 $sort_img = "<img src='images/sort_up.png' alt='/\' border=0>";
255 }else{
256 $sort_img = "<img src='images/sort_down.png' alt='\/' border=0>";
257 }
259 if($this->sort_by == "TargetName"){ $sort_img_1 = $sort_img; } else { $sort_img_1 = "" ;}
260 if($this->sort_by == "TaskID"){ $sort_img_2 = $sort_img; } else { $sort_img_2 = "" ;}
261 if($this->sort_by == "Schedule"){ $sort_img_3 = $sort_img; } else { $sort_img_3 = "" ;}
262 if($this->sort_by == "Action"){ $sort_img_4 = $sort_img; } else { $sort_img_4 = "" ;}
264 /* Display add button if allowed */
265 $header = "<div style='padding:5px'>";
266 if($this->acl_is_removeable()){
267 $header .= "<input type='image' src='images/edittrash.png' name='remove_multiple_task' class='center'> ";
268 }
269 if(preg_match("/w/",$this->getacl(""))){
270 $header .= "<input type='image' src='images/status_stop_all.png' name='stop_all' class='center'> ";
271 $header .= "<input type='image' src='images/status_start_all.png' name='start_all' class='center'> ";
272 }
273 $header .= "</div>";
275 /* Create divlist */
276 $divlist->SetListHeader($header);
278 $plug = $_GET['plug'];
279 $chk = "<input type='checkbox' id='select_all' name='select_all'
280 onClick='toggle_all_(\"^item_selected_[0-9]*$\",\"select_all\");' >";
282 /* set Page header */
283 $divlist->AddHeader(array("string"=> $chk, "attach"=>"style='width:20px;'"));
284 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=TargetName'>"._("Target").$sort_img_1."</a>"));
285 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=TaskID'>"._("Task").$sort_img_2."</a>",
286 "attach"=>"style='width:80px;'"));
287 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Schedule'>"._("Schedule").$sort_img_3."</a>",
288 "attach"=>"style='width:100px;'"));
289 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Action'>"._("Status").$sort_img_4."</a>",
290 "attach"=>"style='width:80px;'"));
291 $divlist->AddHeader(array("string"=>_("Action"),
292 "attach"=>"style='border-right:0px;width:120px;'"));
295 /* Reload the list of entries */
296 $this->reload();
298 foreach($this->entries as $key => $task){
300 $prio_actions = "<input class='center' type='image' src='images/prio_increase.png' name='prio_up_".$key."'> ";
301 $prio_actions.= "<input class='center' type='image' src='images/prio_decrease.png' name='prio_down_".$key."'> ";
302 $prio_actions.= "<input class='center' type='image' src='images/status_stop_all.png' name='stop_".$key."'> ";
303 $prio_actions.= "<input class='center' type='image' src='images/status_start_all.png' name='start_".$key."'> ";
305 $action = "<input type='image' src='images/edit.png' name='edit_task_".$key."'
306 class='center' alt='"._("Edit")."'>";
308 if($this->acl_is_removeable()){
309 $action.= "<input type='image' src='images/edittrash.png' name='remove_task_".$key."'
310 class='center' alt='"._("Reomve")."'>";
311 }
313 $color = "";
314 $display = $task['MACADDRESS'];
315 $display2= $task['HEADERTAG'];
317 if( isset($this->events['BY_EDIT_ACTION'][$display2]['ListImage']) &&
318 !empty($this->events['BY_EDIT_ACTION'][$display2]['ListImage'])){
319 $display2 = $this->events['BY_EDIT_ACTION'][$display2]['ListImage'];
320 }
322 /* Create each field */
323 $field0 = array("string" => "<input type='checkbox' id='item_selected_".$key."' name='item_selected_".$key."'>" ,
324 "attach" => "style='width:20px;".$color."'");
325 $field1 = array("string" => $display,
326 "attach" => "style='".$color."'");
327 $field1a= array("string" => $display2,
328 "attach" => "style='".$color.";width:80px; text-align:right;'");
329 $field2 = array("string" => date("d.m.Y H:i:s",strtotime($task['TIMESTAMP'])),"attach" => "style='".$color.";width:100px;'");
330 $field3 = array("string" => $task['STATUS'],"attach" => "style='".$color.";width:80px;'");
331 $field4 = array("string" => $prio_actions.$action,"attach" => "style='".$color.";text-align:right;width:120px;border-right:0px;'");
332 $divlist->AddElement(array($field0,$field1,$field1a,$field2,$field3,$field4));
333 }
335 $smarty = get_smarty();
336 $smarty->assign("events",$this->events);
337 $smarty->assign("start",$this->start);
338 $smarty->assign("start_real", ($this->start + 1));
339 $smarty->assign("ranges", array("10" => "10",
340 "20" => "20",
341 "25" => "25",
342 "50" => "50",
343 "100"=> "100",
344 "200"=> "200",
345 "9999" => "*"));
347 $count = $this->o_queue->number_of_queued_entries();
348 $smarty->assign("range_selector", range_selector($count, $this->start, $this->range,"range"));
349 $smarty->assign("range",$this->range);
350 $smarty->assign("div",$divlist->Draw());
351 return($smarty->fetch (get_template_path('gotomasses.tpl', TRUE, dirname(__FILE__))));
352 }
355 /*! \brief Move an entry up or down in the queue, by updating its execution timestamp
356 @param $id Integer The ID of the entry which should be updated.
357 @param $type String "up" / "down"
358 @return boolean TRUE in case of success else FALSE
359 */
360 public function update_priority($id,$type = "up")
361 {
362 if($type == "up"){
363 $tmp = $this->o_queue->get_queued_entries(-1,-1,"timestamp DESC");
364 }else{
365 $tmp = $this->o_queue->get_queued_entries(-1,-1,"timestamp ASC");
366 }
367 $last = array();
368 foreach($tmp as $entry){
369 if($entry['ID'] == $id){
370 if(count($last)){
371 $time = strtotime($last['TIMESTAMP']);
372 if($type == "up"){
373 $time ++;
374 }else{
375 $time --;
376 }
377 $time_str = date("YmdHis",$time);
378 return($this->o_queue->update_entries(array($id),array("timestamp" => $time_str)));
379 }else{
380 return(FALSE);
381 }
382 }
383 $last = $entry;
384 }
385 return(FALSE);
386 }
389 /*! \brief Force queue job to be done as far as possible.
390 * @return Boolean TRUE in case of success, else FALSE.
391 */
392 private function start_queue_entries($ids)
393 {
394 if(!count($ids)){
395 return;
396 }
398 $data = array("timestamp" => date("YmdHis"),
399 "status" => "-");
400 if(!$this->o_queue->update_entries($ids,$data)){
401 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
402 return(FALSE);
403 }
404 return(TRUE);
405 }
408 /*! \brief Stops the specified queue entry from execution.
409 * @return Boolean TRUE in case of success, else FALSE.
410 */
411 private function stop_queue_entries($ids)
412 {
413 if(!count($ids)){
414 return;
415 }
416 $data = array("timestamp" => date("YmdHis",(time() + (60*60*24*365))),
417 "status" => _("Stoppped"));
418 if(!$this->o_queue->update_entries($ids,$data)){
419 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
420 return(FALSE);
421 }
422 return(TRUE);
423 }
426 /*! \brief Request list of queued jobs.
427 * @return Returns an array of all queued jobs.
428 */
429 function reload()
430 {
431 $map = array(
432 "QueuePosition" => "id",
433 "Action" => "status",
434 "TaskID" => "headertag",
435 "TargetName" => "macaddress",
436 "Schedule" => "timestamp");
438 if(!isset($map[$this->sort_by])){
439 $sort = "id DESC";
440 }else{
441 $sort = $map[$this->sort_by];
442 if($this->sort_dir == "up"){
443 $sort.= " ASC";
444 }else{
445 $sort.= " DESC";
446 }
447 }
449 $start = $this->start;
450 $stop = $this->range;
452 $entries = $this->o_queue->get_queued_entries($start,$stop,$sort);
453 if ($this->o_queue->is_error()){
455 msg_dialog::display(_("Error"), sprintf(_("Cannot load queue entries: %s"), "<br><br>".$this->o_queue->get_error()), ERROR_DIALOG);
456 }
458 $this->entries = array();
459 foreach($entries as $entry){
460 $this->entries[]= $entry;
461 }
462 }
465 /*! \brief Handle post jobs, like sorting.
466 */
467 function save_object()
468 {
469 $sort_vals = array("Action","QueuePosition","TargetName","Schedule","TaskID");
470 if(isset($_GET['sort']) && in_array($_GET['sort'],$sort_vals)){
471 $sort = $_GET['sort'];
472 if($this->sort_by == $sort){
473 if($this->sort_dir == "up"){
474 $this->sort_dir = "down";
475 }else{
476 $this->sort_dir = "up";
477 }
478 }
479 $this->sort_by = $sort;
480 }
481 if(isset($_POST['range']) && is_numeric($_POST['range'])){
482 $this->range = $_POST['range'];
483 }
484 if(isset($_GET['start'])){
485 $start = $_GET['start'];
486 if(is_numeric($start) || $start == 0){
487 $this->start = $start;
488 }
489 }
491 /* Check start stop and reset if necessary */
492 $count = $this->o_queue->number_of_queued_entries();
493 if($this->start >= $count){
494 $this->start = $count -1;
495 }
496 if($this->start < 0){
497 $this->start = 0;
498 }
499 }
502 /* Return list of object groups */
503 function get_object_groups()
504 {
505 $ret = array();
506 $ldap = $this->config->get_ldap_link();
507 $ldap->cd($this->config->current['BASE']);
508 $ldap->search("(&(objectClass=gosaGroupOfNames)(cn=*))",array("cn"));
509 while($attrs = $ldap->fetch()){
510 $ret[$attrs['cn'][0]] = $attrs['cn'][0];
511 }
512 return($ret);
513 }
516 function save()
517 {
518 // We do not save anything here.
519 }
522 /*! \brief Return a list of all selected items.
523 @return Array Returns an array containing all selected item ids.
524 */
525 function list_get_selected_items()
526 {
527 $ids = array();
528 foreach($_POST as $name => $value){
529 if(preg_match("/^item_selected_[0-9]*$/",$name)){
530 $id = preg_replace("/^item_selected_/","",$name);
531 $ids[$id] = $id;
532 }
533 }
534 return($ids);
535 }
538 static function plInfo()
539 {
540 return (array(
541 "plShortName" => _("System mass deployment"),
542 "plDescription" => _("Provide a mechanism to automatically activate a set of systems"),
543 "plSelfModify" => FALSE,
544 "plDepends" => array(),
545 "plPriority" => 0,
546 "plSection" => array("addon"),
547 "plCategory" => array("gotomasses" => array("objectClass" => "none", "description" => _("System mass deployment"))),
548 "plProvidedAcls" => array("Comment" => _("Description"),
549 "Action" => _("Action"),
550 "Day" => _("Day"),
551 "Minute" => _("Minute"),
552 "Hour" => _("Hour"),
553 "Month" => _("Month"),
554 "Weekday" => _("Week day"),
555 "Target" => _("Target"))
556 ));
557 }
558 }
559 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
560 ?>