Développer une nouvelle application pour eGroupWare

De ClissXXI.

Sommaire

L'arborescence d'une application

Une application eGroupWare doit suivre une arborescence particulière :

  • NomApplication (rep)
    • index.php (fic)
    • setup (rep)
      • setup.inc.php (fic)
      • tables_current.inc.php (fic)
      • phpgw_??.lang (fic)
    • inc (rep)
      • class.????.inc.php (fic)
      • hook.????.inc.php (fic)
    • templates (rep)
      • default (rep)
        • ????.tpl (fic)
        • app.css (fic)
        • images (rep)
          • navbar.png (fic)

Le répertoire setup contient :

  • setup.inc.php : fichier permettant de définir les paramètres utilisés lors de l'installation de l'application.
  • tables_current.inc.php : fichier contenant la définition des tables devant être ajoutées à la base de données.
  • phpgw_??.lang : fichier contenant les traductions. ?? = en pour anglais, fr pour français.

Le répertoire inc contient :

  • class.???.inc.php : fichier contenant le code de l'application. Les noms doivent être définis comme suit :
    • class.uiNomApplication.inc.php : contient le code gérant l'interface avec l'utilisateur.
    • class.boNomApplication.inc.php : contient le code qui traite les données provenant de la base de données.
    • class.soNomApplication.inc.php : contient le code communiquant avec la base de données.
  • hook.???.inc.php : fichier contenant le code des divers menus (préférences, administration, configuration, ...)

Le répertoire templates contient divers répertoires correspondant aux styles d'affichage utilisés. Le répertoire par défaut se nomme default et est composé de :

  • ???.tpl : fichier contenant un template d'affichage.
  • app.css : fichier contenant la css utilisée
  • un répertoire images contient les images utilisées dans l'application. L'icône devant être affichée dans la barre des applications doit se nommer navbar.png.

Le fichier de configuration

La création d'une application commence par la définition du fichier de configuration. Ce fichier doit s'appeler setup.inc.php et doit se trouver dans le répertoire setup de l'application. Il s'agit alors de compléter les champs du tableau setup définissant les paramètres de l'application.

  • setup_info['NomApplication']['name'] : nom de l'application.
  • setup_info['NomApplication']['title'] : titre de l'application.
  • setup_info['NomApplication']['version'] : version de l'application.
  • setup_info['NomApplication']['app_order'] : position de l'application dans la barre de menu.
  • setup_info['NomApplication']['enable'] : '1' permet de spécifier que l'application doit être active, '0' permet de spécifier que l'application ne doit pas être active.
  • setup_info['NomApplication']['author'] : nom de l'auteur de l'application.
  • setup_info['NomApplication']['licence'] : la licence sous laquelle est l'application (par exemple GPL).
  • setup_info['NomApplication']['description'] : description de l'application.
  • setup_info['NomApplication']['maintener'] : nom du développeur qui maintient l'application.
  • setup_info['NomApplication']['maintener_email'] : adresse mail du développeur qui maintient l'application.
  • setup_info['NomApplication']['tables'] : tabeau contenant les noms des tables devant être créées dans la base de données (par exemple : array(egw_table1,egw_tables2)).
  • setup_info['NomApplication']['hooks'][] : nom de la classe définissant les menu (par exemple pour hook.nomMenu.inc.php mettre nomMenu).
  • setup_info['NomApplication']['hooks']['settings'] : chemin vers la définition des préférences NomApplication.NomClassePreference.fonctionPreference (Voir le chapitre concerné pour plus de détails)

Définir les tables devant être intégrées à la base de données

La création des tables de la base de données se fait automatiquement lors de l'installation de l'application dans eGroupWare. Pour cela, il faut définir les tables dans le fichier tables_current.inc.php qui doit se trouver dans le répertoire setup. Ce fichier contient un tableau phpgw_baseline qui contient la définition des différentes tables. Par principe, les tables doivent être définies de la manière suivante : egw_NomTable. Les paramètres sont disposés dans un tableau contenant les champs suivants :

  • fd : (field definition) tableau contenant la définition des champs de la table.
'fd' => array(
           'NomChamp1' => array(
                            'propriété1' => valeur1,
                            'propriété2' => valeur2,
                                  ......
                          );             
           'NomChamp2' => array(
                              ......
                          );
);

