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 $sort_by = "Schedule";
20 var $sort_dir = "down";
21 var $entries = array();
22 var $range = 25;
23 var $start = 0;
25 function gotomasses(&$config, $dn= NULL)
26 {
27 /* Include config object */
28 $this->config= &$config;
29 $this->o_queue = new gosaSupportDaemon(TRUE,10);
30 }
33 function execute()
34 {
35 $smarty = get_smarty();
37 /************
38 * Handle posts
39 ************/
41 $s_entry = $s_action = "";
42 $arr = array(
43 "/^stop_/" => "stop",
44 "/^stop_all/" => "stop_all",
45 "/^start_/" => "start",
46 "/^start_all/" => "start_all",
48 "/^prio_up_/" => "prio_up",
49 "/^prio_down_/" => "prio_down",
51 "/^edit_task_/" => "edit",
52 "/^remove_task_/" => "remove",
53 "/^new_task_/" => "new_task",
54 "/^remove_multiple_task_/" => "remove_multiple");
56 foreach($arr as $regex => $action){
57 foreach($_POST as $name => $value){
58 if(preg_match($regex,$name)){
59 $s_action = $action;
60 $s_entry = preg_replace($regex,"",$name);
61 $s_entry = preg_replace("/_(x|y)$/","",$s_entry);
62 }
63 }
64 }
66 /* Edit posted from list link */
67 if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id']) && isset($this->tasks[$_GET['id']])){
68 $s_action = "edit";
69 $s_entry = $_GET['id'];
70 }
73 /************
74 * Handle Priority modifications
75 ************/
77 if(preg_match("/^prio_/",$s_action)){
79 switch($s_action){
81 case 'prio_down' : $this->update_priority($s_entry,"down");break;
82 case 'prio_up' : $this->update_priority($s_entry,"up");break;
83 }
84 }
86 /************
87 * Handle start/stop modifications
88 ************/
90 if(preg_match("/^start/",$s_action) || preg_match("/^stop/",$s_action)){
92 switch($s_action){
93 case 'start_all' : $this->start_queue_entries($this->list_get_selected_items());break;
94 case 'start' : $this->start_queue_entries(array($s_entry));break;
95 case 'stop_all' : $this->stop_queue_entries ($this->list_get_selected_items());break;
96 case 'stop' : $this->stop_queue_entries (array($s_entry));break;
97 default : trigger_error("Undefined priority setting used.");
98 }
99 if($this->o_queue->is_error()){
100 msg_dialog::display(_("Error"), $this->o_queue->get_error(), ERROR_DIALOG);
101 }
102 }
104 /************
105 * REMOVE
106 ************/
108 /* Remove multiple */
109 if($s_action == "remove_multiple" || $s_action == "remove"){
111 if(!$this->acl_is_removeable()){
112 msg_dialog::display(_("Permission error"), _("You have no permission to delete this entry!"), ERROR_DIALOG);
113 }else{
115 if($s_action == "remove"){
116 $ids = array($s_entry);
117 }else{
118 $ids = $this->list_get_selected_items();
119 }
120 if(count($ids)){
121 $this->ids_to_remove = $ids;
122 $ret = $this->o_queue->ids_exist($this->ids_to_remove);
123 $ret = $this->o_queue->get_entries_by_id($ret);
125 $tmp = "";
126 foreach($ret as $task){
127 $tmp.= "\n".$task['ID']." - ".$task['HEADERTAG']." ".$task['MACADDRESS'];
128 }
129 $smarty->assign("multiple", TRUE);
130 $smarty->assign("info",sprintf(_("Your are about to delete the following tasks: %s"),"<pre>".$tmp."</pre>"));
131 $this->current = $s_entry;
132 return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
133 }
134 }
135 }
137 /* Remove specified tasks */
138 if(count($this->ids_to_remove) && isset($_POST['delete_multiple_confirm'])){
139 $this->o_queue->remove_entries($this->ids_to_remove);
140 $this->save();
141 }
143 /* Remove aborted */
144 if(isset($_POST['delete_cancel'])){
145 $this->ids_to_remove = array();;
146 }
149 /************
150 * EDIT
151 ************/
153 /* Edit selected entry */
154 if($s_action == "edit"){
155 $entry = $this->o_queue->get_entry_by_id($s_entry);
156 if($entry){
157 $this->dialog = new goto_task($this->config,$this,$entry);
158 $this->current = $s_entry;
159 }
160 }
162 /* New entry */
163 if($s_action== "new_task" && $this->acl_is_createable()){
164 $this->dialog = new goto_task($this->config,$this);
165 $this->current = -1;
166 }
168 /* Close dialog */
169 if(isset($_POST['close_goto_task'])){
170 $this->dialog = FALSE;
171 $this->current = -1;
172 }
174 /* Close dialog */
175 if((isset($_POST['save_goto_task']) || isset($_POST['apply_goto_task'])) && is_object($this->dialog) ){
176 $this->dialog->save_object();
177 $msgs = $this->dialog->check();
178 if(count($msgs)){
179 foreach($msgs as $msg){
180 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
181 }
182 }else{
184 if($this->o_queue->id_exists($this->current)){
185 $this->o_queue->update_entries(array($this->current),$this->dialog->save());
186 }else{
187 $tmp = $this->dialog->save();
188 $tmp2= array();
189 $targets =$tmp['Target'];
190 foreach($targets as $target){
191 $tmp['Target'] = array($target);
192 $tmp2[] = $tmp;
193 }
194 if(!$this->o_queue->add_multiple($tmp2)){
195 msg_dialog::display(_("Error"), $this->o_queue->get_error(), ERROR_DIALOG);
196 }
197 }
198 if(!isset($_POST['apply_goto_task'])){
199 $this->dialog = FALSE;
200 $this->current = -1;
201 }
202 $this->save();
203 }
204 }
206 /* Display dialogs if currently opened */
207 if(is_object($this->dialog)){
208 $this->dialog->save_object();
209 return($this->dialog->execute());
210 }
212 /************
213 * Handle Divlist
214 ************/
216 $divlist = new MultiSelectWindow($this->config,"gotoMasses",array("gotomasses"));
217 $divlist->SetInformation(_("This menu allows you to remove and change the properties of GOsa deamon tasks."));
218 $divlist->SetSummary(_("List of queued deamon jobs."));
219 $divlist->EnableCloseButton(FALSE);
220 $divlist->EnableSaveButton(FALSE);
221 $divlist->SetHeadpageMode();
223 if($this->sort_dir == "up"){
224 $sort_img = "<img src='images/sort_up.png' alt='/\' border=0>";
225 }else{
226 $sort_img = "<img src='images/sort_down.png' alt='\/' border=0>";
227 }
229 if($this->sort_by == "TargetName"){ $sort_img_1 = $sort_img; } else { $sort_img_1 = "" ;}
230 if($this->sort_by == "TaskID"){ $sort_img_2 = $sort_img; } else { $sort_img_2 = "" ;}
231 if($this->sort_by == "Schedule"){ $sort_img_3 = $sort_img; } else { $sort_img_3 = "" ;}
232 if($this->sort_by == "Action"){ $sort_img_4 = $sort_img; } else { $sort_img_4 = "" ;}
234 /* Display add button if allowed */
235 $header = "<div style='padding:5px'>";
236 if($this->acl_is_removeable()){
237 $header .= "<input type='image' src='images/edittrash.png' name='remove_multiple_task' class='center'> ";
238 }
239 if(preg_match("/w/",$this->getacl(""))){
240 $header .= "<input type='image' src='images/status_stop_all.png' name='stop_all' class='center'> ";
241 $header .= "<input type='image' src='images/status_start_all.png' name='start_all' class='center'> ";
242 }
243 $header .= "</div>";
245 /* Create divlist */
246 $divlist->SetListHeader($header);
248 $plug = $_GET['plug'];
249 $chk = "<input type='checkbox' id='select_all' name='select_all'
250 onClick='toggle_all_(\"^item_selected_[0-9]*$\",\"select_all\");' >";
252 /* set Page header */
253 $divlist->AddHeader(array("string"=> $chk, "attach"=>"style='width:20px;'"));
254 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=TargetName'>"._("Target").$sort_img_1."</a> / ".
255 "<a href='?plug=".$plug."&sort=TaskID'>"._("Task").$sort_img_2."</a>"));
256 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Schedule'>"._("Schedule").$sort_img_3."</a>",
257 "attach"=>"style='width:100px;'"));
258 $divlist->AddHeader(array("string"=>"<a href='?plug=".$plug."&sort=Action'>"._("Status").$sort_img_4."</a>",
259 "attach"=>"style='width:80px;'"));
260 $divlist->AddHeader(array("string"=>_("Action"),
261 "attach"=>"style='border-right:0px;width:120px;'"));
264 /* Reload the list of entries */
265 $this->reload();
267 foreach($this->entries as $key => $task){
270 $prio_actions = "<input class='center' type='image' src='images/prio_increase.png' name='prio_up_".$task['ID']."'> ";
271 $prio_actions.= "<input class='center' type='image' src='images/prio_decrease.png' name='prio_down_".$task['ID']."'> ";
272 $prio_actions.= "<input class='center' type='image' src='images/status_stop_all.png' name='stop_".$task['ID']."'> ";
273 $prio_actions.= "<input class='center' type='image' src='images/status_start_all.png' name='start_".$task['ID']."'> ";
275 $action = "<input type='image' src='images/edit.png' name='edit_task_".$task['ID']."'
276 class='center' alt='"._("Edit")."'>";
278 if($this->acl_is_removeable()){
279 $action.= "<input type='image' src='images/edittrash.png' name='remove_task_".$task['ID']."'
280 class='center' alt='"._("Reomve")."'>";
281 }
283 $color = "";
284 $display = $task['MACADDRESS'];
285 $display2= $task['HEADERTAG'];
287 /* Create each field */
288 $field0 = array("string" => "<input type='checkbox' id='item_selected_".$task['ID']."' name='item_selected_".$task['ID']."'>" ,
289 "attach" => "style='width:20px;".$color."'");
290 $field1 = array("string" => $display,
291 "attach" => "style='".$color."'");
292 $field1a= array("string" => $display2,
293 "attach" => "style='".$color.";width:80px;'");
294 $field2 = array("string" => date("d.m.Y H:i:s",strtotime($task['TIMESTAMP'])),"attach" => "style='".$color.";width:100px;'");
295 $field3 = array("string" => $task['STATUS'],"attach" => "style='".$color.";width:80px;'");
296 $field4 = array("string" => $prio_actions.$action,"attach" => "style='".$color.";text-align:right;width:120px;border-right:0px;'");
297 $divlist->AddElement(array($field0,$field1,$field1a,$field2,$field3,$field4));
298 }
301 $smarty = get_smarty();
302 $smarty->assign("start",$this->start);
303 $smarty->assign("start_real", ($this->start + 1));
304 $smarty->assign("ranges", array("10" => "10",
305 "20" => "20",
306 "25" => "25",
307 "50" => "50",
308 "100"=> "100",
309 "200"=> "200",
310 "9999" => "*"));
312 $count = $this->o_queue->number_of_queued_entries();
313 $smarty->assign("range_selector", range_selector($count, $this->start, $this->range,"range"));
314 $smarty->assign("range",$this->range);
315 $smarty->assign("div",$divlist->Draw());
316 return($smarty->fetch (get_template_path('gotomasses.tpl', TRUE, dirname(__FILE__))));
317 }
320 /*! \brief Move an entry up or down in the queue, by updating its execution timestamp
321 @param $id Integer The ID of the entry which should be updated.
322 @param $type String "up" / "down"
323 @return boolean TRUE in case of success else FALSE
324 */
325 public function update_priority($id,$type = "up")
326 {
327 if($type == "up"){
328 $tmp = $this->o_queue->get_queued_entries(-1,-1,"timestamp DESC");
329 }else{
330 $tmp = $this->o_queue->get_queued_entries(-1,-1,"timestamp ASC");
331 }
332 $last = array();
333 foreach($tmp as $entry){
334 if($entry['ID'] == $id){
335 if(count($last)){
336 $time = strtotime($last['TIMESTAMP']);
337 if($type == "up"){
338 $time ++;
339 }else{
340 $time --;
341 }
342 $time_str = date("YmdHis",$time);
343 return($this->o_queue->update_entries(array($id),array("timestamp" => $time_str)));
344 }else{
345 return(FALSE);
346 }
347 }
348 $last = $entry;
349 }
350 return(FALSE);
351 }
354 /*! \brief Force queue job to be done as far as possible.
355 * @return Boolean TRUE in case of success, else FALSE.
356 */
357 private function start_queue_entries($ids)
358 {
359 if(!count($ids)){
360 return;
361 }
363 $data = array("timestamp" => date("YmdHis"),
364 "status" => "-");
365 if(!$this->o_queue->update_entries($ids,$data)){
366 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
367 return(FALSE);
368 }
369 return(TRUE);
370 }
373 /*! \brief Stops the specified queue entry from execution.
374 * @return Boolean TRUE in case of success, else FALSE.
375 */
376 private function stop_queue_entries($ids)
377 {
378 if(!count($ids)){
379 return;
380 }
381 $data = array("timestamp" => "20490101010101",
382 "status" => "Stoppped");
383 if(!$this->o_queue->update_entries($ids,$data)){
384 msg_dialog::display(_("Error"), sprintf(_("Could not update queue entry: %s"),$id) , ERROR_DIALOG);
385 return(FALSE);
386 }
387 return(TRUE);
388 }
391 /*! \brief Request list of queued jobs.
392 * @return Returns an array of all queued jobs.
393 */
394 function reload()
395 {
396 $map = array(
397 "QueuePosition" => "id",
398 "Action" => "status",
399 "TaskID" => "headertag",
400 "TargetName" => "macaddress",
401 "Schedule" => "timestamp");
403 if(!isset($map[$this->sort_by])){
404 $sort = "id DESC";
405 }else{
406 $sort = $map[$this->sort_by];
407 if($this->sort_dir == "up"){
408 $sort.= " ASC";
409 }else{
410 $sort.= " DESC";
411 }
412 }
414 $start = $this->start;
415 $stop = $this->range;
417 $entries = $this->o_queue->get_queued_entries($start,$stop,$sort);
418 if(!is_array($entries)){
419 if ($this->o_queue->get_error()){
420 msg_dialog::display(_("Error"), sprintf(_("Cannot load queue entries: %s"), "<br><br>".$this->o_queue->get_error()), ERROR_DIALOG);
421 }
422 return(array());
423 }
425 $this->entries = array();
426 foreach($entries as $entry){
427 $this->entries[]= $entry;
428 }
429 }
432 /*! \brief Handle post jobs, like sorting.
433 */
434 function save_object()
435 {
436 $sort_vals = array("Action","QueuePosition","TargetName","Schedule","TaskID");
437 if(isset($_GET['sort']) && in_array($_GET['sort'],$sort_vals)){
438 $sort = $_GET['sort'];
439 if($this->sort_by == $sort){
440 if($this->sort_dir == "up"){
441 $this->sort_dir = "down";
442 }else{
443 $this->sort_dir = "up";
444 }
445 }
446 $this->sort_by = $sort;
447 }
448 if(isset($_POST['range']) && is_numeric($_POST['range'])){
449 $this->range = $_POST['range'];
450 }
451 if(isset($_GET['start'])){
452 $start = $_GET['start'];
453 if(is_numeric($start) || $start == 0){
454 $this->start = $start;
455 }
456 }
458 /* Check start stop and reset if necessary */
459 $count = $this->o_queue->number_of_queued_entries();
460 if($this->start >= $count){
461 $this->start = $count -1;
462 }
463 if($this->start < 0){
464 $this->start = 0;
465 }
466 }
469 /* Return list of object groups */
470 function get_object_groups()
471 {
472 $ret = array();
473 $ldap = $this->config->get_ldap_link();
474 $ldap->cd($this->config->current['BASE']);
475 $ldap->search("(&(objectClass=gosaGroupOfNames)(cn=*))",array("cn"));
476 while($attrs = $ldap->fetch()){
477 $ret[$attrs['cn'][0]] = $attrs['cn'][0];
478 }
479 return($ret);
480 }
483 function save()
484 {
485 // We do not save anything here.
486 }
489 /*! \brief Return a list of all selected items.
490 @return Array Returns an array containing all selected item ids.
491 */
492 function list_get_selected_items()
493 {
494 $ids = array();
495 foreach($_POST as $name => $value){
496 if(preg_match("/^item_selected_[0-9]*$/",$name)){
497 $id = preg_replace("/^item_selected_/","",$name);
498 $ids[$id] = $id;
499 }
500 }
501 return($ids);
502 }
505 function get_actions()
506 {
507 /* Prepare list of available actions */
508 $actions = array(
509 "gosa_ping" => _("GOsa ping"),
510 "ping" => _("Ping"),
511 "sayHello" => _("Say hello"));
512 return($actions);
513 }
516 static function plInfo()
517 {
518 return (array(
519 "plShortName" => _("System mass deployment"),
520 "plDescription" => _("Provide a mechanism to automatically activate a set of systems"),
521 "plSelfModify" => FALSE,
522 "plDepends" => array(),
523 "plPriority" => 0,
524 "plSection" => array("addon"),
525 "plCategory" => array("gotomasses" => array("objectClass" => "none", "description" => _("System mass deployment"))),
526 "plProvidedAcls" => array("Comment" => _("Description"),
527 "Action" => _("Action"),
528 "Day" => _("Day"),
529 "Minute" => _("Minute"),
530 "Hour" => _("Hour"),
531 "Month" => _("Month"),
532 "Weekday" => _("Week day"),
533 "Target" => _("Target"))
534 ));
535 }
536 }
537 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
538 ?>