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 * REMOVE
126 ************/
128 /* Remove multiple */
129 if($s_action == "remove_multiple" || $s_action == "remove"){
131 if(!$this->acl_is_removeable()){
132 msg_dialog::display(_("Permission error"), _("You have no permission to delete this entry!"), ERROR_DIALOG);
133 }else{
135 if($s_action == "remove"){
136 $ids = array($s_entry);
137 }else{
138 $ids = $this->list_get_selected_items();
139 }
140 if(count($ids)){
141 $this->ids_to_remove = $ids;
142 $ret = $this->o_queue->ids_exist($this->ids_to_remove);
143 $ret = $this->o_queue->get_entries_by_id($ret);
145 $tmp = "";
146 foreach($ret as $task){
147 $tmp.= "\n".$task['ID']." - ".$task['HEADERTAG']." ".$task['MACADDRESS'];
148 }
149 $smarty->assign("multiple", TRUE);
150 $smarty->assign("info",sprintf(_("Your are about to delete the following tasks: %s"),"<pre>".$tmp."</pre>"));
151 $this->current = $s_entry;
152 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
153 }
154 }
155 }
157 /* Remove specified tasks */
158 if(count($this->ids_to_remove) && isset($_POST['delete_multiple_confirm'])){
159 $this->o_queue->remove_entries($this->ids_to_remove);
160 $this->save();
161 }
163 /* Remove aborted */
164 if(isset($_POST['delete_cancel'])){
165 $this->ids_to_remove = array();;
166 }
169 /************
170 * EDIT
171 ************/
173 /* Close dialog */
174 if(isset($_POST['save_event_dialog'])){
176 if($this->dialog->is_new()){
177 $header = $this->dialog->get_header_tag();
178 $targets = $this->dialog->get_targets();
179 $data = $this->dialog->save();
180 $data['TIMESTAMP'] = $this->dialog->get_timestamp();
182 foreach($targets as $target){
183 if(!$this->o_queue->send($header,$target,$data)){
184 msg_dialog::display(_("Daemon"),sprintf(_("Something went wrong while talking to the daemon: %s."),
185 $this->o_queue->get_error()),ERROR_DIALOG);
186 }
187 }
188 $this->dialog = FALSE;
189 $this->current = -1;
190 }
191 }
194 /* Close dialog */
195 if(isset($_POST['abort_event_dialog'])){
196 $this->dialog = FALSE;
197 $this->current = -1;
198 }
200 /* Display dialogs if currently opened */
201 if(is_object($this->dialog)){
202 $this->dialog->save_object();
203 return($this->dialog->execute());
204 }
206 /************
207 * Handle Divlist
208 ************/
210 $divlist = new MultiSelectWindow($this->config,"gotoMasses",array("gotomasses"));
211 $divlist->SetInformation(_("This menu allows you to remove and change the properties of GOsa deamon tasks."));
212 $divlist->SetSummary(_("List of queued deamon jobs."));
213 $divlist->EnableCloseButton(FALSE);
214 $divlist->EnableSaveButton(FALSE);
215 $divlist->SetHeadpageMode();
216 $s = ".|"._("Actions")."|\n";
217 $s.= "..|<img src='images/list_new.png' alt='' border='0' class='center'> "._("Create")."\n";
218 foreach($this->events as $name => $event){
219 $s.= "...|".$event['MenuImage']." ".$event['MenuName']."|add_event_".$name."\n";
220 }
222 $divlist->SetDropDownHeaderMenu($s);
224 if($this->sort_dir == "up"){
225 $sort_img = "<img src='images/sort_up.png' alt='/\' border=0>";
226 }else{
227 $sort_img = "<img src='images/sort_down.png' alt='\/' border=0>";
228 }
230 if($this->sort_by == "TargetName"){ $sort_img_1 = $sort_img; } else { $sort_img_1 = "" ;}
231 if($this->sort_by == "TaskID"){ $sort_img_2 = $sort_img; } else { $sort_img_2 = "" ;}
232 if($this->sort_by == "Schedule"){ $sort_img_3 = $sort_img; } else { $sort_img_3 = "" ;}
233 if($this->sort_by == "Action"){ $sort_img_4 = $sort_img; } else { $sort_img_4 = "" ;}
235 /* Display add button if allowed */
236 $header = "<div style='padding:5px'>";
237 if($this->acl_is_removeable()){
238 $header .= "<input type='image' src='images/edittrash.png' name='remove_multiple_task' class='center'> ";
239 }
240 if(preg_match("/w/",$this->getacl(""))){
241 $header .= "<input type='image' src='images/status_stop_all.png' name='stop_all' class='center'> ";
242 $header .= "<input type='image' src='images/status_start_all.png' name='start_all' class='center'> ";
243 }
244 $header .= "</div>";
246 /* Create divlist */
247 $divlist->SetListHeader($header);
249 $plug = $_GET['plug'];
250 $chk = "<input type='checkbox' id='select_all' name='select_all'
251 onClick='toggle_all_(\"^item_selected_[0-9]*$\",\"select_all\");' >";
253 /* set Page header */
254 $divlist->AddHeader(array("string"=> $chk, "attach"=>"style='width:20px;'"));
255 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=TargetName'>"._("Target").$sort_img_1."</a> / ".
256 "<a href='?plug=".$plug."&sort=TaskID'>"._("Task").$sort_img_2."</a>"));
257 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Schedule'>"._("Schedule").$sort_img_3."</a>",
258 "attach"=>"style='width:100px;'"));
259 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Action'>"._("Status").$sort_img_4."</a>",
260 "attach"=>"style='width:80px;'"));
261 $divlist->AddHeader(array("string"=>_("Action"),
262 "attach"=>"style='border-right:0px;width:120px;'"));
265 /* Reload the list of entries */
266 $this->reload();
268 foreach($this->entries as $key => $task){
271 $prio_actions = "<input class='center' type='image' src='images/prio_increase.png' name='prio_up_".$task['ID']."'> ";
272 $prio_actions.= "<input class='center' type='image' src='images/prio_decrease.png' name='prio_down_".$task['ID']."'> ";
273 $prio_actions.= "<input class='center' type='image' src='images/status_stop_all.png' name='stop_".$task['ID']."'> ";
274 $prio_actions.= "<input class='center' type='image' src='images/status_start_all.png' name='start_".$task['ID']."'> ";
276 $action = "<input type='image' src='images/edit.png' name='edit_task_".$task['ID']."'
277 class='center' alt='"._("Edit")."'>";
279 if($this->acl_is_removeable()){
280 $action.= "<input type='image' src='images/edittrash.png' name='remove_task_".$task['ID']."'
281 class='center' alt='"._("Reomve")."'>";
282 }
284 $color = "";
285 $display = $task['MACADDRESS'];
286 $display2= $task['HEADERTAG'];
288 /* Create each field */
289 $field0 = array("string" => "<input type='checkbox' id='item_selected_".$task['ID']."' name='item_selected_".$task['ID']."'>" ,
290 "attach" => "style='width:20px;".$color."'");
291 $field1 = array("string" => $display,
292 "attach" => "style='".$color."'");
293 $field1a= array("string" => $display2,
294 "attach" => "style='".$color.";width:80px;'");
295 $field2 = array("string" => date("d.m.Y H:i:s",strtotime($task['TIMESTAMP'])),"attach" => "style='".$color.";width:100px;'");
296 $field3 = array("string" => $task['STATUS'],"attach" => "style='".$color.";width:80px;'");
297 $field4 = array("string" => $prio_actions.$action,"attach" => "style='".$color.";text-align:right;width:120px;border-right:0px;'");
298 $divlist->AddElement(array($field0,$field1,$field1a,$field2,$field3,$field4));
299 }
302 $smarty = get_smarty();
303 $smarty->assign("start",$this->start);
304 $smarty->assign("start_real", ($this->start + 1));
305 $smarty->assign("ranges", array("10" => "10",
306 "20" => "20",
307 "25" => "25",
308 "50" => "50",
309 "100"=> "100",
310 "200"=> "200",
311 "9999" => "*"));
313 $count = $this->o_queue->number_of_queued_entries();
314 $smarty->assign("range_selector", range_selector($count, $this->start, $this->range,"range"));
315 $smarty->assign("range",$this->range);
316 $smarty->assign("div",$divlist->Draw());
317 return($smarty->fetch (get_template_path('gotomasses.tpl', TRUE, dirname(__FILE__))));
318 }
321 /*! \brief Move an entry up or down in the queue, by updating its execution timestamp
322 @param $id Integer The ID of the entry which should be updated.
323 @param $type String "up" / "down"
324 @return boolean TRUE in case of success else FALSE
325 */
326 public function update_priority($id,$type = "up")
327 {
328 if($type == "up"){
329 $tmp = $this->o_queue->get_queued_entries(-1,-1,"timestamp DESC");
330 }else{
331 $tmp = $this->o_queue->get_queued_entries(-1,-1,"timestamp ASC");
332 }
333 $last = array();
334 foreach($tmp as $entry){
335 if($entry['ID'] == $id){
336 if(count($last)){
337 $time = strtotime($last['TIMESTAMP']);
338 if($type == "up"){
339 $time ++;
340 }else{
341 $time --;
342 }
343 $time_str = date("YmdHis",$time);
344 return($this->o_queue->update_entries(array($id),array("timestamp" => $time_str)));
345 }else{
346 return(FALSE);
347 }
348 }
349 $last = $entry;
350 }
351 return(FALSE);
352 }
355 /*! \brief Force queue job to be done as far as possible.
356 * @return Boolean TRUE in case of success, else FALSE.
357 */
358 private function start_queue_entries($ids)
359 {
360 if(!count($ids)){
361 return;
362 }
364 $data = array("timestamp" => date("YmdHis"),
365 "status" => "-");
366 if(!$this->o_queue->update_entries($ids,$data)){
367 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
368 return(FALSE);
369 }
370 return(TRUE);
371 }
374 /*! \brief Stops the specified queue entry from execution.
375 * @return Boolean TRUE in case of success, else FALSE.
376 */
377 private function stop_queue_entries($ids)
378 {
379 if(!count($ids)){
380 return;
381 }
382 $data = array("timestamp" => date("YmdHis",(time() + (60*60*24*365))),
383 "status" => _("Stoppped"));
384 if(!$this->o_queue->update_entries($ids,$data)){
385 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
386 return(FALSE);
387 }
388 return(TRUE);
389 }
392 /*! \brief Request list of queued jobs.
393 * @return Returns an array of all queued jobs.
394 */
395 function reload()
396 {
397 $map = array(
398 "QueuePosition" => "id",
399 "Action" => "status",
400 "TaskID" => "headertag",
401 "TargetName" => "macaddress",
402 "Schedule" => "timestamp");
404 if(!isset($map[$this->sort_by])){
405 $sort = "id DESC";
406 }else{
407 $sort = $map[$this->sort_by];
408 if($this->sort_dir == "up"){
409 $sort.= " ASC";
410 }else{
411 $sort.= " DESC";
412 }
413 }
415 $start = $this->start;
416 $stop = $this->range;
418 $entries = $this->o_queue->get_queued_entries($start,$stop,$sort);
419 if ($this->o_queue->is_error()){
421 msg_dialog::display(_("Error"), sprintf(_("Cannot load queue entries: %s"), "<br><br>".$this->o_queue->get_error()), ERROR_DIALOG);
422 }
424 $this->entries = array();
425 foreach($entries as $entry){
426 $this->entries[]= $entry;
427 }
428 }
431 /*! \brief Handle post jobs, like sorting.
432 */
433 function save_object()
434 {
435 $sort_vals = array("Action","QueuePosition","TargetName","Schedule","TaskID");
436 if(isset($_GET['sort']) && in_array($_GET['sort'],$sort_vals)){
437 $sort = $_GET['sort'];
438 if($this->sort_by == $sort){
439 if($this->sort_dir == "up"){
440 $this->sort_dir = "down";
441 }else{
442 $this->sort_dir = "up";
443 }
444 }
445 $this->sort_by = $sort;
446 }
447 if(isset($_POST['range']) && is_numeric($_POST['range'])){
448 $this->range = $_POST['range'];
449 }
450 if(isset($_GET['start'])){
451 $start = $_GET['start'];
452 if(is_numeric($start) || $start == 0){
453 $this->start = $start;
454 }
455 }
457 /* Check start stop and reset if necessary */
458 $count = $this->o_queue->number_of_queued_entries();
459 if($this->start >= $count){
460 $this->start = $count -1;
461 }
462 if($this->start < 0){
463 $this->start = 0;
464 }
465 }
468 /* Return list of object groups */
469 function get_object_groups()
470 {
471 $ret = array();
472 $ldap = $this->config->get_ldap_link();
473 $ldap->cd($this->config->current['BASE']);
474 $ldap->search("(&(objectClass=gosaGroupOfNames)(cn=*))",array("cn"));
475 while($attrs = $ldap->fetch()){
476 $ret[$attrs['cn'][0]] = $attrs['cn'][0];
477 }
478 return($ret);
479 }
482 function save()
483 {
484 // We do not save anything here.
485 }
488 /*! \brief Return a list of all selected items.
489 @return Array Returns an array containing all selected item ids.
490 */
491 function list_get_selected_items()
492 {
493 $ids = array();
494 foreach($_POST as $name => $value){
495 if(preg_match("/^item_selected_[0-9]*$/",$name)){
496 $id = preg_replace("/^item_selected_/","",$name);
497 $ids[$id] = $id;
498 }
499 }
500 return($ids);
501 }
504 static function plInfo()
505 {
506 return (array(
507 "plShortName" => _("System mass deployment"),
508 "plDescription" => _("Provide a mechanism to automatically activate a set of systems"),
509 "plSelfModify" => FALSE,
510 "plDepends" => array(),
511 "plPriority" => 0,
512 "plSection" => array("addon"),
513 "plCategory" => array("gotomasses" => array("objectClass" => "none", "description" => _("System mass deployment"))),
514 "plProvidedAcls" => array("Comment" => _("Description"),
515 "Action" => _("Action"),
516 "Day" => _("Day"),
517 "Minute" => _("Minute"),
518 "Hour" => _("Hour"),
519 "Month" => _("Month"),
520 "Weekday" => _("Week day"),
521 "Target" => _("Target"))
522 ));
523 }
524 }
525 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
526 ?>