Add import feature

This commit is contained in:
Benjamin Renard 2015-07-30 16:37:42 +02:00
parent 303702a4ee
commit 0055ea1d7a
17 changed files with 1925 additions and 808 deletions

View file

@ -65,6 +65,11 @@
// Configuration des recherches de l'objet // Configuration des recherches de l'objet
), // fin LSsearch ), // fin LSsearch
// ioFormat
'ioFormat' => array (
// Configuration des formats d'import/export de l'objet
),
// Attributs // Attributs
'attrs' => array ( 'attrs' => array (
// Configuration des attributs du type d'LSobjet // Configuration des attributs du type d'LSobjet
@ -237,6 +242,16 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>ioFormat</term>
<listitem>
<simpara>Tableau associatif contenant les paramètres de configuration
des formats de fichiers d'import/export de ce type d'&LSobject;.
<link linkend="config-LSobject-ioFormat">Voir la section concernée</link>.
</simpara>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>filter</term> <term>filter</term>
<listitem> <listitem>
@ -264,5 +279,6 @@
&conf-LSobject-LSrelation; &conf-LSobject-LSrelation;
&conf-LSobject-LSform; &conf-LSobject-LSform;
&conf-LSobject-LSsearch; &conf-LSobject-LSsearch;
&config-LSobject-ioFormat;
</sect1> </sect1>

View file

@ -0,0 +1,141 @@
<sect2 id="config-LSobject-ioFormat">
<title>ioFormat</title>
<para>Cette section décrit la manière de paramétrer les formats d'import/export
pour un type d'&LSobject; donné.</para>
<para>La configuration des <emphasis>ioFormats</emphasis> se situe dans la
configuration des &LSobjects;, dans la variable <varname>ioFormat</varname>
(<emphasis>$GLOBALS['LSobjects']['[nom du type d'LSobject]']['ioFormat']</emphasis>).
Cette variable est un tableau associatif dont la clé est l'identifiant du format et
dont la valeur associée est la configuration du format.
<programlisting>
<citetitle>Structure</citetitle>
<![CDATA[$GLOBALS['LSobjects']['[nom du type d'LSobject]']['ioFormat'] = array (
'[ioFormat ID]' => array (
'label' => '[Label du type de fichier]',
'driver' => '[Pilote d'ioFormat utilisé]',
'driver_options' => array([Options du pilote d'ioFormat utilisé]),
'fields => array (
'[champ 1]' => '[attribut 1]',
'[champ 2]' => '[attribut 2]',
[...]
),
'generated_fields' => array (
'[attribute 3]' => '[LSformat]',
'[attribute 4]' => '[LSformat]',
[...]
)
),
[...]
);]]>
</programlisting>
<variablelist>
<title>Paramètres de configuration</title>
<varlistentry>
<term>label</term>
<listitem>
<simpara>Le label du format</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>driver</term>
<listitem>
<simpara>Le pilote a utilisé pour ce format. Le pilote permet de gérér la lecture
et l'écriture dans un type de fichier d'import/export. Pour plus d'information sur
les pilotes disponibles, <link linkend='config-LSobject-ioFormat-drivers'>Voir la
section concernée.</link></simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>driver_options</term>
<listitem>
<simpara>Tableau associatif des options du pilote utilisé pour ce format. Pour
plus d'informations, consulter la documentation du pilote utilisé.</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>fields</term>
<listitem>
<simpara>Tableau associatif permettant d'associer un champ du fichier source (la clé)
avec attribut de l'objet LDAP (la valeur).</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>generated_fields</term>
<listitem>
<simpara>Tableau associatif permettant de définir des &LSformats; pour générer des valeurs
d'attributs automatiquement. Ce tableau contient en clé, le nom de l'attribut à généré,
et en valeur associée, le &LSformat; à utilisé. Ce &LSformat; est composé à l'aide des
valeurs des autres attributs de l'objet.</simpara>
</listitem>
</varlistentry>
</variablelist>
</para>
<sect3 id="config-LSobject-ioFormat-drivers">
<title>Pilote d'ioFormat</title>
<para>Cette section décrit la manière de configurer les pilotes d'ioFormat utilisés
lors des imports/exports d'&LSobjects;.</para>
<sect4 id="config-LSobject-ioFormat-drivers-CSV">
<title>Pilote de fichiers CSV</title>
<para>Ce pilote permet de gérer l'import/export de &LSobject; à partir d'un fichier
<literal>CSV</literal>. Ce pilote utilise la classe PEAR <application>
<ulink url='http://pear.php.net/package/File_CSV_DataSource'>File_CSV_DataSource
</ulink></application>. Par défaut, les paramètres de lecture et d'écriture des
fichiers sont : la virgule sert de délimiteur, le caractère <literal>"</literal> peut
être utilisé pour encadrer les valeurs des champs et la longueur maximale d'une ligne
est 999999. Ces paramètres peuvent être modifiés en configurant les options du pilote.
<programlisting>
<citetitle>Structure</citetitle>
<![CDATA[$GLOBALS['LSobjects']['[nom du type d'LSobject]']['ioFormat']['[ID ioFormat]']['driver_options'] = array (
'delimiter' => '[délimiteur]',
'length' => [longueur maximale d'une ligne],
'escape' => '[caratère d'encadrement]'
);]]>
</programlisting>
<variablelist>
<title>Paramètres de configuration</title>
<varlistentry>
<term>delimiter</term>
<listitem>
<simpara>Le caractère utilisé pour délimiter les champs (Par défault, une virgule).</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>length</term>
<listitem>
<simpara>La longueur maximale d'une ligne du fichier. Si zéro est spécifié, la longueur d'une
ligne ne sera pas limité, mais la lecture du fichier sera ralenti. (Par défaut : <literal>999999
</literal>)
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>escape</term>
<listitem>
<simpara>Le caractère utilisé pour encadrer les valeurs des champs
(Par défault : <literal>"</literal>).</simpara>
</listitem>
</varlistentry>
</variablelist>
</para>
</sect4>
</sect3>
</sect2>

View file

@ -19,6 +19,7 @@
<!ENTITY conf-LSobject-LSsearch SYSTEM "LSobject/LSsearch.docbook"> <!ENTITY conf-LSobject-LSsearch SYSTEM "LSobject/LSsearch.docbook">
<!ENTITY conf-LSobject-customActions SYSTEM "LSobject/customActions.docbook"> <!ENTITY conf-LSobject-customActions SYSTEM "LSobject/customActions.docbook">
<!ENTITY conf-LSobject-LSrelation SYSTEM "LSobject/LSrelation.docbook"> <!ENTITY conf-LSobject-LSrelation SYSTEM "LSobject/LSrelation.docbook">
<!ENTITY config-LSobject-ioFormat SYSTEM "LSobject/ioFormat.docbook">
<!ENTITY conf-LSattribute SYSTEM "LSattribute.docbook"> <!ENTITY conf-LSattribute SYSTEM "LSattribute.docbook">
<!ENTITY conf-LSattribute-LSattr_html SYSTEM "LSattribute/LSattr_html.docbook"> <!ENTITY conf-LSattribute-LSattr_html SYSTEM "LSattribute/LSattr_html.docbook">

View file

@ -0,0 +1,3 @@
"login";"civility";"firstname";"name";"mail";"password";"gid";"shell"
"lmartin";"Mme";"Ludivine";"MARTIN";"lmartin@gmail.com";"123Yh%uT";"102009";"no"
"rturin";"M.";"Roger";"TURIN";"rturin@gmail.com";"5-8uHtG34";"102013";"yes"
1 login civility firstname name mail password gid shell
2 lmartin Mme Ludivine MARTIN lmartin@gmail.com 123Yh%uT 102009 no
3 rturin M. Roger TURIN rturin@gmail.com 5-8uHtG34 102013 yes

View file

@ -40,6 +40,32 @@ $GLOBALS['LSobjects']['LSpeople'] = array (
) )
), ),
'ioFormat' => array (
'mycsv' => array (
'label' => 'Simple CSV',
'driver' => 'CSV',
'driver_options' => array (
'delimiter' => ';',
'escape' => '"',
'eol' => ';',
'length' => 2
),
'fields' => array (
'login' => 'uid',
'civility' => 'personalTitle',
'firstname' => 'givenName',
'name' => 'sn',
'mail' => 'mail',
'password' => 'userPassword',
'gid' => 'gidNumber',
'shell' => 'loginShell',
),
'generated_fields' => array (
'cn' => '%{personalTitle} %{givenName} %{sn}'
)
)
),
'before_modify' => 'valid', 'before_modify' => 'valid',
'after_modify' => 'valid', 'after_modify' => 'valid',
//'after_create' => 'createMaildirByFTP', //'after_create' => 'createMaildirByFTP',