Voici une liste non exhaustive des propriétés des champs :

  • 'type' :
    • auto : indice auto-incrémental
    • varchar : chaine de caractères, indiquer la longueur avec la propriété 'precision'
    • text : texte
    • int : entier, indiquer la longueur avec la propriété 'précision'
    • char : caractère
  • 'nullable' : (True,False) indique si le champ peut être null
  • 'default' : permet de préciser une valeur par défaut


  • pk : (primary key) tableau contenant la définition de la clé primaire.
'pk' => array(
          'NomChamp1',
          'NomChamp2',
             .....
        );
);
  • fk : (foreign key) tableau contenant la définition des clés étrangères.
'fk' => array(
           'NomChamp1',
           'NomChamp2',
              .....
        );
);        
  • ix
  • uc

Exemple de fichier tables_current.inc.php

<?
  phpgw_baseline = array(
         'egw_personne' => array(
                       'fd' => array(
                                  'personne_id' => array('type' => 'auto', 'nullable' => False),
                                  'personne_nom' => array('type' => 'varchar', 'precision' => '64'),
                                  'personne_prenom' => array('type' => 'varchar', 'precision' => '64'), 
                        ),
                       'pk' => array(personne_id),
                       'fk' => array(),
                       'ix' => array(),
                       'uc' => array(),
          ),
  );         
?>

Le fichier index.php

Le fichier index.php est important car c'est lui qui est appelé en premier lors du lancement de l'application. Ce fichier doit se trouver à la racine de l'application. index.php sert en fait à rediriger vers une fonction d'une classe du répertoire inc/. Ce fichier doit contenir le code suivant :

<?php
   header('Location: ../index.php?menuaction=NomApplication.Classe.Fonction');

NomApplication est le nom de l'application, Classe.Fonction est la première fonction à appeler (Classe est le nom de la classe sans 'class.' et sans '.inc.php').


Construire la colonne des menus

Pour construire une colonne de menu, il suffit de créer des fichiers "hook.???.inc.php" dans le répertoire 'MonApplication/inc/' et de modifier le fichier MonApplication/setup/setup.inc.php pour prendre en compte le nouveau menu. Pour construire un menu, il suffit de définir un titre, un tableau contenant les liens vers les pages à appeler et d'appeler la fonction display_sidebox(nomApplicationtitre,tableau_liens).

Prenons par exemple le fichier 'hook.exemple.inc.php'. Ce fichier contiendra 2 menus (configuration et préférences).

  • Modifier le fichier MonApplication/setup/setup.inc.php :

On ajoute la ligne suivante :

 setup_info['MonApplication']['hooks'][] = 'exemple';
  • Créer le fichier MonApplication/inc/hook.exemple.inc.php
<?
 // Création du menu 'Configuration'
 $menu_title = 'Configuration';
 $file = array(
           'Configurer les catégories' => $GLOBALS['egw']->link('/index.php',array('menuaction'=>'MonApplication.configuration.index','param'=>'cat')),
           'Configurer les droits' => $GLOBALS['egw']->link('/index.php',array('menuaction'=>'MonApplication.configuration.index','param'=>'droit')),
 );
 display_sidebox($appname, $menu_title, $file);
 // Création du menu 'Préférences'
 $menu_title = 'Préférences';
 $file = array(
           'Configurer les préférences' => $GLOBALS['egw']->link('/index.php',array('menuaction'=>'MonApplication.preferences.index')),
 );
 display_sidebox($appname, $menu_title, $file);
?>

Remarque : La fonction '$GLOBALS['egw']->link()' sert à créer des liens sécurisés. Cette fonction prend 2 paramètres : une URL de base (ici /index.php) et un tableau contenant les paramètres à ajouter à l'URL. Le champ 'menuaction' est un peu spécial car il sert à compléter l'adresse. Ainsi, si 'menuaction' vaut 'appli.classe.fonction' alors l'adresse sera dirigée sur la fonction 'fonction' de la classe 'classe' de l'application 'appli'.

Construire une page à onglets de configuration des préférences

Deux étapes sont nécessaires pour construire une page à onglets de préferences : modifier le fichier de configuration MonApplication/setup/setup.inc.php et constuire une classe qui contient les informations nécessaires à l'affichages des préférences.

  • Modification du fichier de configuration MonApplication/setup/setup.inc.php

On ajoute la ligne suivante :

$setup_info['MonApplication']['hooks']['settings'] = 'MonApplication.NomClassePref.FonctionDef';

