From e2aa2eee6a22d47192f24b0840227111506366bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=B4me=20Chilliet?= <come@opensides.be>
Date: Tue, 6 Mar 2018 12:35:43 +0100
Subject: [PATCH] :sparkles: feat(management) Add filter in plugin class infos

This allows to do tab filters and property column without having to
 create objects of each tab.
Adaptations will be needed in all plugins.
This also activates new management class for groups to test it with
 several object types.
---
 include/class_pluglist.inc                    |  3 +
 include/management/class_FilterElement.inc    |  9 +-
 .../management/class_managementListing.inc    |  6 +-
 include/management/columns/class_Column.inc   | 12 +--
 .../columns/class_PropertiesColumn.inc        | 51 +++++++-----
 include/simpleplugin/class_simplePlugin.inc   | 81 ++++++++++++------
 .../admin/groups/class_groupManagement.inc    | 82 ++++---------------
 plugins/admin/groups/class_ogroup.inc         | 17 +---
 plugins/admin/groups/main.inc                 |  4 +-
 plugins/personal/generic/class_user.inc       |  7 +-
 10 files changed, 122 insertions(+), 150 deletions(-)

diff --git a/include/class_pluglist.inc b/include/class_pluglist.inc
index 817f4df78..a3a45571a 100644
--- a/include/class_pluglist.inc
+++ b/include/class_pluglist.inc
@@ -150,6 +150,9 @@ class pluglist {
         if (!isset($infos['plTitle']) && isset($infos['plShortName'])) {
           $infos['plTitle'] = $infos['plShortName'];
         }
+        if (isset($infos['plFilter'])) {
+          $infos['plFilterObject'] = ldapFilter::parse($infos['plFilter']);
+        }
         $infos['plForeignRefs']         = array();
         $infos['INDEX']                 = $index;
         $this->info[$cname]             = $infos;
diff --git a/include/management/class_FilterElement.inc b/include/management/class_FilterElement.inc
index b46dc3536..4ca56378e 100644
--- a/include/management/class_FilterElement.inc
+++ b/include/management/class_FilterElement.inc
@@ -67,12 +67,11 @@ class TabFilterElement extends FilterElement
           continue;
         }
         if (class_available($class)) {
-          $tab    = new $class('new');
-          $filter = $tab->getLdapFilter();
-          if (!empty($filter)) {
+          $classInfos = pluglist::pluginInfos($class);
+          if (isset($classInfos['plFilterObject'])) {
             $this->tabs[$class] = array(
-              'filter'  => ldapFilter::parse($filter),
-              'infos'   => pluglist::pluginInfos($class),
+              'filter'  => $classInfos['plFilterObject'],
+              'infos'   => $classInfos,
               'checked' => FALSE,
             );
           }
diff --git a/include/management/class_managementListing.inc b/include/management/class_managementListing.inc
index a646cb016..6c94d6f49 100644
--- a/include/management/class_managementListing.inc
+++ b/include/management/class_managementListing.inc
@@ -93,11 +93,7 @@ class managementListing
 
     $this->columns = array();
     foreach ($columnInfos as $columnInfo) {
-      $this->columns[] = Column::build($columnInfo[0], $columnInfo[1]);
-    }
-
-    foreach ($this->columns as $column) {
-      $column->setParent($this);
+      $this->columns[] = Column::build($this, $columnInfo[0], $columnInfo[1]);
     }
 
     $this->columns[1]->setTemplateAttribute('cn');
diff --git a/include/management/columns/class_Column.inc b/include/management/columns/class_Column.inc
index abae2ea88..0111b3bac 100644
--- a/include/management/columns/class_Column.inc
+++ b/include/management/columns/class_Column.inc
@@ -38,7 +38,7 @@ class Column
    * \param string $type a column class
    * \param array $data an associative array with attribute and label
    * */
-  static function build($type, array $data)
+  static function build(managementListing $parent, $type, array $data)
   {
     $attribute  = NULL;
     $label      = NULL;
@@ -49,11 +49,12 @@ class Column
       $label = $data['label'];
     }
 
-    return new $type($attribute, $label);
+    return new $type($parent, $attribute, $label);
   }
 
-  function __construct($attribute = NULL, $label = NULL)
+  function __construct(managementListing $parent, $attribute = NULL, $label = NULL)
   {
+    $this->parent     = $parent;
     $this->attribute  = $attribute;
     $this->label      = $label;
   }
@@ -63,11 +64,6 @@ class Column
     $this->templateAttribute = $attribute;
   }
 