28
public_html/css/default/LSimport.css vendored Normal file
View file

@ -0,0 +1,28 @@
h3.LSimport {
margin-left: 1.5em;
border-bottom: 1px solid;
}
div.LSimport_error {
padding: 0 2em;
}
ul.LSimport_global_errors {
background-color: #F56A6A;
list-style-type: none;
padding: 1em;
text-align: center;
}
ul.LSimport_data_errors {
font-style: italic;
font-size: 0.8em;
}
ul.LSimport_attr_errors {
padding-left: 1.5em;
}
ul.LSimport_attr_errors li {
color: #f00;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

84
public_html/import.php Normal file
View file

@ -0,0 +1,84 @@
<?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($_POST['LSform_objecttype'])) {
$LSobject = $_POST['LSform_objecttype'];
}
else if (isset($_GET['LSobject'])) {
$LSobject = $_GET['LSobject'];
}
if (isset($LSobject)) {
// LSObject creation
if (LSsession ::loadLSobject($LSobject)) {
if ( LSsession :: canCreate($LSobject) ) {
if ( LSsession :: loadLSclass('LSimport')) {
$object = new $LSobject();
LStemplate :: assign('LSobject',$LSobject);
$ioFormats=$object->listValidIOformats();
if (is_array($ioFormats) && !empty($ioFormats)) {
LStemplate :: assign('ioFormats',$ioFormats);
if (LSimport::isSubmit()) {
$result=LSimport::importFromPostData();
LSdebug($result,1);
if(is_array($result)) {
LStemplate :: assign('result',$result);
}
}
}
else {
LStemplate :: assign('ioFormats',array());
LSerror :: addErrorCode('LSsession_16');
}
// Define page title
LStemplate :: assign('pagetitle',_('Import').' : '.$object->getLabel());
LSsession :: addCssFile('LSform.css');
LSsession :: addCssFile('LSimport.css');
LSsession :: setTemplate('import.tpl');
}
else {
LSerror :: addErrorCode('LSsession_05','LSimport');
}
}
else {
LSerror :: addErrorCode('LSsession_11');
}
}
else {
LSerror :: addErrorCode('LSldapObject_01');
}
}
else {
LSerror :: addErrorCode('LSsession_12');
}
}
else {
LSsession :: setTemplate('login.tpl');
}
LSsession :: displayTemplate();