'MonApplication' est le nom de l'application. 'NomClasseDef' est le nom de la classe contenant les définitions des préférences. 'FonctionDef' est le nom de la fonction de la classe 'NomClasseDef' contenant les définitions des préférences.

  • Définir les préférences :

Les préférences sont définies dans une fonction d'une classe du répertoire inc/. Pour définir une préférence, il suffit de compléter les champs du tableau $GLOBALS['settings']['nom_de_la_preference'] :

    • 'type' : mettre 'select' pour avoir une boite de selection.
    • 'label' : label qui sera affiché devant la boite de selection.
    • 'name' : nom de la préférence.
    • 'default' : valeur par défaut de la préférence.
    • 'values' : tableau contenant les options de la boite de sélection. Les option sont définies comme ceci : valeur => intitulé.
    • 'help' : message d'aide devant être affiché.
    • 'xmlrpc' : (True ou False)
    • 'admin' : (True ou False) définit si la préférence n'est accessible que par l'administrateur.

Exemple d'une classe :

<?
  class preference
  {
     var $appname;
     // le constructeur
     function preference()
     {
        $this->appname = 'MonApplication';
     }
     function uisettings()
     {
        $GLOBALS['settings']['ma_preference'] = array(
             'type' => 'select',
             'label' => 'Choisissez une préférence',
             'name' => 'ma_preference',
             'default' => 'valeur0',
             'values' => array(
                           'valeur0' => 'Ma préférence 0',
                           'valeur1' => 'Ma préférence 1',
                           'valeur2' => 'Ma préférence 2', 
              ),
              'help' => 'il faut choisir une préférence',
              'xmlrpc' => True,
              'admin' => false,
        );
        $GLOBALS['settings']['ma_preference2'] = array(
                     .......
        );
     }
  }
?>

Construire une page

En dehors de l'affichage de l'application elle-même, il faut afficher l'entête d'egroupware (par exemple la barre des icônes) et le pied de page. Ceci peut être fait avec les deux fonctions suivantes : création de l'entête :

public function create_header()
{
    $GLOBALS['egw']->common->egw_header();
    echo parse_navbar();
}

création du pied de page :

public function create_footer()
{
    $GLOBALS['egw']->common->egw_footer();
}

La fonction create_header devra être appelée avant d'effectuer un affichage. La fonction create_footer devra être appelée après avoir effectué l'affichage.

Utiliser des templates simples

Il existe deux façons d'afficher des éléments : utiliser les 'etemplates' ou utiliser les templates 'simples'. Ici, on s'intéressera à l'utilisation des templates 'simples'.

  • Les templates

Les templates sont des fichiers contenant du code HTML. Ces fichiers se terminent par '.tpl' et sont placés dans un des répertoires de 'MonApplication/templates/' (par exemple dans 'MonApplication/templates/default/'). Ces templates contiennent en plus du code HTML des 'clés' qui seront remplacées par leur valeur par le code de l'application (Une 'clé' est en fait un mot contenu entre deux accolades) et des délimiteurs de blocs et .

Exemple de template 'exemple.tpl':

 <!-- BEGIN bloc_exemple -->
  <h3>{titre}</h3>
 <!-- END bloc_exemple -->
 
  • Associer une valeur à une clé

