Code

Updated infoPage
[gosa.git] / gosa-core / include / class_pluglist.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 pluglist 
24 {
25     // The id of the last registered plugin id 
26     var $index= 0;
28     var $config= NULL;
29     var $ui= NULL;
31     // Contains a list of the paths for all registered plugins.
32     var $dirlist= array();
34     // Seems to be used in the help menu to generate an overview.
35     var $headlines = array();
36     // Remember stuff in here.
37     var $silly_cache= array();
39     // The pluglist keeps track of all registered plugins.
40     // (Registered plugins are those we are able to access)
41     var $pluginList = array();
43     // Some cache vars to avoid regenration of the menus.   
44     var $pathMenu = "";
45     var $menu= "";
46     var $iconmenu= "";
48     // Classes plInfo list
49     var $info = array();
50     var $registeredMenuEntries = array();
51     var $registeredPathEntries = array();
52     var $registeredIconEntries = array();
53     var $registeredShortCutEntries = array();
56     function getRegisteredMenuEntries ()
57     {
58         return($this->registeredMenuEntries);
59     }
62     function getRegisteredPathEntries ()
63     {
64         return($this->registeredPathEntries);
65     }
68     function getRegisteredIconEntries ()
69     {
70         return($this->registeredIconEntries);
71     }
74     function getRegisteredShortCutEntries ()
75     {
76         return($this->registeredShortCutEntries);
77     }
80     function pluglist(&$config, &$ui)
81     {
82         $this->ui= &$ui;
83         $this->config= &$config;
84         $this->loadPluginList();
85     }
87     function loadPluginList()
88     {
89         $this->pluginList = array();
91         /* Fill info part of pluglist */
92         $classes= get_declared_classes();
93         foreach ($classes as $cname){
94             $cmethods = get_class_methods($cname);
95             if (in_array_ics('plInfo',$cmethods)){
96                 $this->info[$cname]= call_user_func(array($cname, 'plInfo'));
97             }
98         }
100         if(!session::is_set('maxC')){
101             session::set('maxC',"RO0K9CzEYCSAAOtOICCFhEDBKGSKANyHMKDHAEwFLNTJILwEMODJYPgMRA0F9IOPSPUKNEVCUKyDBAHNbIWFJOIP");
102         }
103         //
104         //   // Now generate menu - usually they are cached
105         //   $this->gen_menu();
106         //   $this->show_iconmenu();
107         //   $this->genPathMenu();
108     }
111     /*! \brief    Tries to register a plugin in the pluglist
112      *            Checks existence and ACL for the given plugin.
113      *            Returns true in case of success else false. 
114      */
115     function registerPlugin(&$plug)
116     {
117         global $class_mapping;
119         // Clean ACL string, we do not want any spaces or lines breaks here. 
120         $plug['ACL'] = trim($plug['ACL']);
122         // Clean ACL string, we do not want any spaces or lines breaks here.
123         $acl = trim($plug['ACL']);
124         if(preg_match("/,/",$acl)){
125             $acls = explode(",",$acl);
126         }else{
127             $acls = array($acl);
128         }
129         foreach($acls as $key => $aclEntry){
130             $aclEntry = trim($aclEntry);
131             $tmp = preg_replace("/[^a-z0-9\/:]/i","",$aclEntry);
133             // Check if cleaned 'acl' tag doesn't match the configured one from the gosa.conf.
134             // Display a notification to tell the user that there is something wrong.
135             if($tmp != $aclEntry){
136                 trigger_error("Please check acl='{$aclEntry}' tag for plugin '{$plug['CLASS']}' in your gosa.conf, it contains invalid characters!" );
137             }
138             $acls[$key] = $tmp;
139         }
140         $plug['ACL'] = implode(',',$acls);
143         // Check class
144         if (!isset($plug['CLASS'])){
145             msg_dialog::display(
146                     _("Configuration error"),
147                     _("The configuration format has changed: please run the setup again!"),
148                     FATAL_ERROR_DIALOG);
149             exit();
150         }
151         if (!plugin_available($plug['CLASS'])){
152             return(FALSE);
153         }
154         if (!$this->check_access($plug['ACL'])){
155             return(FALSE);
156         }
157         $this->dirlist[$this->index] = dirname($class_mapping[$plug['CLASS']]);
158         $this->pluginList[$this->index] = $plug['CLASS'];
159         $this->index++;
160         return(TRUE);
161     }
164     /*! \brief  Check whether we are allowed to modify the given acl or not..
165      *          This function is used to check which plugins are visible.
166      *          
167      *  @param  The acl tag to check for, eg.   "users/user:self", "systems", ...
168      *  @return Boolean TRUE on success else FALSE
169      */
170     function check_access($aclname)
171     {
172         if (isset($this->silly_cache[$aclname])) {
173             return $this->silly_cache[$aclname];
174         }
176         // Split given acl string into an array. e.g. "user,systems" => array("users","systems");
177         $acls_to_check = array();
178         if(preg_match("/,/",$aclname)){
179             $acls_to_check = explode(",",$aclname);
180         }else{
181             $acls_to_check = array($aclname);
182         }
184         foreach($acls_to_check as $acl_to_check){
186             // Remove spaces and line breaks.
187             $acl_to_check = trim($acl_to_check);
188             $acl_to_check = preg_replace("/ /","",$acl_to_check);
190             if($acl_to_check == "none"){
191                 $this->silly_cache[$aclname]= TRUE;
192                 return(TRUE);
193             }
195             /* Check if the given acl tag is only valid for self acl entries  
196              *          <plugin acl="users/user:self" class="user"...  
197              */ 
198             if(preg_match("/:self$/",$acl_to_check)){
199                 $acl_to_check = preg_replace("/:self$/","",$acl_to_check);      
200                 if(strpos($acl_to_check,"/")){
201                     if($this->ui->get_permissions($this->ui->dn,$acl_to_check,"") != ""){
202                         $this->silly_cache[$aclname]= TRUE;
203                         return(TRUE);
204                     }
205                 }else{
206                     if($this->ui->get_category_permissions($this->ui->dn,$acl_to_check,"") != ""){
207                         $this->silly_cache[$aclname]= TRUE;
208                         return(TRUE);
209                     }
210                 }
211             }else{
213                 // No self acls. Check if we have any acls for the given ACL type 
214                 $deps = $this->ui->get_module_departments($acl_to_check,TRUE);
215                 if(count($deps)){
216                     $this->silly_cache[$aclname]= TRUE;
217                     return TRUE;
218                 }
219             }
220         }
222         $this->silly_cache[$aclname]= FALSE;
223         return (FALSE);
224     }
228     /*! \brief    Generate the GOsa Main-Menu here (The menu on the left), 
229      *             this usually only done once during login.
230      *            -----------------------------------------------------------------
231      *            Do NOT add style changes here manually, use the style.css or 
232      *             if you prefer create your own theme!!
233      *            -----------------------------------------------------------------
234      */
235     function gen_menu()
236     {
237         if ($this->menu == ""){
239             // First load the menu plugins and try to register them in the pluglist
240             //  if this fails for some reason, then remove the plugin from the menu.
241             if(isset($this->config->data['MENU'])){
242                 foreach($this->config->data['MENU'] as $section => $plugins){
243                     foreach($plugins as $id => $plug){
244                         if(!$this->registerPlugin($this->config->data['MENU'][$section][$id])){ 
245                             unset($this->config->data['MENU'][$section][$id]); 
246                         }
247                     }
249                     // Remove empty sections 
250                     if(count($this->config->data['MENU'][$section]) == 0){ 
251                         unset($this->config->data['MENU'][$section]); 
252                     } 
253                 }
254             }
256             $disabledPlugins = $this->config->configRegistry->getDisabledPlugins();
258             $cfg= $this->config->data['MENU'];
259             $menu = "";
260             foreach ($cfg as $headline => $plug){
263                 if(!count($plug)) continue;
265                 $menu.= "\n        <div class='menu'>";
266                 $menu.= "\n          <ul>";
267                 $menu.= "\n            <li class='menu-header'>"._($headline)."</li>";
268                 $id = 0;
269                 foreach ($plug as $info){
271                     // The Plugin has been deactivated for some reason, perhabs a missing ldap schema.
272                     if(isset($disabledPlugins[$info['CLASS']])) continue;
274                     // Used to detect the last element in the menu
275                     $id ++;
277                     list($index, $title, $desc, $icon) = $this->getPlugData($info['CLASS']);
278                     $class= "";
279                     if($id == count($plug)) $class=" class='menu-last' ";
280                     $menu .=  "\n            <li id='plugMenuId_{$index}' $class onClick='return openPlugin({$index});'>".$title."</li>";
282                     $this->registeredMenuEntries[] = $index;
283                 }
284                 $menu.= "\n          </ul>";
285                 $menu.= "\n          <div style='font-size:0'>&nbsp;</div>";
286                 $menu.= "\n        </div>\n";
287                 $menu.= "\n        <div style='font-size:0'>&nbsp;</div>";
288                 $menu.= "\n        <div class='v-spacer'></div>\n";
289             }
290             if(count($this->registeredMenuEntries)){
291                 $this->menu = "\n<div class='navigation'>\n{$menu}</div>";
292             }
294             // Add javascript method to print out warning messages while leaving an unsaved form.
295             // We do it in here to get the string translated.
296             $this->menu .=  
297                 "\n      <script language='javascript' type='text/javascript'>".
298                 "\n        function openPlugin(id, plugin){".
299                 "\n          return question(\""._("You are currently editing a database entry. Do you want to discard the changes?")."\",".
300                 "\n            \"main.php?plug=\" + id + \"&reset=1&pluginTab=\" + plugin);".
301                 "\n        }".
302                 "\n      </script>\n"; 
303         }
305         // Use javascript to mark the currently selected plugin.
306         $menu = $this->menu;
307         if(isset($_GET['plug'])){
308             $menu.= 
309                 "\n      <script language='javascript' type='text/javascript'>".
310                 "\n        if($('plugMenuId_".$_GET['plug']."')){".
311                 "\n          $('plugMenuId_".$_GET['plug']."').className= 'current'".
312                 "\n        }".
313                 "\n      </script>\n";
314         }
316         // Return the generated/cached gosa menu.
317         return ($menu);
318     }
321     /*! \brief    Generate the GOsa Icon-Menu here, this usually only done once during
322      *             login.
323      *            -----------------------------------------------------------------
324      *            Do NOT add style changes here manually, use the style.css or 
325      *             if you prefer create your own theme!!
326      *            -----------------------------------------------------------------
327      */
328     function show_iconmenu()
329     {
330         $add_hr =FALSE;
331         if ($this->iconmenu == ""){
333             $disabledPlugins = $this->config->configRegistry->getDisabledPlugins();
335             $cfg= $this->config->data['MENU'];
336             foreach ($cfg as $headline => $plug){
337                 $col= 0;
339                 $this->iconmenu .= "\n        <div class='clear'></div>";
340                 if($add_hr){
341                     $add_hr = FALSE;
342                     $this->iconmenu .= "\n        <hr>";
343                 }
344                 $this->iconmenu .= "\n        <h3 class='icon-menu-title'>". _($headline)."</h3>";
346                 foreach ($plug as $info){
348                     // Get Plugin info
349                     list($index, $title, $desc, $icon) = $this->getPlugData($info['CLASS']);
350                     $this->registeredIconEntries[] = $index;
352                     // The Plugin has been deactivated for some reason, perhabs a missing ldap schema.
353                     if(isset($disabledPlugins[$info['CLASS']])) continue;
355                     // Add a seperating row
356                     if (($col % 4) == 0){ 
357                         $this->iconmenu .= "\n        <div class='clear'></div>";
358                     }
360                     $this->iconmenu.= "\n        <div class='icon-menu-item' style='width: 25%;' onclick='openPlugin({$index})'>";
361                     $this->iconmenu.= "\n          ".image($icon);
362                     $this->iconmenu.= "\n          <div class='dsc'>";
363                     $this->iconmenu.= "\n            <h1>{$title}</h1>";
364                     $this->iconmenu.= "\n            <p>{$desc}</p>";
365                     $this->iconmenu.= "\n          </div>";
366                     $this->iconmenu.= "\n        </div>";
367                     $col++ ;
368                 }
369                 $add_hr = TRUE;
370             }
371         }
372         return ($this->iconmenu);
373     }
376     /*! \brieg    Generates and the path menu (the one on the upper right) and keeps
377      *             the generated HTML content, so we are not forced to generate it on every 
378      *             page request.
379      *            (See <pathMenu> of your gosa.conf)
380      */
381     function genPathMenu()
382     {
383         if(empty($this->pathMenu)){
385             $disabledPlugins = $this->config->configRegistry->getDisabledPlugins();
387             // Now load the icon menu and try to register the plugins in the pluglist
388             //  if this fails for some reason, then remove the plugins from the menu.
389             if(isset($this->config->data['SHORTCUTMENU'])){
390                 foreach($this->config->data['SHORTCUTMENU'] as $id => $plugin){
391                     if(!$this->registerPlugin($this->config->data['SHORTCUTMENU'][$id])){
392                         unset($this->config->data['SHORTCUTMENU'][$id]); 
393                     } 
394                 }
395             }
397             // Now load the path menu and try to register the plugins in the pluglist
398             //  if this fails for some reason, then remove the plugin from the menu.
399             if(isset($this->config->data['PATHMENU'])){
400                 foreach($this->config->data['PATHMENU'] as $id => $plugin){
401                     if(!$this->registerPlugin($this->config->data['PATHMENU'][$id])){
402                         unset($this->config->data['PATHMENU'][$id]); 
403                     } 
404                 }
405             }
407             $this->pathMenu = 
408                 "\n        <div class='plugin-path'>".
409                 "\n          <ul class='path-navigation'>";
411             // Check if we've at least one entry defined ih the iconmenu
412             if(isset($this->config->data['SHORTCUTMENU'])){
413                 $icfg= &$this->config->data['SHORTCUTMENU'];
414                 $rcfg = array_reverse($icfg);
415                 foreach($rcfg as $id => $plug){
416                     list($index, $title, $desc, $icon, $shortIcon) = $this->getPlugData($plug['CLASS']);
417                     $this->registeredShortCutEntries[] = $index;
419                     // The Plugin has been deactivated for some reason, perhabs a missing ldap schema.
420                     if(isset($disabledPlugins[$plug['CLASS']])) continue;
422                     $cssClass= (!isset($rcfg[$id+1]))? 'left' : 'left right-border';
423                     $this->pathMenu.= "            
424                         <li class='{$cssClass}' onClick='openPlugin({$index})' title='{$title}'>".
425                         image(get_template_path($shortIcon))."</li>";
426                 }
427             }
429             // Place the navigator part, this will be replaced during runtime.
430             $this->pathMenu .= "\n            %navigator%";
432             // Check if we've at least one entry defined ih the pathmenu
433             if(isset($this->config->data['PATHMENU'])){
434                 $cfg= &$this->config->data['PATHMENU'];
435                 $rcfg = array_reverse($cfg);
436                 foreach($rcfg as $id => $plug){
437                     list($index, $title, $desc, $icon) = $this->getPlugData($plug['CLASS']);
438                     $this->registeredPathEntries[] = $index;
440                     // The Plugin has been deactivated for some reason, perhabs a missing ldap schema.
441                     if(isset($disabledPlugins[$plug['CLASS']])) continue;
443                     $this->pathMenu.= "\n            <li class='right left-border' onClick='openPlugin({$index})'>{$title}</li>";
444                 }
445             }
446             $this->pathMenu.= "\n          </ul>";
447             $this->pathMenu.= "\n        </div>";
448         }
450         $menu = pathNavigator::getCurrentPath();
451         return(preg_replace("/%navigator%/", $menu, $this->pathMenu)); 
452     }
455     /*! \brief    Returns additional info for a given class name, like 
456      *             plugin-icon, title, description and the index of the element 
457      in the pluglist which uses this class.
458      */
459     function getPlugData($class)
460     {
461         global $class_mapping;
462         $vars= get_class_vars($class);
463         $plHeadline= _($vars['plHeadline']);
464         $plDescription= _($vars['plDescription']);
465         $plIcon = (isset($vars['plIcon'])) ? $vars['plIcon']: "plugin.png";
466         $plShortIcon = (isset($vars['plShortIcon'])) ? $vars['plShortIcon']: "plugin.png";
468         $index= $this->get_index($class);
470         /* Check if class is available. If the class doesn't exists display error symbol
471          *  to avoid that a user clicks on a non existing plugin
472          */
473         if(!$vars){
474             $plHeadline = $plDescription = _("Unknown");
475             $plIcon = "error.png";
476             $index = '';
477         } 
479         // Detect the correct position of the plugin icon
480         if(!preg_match("/\//",$plIcon)){
481             $image= get_template_path("plugins/".preg_replace('%^.*/([^/]+)/[^/]+$%', '\1', 
482                         $class_mapping[$class])."/images/$plIcon");
483         }else{
484             $image = $plIcon; 
485         }
486         // Detect the correct position of the plugin icon
487         if(!preg_match("/\//",$plShortIcon)){
488             $shortImage= get_template_path("plugins/".preg_replace('%^.*/([^/]+)/[^/]+$%', '\1', 
489                         $class_mapping[$class])."/images/$plShortIcon");
490         }else{
491             $shortImage = $plShortIcon; 
492         }
493         return(array($index, $plHeadline, $plDescription, $image, $shortImage));
494     }
497     /*! \brief    Returns the installation path of a plugin.
498      *            e.g. '../plugins/admin/mimetypes'
499      */
500     function get_path($index)
501     {
502         if(!isset($this->dirlist[$index])){
503             return ("");
504         }
505         return ("../".$this->dirlist[$index]);
506     }
509     /*! \brief    Returns the plugins id for a given class.
510      */
511     function get_index($class)
512     {
513         return (array_search($class, $this->pluginList));
514     }
517     /*! \brief    Returns the plugins id for a given class.
518      */
519     function get_class($index)
520     {
521         return($this->pluginList[$index]);
522     }
525     /*! \brief  This function checks if we are allowed to view the plugin with the given id 
526      *
527      *  @param  $plug_id  Integer  The ID of the plugin.
528      *  @return Boolean   TRUE if we are allowed to view the plugin else FASLE
529      */
530     function plugin_access_allowed($plug_id)
531     {
532         return(isset($this->pluginList[$plug_id]));
533     }
536     /*! \brief  Force the menu to be recreated 
537      */
538     function reset_menus()
539     {
540         $this->menu = "";
541         $this->iconmenu ="";
542     }
545     /*! \brief    Generates an array containing plugin names (headlines) and theirs ids.
546      *            This is just used in the helpviewer.php  
547      */
548     function gen_headlines()
549     {
550         $ret = array();
551         if(count($this->headlines) == 0){
552             foreach($this->config->data['MENU'] as $headline => $plugins){
553                 foreach( $plugins as $id => $plug){
554                     if (plugin_available($plug['CLASS'])){
555                         $attrs = (get_class_vars($plug['CLASS']));
556                         $ret[$id]['HEADLINE'] = $headline;
557                         $ret[$id]['NAME']         = $attrs['plHeadline'];
558                     }
559                 }
560             }
561             $this->headlines = $ret;
562         }
563         return($this->headlines);
564     }
566 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
567 ?>