View file

@ -0,0 +1,333 @@
<?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.
******************************************************************************/
LSsession::loadLSclass('LSioFormat');
/**
* Manage Import LSldapObject
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*/
class LSimport {
/**
* Check if the form was posted by check POST data
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @retval boolean true if the form was posted, false otherwise
*/
function isSubmit() {
if (isset($_POST['validate']) && ($_POST['validate']=='LSimport'))
return true;
return;
}
/**
* Retrieve the post file
*
* @retval mixed The path of the temporary file, false on error
*/
function getPostFile() {
if (is_uploaded_file($_FILES['importfile']['tmp_name'])) {
$fp = fopen($_FILES['importfile']['tmp_name'], "r");
$buf = fread($fp, filesize($_FILES['importfile']['tmp_name']));
fclose($fp);
$tmp_file = LS_TMP_DIR.'importfile'.'_'.rand().'.tmp';
if (move_uploaded_file($_FILES['importfile']['tmp_name'],$tmp_file)) {
LSsession :: addTmpFile($buf,$tmp_file);
}
return $tmp_file;
}
return false;
}
/**
* Retreive POST data
*
* This method retrieve and format POST data.
*
* The POST data are return as an array containing :
* - LSobject : The LSobject type if this import
* - ioFormat : The IOformat name choose by user
* - justTry : Boolean defining wether the user has chosen to enable
* just try mode (no modification)
* - updateIfExists : Boolean defining wether the user has chosen to
* allow update on existing object.
* - importfile : The path of the temporary file to import
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @retval mixed Array of POST data, false on error
*/
function getPostData() {
if (isset($_REQUEST['LSobject']) && isset($_POST['ioFormat'])) {
$file=self::getPostFile();
if ($file) {
return array (
'LSobject' => $_REQUEST['LSobject'],
'ioFormat' => $_POST['ioFormat'],
'justTry' => ($_POST['justTry']=='yes'),
'updateIfExists' => ($_POST['updateIfExists']=='yes'),
'importfile' => $file
);
}
}
return False;
}
/**
* Import objects form POST data
*
* This method retreive, validate and import POST data.
*
* If import could start, the return value is an array :
*
*
* array (
* 'imported' => array (
* '[object1 dn]' => '[object1 display name]',
* '[object2 dn]' => '[object2 display name]',
* [...]
* ),
* 'updated' => array (
* '[object3 dn]' => '[object3 display name]',
* '[object4 dn]' => '[object4 display name]',
* [...]
* ),
* 'errors' => array (
* array (
* 'data' => array ([object data as read from source file]),
* 'errors' => array (
* 'globals' => array (
* // Global error of this object importation that not
* // concerning only one attribute)
* ),
* 'attrs' => array (
* '[attr1]' => array (
* '[error 1]',
* '[error 2]',
* [...]
* )
* )
* )
* ),
* [...]
* )
* )
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @retval boolean Array of the import result, false on error
*/
function importFromPostData() {
// Get data from $_POST
$data=self::getPostData();
if (is_array($data)) {
LSdebug($data,1);
// Load LSobject
if (!isset($data['LSobject']) || LSsession::loadLSobject($data['LSobject'])) {
$LSobject=$data['LSobject'];
// Validate ioFormat
$object = new $LSobject();
if($object -> isValidIOformat($data['ioFormat'])) {
// Create LSioFormat object
$ioFormat = new LSioFormat($LSobject,$data['ioFormat']);
if ($ioFormat -> ready()) {
// Load data in LSioFormat object
if ($ioFormat -> loadFile($data['importfile'])) {
LSdebug('file loaded');
$return=array(
'imported' => array(),
'updated' => array(),
);
// Retreive object from ioFormat
$objectsData=$ioFormat -> getAll();
$objectsInError=array();
LSdebug($objectsData);
// Browse inputed objects
foreach($objectsData as $objData) {
$globalErrors=array();
// Instanciate an LSobject
$object = new $LSobject();
// Instanciate a creation LSform
$form = $object -> getForm('create');
// Set form data from inputed data
if ($form -> setPostData($objData,true)) {
// Validate form
if ($form -> validate()) {
// Validate data (just validate)
if ($object -> updateData('create',True)) {
LSdebug('Data is correct, retreive object DN');
$dn = $object -> getDn();
if ($dn) {
// Check if object already exists
$entry=LSldap::getLdapEntry($dn);
if ($entry===False) {
LSdebug('New object, perform creation');
if ($data['justTry'] || $object -> updateData('create')) {
LSdebug('Object '.$object -> getDn().' imported');
$return['imported'][$object -> getDn()]=$object -> getDisplayName();
continue;
}
else {
LSdebug('Failed to updateData on : '.print_r($objData,True));
$globalErrors[]=_('Error creating object on LDAP server.');
}
}
// This object already exist, check 'updateIfExists' mode
elseif ($data['updateIfExists']) {
LSdebug('Object exist, perform update');
// Restart import in update mode
// Instanciate a new LSobject and load data from it's DN
$object = new $LSobject();
if ($object -> loadData($dn)) {
// Instanciate a modify form
$form = $object -> getForm('modify');
// Set form data from inputed data
if ($form -> setPostData($objData,true)) {
// Validate form
if ($form -> validate()) {
// Update data on LDAP server
if ($data['justTry'] || $object -> updateData('modify')) {
LSdebug('Object '.$object -> getDn().' updated');
$return['updated'][$object -> getDn()]=$object -> getDisplayName();
continue;
}
else {
LSdebug('Failed to updateData (modify) on : '.print_r($objData,True));
$globalErrors[]=_('Error updating object on LDAP server.');
}
}
else {
LSdebug('Failed to validate update form on : '.print_r($objData,True));
LSdebug('Form errors : '.print_r($form->getErrors(),True));
$globalErrors[]=_('Error validating update form.');
}
}
else {
LSdebug('Failed to setPostData on update form : '.print_r($objData,True));
$globalErrors[]=_('Failed to set post data on update form.');
}
}
else {
LSdebug('Failed to load data of '.$dn);
$globalErrors[]=getFData(_("Failed to load existing object %{dn} from LDAP server. Can't update object."));
}
}
else {
LSdebug('Object '.$dn.' already exist');
$globalErrors[]=getFData(_('An object already exist on LDAP server with DN %{dn}.'),$dn);
}
}
else {
$globalErrors[]=_('Failed to generate DN for this object.');
}
}
else {
$globalErrors[]=_('Failed to validate object data.');
}
}
else {
LSdebug('Failed to validate form on : '.print_r($objData,True));
LSdebug('Form errors : '.print_r($form->getErrors(),True));
$globalErrors[]=_('Error validating creation form.');
}
}
else {
LSdebug('Failed to setPostData on : '.print_r($objData,True));
$globalErrors[]=_('Failed to set post data on creation form.');
}
$objectsInError[]=array(
'data' => $objData,
'errors' => array (
'globals' => $globalErrors,
'attrs' => $form->getErrors()
)
);
}
$return['errors']=$objectsInError;
return $return;
}
}
else {
LSerror :: addErrorCode('LSimport_04');
}
}
else {
LSerror :: addErrorCode('LSimport_03',$data['ioFormat']);
}
}
else {
LSerror :: addErrorCode('LSimport_02');
}
}
else {
LSerror :: addErrorCode('LSimport_01');
}
return False;
}
}
/*
* LSimport_implodeValues template function
*
* This function permit to implode field values during
* template processing. This function take as parameters
* (in $params) :
* - $values : the field's values to implode
*
* @param[in] $params The template function parameters
* @param[in] $template Smarty object
*
* @retval void
**/
function LSimport_implodeValues($params, $template) {
extract($params);
if (isset($values) && is_array($values)) {
echo implode(',',$values);
}
}
LStemplate :: registerFunction('LSimport_implodeValues','LSimport_implodeValues');
LSerror :: defineError('LSimport_01',
_("LSimport : Post data not found or not completed.")
);
LSerror :: defineError('LSimport_02',
_("LSimport : object type invalid.")
);
LSerror :: defineError('LSimport_03',
_("LSimport : input/output format %{format} invalid.")
);
LSerror :: defineError('LSimport_04',
_("LSimport : Fail to initialize input/output driver")
);
?>