-  function setParent(managementListing $parent)
-  {
-    $this->parent = $parent;
-  }
-
   function isSortable()
   {
     return TRUE;
diff --git a/include/management/columns/class_PropertiesColumn.inc b/include/management/columns/class_PropertiesColumn.inc
index c4cc5393d..502b701e5 100644
--- a/include/management/columns/class_PropertiesColumn.inc
+++ b/include/management/columns/class_PropertiesColumn.inc
@@ -23,37 +23,49 @@
  */
 class PropertiesColumn extends Column
 {
-  function isSortable()
-  {
-    return FALSE;
-  }
+  protected $tabs;
 
-  function fillNeededAttributes(array &$attrs)
-  {
-    $attrs['objectClass'] = '*';
-  }
-
-  function renderCell(ListingEntry $entry)
+  function __construct(managementListing $parent, $attribute = NULL, $label = NULL)
   {
     global $config;
 
-    $infos = objects::infos($entry->getTemplatedType());
+    parent::__construct($parent, $attribute, $label);
 
-    static $tabs = array();
+    $this->tabs = array();
 
-    if (empty($tabs[$entry->type])) {
-      $tabs[$entry->type] = array();
+    foreach ($this->parent->parent->objectTypes as $type) {
+      $infos = objects::infos($type);
+      $this->tabs[$type] = array();
       foreach ($config->data['TABS'][$infos['tabGroup']] as $plug) {
         if ($plug['CLASS'] == $infos['mainTab']) {
           continue;
         }
         if (class_available($plug['CLASS'])) {
-          $name = $plug['CLASS'];
-
-          $tabs[$entry->type][$name] = new $name('new');
+          $this->tabs[$type][] = $plug['CLASS'];
         }
       }
     }
+  }
+
+  function isSortable()
+  {
+    return FALSE;
+  }
+
+  function fillNeededAttributes(array &$attrs)
+  {
+    foreach ($this->tabs as $type => $tabs) {
+      foreach ($tabs as $class) {
+        $class::fillAccountAttrsNeeded($attrs);
+      }
+    }
+  }
+
+  function renderCell(ListingEntry $entry)
+  {
+    global $config;
+
+    $infos = objects::infos($entry->getTemplatedType());
 
     /* Main tab is always there */
     $pInfos = pluglist::pluginInfos($infos['mainTab']);
@@ -66,8 +78,9 @@ class PropertiesColumn extends Column
       } else {
         $attrs = $entry;
       }
-      foreach ($tabs[$entry->type] as $class => $tab) {
-        if ($tab->is_this_account($attrs)) {
+      foreach ($this->tabs[$entry->type] as $class) {
+        $status = $class::isAccount($attrs);
+        if ($status !== FALSE) {
           $pInfos = pluglist::pluginInfos($class);
           if (isset($pInfos['plSmallIcon'])) {
             $result .= '<input type="image" src="'.htmlentities($pInfos['plSmallIcon'], ENT_COMPAT, 'UTF-8').'" '.
diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc
index 2b8b43a1c..3c0db9253 100644
--- a/include/simpleplugin/class_simplePlugin.inc
+++ b/include/simpleplugin/class_simplePlugin.inc
@@ -318,26 +318,24 @@ class simplePlugin
 
   function is_this_account($attrs)
   {
-    $found = TRUE;
-    foreach ($this->objectclasses as $obj) {
-      if (preg_match('/^top$/i', $obj)) {
-        continue;
-      }
-      if (!isset($attrs['objectClass']) || !in_array_ics ($obj, $attrs['objectClass'])) {
-        $found = FALSE;
-        break;
+    $result = static::isAccount($attrs);
+    if ($result === NULL) {
+      if (!empty($this->objectclasses)) {
+        trigger_error('Deprecated fallback was used for '.get_called_class().'::is_this_account');
+      }
+      $found = TRUE;
+      foreach ($this->objectclasses as $obj) {
+        if (preg_match('/^top$/i', $obj)) {
+          continue;
+        }
+        if (!isset($attrs['objectClass']) || !in_array_ics ($obj, $attrs['objectClass'])) {
+          $found = FALSE;
+          break;
+        }
       }
+      return $found;
     }
-    return $found;
-  }
-
-  function getLdapFilter()
-  {
-    if (!empty($this->objectclasses)) {
-      return '(&(objectClass='.implode(')(objectClass=', $this->objectclasses).'))';
-    } else {
-      return FALSE;
-    }
+    return $result;
   }
 
   function setTemplate ($bool)
@@ -408,11 +406,8 @@ class simplePlugin
    */
   function getObjectClassFilter ()
   {
-    if (!empty($this->objectclasses)) {
-      return '(&(objectClass='.implode(')(objectClass=', $this->objectclasses).'))';
-    } else {
-      return '';
-    }
+    trigger_error('Deprecated');
+    return static::getLdapFilter();
   }
 
   /*! \brief This function allows to use the syntax $plugin->attributeName to get attributes values
@@ -1958,6 +1953,46 @@ class simplePlugin
     return (isset($this->dialog) && $this->dialog);
   }
 
+  static function fillAccountAttrsNeeded(&$needed)
+  {
+    $infos = pluglist::pluginInfos(get_called_class());
+    if (isset($infos['plFilterObject'])) {
+      $attrs = $infos['plFilterObject']->listUsedAttributes();
+      foreach ($attrs as $attr) {
+        if (!isset($needed[$attr])) {
+          $needed[$attr] = '*';
+        }
+      }
+    }
+  }
+
+  static function isAccount($attrs)
+  {
+    $infos = pluglist::pluginInfos(get_called_class());
+    if (isset($infos['plFilterObject'])) {
+      return $infos['plFilterObject']($attrs);
+    }
+    return NULL;
+  }
+
+  static function getLdapFilter()
+  {
+    $infos = pluglist::pluginInfos(get_called_class());
+    if (isset($infos['plFilter'])) {
+      return $infos['plFilter'];
+    }
+    return NULL;
+  }
+
+  static function getLdapFilterObject()
+  {
+    $infos = pluglist::pluginInfos(get_called_class());
+    if (isset($infos['plFilterObject'])) {
+      return $infos['plFilterObject'];
+    }
+    return NULL;
+  }
+
   /*!
    * \brief Return plugin informations for acl handling
    *
diff --git a/plugins/admin/groups/class_groupManagement.inc b/plugins/admin/groups/class_groupManagement.inc
index 39498a09a..2a71c227f 100644
--- a/plugins/admin/groups/class_groupManagement.inc
+++ b/plugins/admin/groups/class_groupManagement.inc
@@ -2,7 +2,7 @@
 /*
   This code is part of FusionDirectory (http://www.fusiondirectory.org/)
   Copyright (C) 2003  Cajus Pollmeier
-  Copyright (C) 2011-2016  FusionDirectory
+  Copyright (C) 2011-2018  FusionDirectory
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -19,15 +19,19 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 */
 
-class groupManagement extends simpleManagement
+class groupManagement extends management
 {
-  protected $objectTypes  = array('ogroup', 'role', 'group');
-
-  protected $autoFilter = FALSE;
-
   public static $skipTemplates = FALSE;
 
-  protected $siActive = FALSE;
+  public static $columns = array(
+    array('ObjectTypeColumn', array()),
+    array('LinkColumn',       array('attribute' => 'cn',          'label' => 'Name')),
+    array('LinkColumn',       array('attribute' => 'description', 'label' => 'Description')),
+    array('PropertiesColumn', array('label' => 'Properties')),
+    array('ActionsColumn',    array('label' => 'Actions')),
+  );
+
+  //~ protected $siActive = FALSE;
 
   static function plInfo()
   {
@@ -46,8 +50,8 @@ class groupManagement extends simpleManagement
 
   function __construct()
   {
-    $this->filterXMLPath  = get_template_path('group-filter.xml', TRUE, dirname(__FILE__));
-    $this->listXMLPath    = get_template_path('group-list.xml', TRUE, dirname(__FILE__));
+    //~ $this->filterXMLPath  = get_template_path('group-filter.xml', TRUE, dirname(__FILE__));
+    //~ $this->listXMLPath    = get_template_path('group-list.xml', TRUE, dirname(__FILE__));
 
     // Check if we are able to communicate with Argonaut server
     if (class_available('supportDaemon') && class_available('argonautAction')) {
@@ -57,7 +61,7 @@ class groupManagement extends simpleManagement
 
     parent::__construct();
 
-    $this->headpage->registerElementFilter('filterProperties', 'groupManagement::filterProperties');
+    //~ $this->headpage->registerElementFilter('filterProperties', 'groupManagement::filterProperties');
   }
 
   function configureFilter ()
@@ -231,7 +235,7 @@ class groupManagement extends simpleManagement
 
   /*! \brief  Detects actions/events send by the ui
    *           and the corresponding targets.
-   */
+   *//*
   function detectPostActions()
   {
     $action = parent::detectPostActions();
@@ -243,60 +247,6 @@ class groupManagement extends simpleManagement
     return $action;
   }
 
-  static function filterProperties($row, $dn, $objectType, $attrs, $gosaGroupObjects = NULL)
-  {
-    global $config;
-    static $grouptabs = array();
-
-    // Load information if needed
-    $result = '&nbsp;';
-    if (!empty($attrs)) {
-      if (strtolower($objectType) == 'ogroup') {
-        if (empty($gosaGroupObjects)) {
-          return $result;
-        } else {
-          return static::filterGroupObjects($row, $gosaGroupObjects);
-        }
-      }
-      if (strtolower($objectType) == 'role') {
-        return '<input class="center" type="image" src="geticon.php?context=types&amp;icon=role&amp;size=16" '.
-                 'alt="'._('Role').'" title="'._('Edit role properties').'" '.
-                 'name="listing_edit_'.$row.'" style="padding:1px"/>';
-      }
-      if (empty($grouptabs)) {
-        foreach ($config->data['TABS']['GROUPTABS'] as $plug) {
-          if ($plug['CLASS'] == 'posixGroup') {
-            continue;
-          }
-          if (class_available($plug['CLASS'])) {
-            $name = $plug['CLASS'];
-
-            $grouptabs[$name] = new $name($dn);
-          }
-        }
-      }
-      $result = '<input class="center" type="image" src="geticon.php?context=types&amp;icon=user-group&amp;size=16" '.
-                       'alt="'._('Posix').'" title="'._('Edit posix properties').'" '.
-                       'name="listing_edit_tab_group_'.$row.'" style="padding:1px"/>';
-      foreach ($grouptabs as $class => $grouptab) {
-        if ($grouptab->is_this_account($attrs)) {
-          $infos = pluglist::pluginInfos($class);
-          if (isset($infos['plSmallIcon'])) {
-            $result .= '<input class="center" type="image" src="'.htmlentities($infos['plSmallIcon'], ENT_COMPAT, 'UTF-8').'" '.
-                       'alt="'.$infos['plTitle'].'" title="'.$infos['plTitle'].'" '.
-                       'name="listing_edit_tab_'.$class.'_'.$row.'" style="padding:1px"/>';
-          } else {
-            @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $infos['plShortName']." ($class)", 'No icon for');
-          }
-        } else {
-          $result .= '<img src="images/empty.png" alt=" " class="center optional '.$class.'" style="padding:1px"/>';
-        }
-      }
-    }
-
-    return $result;
-  }
-
   static function filterGroupObjects($row, $gosaGroupObjects)
   {
     $types  = preg_replace('/[^a-z]/i', '', $gosaGroupObjects[0]);
@@ -359,6 +309,6 @@ class groupManagement extends simpleManagement
     $this->headpage->update();
     $display = $this->headpage->render();
     return $this->getHeader().$display;
-  }
+  }*/
 }
 ?>
diff --git a/plugins/admin/groups/class_ogroup.inc b/plugins/admin/groups/class_ogroup.inc
index 2dcca5042..c34532dee 100644
--- a/plugins/admin/groups/class_ogroup.inc
+++ b/plugins/admin/groups/class_ogroup.inc
@@ -174,7 +174,7 @@ class ogroup extends simplePlugin
     return array(
       'plShortName'   => _('Object group'),
       'plDescription' => _('Object group information'),
-      'plSelfModify'  => FALSE,
+      'plFilter'      => '(objectClass=groupOfNames)',
       'plPriority'    => 1,
       'plObjectType'  => array('ogroup' => array(
         'name'        => _('Group'),
@@ -299,21 +299,6 @@ class ogroup extends simplePlugin
     $this->savedTypedMembers = $this->attributesAccess['member']->getTypedValues();
   }
 
-  /*! \brief This function returns an LDAP filter for this plugin object classes
-   */
-  function getObjectClassFilter ()
-  {
-    return '(objectClass=groupOfNames)';
-  }
-
-  function is_this_account($attrs)
-  {
-    $this->objectclasses  = array('groupOfNames');
-    $found = parent::is_this_account($attrs);
-    $this->objectclasses  = array('groupOfNames', 'gosaGroupOfNames');
-    return $found;
-  }
-
   function prepare_save()
   {
     $this->reload();
diff --git a/plugins/admin/groups/main.inc b/plugins/admin/groups/main.inc
index eba2e1f99..e1be2670b 100644
--- a/plugins/admin/groups/main.inc
+++ b/plugins/admin/groups/main.inc
@@ -1,7 +1,7 @@
 <?php
 /*
   This code is part of FusionDirectory (http://www.fusiondirectory.org/)
-  Copyright (C) 2013-2016  FusionDirectory
+  Copyright (C) 2013-2018  FusionDirectory
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -18,5 +18,5 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 */
 
-simpleManagement::mainInc('groupManagement');
+management::mainInc('groupManagement');
 ?>
diff --git a/plugins/personal/generic/class_user.inc b/plugins/personal/generic/class_user.inc
index 2e4c64cba..30d80ddc1 100644
--- a/plugins/personal/generic/class_user.inc
+++ b/plugins/personal/generic/class_user.inc
@@ -277,6 +277,7 @@ class user extends simplePlugin
     return array(
       'plShortName'   => _('User'),
       'plDescription' => _('User account information'),
+      'plFilter'      => '(objectClass=inetOrgPerson)',
       'plIcon'        => 'geticon.php?context=applications&icon=user-info&size=48',
       'plSmallIcon'   => 'geticon.php?context=applications&icon=user-info&size=16',
       'plSelfModify'  => TRUE,
@@ -491,12 +492,6 @@ class user extends simplePlugin
     $this->was_locked = $this->attributesAccess['userPassword']->isLocked();
   }
 
-  function is_this_account($attrs)
-  {
-    /* Only inetOrgPerson is needed, it has the two others as SUP classes */
-    return (isset($attrs['objectClass']) && in_array_ics('inetOrgPerson', $attrs['objectClass']));
-  }
-
   function resetCopyInfos()
   {
     parent::resetCopyInfos();
-- 
GitLab