LSsearch : add customAction feature
authorBenjamin Renard <brenard@easter-eggs.com>
Wed, 8 Oct 2014 15:24:30 +0000 (17:24 +0200)
committerBenjamin Renard <brenard@easter-eggs.com>
Wed, 8 Oct 2014 15:24:30 +0000 (17:24 +0200)
doc/LS.entities.xml
doc/conf/LSobject/LSsearch.docbook
public_html/custom_search_action.php [new file with mode: 0644]
public_html/includes/class/class.LSsearch.php
public_html/includes/class/class.LSsession.php
public_html/lang/generate_lang_file.php
public_html/view.php

index a1849ef..5e6027c 100644 (file)
@@ -18,6 +18,7 @@
 <!ENTITY LSattribute "<link linkend='config-LSattribute'>LSattribute</link>">
 <!ENTITY LSattributes "<link linkend='config-LSattribute'>LSattributes</link>">
 <!ENTITY customActions "<link linkend='config-LSobject-customActions'>customActions</link>">
 <!ENTITY LSattribute "<link linkend='config-LSattribute'>LSattribute</link>">
 <!ENTITY LSattributes "<link linkend='config-LSattribute'>LSattributes</link>">
 <!ENTITY customActions "<link linkend='config-LSobject-customActions'>customActions</link>">
+<!ENTITY customSearchActions "<link linkend='config-LSobject-customSearchActions'>customActions</link>">
 <!ENTITY LSrelation "<link linkend='config-LSobject-LSrelation'>LSrelation</link>">
 <!ENTITY LSrelations "<link linkend='config-LSobject-LSrelation'>LSrelations</link>">
 <!ENTITY LSform "<link linkend='config-LSobject-LSform'>LSform</link>">
 <!ENTITY LSrelation "<link linkend='config-LSobject-LSrelation'>LSrelation</link>">
 <!ENTITY LSrelations "<link linkend='config-LSobject-LSrelation'>LSrelations</link>">
 <!ENTITY LSform "<link linkend='config-LSobject-LSform'>LSform</link>">
@@ -28,3 +29,4 @@
 <!ENTITY LSaddons "<link linkend='config-LSaddon'>LSaddons</link>">
 <!ENTITY LSauthMethod "<link linkend='config-LSauthMethod'>LSauthMethod</link>">
 <!ENTITY LSselect "<emphasis>LSselect</emphasis>">
 <!ENTITY LSaddons "<link linkend='config-LSaddon'>LSaddons</link>">
 <!ENTITY LSauthMethod "<link linkend='config-LSauthMethod'>LSauthMethod</link>">
 <!ENTITY LSselect "<emphasis>LSselect</emphasis>">
+<!ENTITY LSsearch "<link linkend='config-LSobject-LSsearch'>LSsearch</link>">
index 7327bbd..129a4bb 100644 (file)
@@ -52,6 +52,9 @@ configuration des &LSobjects;, dans la variable <varname>LSsearch</varname>
         '[LSformat 2]'
       )
     )
         '[LSformat 2]'
       )
     )
+  ),
+  'customActions' =>  array (
+    // Configuration des customActions pour les recherches de ce type d'objet
   )
 );]]>
 </programlisting>
   )
 );]]>
 </programlisting>
@@ -269,7 +272,169 @@ contexte dans lequel cette recherche est effectuée.</para>
   </listitem>
 </varlistentry>
 
   </listitem>
 </varlistentry>
 
+<varlistentry>
+  <term>customActions</term>
+  <listitem>
+    <simpara>Tableau associatif contenant les paramètres de configuration
+    des &customSearchActions;. <link linkend="config-LSobject-customSearchActions">Voir la section
+    concernée</link>.</simpara>
+  </listitem>
+</varlistentry>
+
 </variablelist>
 </para>
 
 </variablelist>
 </para>
 