View file

@ -0,0 +1,93 @@
<?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.
******************************************************************************/
/**
* Manage IOformat of LSldapObject import/export
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*/
class LSioFormat {
var $config=False;
var $driver=False;
/**
* Constructor
*
* @param[in] string $LSobject The LSobject type name
* @param[in] string $ioFormat The ioFormat name
*
* @retval void
**/
function LSioFormat($LSobject,$ioFormat) {
$conf=LSconfig::get('LSobjects.'.$LSobject.".ioFormat.".$ioFormat);
if(is_array($conf)) {
$this -> config=$conf;
if (isset($this -> config['driver']) && LSsession :: loadLSclass('LSioFormat'.$this -> config['driver'])) {
$driverClass='LSioFormat'.$this -> config['driver'];
$driverOptions=array();
if (isset($this -> config['driver_options'])) $driverOptions = $this -> config['driver_options'];
$this -> driver = new $driverClass($driverOptions);
}
else {
LSerror :: addErrorCode('LSioFormat_01',$this -> config['driver']);
}
}
}
/**
* Check if ioFormat driver is ready
*
* @retval boolean True if ioFormat driver is ready, false otherwise
**/
function ready() {
return (is_array($this -> config) && $this -> driver !== False);
}
/**
* Load and valid file
*
* @param[in] string $file The file path to load
*
* @retval boolean True if file is loaded and valid, false otherwise
**/
function loadFile($file) {
if ($this -> driver -> loadFile($file)) {
return $this -> driver -> isValid();
}
return False;
}
/**
* Retreive all objects contained by the loaded file
*
* @retval array The objects contained by the loaded file
**/
function getAll() {
return $this -> driver -> getAllFormated($this -> config['fields'],$this -> config['generated_fields']);
}
}
LSerror :: defineError('LSioFormat_01',
_("LSioFormat : IOformat driver %{driver} invalid or unavailable.")
);