On utilise l'objet "phpgwapi.Template" que l'on crée dans le constructeur de la classe. Cet objet propose les fonctions suivantes : (a utiliser dans l'ordre)

  • set_file(param) : param est un tableau un fichier template à une clé (on l'appellera cle_page) (ex: array("body"=>'exemple.tpl'))
  • set_block('clé_page','nom_bloc') : associe 'nom_bloc' à la clé 'clé_page'
  • set_var('clé','valeur') : associe la valeur 'valeur' à la clé 'clé'
  • parse('sortie','nom_bloc') : construit le bloc et le met sur 'sortie' ('sortie' vaut 'out')
  • get('sortie','nom_bloc') : retourne le bloc 'nom_bloc' prêt à être affiché

Exemple : on reprend le template définit ci-dessus

//déclaration
var $t;
//dans le constructeur
$this->t =& CreateObject('phpgwapi.Template',EGW_APP_TPL);
//dans une fonction
$this->t->set_file(array("body"=>'exemple.tpl'));
$this->t->set_block('body','bloc_exemple');
$this->t->set_var('titre','Un joli titre');
$this->t->parse('out','bloc_exemple');
print $this->t->get('out','bloc_exemple'); 
  • Cas où une clé doit prendre plusieurs valeurs (exemple: pour créer un tableau)

Dans ce cas, on définit la partie devant être répétée dans un bloc à part et on place une clé à l'endroit où doit se trouver ce bloc. La fonction parse devient parse('cle_ou_doit_se_trouver_bloc','nom_bloc_a_répété',True).

Exemple : page.tpl

 <!-- BEGIN tableau-->
  <h3>{titre_tableau}</h3>
  <table>
   {les_lignes}
  </table>
 <!-- END tableau-->
 <!-- BEGIN ligne -->
  <tr><td>{valeur1}</td><td>{valeur2}</td></tr>
 <!-- END ligne -->
 

dans le code

       ......
$this->t->set_file(array("body","page.tpl"));
$this->t->set_block('body','tableau');
$this->t->set_block('body','ligne');
$this->t->set_var('titre_tableau','Un joli tableau');
for( ...... )
{
  $this->t->set_var('valeur1',1234);
  $this->t->set_var('valeur2',4321);
  $this->t->parse('les_lignes','ligne',True);
}
$this->t->parse("out","tableau");
print $this->t->get('out','tableau');
       ......


Communiquer simplement avec la base de données

Pour communiquer simplement avec la base de données, il faut utiliser l'objet 'so_sql'. Cet objet permet d'effectuer les principales actions sur la base de données : recherche, sauvegarde, suppression, modification. Les accès à cet objet se font depuis la classe class.bo???.inc.php qui étend cet objet.

  • Configurer la classe class.bo???.inc.php pour l'utilisation de l'objet 'so_sql'

Il faut étendre la classe 'so_sql':

require_once(EGW_INCLUDE_ROOT.'etemplate/inc/class.so_sql.inc.php');
class bo??? extends so_sql
{
  //constructeur
  function bo???()
  {
       $this->so_sql('nom_application','nom_table');
           ....
  }
    ....
}
  • Effectuer une recherche

Il suffit d'utiliser la fonction existante de la classe parente.

parent::search($criteria,$only_keys,$order_by,$extra_cols,$wildcard,$empty,$op,$start,$filter);
  • Effectuer une sauvegarde

Il suffit d'utiliser la fonction save() de la classe parente. Pour passer les valeurs il faut remplir le tableau data('nom_col'=>valeur) de la classe parente.

function save($valeur1,$valeur2)
{
  $this->data['champ1'] = $valeur1;
  $this->data['champ2'] = $valeur2;
  if(!parent::save()) echo 'sauvegarde effectuée';
  else echo 'problème lors de la sauvegarde';
}
  • Effectuer une suppression

Il suffit d'utiliser la fonction delete() de la classe parente qui prend en paramètre un tableau contenant les conditions devant apparaitre dans le "WHERE". Par exemple : pour supprimer l'enregistrement où id_personne vaut 12 :

$this->delete(array('id_personne'=>12)); 
  • Effectuer une modification

Il suffit d'utiliser la fonction save() vue plus haut et de mettre dans le tableau de paramètres la clé primaire et sa valeur de l'enregistrement à modifier.

Internationaliser l'application

L'internationalisation passe par la création de fichiers de traduction et par un légère modification du code.

  • Modification du code

Tous les messages doivent être mis en paramètre de la fonction lang(). Ces messages serviront de 'clés' pour la traduction. Il est préférable d'utiliser les traductions anglaises comme clé.

  • Créer un fichier de traduction

Les fichiers de traduction doivent être placés dans le répertoire 'MonApplication/setup/'. Leur nom ne peut pas être choisi n'importe comment : pour les traductions anglaises le fichier se nomme 'phpgw_en.lang' et pour les traductions françaises le fichier se nomme 'phpgw_fr.lang'. Une traduction doit être définie comme suit : clé<tabulation>nom_application<tabulation>langue(en=anglais/fr=français)<tabulation>traduction<retour à la ligne>

Exemples de fichiers de traduction :

  • phpgw_en.lang
Hello World!     MonApplication     en     Hello World!
cancel     MonApplication     en     cancel
  • phpgw_fr.lang
Hello World!     MonApplication     fr     Bonjour le Monde!
cancel     MonApplication     fr     annuler
  • utilisation dans le code
$intituleBouton = lang('cancel');
echo " Phrase : ".lang('Hello World!')." ";
Outils personnels