+<sect3 id="config-LSobject-customSearchActions">
+  <title>customActions</title>
+  <para>Cette section décrit la manière de configurer les actions personnalisées exécutables
+  sur les recherches d'&LSobjects; appelées &customSearchActions;.</para>
+
+<programlisting>
+<citetitle>Structure</citetitle>
+<![CDATA[$GLOBALS['LSobjects']['[nom du type d'LSobject]']['LSsearch']['customActions'] = array (
+  'action1' => array(
+    'label' => '[label l'action]',
+    'hideLabel' => '[booléen]',
+    'icon' => '[nom de l'icône de l'action]',
+    'function' => '[fonction à exécuter]',
+    'question_format' => '[LSformat de la question de confirmation]',
+    'onSuccessMsgFormat' => '[LSformat du message à afficher en cas de succès de l'action]',
+    'disableOnSuccessMsg' => '[booléen]',
+    'noConfirmation' => '[booléen]',
+    'redirectToObjectList' => '[booléen]',
+    'rights' => array(
+      'LSprofile1',
+      'LSprofile2',
+      ...
+    )
+  )
+);]]>
+</programlisting>
+
+<variablelist>
+<title>Paramètres de configuration</title>
+
+<varlistentry>
+  <term>label</term>
+  <listitem>
+    <simpara>Le label de l'action.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>hideLabel</term>
+  <listitem>
+    <simpara>Cache le label dans le bouton de l'action.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>icon</term>
+  <listitem>
+    <simpara>Nom de l'îcone à afficher dans le bouton de l'action. Ce nom correspond
+    au nom du fichier de l'image (sans l'extention) qui devra se trouver dans le 
+    dossier <emphasis>/public_html/images/[nom du theme d'images]/</emphasis>.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>function</term>
+  <listitem>
+    <simpara>Le nom de la fonction à exécuter qui implémente l'action personnalisée
+    Cette fonction prendra en seule paramètre l'objet &LSsearch; sur lequel l'action
+    devra être exécutée et retournera <emphasis>True</emphasis> en cas de succès ou 
+    <emphasis>False</emphasis> en cas d'échec d'exécution de la fonction.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>question_format</term>
+  <listitem>
+    <simpara>Le &LSformat; de la question de confirmation d'exécution de l'action.
+    Ce &LSformat; sera composé à l'aide du label de l'action.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>onSuccessMsgFormat</term>
+  <listitem>
+    <simpara>Le &LSformat; du message à afficher en cas de succès d'exécution de
+    l'action. Ce &LSformat; sera composé à l'aide du label de l'action.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>disableOnSuccessMsg</term>
+  <listitem>
+    <simpara>Booléen permetant de désactiver le message afficher en cas de succès
+    d'exécution de l'action.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>noConfirmation</term>
+  <listitem>
+    <simpara>Booléen permetant de désactiver la confirmation de l'exécution de
+    l'action.</simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>redirectToObjectList</term>
+  <listitem>
+    <simpara>Booléen permetant de rediriger ou non l'utilisateur vers la liste
+    des objets (Vrai par défaut). Si l'utilisateur n'est redirigé, le template
+    par défaut (ou celui défini durant l'éxécution de la fonction) sera affiché.
+    </simpara>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
+  <term>rights</term>
+  <listitem>
+    <simpara>Tableau contenant la liste des noms des &LSprofiles; ayant le droit
+    d'exécuter cette action.</simpara>
+  </listitem>
+</varlistentry>
+
+</variablelist>
+
+<sect4>
+    <title>Ecriture d'une fonction implémentant une customAction</title>
+    <para>Une fonction implémentant une <emphasis>customAction</emphasis> se déclare de
+    la manière suivante :
+    <programlisting linenumbering="unnumbered"><![CDATA[
+/*
+ * Ma fonction implémentant ma customAction
+ *
+ * Paramètre :
+ *     - $search : L'objet LSsearch de la recherche sur lequel mon action doit être exécutée
+ *
+ * Valeurs retournées :
+ *     - True : Tout s'est bien passé
+ *     - False : Une erreur est survenue
+ */
+function maFonction ($search) {
+
+  // Actions
+
+}
+    ]]></programlisting>
+Cette fonction doit prendre pour seul paramètre, l'objet &LSsearch; sur lequel l'action
+personnalisée doit être exécutée et doit retourner soit <literal>True</literal> si
+tout s'est bien passé, soit <literal>False</literal> en cas de problème.</para>
+
+<important><simpara>La recherche passée en paramètre n'a pas encore été exécutée. En conséquence,
+si vous avez besoin d'accéder au résultat de la recherche, il est nécessaire d'exécuter au préalable :
+<literal>$search -> run();</literal>. Cela permet en outre, de modifier les paramètres de la recherche
+avant de l'exécuter. Cela peut par exemple être utile, si vous avez besoin d'accèder aux valeurs
+d'attributs particuliers, d'ajouter des attributs au résultat de la recherche :
+<literal>$search -> setParam('attributes',array('attr1','attr2'));</literal>.</simpara></important>
+
+<note><simpara>Ces fonctions sont le plus couramment définies au sein d'&LSaddon;.</simpara></note>
+
+</sect4>
+
+</sect3>
+
 </sect2>
 </sect2>
diff --git a/public_html/custom_search_action.php b/public_html/custom_search_action.php
new file mode 100644 (file)
index 0000000..b223ef9
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+/*******************************************************************************
+ * Copyright (C) 2007 Easter-eggs
+ * http://ldapsaisie.labs.libre-entreprise.org
+ *
+ * Author: See AUTHORS file in top-level directory.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+******************************************************************************/
+
+require_once 'core.php';
+
+if(LSsession :: startLSsession()) {
+
+  if ((isset($_GET['LSobject'])) && (isset($_GET['customAction']))) {
+    $LSobject=urldecode($_GET['LSobject']);
+    $customAction=urldecode($_GET['customAction']);
+
+    if (LSsession :: loadLSclass('LSsearch')) {
+        $LSsearch = new LSsearch($LSobject,'LSview');
+        $LSsearch -> setParam('extraDisplayedColumns',True);
+        $LSsearch -> setParamsFormPostData();
+
+        if ( LSsession :: canExecuteLSsearchCustomAction($LSsearch,$customAction) ) {
+          $config = LSconfig :: get('LSobjects.'.$LSobject.'.LSsearch.customActions.'.$customAction);
+          if (isset($config['function']) && is_callable($config['function'])) {
+            if (isset($config['label'])) {
+              $title=__($config['label']);
+            }
+            else {
+              $title=__($customAction);
+            }
+            if (isset($_GET['valid']) || $config['noConfirmation']) {
+              LStemplate :: assign('pagetitle',$title);
+              if ($config['function']($LSsearch)) {
+                if ($config['disableOnSuccessMsg']!=true) {
+                  if ($config['onSuccessMsgFormat']) {
+                    LSsession :: addInfo(getFData(__($config['onSuccessMsgFormat']),$objectname));
+                  }
+                  else {
+                    LSsession :: addInfo(getFData(_('The custom action %{title} have been successfully execute this search.'),$title));
+                  }
+                }
+                if (!isset($config['redirectToObjectList']) || $config['redirectToObjectList']) {
+                  LSsession :: redirect('view.php?LSobject='.$LSobject.'&refresh');
+                }
+              }
+              else {
+                LSerror :: addErrorCode('LSsearch_16',$customAction);
+              }
+            }
+            else {
+              $question=(
+               isset($config['question_format'])?
+               getFData(__($config['question_format']),$title):
+               getFData(_('Do you really want to execute custom action %{title} on this search ?'),$title)
+             );
+              LStemplate :: assign('pagetitle',$title);
+              LStemplate :: assign('question',$question);
+              LStemplate :: assign('validation_url','custom_search_action.php?LSobject='.urlencode($LSobject).'&amp;customAction='.urlencode($customAction).'&amp;valid');
+              LStemplate :: assign('validation_label',_('Validate'));
+              LSsession :: setTemplate('question.tpl');
+            }
+          }
+          else {
+            LSerror :: addErrorCode('LSsession_13');
+          }
+        }
+        else {
+          LSerror :: addErrorCode('LSsession_11');
+        }
+    }
+    else {
+      LSsession :: addErrorCode('LSsession_05','LSsearch');
+    }
+  }
+  else {
+    LSerror :: addErrorCode('LSsession_12');
+  }
+
+}
+else {
+  LSsession :: setTemplate('login.tpl');
+}
+
+// Affichage des retours d'erreurs
+LSsession :: displayTemplate();
+?>
index cecacf2..edcff01 100644 (file)
@@ -1011,6 +1011,7 @@ class LSsearch {
    **/
   public function __get($key) {
     $params = array (
    **/
   public function __get($key) {
     $params = array (
+      'basedn',
       'sortBy',
       'sortDirection'
     );
       'sortBy',
       'sortDirection'
     );
@@ -1314,5 +1315,6 @@ _("LSsearch : The function of the custum information %{name} is not callable.")
 LSerror :: defineError('LSsearch_15',
 _("LSsearch : Invalid predefinedFilter for LSobject type %{type} : %{label} (filter : %{filter}).")
 );
 LSerror :: defineError('LSsearch_15',
 _("LSsearch : Invalid predefinedFilter for LSobject type %{type} : %{label} (filter : %{filter}).")
 );
-
-?>
+LSerror :: defineError('LSsearch_16',
+_("LSsearch : Error during execution of the custom action %{customAction}.")
+);
index 934c82a..8d30882 100644 (file)
@@ -1897,6 +1897,35 @@ class LSsession {
   }
 
   /**
   }
 
   /**
+   * Retourne le droit de l'utilisateur a executer une customAction
+   * sur une recherche
+   *
+   * @param[in] string $LSsearch L'objet LSsearch
+   * @param[in] string $customActionName Le nom de la customAction
+   *
+   * @retval boolean True si l'utilisateur peut executer cette customAction, false sinon
+   */
+  public static function canExecuteLSsearchCustomAction($LSsearch,$customActionName) {
+    $conf=LSconfig :: get('LSobjects.'.$LSsearch -> LSobject.'.LSsearch.customActions.'.$customActionName);
+    if (!is_array($conf))
+      return;
+    $dn=$LSsearch -> basedn;
+    if (is_null($dn)) $dn=self::getTopDn();
+
+    $whoami = self :: whoami($dn);
+
+    if (isset($conf['rights']) && is_array($conf['rights'])) {
+      foreach($whoami as $who) {
+        if (in_array($who,$conf['rights'])) {
+          return True;
+        }
+      }
+    }
+
+    return;
+  }
+
+  /**
    * Ajoute un fichier temporaire
    * 
    * @author Benjamin Renard <brenard@easter-eggs.com>
    * Ajoute un fichier temporaire
    * 
    * @author Benjamin Renard <brenard@easter-eggs.com>
index 1d52500..be92163 100755 (executable)
@@ -127,6 +127,14 @@ if (loadDir('../'.LS_OBJECTS_DIR) && loadDir('../'.LS_LOCAL_DIR.LS_OBJECTS_DIR))
         add($cconf['label']);
       }
     }
         add($cconf['label']);
       }
     }
+    if (is_array($conf['LSsearch']['customActions'])) {
+      foreach($conf['LSsearch']['customActions'] as $act) {
+        add($act['label']);
+        add($act['question_format']);
+        add($act['onSuccessMsgFormat']);
+      }
+    }
+
 
     
     if(is_array($conf['attrs'])) {
 
     
     if(is_array($conf['attrs'])) {
index 78afd76..0b996c4 100644 (file)
@@ -151,6 +151,23 @@ if(LSsession :: startLSsession()) {
             'url' => 'view.php?LSobject='.$LSobject.'&amp;LSsearchPurgeSession',
             'action' => 'delete'
           );*/
             'url' => 'view.php?LSobject='.$LSobject.'&amp;LSsearchPurgeSession',
             'action' => 'delete'
           );*/
+
+          // Custum Actions
+          $customActionsConfig = LSconfig :: get('LSobjects.'.$LSobject.'.LSsearch.customActions');
+          if (is_array($customActionsConfig)) {
+            foreach($customActionsConfig as $name => $config) {
+              if (LSsession :: canExecuteLSsearchCustomAction($LSsearch,$name)) {
+                $LSview_actions[] = array (
+                  'label' => ((isset($config['label']))?__($config['label']):__($name)),
+                  'hideLabel' => ((isset($config['hideLabel']))?$config['hideLabel']:False),
+                  'url' => 'custom_search_action.php?LSobject='.$LSobject.'&amp;customAction='.$name,
+                  'action' => ((isset($config['icon']))?$config['icon']:'generate'),
+                  'class' => 'LScustomActions'.(($config['noConfirmation'])?' LScustomActions_noConfirmation':'')
+                );
+              }
+            }
+          }
+
           LStemplate :: assign('LSview_actions',$LSview_actions);
           
           $LSsearch -> run();
           LStemplate :: assign('LSview_actions',$LSview_actions);
           
           $LSsearch -> run();