View file

@ -0,0 +1,109 @@
<?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 'File/CSV/DataSource.php';
LSsession :: loadLSclass('LSioFormatDriver');
/**
* Driver to manage CSV ioFormat file of LSldapObject import/export
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*/
class LSioFormatCSV extends LSioFormatDriver {
// File_CSV_DataSource object
private $csv=false;
/**
* Load file
*
* @param[in] string $file The file path to load
*
* @retval boolean True if file is loaded, false otherwise
**/
public function loadFile($path) {
$this->csv=new File_CSV_DataSource;
if (is_array($this -> options)) {
foreach ($this -> options as $opt_key => $opt_val) {
if (isset($this->csv -> settings[$opt_key]))
$this->csv -> settings[$opt_key] = $opt_val;
}
}
if ($this->csv->load($path)) {
return True;
}
return false;
}
/**
* Check if loaded file data are valid
*
* @retval boolean True if loaded file data are valid, false otherwise
**/
public function isValid() {
if ($this -> csv && $this -> csv -> isSymmetric()) {
return True;
}
return False;
}
/**
* Retreive all object data contained by the loaded file
*
* The objects are returned in array :
*
* array (
* array ( // Object 1
* '[field1]' => '[value1]',
* '[field2]' => '[value2]',
* [...]
* ),
* array ( // Object 2
* '[field1]' => '[value1]',
* '[field2]' => '[value2]',
* [...]
* ),
* )
*
* @retval array The objects contained by the loaded file
**/
public function getAll() {
return $this -> csv -> connect();
}
/**
* Retreive fields names of the loaded file
*
* The fields names are returned in array :
*
* array (
* '[field1]',
* '[field2]',
* [...]
* )
*
* @retval array The fields names of the loaded file
**/
public function getFieldNames() {
return $this -> csv -> getHeaders();
}
}

View file

@ -0,0 +1,142 @@
<?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.
******************************************************************************/
/**
* Driver to manage ioFormat file of LSldapObject import/export
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*/
class LSioFormatDriver {
protected $options=array();
/**
* Constructor
*
* @param[in] array $options Driver's options
*
* @retval void
**/
function __construct($options) {
$this -> options = $options;
}
/**
* Load file
*
* @param[in] string $file The file path to load
*
* @retval boolean True if file is loaded, false otherwise
**/
function loadFile($path) {
return False;
}
/**
* Check if loaded file data are valid
*
* @retval boolean True if loaded file data are valid, false otherwise
**/
function isValid() {
return False;
}
/**
* Retreive all object data contained by the loaded file
*
* The objects are returned in array :
*
* array (
* array ( // Object 1
* '[field1]' => '[value1]',
* '[field2]' => '[value2]',
* [...]
* ),
* array ( // Object 2
* '[field1]' => '[value1]',
* '[field2]' => '[value2]',
* [...]
* ),
* )
*
* @retval array The objects contained by the loaded file
**/
function getAll() {
return array();
}
/**
* Retreive fields names of the loaded file
*
* The fields names are returned in array :
*
* array (
* '[field1]',
* '[field2]',
* [...]
* )
*
* @retval array The fields names of the loaded file
**/
function getFieldNames() {
return array();
}
/**
* Retreive all objects data of the loaded file formated
*
* This method format objects data using ioFormat configuration
* given as parameters.
*
* @param[in] $fields Array of file's fields name mapping with object attribute
* @param[in] $generated_fields Array of object attribute to generate using other object data
*
* @retval array All objects data of the loaded file formated
**/
function getAllFormated($fields,$generated_fields) {
if (!is_array($fields)) return False;
if (!is_array($generated_fields)) $generated_fields=array();
$all=$this -> getAll();
if (!is_array($all)) return False;
$retall=array();
foreach($all as $one) {
$retone=array();
foreach($fields as $key => $attr) {
if (!isset($one[$key])) continue;
if (!isset($retone[$attr])) $retone[$attr]=array();
$retone[$attr][]=$one[$key];
}
if (is_array($generated_fields)) {
foreach ($generated_fields as $attr => $format) {
$value=getFData($format,$retone);
if (!empty($value)) {
$retone[$attr]=array($value);
}
}
}
$retall[]=$retone;
}
return $retall;
}
}

View file

@ -276,15 +276,21 @@ class LSldapObject {
} }
/** /**
* Met à jour les données de l'objet à partir d'un retour d'un formulaire. * Update LDAP object data from one form specify by it's ID.
* *
* @param[in] $idForm Identifiant du formulaire d'origine * This method just valid form ID, extract form data and call
* _updateData() private method.
*
* @param[in] $idForm Form ID
* @param[in] $justValidate Boolean to enable just validation mode
*
* @see _updateData()
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
* @retval boolean true si la mise à jour a réussi, false sinon * @retval boolean true if object data was updated, false otherwise
*/ */
public function updateData($idForm=NULL) { public function updateData($idForm=NULL,$justValidate=False) {
if($idForm!=NULL) { if($idForm!=NULL) {
if(isset($this -> forms[$idForm])) if(isset($this -> forms[$idForm]))
$LSform = $this -> forms[$idForm][0]; $LSform = $this -> forms[$idForm][0];
@ -307,22 +313,28 @@ class LSldapObject {
} }
} }
$new_data = $LSform -> exportValues(); $new_data = $LSform -> exportValues();
return $this -> _updateData($new_data,$idForm); return $this -> _updateData($new_data,$idForm,$justValidate);
} }
/** /**
* Met à jour les données de l'objet et de l'entré de l'annuaire * Update LDAP object data from one form specify by it's ID.
* *
* @param[in] $new_data Tableau des données de modification de l'objet * This method implement the continuation and the end of the object data
* udpate.
*
* @param[in] $new_data Array of object data
* @param[in] $idForm Form ID
* @param[in] $justValidate Boolean to enable just validation mode
* *
* @author Benjamin Renard <brenard@easter-eggs.com> * @author Benjamin Renard <brenard@easter-eggs.com>
* *
* @retval boolean true si la mise à jour a réussi, false sinon * @retval boolean true if object data was updated, false otherwise
* *
* @see updateData()
* @see validateAttrsData() * @see validateAttrsData()
* @see submitChange() * @see submitChange()
*/ */
private function _updateData($new_data,$idForm=null) { private function _updateData($new_data,$idForm=null,$justValidate=False) {
if(!is_array($new_data)) { if(!is_array($new_data)) {
return; return;
} }
@ -333,6 +345,10 @@ class LSldapObject {
} }
if($this -> validateAttrsData($idForm)) { if($this -> validateAttrsData($idForm)) {
LSdebug("les données sont validées"); LSdebug("les données sont validées");
if ($justValidate) {
LSdebug('Just validate mode');
return True;
}
if (!$this -> fireEvent('before_modify')) { if (!$this -> fireEvent('before_modify')) {
return; return;
@ -1820,6 +1836,35 @@ class LSldapObject {
} }
} }
/**
* List IOformats of this object type
*
* @retval mixed Array of valid IOformats of this object type
**/
function listValidIOformats() {
$ret=array();
if (isset($this -> config['ioFormat']) && is_array($this -> config['ioFormat'])) {
foreach($this -> config['ioFormat'] as $name => $conf) {
$ret[$name]=_((isset($conf['label'])?$conf['label']:$name));
}
}
return $ret;
}
/**
* Check if an IOformat is valid for this object type
*
* @param[in] $f string The IOformat name to check
*
* @retval boolean True if it's a valid IOformat, false otherwise
**/
function isValidIOformat($f) {
if (isset($this -> config['ioFormat']) && is_array($this -> config['ioFormat']) && isset($this -> config['ioFormat'][$f])) {
return True;
}
return False;
}
} }
/** /**

View file

@ -2338,7 +2338,9 @@ class LSsession {
LSerror :: defineError('LSsession_15', LSerror :: defineError('LSsession_15',
_("LSsession : Fail to reconnect to LDAP server with user's LDAP credentials.") _("LSsession : Fail to reconnect to LDAP server with user's LDAP credentials.")
); );
// 16 : not yet used LSerror :: defineError('LSsession_16',
_("LSsession : No import/export format define for this object type.")
);
LSerror :: defineError('LSsession_17', LSerror :: defineError('LSsession_17',
_("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})") _("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})")
); );

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,76 @@
{include file='ls:top.tpl'}
{if $pagetitle != ''}<h1 id='LSview_title'>{$pagetitle}</h1>{/if}
<div class='LSform'>
<form action='import.php?LSobject={$LSobject}' method='post' enctype="multipart/form-data">
<input type='hidden' name='validate' value='LSimport'/>
<dl class='LSform'>
<dt class='LSform'><label for='importfile'>{tr msg='File'}</label></dt>
<dd class='LSform'><input type='file' name='importfile'/></dd>
<dt class='LSform'><label for='ioFormat'>{tr msg='Format'}</label></dt>
<dd class='LSform'><select name='ioFormat'>{html_options options=$ioFormats}</select></dd>
<dt class='LSform'><label for='justTry'>{tr msg='Update objects if exists'}</label></dt>
<dd class='LSform'><input type='radio' name='updateIfExists' value='yes'/>{tr msg='yes'} <input type='radio' name='updateIfExists' value='no' checked/>{tr msg='no'}</select></dd>
<dt class='LSform'><label for='justTry'>{tr msg='Only validate data'}</label></dt>
<dd class='LSform'><input type='radio' name='justTry' value='yes'/>{tr msg='yes'} <input type='radio' name='justTry' value='no' checked/>{tr msg='no'}</select></dd>
<dd class='LSform'><input type='submit' value='{tr msg='Valid'}'/></dd>
</dl>
</form>
</div>
{if is_array($result)}
<h1>{tr msg='Result'}</h1>
{if !empty($result.errors)}
<h2>{tr msg='Errors'}</h2>
{foreach $result.errors as $error}
<h3 class='LSimport'>Object {$error@iteration}</h3>
<div class='LSimport_error'>
{if !empty($error.errors.globals)}
<ul class='LSimport_global_errors'>
{foreach $error.errors.globals as $e}
<li>{$e}</li>
{/foreach}
</ul>
{/if}
<ul class='LSimport_data_errors'>
{foreach $error.data as $key => $val}
<li>
<strong>{$key} :</strong>
{if empty($val)}{tr msg='No value'}{else}{LSimport_implodeValues values=$val}{/if}
{if isset($error.errors.attrs[$key])}
<ul class='LSimport_attr_errors'>
{foreach $error.errors.attrs.$key as $e}
<li>{$e}</li>
{/foreach}
</ul>
{/if}
</li>
{/foreach}
</ul>
</div>
{/foreach}
{/if}
<h2 class='LSimport_imported_objects'>{tr msg='Imported objects'} ({count($result.imported)})</h2>
<ul class='LSimport_imported_objects'>
{foreach $result.imported as $dn => $name}
<li><a href='view.php?LSobject={$LSobject}&dn={$dn}'>{$name}</a></li>
{foreachelse}
<li>{tr msg='No imported object'}</li>
{/foreach}
</ul>
{if !empty($result.updated)}
<h2 class='LSimport_updated_objects'>{tr msg='Updated objects'} ({count($result.updated)})</h2>
<ul class='LSimport_updated_objects'>
{foreach $result.updated as $dn => $name}
<li><a href='view.php?LSobject={$LSobject}&dn={$dn}'>{$name}</a></li>
{/foreach}
</ul>
{/if}
{/if}
{include file='ls:bottom.tpl'}

View file

@ -140,6 +140,11 @@ if(LSsession :: startLSsession()) {
'url' => 'create.php?LSobject='.$LSobject, 'url' => 'create.php?LSobject='.$LSobject,
'action' => 'create' 'action' => 'create'
); );
$LSview_actions['import'] = array (
'label' => 'Import',
'url' => 'import.php?LSobject='.$LSobject,
'action' => 'import'
);
} }
$LSview_actions['refresh'] = array ( $LSview_actions['refresh'] = array (
'label' => 'Refresh', 'label' => 'Refresh',