Merge branch 'master' of gitlab.easter-eggs.com:ee/ldapsaisie

Local 1.7-2 Debian package version with a small fix
This commit is contained in:
Benjamin Renard 2018-05-22 16:33:15 +02:00
commit 18278bcc23
36 changed files with 1162 additions and 110 deletions

25
debian/changelog vendored
View file

@ -1,3 +1,28 @@
ldapsaisie (1.8-1) unstable; urgency=medium
* LSdefault : encode LSjsConfig data in Base64
* LSattr_html :
+ password : add get_mail_attr_function parameter
+ valueWithUnit : add translate_labels, store_integer and round_down parameters
+ jsonCompositeAttribute :
+ Add help_info and multiple parameters on components
+ Fix foreach syntax for retro-compat with old Smarty versions
+ fix JS clear value method
+ select_list :
+ add possiblity to use values of other attribute as possible values
+ fix warning on empty jsonCompositeAttribute possible values
+ fix invalid possible values on empty other attribute value
* LSldap : fix/improve getAttr() method
* LSformElement.js : do not handle sub li elements during initialization
* Translation : fix error when trying to translate empty string
* ldapsaisie-generate-lang-file (generate_lang_file.php) :
+ improve to handle new config parameters
+ add interactive mode
+ add output file feature
+ add short parameters
-- Benjamin Renard <brenard@easter-eggs.com> Wed, 16 May 2018 17:42:02 +0200
ldapsaisie (1.7-2) unstable; urgency=medium ldapsaisie (1.7-2) unstable; urgency=medium
* Fix cron and doc about new tmp dir path * Fix cron and doc about new tmp dir path

View file

@ -7,6 +7,7 @@
&conf-LSattr_html_date; &conf-LSattr_html_date;
&conf-LSattr_html_image; &conf-LSattr_html_image;
&conf-LSattr_html_jsonCompositeAttribute; &conf-LSattr_html_jsonCompositeAttribute;
&conf-LSattr_html_labeledValue;
&conf-LSattr_html_mail; &conf-LSattr_html_mail;
&conf-LSattr_html_maildir; &conf-LSattr_html_maildir;
&conf-LSattr_html_mailQuota; &conf-LSattr_html_mailQuota;

View file

@ -3,6 +3,7 @@
<!ENTITY conf-LSattr_html_date SYSTEM "LSattr_html_date.docbook"> <!ENTITY conf-LSattr_html_date SYSTEM "LSattr_html_date.docbook">
<!ENTITY conf-LSattr_html_image SYSTEM "LSattr_html_image.docbook"> <!ENTITY conf-LSattr_html_image SYSTEM "LSattr_html_image.docbook">
<!ENTITY conf-LSattr_html_jsonCompositeAttribute SYSTEM "LSattr_html_jsonCompositeAttribute.docbook"> <!ENTITY conf-LSattr_html_jsonCompositeAttribute SYSTEM "LSattr_html_jsonCompositeAttribute.docbook">
<!ENTITY conf-LSattr_html_labeledValue SYSTEM "LSattr_html_labeledValue.docbook">
<!ENTITY conf-LSattr_html_mail SYSTEM "LSattr_html_mail.docbook"> <!ENTITY conf-LSattr_html_mail SYSTEM "LSattr_html_mail.docbook">
<!ENTITY conf-LSattr_html_maildir SYSTEM "LSattr_html_maildir.docbook"> <!ENTITY conf-LSattr_html_maildir SYSTEM "LSattr_html_maildir.docbook">
<!ENTITY conf-LSattr_html_mailQuota SYSTEM "LSattr_html_mailQuota.docbook"> <!ENTITY conf-LSattr_html_mailQuota SYSTEM "LSattr_html_mailQuota.docbook">
@ -20,4 +21,5 @@
<!ENTITY conf-LSattr_html_valueWithUnit SYSTEM "LSattr_html_valueWithUnit.docbook"> <!ENTITY conf-LSattr_html_valueWithUnit SYSTEM "LSattr_html_valueWithUnit.docbook">
<!ENTITY conf-LSattr_html_xmpp SYSTEM "LSattr_html_xmpp.docbook"> <!ENTITY conf-LSattr_html_xmpp SYSTEM "LSattr_html_xmpp.docbook">
<!ENTITY LSattr_html_jsonCompositeAttribute "<link linkend='config-LSattr_html_jsonCompositeAttribute'>LSattr_html_jsonCompositeAttribute</link>">
<!ENTITY LSattr_html_select_list "<link linkend='config-LSattr_html_select_list'>LSattr_html_select_list</link>"> <!ENTITY LSattr_html_select_list "<link linkend='config-LSattr_html_select_list'>LSattr_html_select_list</link>">

View file

@ -19,8 +19,10 @@
'components' => array ( 'components' => array (
'[clé composant 1]' => array ( '[clé composant 1]' => array (
'label' => '[Label du composant]', 'label' => '[Label du composant]',
'help_info' => '[Message d'aide sur le composant]',
'type' => '[Type de la valeur stocké]', 'type' => '[Type de la valeur stocké]',
'required' => [Booléen], 'required' => [Booléen],
'multiple' => [Booléen],
'check_data' => => array ( 'check_data' => => array (
// Régle de vérification syntaxique des données saisies // Régle de vérification syntaxique des données saisies
), ),
@ -57,6 +59,14 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>help_info</term>
<listitem>
<simpara>Message d'aide sur le composant (affiché uniquement en mode édition).
</simpara>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>type</term> <term>type</term>
<listitem> <listitem>
@ -77,6 +87,22 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>multiple</term>
<listitem>
<simpara>Booléen définissant si ce composant peut stocker plusieurs valeurs (Défaut :
<emphasis>Faux</emphasis>).</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>required</term>
<listitem>
<simpara>Booléen définissant si ce composant doit obligatoirement être défini (Défaut :
<emphasis>Faux</emphasis>).</simpara>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term>check_data</term> <term>check_data</term>
<listitem> <listitem>

View file

@ -0,0 +1,33 @@
<sect4 id="config-LSattr_html_labeledValue">
<title>LSattr_html_labeledValue</title>
<para>Ce type est utilisé pour la gestion des attributs dont la valeur est
prefixé d'un <literal>label</literal> et qui respecte le format suivant :
<literal>[label]valeur</literal>.</para>
<programlisting linenumbering="unnumbered">
<citetitle>Structure</citetitle>...
<![CDATA['html_options' => array(
'labels' => array ( // Liste des labels possible
'label1' => 'Libellé label1',
'label2' => 'Libellé label2',
[...]
),
),]]>
...
</programlisting>
<variablelist>
<title>Paramètres de configuration</title>
<varlistentry>
<term>labels</term>
<listitem>
<simpara>Tableau associatif obligatoire contenant en valeur clé, le
<literal>label</literal> utilisé dans la valeur stockée et en valeur
associée, le valeur d'affichage du <literal>label</literal>.</simpara>
</listitem>
</varlistentry>
</variablelist>
</sect4>

View file

@ -22,6 +22,19 @@
'basedn' => '[Basedn de la recherche]', 'basedn' => '[Basedn de la recherche]',
'onlyAccessible' => '[Booléen]' 'onlyAccessible' => '[Booléen]'
), ),
'OTHER_ATTRIBUTE' => '[attr]',
// Or :
'OTHER_ATTRIBUTE' => array(
'[attr1]' => '[label1]',
'[attr2]' => '[label2]',
[...]
),
// Or :
'OTHER_ATTRIBUTE' => array(
'attr' => [attr],
'json_component_key' => '[Composant JSON clé]',
'json_component_label' => '[Composant JSON label]',
),
array ( array (
'label' => '[LSformat du nom du groupe de valeurs]', 'label' => '[LSformat du nom du groupe de valeurs]',
'possible_values' => array ( 'possible_values' => array (
@ -128,6 +141,37 @@
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para>Si la valeur clé est égale à <literal>OTHER_ATTRIBTE</literal>, une liste
de valeur possible sera composée à l'aide des valeurs d'un (ou plusieurs) autre
attribut de l'objet courant. La valeur associée peut être alors&nbsp;:
<itemizedlist>
<listitem>
<simpara>soit le nom d'un attribut dont les valeurs seront utilisées comme valeurs
possibles (la valeur affichée est égale à la valeur stockée).</simpara>
</listitem>
<listitem>
<simpara>soit un tableau associatif dont les valeurs clés sont les noms des attributs
dont les valeurs seront utilisés comme valeurs possibles et dont les valeurs associés
seront les labels sous lesquels ces valeurs seront regroupées (la valeur
affichée est égale à la valeur stockée).</simpara>
</listitem>
<listitem>
<simpara>soit un tableau associatif référençant un attribut sous la clé <emphasis>attr
</emphasis> dont les valeurs seront utilisées comme valeurs possibles. Cet attribut
peut-être du type &LSattr_html_jsonCompositeAttribute;. Il sera alors possible d'utiliser
les valeurs d'un composant en particulier en le référençant à l'aide de la clé <emphasis>
json_component_key</emphasis>. Il est également possible de référencer un autre composant
à l'aide de la clé <emphasis>json_component_label</emphasis> et dont les valeurs seront
utilisées comme valeurs affichées lors de la sélection. À défaut, les valeurs affichées
seront identiques à celles stockées.</simpara>
</listitem>
</itemizedlist>
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View file

@ -5,6 +5,7 @@
&conf-LSattr_ldap_ascii; &conf-LSattr_ldap_ascii;
&conf-LSattr_ldap_boolean; &conf-LSattr_ldap_boolean;
&conf-LSattr_ldap_compositeValueToJSON;
&conf-LSattr_ldap_date; &conf-LSattr_ldap_date;
&conf-LSattr_ldap_image; &conf-LSattr_ldap_image;
&conf-LSattr_ldap_numeric; &conf-LSattr_ldap_numeric;

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!ENTITY conf-LSattr_ldap_ascii SYSTEM "LSattr_ldap_ascii.docbook"> <!ENTITY conf-LSattr_ldap_ascii SYSTEM "LSattr_ldap_ascii.docbook">
<!ENTITY conf-LSattr_ldap_boolean SYSTEM "LSattr_ldap_boolean.docbook"> <!ENTITY conf-LSattr_ldap_boolean SYSTEM "LSattr_ldap_boolean.docbook">
<!ENTITY conf-LSattr_ldap_compositeValueToJSON SYSTEM "LSattr_ldap_compositeValueToJSON.docbook">
<!ENTITY conf-LSattr_ldap_date SYSTEM "LSattr_ldap_date.docbook"> <!ENTITY conf-LSattr_ldap_date SYSTEM "LSattr_ldap_date.docbook">
<!ENTITY conf-LSattr_ldap_image SYSTEM "LSattr_ldap_image.docbook"> <!ENTITY conf-LSattr_ldap_image SYSTEM "LSattr_ldap_image.docbook">
<!ENTITY conf-LSattr_ldap_numeric SYSTEM "LSattr_ldap_numeric.docbook"> <!ENTITY conf-LSattr_ldap_numeric SYSTEM "LSattr_ldap_numeric.docbook">

View file

@ -0,0 +1,9 @@
<sect4 id="config-LSattr_ldap_compositeValueToJSON">
<title>LSattr_ldap_compositeValueToJSON</title>
<para>Ce type est utilisé pour la gestion des attributs composites dont les
valeurs respectent le format suivant :
<literal>[key1=value1][key2=value2][...]</literal></para>
<para>Ce type d'attribut LDAP sera utilisé pour convertir la valeur en son
équivalent <literal>JSON</literal> pour pouvoir être traité à l'aide du type d'
attribut HTML &LSattr_html_jsonCompositeAttribute;.</para>
</sect4>

View file

@ -7,12 +7,29 @@ ul.LSformElement_jsonCompositeAttribute li.noValue {
border: none; border: none;
} }
ul.LSformElement_jsonCompositeAttribute p { ul.LSformElement_jsonCompositeAttribute div {
margin: 0;
margin-bottom: 2px;
}
ul.LSformElement_jsonCompositeAttribute div label {
display: inline-block;
height: 100%;
vertical-align: top;
width: 10em;
font-weight: bold;
}
ul.LSformElement_jsonCompositeAttribute div ul {
display: inline-block;
list-style-type: none;
padding: 0;
margin: 0; margin: 0;
} }
ul.LSformElement_jsonCompositeAttribute p label { ul.LSformElement_jsonCompositeAttribute div ul li {
font-weight: bold; margin-bottom: 2px;
border: none;
} }
div.jsonCompositeAttribute_possibleValues ul { div.jsonCompositeAttribute_possibleValues ul {

View file

@ -0,0 +1,32 @@
<?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.
******************************************************************************/
/**
* Type d'attribut HTML labeledValue
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*/
class LSattr_html_labeledValue extends LSattr_html {
var $LSformElement_type = 'labeledValue';
}

View file

@ -88,6 +88,10 @@ class LSattr_html_select_list extends LSattr_html{
$objInfos=self :: getLSobjectPossibleValues($val_label,$options,$name); $objInfos=self :: getLSobjectPossibleValues($val_label,$options,$name);
$retInfos=self :: _array_merge($retInfos,$objInfos); $retInfos=self :: _array_merge($retInfos,$objInfos);
} }
elseif($val_key==='OTHER_ATTRIBUTE') {
$attrInfos=self :: getLSattributePossibleValues($val_label, $options, $name, $ldapObject);
$retInfos=self :: _array_merge($retInfos,$attrInfos);
}
elseif (is_array($val_label)) { elseif (is_array($val_label)) {
if (!isset($val_label['possible_values']) || !is_array($val_label['possible_values']) || !isset($val_label['label'])) if (!isset($val_label['possible_values']) || !is_array($val_label['possible_values']) || !isset($val_label['label']))
continue; continue;
@ -273,6 +277,90 @@ class LSattr_html_select_list extends LSattr_html{
return $retInfos; return $retInfos;
} }
/**
* Retourne un tableau des valeurs possibles d'un autre attribut
*
* @param[in] $attr OTHER_ATTRIBUTE configuration value
* @param[in] $options array|false Attribute options
* @param[in] $name Attribute name
* @param[in] $LSldapObject LSldapObject reference
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*
* @retval array Tableau associatif des valeurs possible de la liste avec en clé
* la valeur des balises option et en valeur ce qui sera affiché.
*/
protected function getLSattributePossibleValues($attr, $options ,$name ,&$ldapObject) {
$retInfos=array();
if (is_string($attr)) {
if (isset($ldapObject->attrs[$attr]) && $ldapObject->attrs[$attr] instanceof LSattribute) {
$attr_values = $ldapObject->attrs[$attr]->getValue();
if (!$attr_values)
$attr_values = array();
elseif (!is_array($attr_values))
$attr_values = array($attr_values);
foreach($attr_values as $attr_value)
$retInfos[$attr_value] = __($attr_value);
}
else
LSerror :: addErrorCode('LSattr_html_select_list_02',$attr);
}
elseif (is_array($attr)) {
if (isset($attr['attr'])) {
if (isset($ldapObject->attrs[$attr['attr']]) && $ldapObject->attrs[$attr['attr']] instanceof LSattribute) {
if (isset($attr['json_component_key'])) {
if (get_class($ldapObject->attrs[$attr['attr']]->html) == 'LSattr_html_jsonCompositeAttribute') {
$attr_values = $ldapObject->attrs[$attr['attr']]->getValue();
if (!$attr_values)
$attr_values = array();
elseif (!is_array($attr_values))
$attr_values = array($attr_values);
foreach($attr_values as $attr_value) {
$value_data = @json_decode($attr_value, true);
if (!isset($value_data[$attr['json_component_key']])) {
LSerror :: addErrorCode('LSattr_html_select_list_05', array('attr' => $attr['attr'], 'value' => $attr_value, 'component' => $attr['json_component_key']));
return $retInfos;
}
$key = $value_data[$attr['json_component_key']];
if (isset($attr['json_component_label'])) {
if (!isset($value_data[$attr['json_component_label']])) {
LSerror :: addErrorCode('LSattr_html_select_list_05', array('attr' => $attr['attr'], 'value' => $attr_value, 'component' => $attr['json_component_label']));
return $retInfos;
}
$label = $value_data[$attr['json_component_label']];
}
else
$label = $key;
$retInfos[$key] = $label;
}
}
else
LSerror :: addErrorCode('LSattr_html_select_list_03',$attr['attr']);
}
else
$retInfos = self :: getLSattributePossibleValues($attr['attr'], $options ,$name ,$ldapObject);
}
else
LSerror :: addErrorCode('LSattr_html_select_list_02',$attr['attr']);
}
else {
foreach($attr as $sub_attr => $sub_label) {
$subRetInfos = self :: getLSattributePossibleValues($sub_attr, $options ,$name ,$ldapObject);
self :: _sort($subRetInfos,$options);
$retInfos[] = array (
'label' => $sub_label,
'possible_values' => $subRetInfos
);
}
}
}
self :: _sort($retInfos,$options);
return $retInfos;
}
} }
/* /*
@ -281,3 +369,15 @@ class LSattr_html_select_list extends LSattr_html{
LSerror :: defineError('LSattr_html_select_list_01', LSerror :: defineError('LSattr_html_select_list_01',
_("LSattr_html_select_list : Configuration data are missing to generate the select list of the attribute %{attr}.") _("LSattr_html_select_list : Configuration data are missing to generate the select list of the attribute %{attr}.")
); );
LSerror :: defineError('LSattr_html_select_list_02',
_("LSattr_html_select_list : Invalid attribute %{attr} reference as OTHER_ATTRIBUTE possible values.")
);
LSerror :: defineError('LSattr_html_select_list_03',
_("LSattr_html_select_list : Attribute %{attr} referenced as OTHER_ATTRIBUTE possible values is not a jsonCompositeAttribute.")
);
LSerror :: defineError('LSattr_html_select_list_04',
_("LSattr_html_select_list : Fail to decode the following attribute %{attr} value as JSON : %{value}")
);
LSerror :: defineError('LSattr_html_select_list_05',
_("LSattr_html_select_list : No component %{component} found in the following attribute %{attr} JSON value : %{value}")
);

View file

@ -0,0 +1,90 @@
<?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.
******************************************************************************/
/**
* Type d'attribut Ldap compositeValueToJSON
* Convertit les attributes composite du format suivant :
* [key1=value1][key2=value2]..
* Au format JSON (utilisable par le LSformElement_jsonCompositeAttribute ) :
* {"key1":"value1","key2":"value2"}
*/
class LSattr_ldap_compositeValueToJSON extends LSattr_ldap {
/**
* Retourne la valeur d'affichage de l'attribut après traitement lié à son type ldap
*
* @param[in] $data mixed La valeur de l'attribut
*
* @retval mixed La valeur d'affichage de l'attribut
*/
function getDisplayValue($data) {
if ($data) {
if (!is_array($data))
$data = array($data);
$ret = array();
foreach($data as $key => $val)
$ret[$key] = json_encode(self :: parseValue($val));
return $ret;
}
return $data;
}
/**
* Retourne la valeur de l'attribut après traitement lié à son type ldap
*
* @param[in] $data mixed La valeur de l'attribut
*
* @retval mixed La valeur traitée de l'attribut
*/
function getUpdateData($data) {
if ($data) {
if (!is_array($data))
$data = array($data);
$ret = array();
foreach($data as $key => $val)
$ret[$key] = self :: encodeValue(json_decode($val, true));
return $ret;
}
return $data;
}
function parseValue($value) {
if (preg_match_all('/\[([^=]*)=([^\]]*)\]/',$value,$matches)) {
$parseValue=array();
for($i=0;$i<count($matches[0]);$i++) {
$parseValue[$matches[1][$i]]=$matches[2][$i];
}
return $parseValue;
}
return;
}
function encodeValue($value) {
if (is_array($value)) {
$ret="";
foreach($value as $key => $val)
$ret.="[$key=$val]";
return $ret;
}
return False;
}
}

View file

@ -100,6 +100,20 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
) )
); );
LSsession :: addCssFile('LSformElement_jsonCompositeAttribute.css'); LSsession :: addCssFile('LSformElement_jsonCompositeAttribute.css');
if (!$this -> isFreeze()) {
LSsession :: addJSconfigParam(
$this -> name,
array (
'components' => $this -> components,
)
);
LSsession :: addJSscript('LSformElement_jsonCompositeAttribute_field_value_component_text_value.js');
LSsession :: addJSscript('LSformElement_jsonCompositeAttribute_field_value_component.js');
LSsession :: addJSscript('LSformElement_jsonCompositeAttribute_field_value.js');
LSsession :: addJSscript('LSformElement_jsonCompositeAttribute_field.js');
LSsession :: addJSscript('LSformElement_jsonCompositeAttribute.js');
}
return $return; return $return;
} }
@ -132,10 +146,19 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
* *
* @param[in] $c string The component name * @param[in] $c string The component name
* @param[in] $value string The value * @param[in] $value string The value
* @param[in] $inLoop boolean Internal param to control recursion
* *
* @retval array * @retval array
**/ **/
function translateComponentValue($c,$value) { function translateComponentValue($c,$value,$inLoop=false) {
if (!$inLoop && isset($this -> components[$c]['multiple']) && $this -> components[$c]['multiple']) {
$retval = array();
if (!is_array($value))
$value = array($value);
foreach($value as $val)
$retval[] = $this -> translateComponentValue($c, $val, true);
}
else {
$retval = array ( $retval = array (
'translated' => $value, 'translated' => $value,
'value' => $value, 'value' => $value,
@ -146,6 +169,7 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
} }
//elseif type == 'text' => no transformation //elseif type == 'text' => no transformation
} }
}
return $retval; return $retval;
} }
@ -202,28 +226,27 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
return true; return true;
} }
$count=0;
$end=false;
$return[$this -> name]=array(); $return[$this -> name]=array();
while ($end==false) { if (is_array($_POST[$this -> name.'__values_uuid'])) {
foreach ($_POST[$this -> name.'__values_uuid'] as $uuid) {
$value=array(); $value=array();
$parseValue=array(); $parseValue=array();
$errors=array(); $errors=array();
$unemptyComponents=array(); $unemptyComponents=array();
foreach ($this -> components as $c => $cconf) { foreach ($this -> components as $c => $cconf) {
if (isset($_POST[$this -> name.'__'.$c][$count])) { if (isset($_POST[$this -> name.'__'.$c.'__'.$uuid])) {
$parseValue[$c]=$_POST[$this -> name.'__'.$c][$count]; if (!is_array($_POST[$this -> name.'__'.$c.'__'.$uuid]))
if ($cconf['required'] && empty($parseValue[$c])) { $_POST[$this -> name.'__'.$c.'__'.$uuid] = array($_POST[$this -> name.'__'.$c.'__'.$uuid]);
$errors[]=getFData(__('Component %{c} must be defined'),__($cconf['label']));
$parseValue[$c]=array();
foreach($_POST[$this -> name.'__'.$c.'__'.$uuid] as $val) {
if (empty($val))
continue; continue;
} $parseValue[$c][] = $val;
if (empty($parseValue[$c])) {
continue;
}
$unemptyComponents[]=$c;
if ($cconf['type']=='select_list') { if ($cconf['type']=='select_list') {
if (!$this -> getSelectListComponentValueLabel($c, $parseValue[$c])) { if (!$this -> getSelectListComponentValueLabel($c, $val)) {
$errors[]=getFData(__('Invalid value for component %{c}.'),__($cconf['label'])); $errors[]=getFData(_('Invalid value "%{value}" for component %{component}.'),array('value' => $val, 'component' => __($cconf['label'])));
} }
} }
if (is_array($cconf['check_data'])) { if (is_array($cconf['check_data'])) {
@ -231,37 +254,45 @@ class LSformElement_jsonCompositeAttribute extends LSformElement {
$className='LSformRule_'.$ruleType; $className='LSformRule_'.$ruleType;
if (LSsession::loadLSclass($className)) { if (LSsession::loadLSclass($className)) {
$r=new $className(); $r=new $className();
if (!$r -> validate($parseValue[$c],$rconf,$this)) { if (!$r -> validate($val,$rconf,$this)) {
if (isset($rconf['msg'])) { if (isset($rconf['msg'])) {
$errors[]=getFData(__($rconf['msg']),__($cconf['label'])); $errors[]=getFData(__($rconf['msg']),__($cconf['label']));
} }
else { else {
$errors[]=getFData(__('Invalid value for component %{c}.'),__($cconf['label'])); $errors[]=getFData(_('Invalid value "%{value}" for component %{component}.'),array('value' => $val, 'component' => __($cconf['label'])));
} }
} }
} }
else { else {
$errors[]=getFData(__("Can't validate value of component %{c}."),__($cconf['label'])); $errors[]=getFData(_("Can't validate value of component %{c}."),__($cconf['label']));
} }
} }
} }
$value[$c]=$parseValue[$c];
}
else {
// end of value break
$end=true;
break;
} }
if (!isset($cconf['multiple']) || !$cconf['multiple']) {
if (count($parseValue[$c])>=1)
$parseValue[$c] = $parseValue[$c][0];
else
$parseValue[$c] = '';
} }
if (!$end) {
if ($cconf['required'] && empty($parseValue[$c])) {
$errors[]=getFData(_('Component %{c} must be defined'),__($cconf['label']));
continue;
}
$unemptyComponents[]=$c;
$value[$c]=$parseValue[$c];
}
}
if (!empty($unemptyComponents)) { if (!empty($unemptyComponents)) {
foreach($errors as $e) { foreach($errors as $e) {
$this -> form -> setElementError($this -> attr_html,$e); $this -> form -> setElementError($this -> attr_html,$e);
} }
$return[$this -> name][]=json_encode($value); $return[$this -> name][]=json_encode($value);
} }
$count++;
} }
} }
return true; return true;

View file

@ -0,0 +1,128 @@
<?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('LSformElement');
/**
* Element labeledValue d'un formulaire pour LdapSaisie
*
* Cette classe définis les éléments labeledValue des formulaires.
* Elle étant la classe basic LSformElement.
*
* @author Benjamin Renard <brenard@easter-eggs.com>
*/
class LSformElement_labeledValue extends LSformElement {
var $template = 'LSformElement_labeledValue.tpl';
var $fieldTemplate = 'LSformElement_labeledValue_field.tpl';
/**
* Retourne les infos d'affichage de l'élément
*
* Cette méthode retourne les informations d'affichage de l'élement
*
* @retval array
*/
function getDisplay(){
$return = $this -> getLabelInfos();
$parseValues=array();
foreach($this -> values as $val) {
$parseValues[]=$this -> parseValue($val);
}
$return['html'] = $this -> fetchTemplate(NULL,array(
'labels' => $this -> params['html_options']['labels'],
'parseValues' => $parseValues,
'unrecognizedValueTxt' => __('(unrecognized value)'),
'unrecognizedLabelTxt' => __('(unrecognized label)'),
));
return $return;
}
/**
* Retourne le code HTML d'un champ vide
*
* @retval string Code HTML d'un champ vide.
*/
function getEmptyField() {
return $this -> fetchTemplate($this -> fieldTemplate,array(
'labels' => $this -> params['html_options']['labels'],
));
}
/**
* Parse une valeur
*
* @param[in] $value La valeur
*
* @retval array Un tableau cle->valeur contenant value et label
**/
function parseValue($value) {
$ret=array('raw_value' => $value);
if (preg_match('/^\[([^\]]*)\](.*)$/',$value,$m)) {
$ret['label'] = $m[1];
if (isset($this -> params['html_options']['labels'][$ret['label']]))
$ret['translated_label'] = $this -> params['html_options']['labels'][$ret['label']];
$ret['value'] = $m[2];
}
return $ret;
}
/**
* Recupère la valeur de l'élement passée en POST
*
* Cette méthode vérifie la présence en POST de la valeur de l'élément et la récupère
* pour la mettre dans le tableau passer en paramètre avec en clef le nom de l'élément
*
* @param[] array Pointeur sur le tableau qui recupèrera la valeur.
*
* @retval boolean true si la valeur est présente en POST, false sinon
*/
function getPostData(&$return) {
if($this -> isFreeze()) {
return true;
}
if (isset($_POST[$this -> name."_labels"]) && isset($_POST[$this -> name."_values"])) {
$return[$this -> name]=array();
if(!is_array($_POST[$this -> name."_labels"])) {
$_POST[$this -> name."_labels"] = array($_POST[$this -> name."_labels"]);
}
if(!is_array($_POST[$this -> name."_values"])) {
$_POST[$this -> name."_values"] = array($_POST[$this -> name."_values"]);
}
foreach($_POST[$this -> name."_labels"] as $key => $label) {
$val=$_POST[$this -> name."_values"][$key];
if (!empty($label) && (!empty($val)||(is_string($val)&&($val=="0")))) {
$return[$this -> name][$key] = "[$label]$val";
}
}
return true;
}
else {
$return[$this -> name] = array();
return true;
}
}
}

View file

@ -194,12 +194,7 @@ class LSldap {
$infos = ldap_explode_dn($dn,0); $infos = ldap_explode_dn($dn,0);
if((!$infos)||($infos['count']==0)) if((!$infos)||($infos['count']==0))
return; return;
$basedn=''; $return=self :: search('(objectClass=*)',$dn);
for ($i=1;$i<$infos['count'];$i++) {
$sep=($basedn=='')?'':',';
$basedn.=$sep.$infos[$i];
}
$return=self :: search($infos[0],$basedn);
return $return[0]['attrs']; return $return[0]['attrs'];
} }

View file

@ -1364,7 +1364,7 @@ class LSsession {
self :: addJSconfigParam('keepLSsessionActive',ini_get('session.gc_maxlifetime')); self :: addJSconfigParam('keepLSsessionActive',ini_get('session.gc_maxlifetime'));
} }
LStemplate :: assign('LSjsConfig',json_encode(self :: $_JSconfigParams)); LStemplate :: assign('LSjsConfig',base64_encode(json_encode(self :: $_JSconfigParams)));
if (LSdebug) { if (LSdebug) {
$JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n"; $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n";

View file

@ -122,6 +122,7 @@ class LStemplate {
self :: registerFunction("tr", "LStemplate_smarty_tr"); self :: registerFunction("tr", "LStemplate_smarty_tr");
self :: registerFunction("img", "LStemplate_smarty_img"); self :: registerFunction("img", "LStemplate_smarty_img");
self :: registerFunction("css", "LStemplate_smarty_css"); self :: registerFunction("css", "LStemplate_smarty_css");
self :: registerFunction("uniqid", "LStemplate_smarty_uniqid");
return True; return True;
} }
@ -297,6 +298,12 @@ function LStemplate_smarty_css($params) {
echo LStemplate :: getCSSPath($name); echo LStemplate :: getCSSPath($name);
} }
function LStemplate_smarty_uniqid($params, &$smarty) {
if (!isset($params['var']))
$params['var'] = 'uniqid';
$smarty -> assign($params['var'], uniqid());
}
// Errors // Errors
LSerror :: defineError('LStemplate_01', LSerror :: defineError('LStemplate_01',
_("LStemplate : Template %{file} not found.") _("LStemplate : Template %{file} not found.")

View file

@ -473,6 +473,7 @@ function LSdebugDefined() {
} }
function __($msg) { function __($msg) {
if (empty($msg)) return $msg;
if (isset($GLOBALS['LSlang'][$msg])) { if (isset($GLOBALS['LSlang'][$msg])) {
return $GLOBALS['LSlang'][$msg]; return $GLOBALS['LSlang'][$msg];
} }

View file

@ -24,7 +24,7 @@ var LSdefault = new Class({
// LSjsConfig // LSjsConfig
this.LSjsConfigEl = $('LSjsConfig'); this.LSjsConfigEl = $('LSjsConfig');
if ($type(this.LSjsConfigEl)) { if ($type(this.LSjsConfigEl)) {
this.LSjsConfig = JSON.decode(this.LSjsConfigEl.innerHTML); this.LSjsConfig = JSON.decode(atob(this.LSjsConfigEl.innerHTML));
} }
else { else {
this.LSjsConfig = []; this.LSjsConfig = [];

View file

@ -10,7 +10,7 @@ var LSformElement = new Class({
initializeLSformElement: function(li) { initializeLSformElement: function(li) {
if (typeof(li) == 'undefined') { if (typeof(li) == 'undefined') {
var elements = this.ul.getElements('li'); var elements = this.ul.getChildren('li');
} }
else { else {
var elements = [li]; var elements = [li];
@ -50,7 +50,7 @@ var LSformElement = new Class({
}, },
onRemoveFieldBtnClick: function(field) { onRemoveFieldBtnClick: function(field) {
if (this.ul.getElements('li').length == 1) { if (this.ul.getChildren('li').length == 1) {
field.clearValue.bind(field)(); field.clearValue.bind(field)();
} }
else { else {

View file

@ -0,0 +1,18 @@
var LSformElement_jsonCompositeAttribute = new Class({
initialize: function(){
this.fields = [];
this.initialiseLSformElement_jsonCompositeAttribute();
},
initialiseLSformElement_jsonCompositeAttribute: function(el) {
if (!$type(el)) {
el = document;
}
el.getElements('ul.LSformElement_jsonCompositeAttribute').each(function(ul) {
this.fields[ul.id] = new LSformElement_jsonCompositeAttribute_field(ul);
}, this);
}
});
window.addEvent(window.ie ? 'load' : 'domready', function() {
varLSformElement_jsonCompositeAttribute = new LSformElement_jsonCompositeAttribute();
});

View file

@ -0,0 +1,32 @@
var LSformElement_jsonCompositeAttribute_field = new Class({
initialize: function(ul){
this.ul=ul;
this.dd=ul.getParent();
this.name = ul.id;
this.values = [];
this.field_type = ul.get('data-fieldType');
this.initializeLSformElement_jsonCompositeAttribute_field();
varLSform.addField(this.name,this);
},
initializeLSformElement_jsonCompositeAttribute_field: function(el) {
if (!$type(el)) {
el = this.ul;
}
el.getChildren('li').each(function(li) {
this.values.push(new LSformElement_jsonCompositeAttribute_field_value(li,this.name,this.field_type));
}, this);
},
clearValue: function() {
if (this.values.length>1) {
for(var i=1; i<=this.values.length; i++) {
$(this.values[i].li).dispose();
}
this.values[0].clear();
}
else if (this.values.length==1) {
this.values[0].clear();
}
}
});

View file

@ -0,0 +1,31 @@
var LSformElement_jsonCompositeAttribute_field_value = new Class({
initialize: function(li,name,field_type){
this.li=li;
this.name = name;
this.input_uuid = li.getElement('input[name='+name+'__values_uuid[]]');
this.uuid = this.input_uuid.get('value');
this.components = {};
this.field_type = field_type;
this.initializeLSformElement_jsonCompositeAttribute_field_value();
varLSform.addModule(field_type,this);
},
initializeLSformElement_jsonCompositeAttribute_field_value: function(el) {
if (!$type(el)) {
el = this.li;
}
el.getElements('div').each(function(div) {
this.components[div.get('data-component')]=new LSformElement_jsonCompositeAttribute_field_value_component(div,div.get('data-component'),this.name,this.uuid);
}, this);
},
reinitialize: function(el) {
this.initializeLSformElement_jsonCompositeAttribute_field_value(el);
},
clear: function() {
for (c in this.components) {
this.components[c].clear();
}
}
});

View file

@ -0,0 +1,62 @@
var LSformElement_jsonCompositeAttribute_field_value_component = new Class({
initialize: function(div,name,field_name,field_uuid){
this.div = div;
this.field_name = field_name;
this.field_uuid = field_uuid;
this.field_params = varLSdefault.LSjsConfig[this.field_name];
this.name = name;
this.params = this.field_params['components'][this.name];
this.label = div.getElement('label');
if (this.params.type == 'select_list') {
this.select = div.getElement('select');
}
else {
// Type text
this.ul = div.getElement('ul');
this.lis = {};
this.values = {};
this.ul.getElements('li').each(function(li) {
this.initTextComponentValue(li);
}, this);
}
},
initTextComponentValue: function(li) {
var uuid = generate_uuid();
this.lis[uuid] = li;
this.values[uuid] = new LSformElement_jsonCompositeAttribute_field_value_component_text_value(this,li);
},
onAddTextValueBtnClick: function(after) {
var li = new Element('li');
var input = new Element('input');
input.type='text';
input.name=this.field_name+'__'+this.name+'__'+this.field_uuid+'[]';
input.injectInside(li);
li.injectAfter(after.li);
this.initTextComponentValue(li);
},
onRemoveTextValueBtnClick: function(value) {
if (this.ul.getElements('li').length == 1) {
value.clear.bind(value)();
}
else {
value.remove.bind(value)();
}
},
clear: function() {
if (this.params.type == 'select_list') {
this.select.selectedIndex=-1;
}
else {
Object.each(this.values, function(value) {
value.clear();
}, this);
}
}
});

View file

@ -0,0 +1,30 @@
var LSformElement_jsonCompositeAttribute_field_value_component_text_value = new Class({
initialize: function(component,li) {
this.component = component;
this.li = li;
this.input = li.getElement('input');
if (this.component.params.multiple) {
this.addValueBtn = new Element('img');
this.addValueBtn.src = varLSdefault.imagePath('add');
this.addValueBtn.addClass('btn');
this.addValueBtn.addEvent('click',this.component.onAddTextValueBtnClick.bind(this.component,this));
this.addValueBtn.injectInside(this.li);
this.removeValueBtn = new Element('img');
this.removeValueBtn.src = varLSdefault.imagePath('remove');
this.removeValueBtn.addClass('btn');
this.removeValueBtn.addEvent('click',this.component.onRemoveTextValueBtnClick.bind(this.component,this));
this.removeValueBtn.injectInside(this.li);
}
},
clear: function() {
this.input.value = '';
},
remove: function() {
this.li.destroy();
}
});

View file

@ -244,3 +244,105 @@ function urlAddVar(url,name,value) {
} }
return url; return url;
} }
/*
* Generate UUID
*/
function generate_uuid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
}
/*
* Base64 compatibility
*
* Source : http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html
*/
if ($type(atob) != 'function') {
B64keyStr = "ABCDEFGHIJKLMNOP" +
"QRSTUVWXYZabcdef" +
"ghijklmnopqrstuv" +
"wxyz0123456789+/" +
"=";
function btoa(input) {
input = escape(input);
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
B64keyStr.charAt(enc1) +
B64keyStr.charAt(enc2) +
B64keyStr.charAt(enc3) +
B64keyStr.charAt(enc4);
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return output;
}
function atob(input) {
var output = "";
var chr1, chr2, chr3 = "";
var enc1, enc2, enc3, enc4 = "";
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
var base64test = /[^A-Za-z0-9\+\/\=]/g;
if (base64test.exec(input)) {
alert("There were invalid base64 characters in the input text.\n" +
"Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
"Expect errors in decoding.");
}
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = B64keyStr.indexOf(input.charAt(i++));
enc2 = B64keyStr.indexOf(input.charAt(i++));
enc3 = B64keyStr.indexOf(input.charAt(i++));
enc4 = B64keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
chr1 = chr2 = chr3 = "";
enc1 = enc2 = enc3 = enc4 = "";
} while (i < input.length);
return unescape(output);
}
}

View file

@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: LdapSaisie\n" "Project-Id-Version: LdapSaisie\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-02-08 18:12+0100\n" "POT-Creation-Date: 2018-04-26 11:40+0200\n"
"PO-Revision-Date: 2018-02-08 18:13+0100\n" "PO-Revision-Date: 2018-04-26 11:44+0200\n"
"Last-Translator: Benjamin Renard <brenard@zionetrix.net>\n" "Last-Translator: Benjamin Renard <brenard@zionetrix.net>\n"
"Language-Team: LdapSaisie <ldapsaisie-users@lists.labs.libre-entreprise." "Language-Team: LdapSaisie <ldapsaisie-users@lists.labs.libre-entreprise."
"org>\n" "org>\n"
@ -435,7 +435,7 @@ msgstr "Affichier la clé en entier."
msgid "Unknown type" msgid "Unknown type"
msgstr "Type inconnu" msgstr "Type inconnu"
#: includes/class/class.LSformElement_valueWithUnit.php:190 #: includes/class/class.LSformElement_valueWithUnit.php:200
msgid "" msgid ""
"LSformElement_valueWithUnit : Units configuration data are missing for the " "LSformElement_valueWithUnit : Units configuration data are missing for the "
"attribute %{attr}." "attribute %{attr}."
@ -490,12 +490,12 @@ msgstr "LStemplate : Impossible de charger le fichier de support de Smarty 3."
msgid "LStemplate : Smarty version not recognized." msgid "LStemplate : Smarty version not recognized."
msgstr "LStemplate : Version de Smarty non reconnue." msgstr "LStemplate : Version de Smarty non reconnue."
#: includes/class/class.LStemplate.php:129 #: includes/class/class.LStemplate.php:130
msgid "LStemplate : Can't load Smarty." msgid "LStemplate : Can't load Smarty."
msgstr "" msgstr ""
"LStemplate : Impossible de charger le moteur de gestion de template Smarty." "LStemplate : Impossible de charger le moteur de gestion de template Smarty."
#: includes/class/class.LStemplate.php:302 #: includes/class/class.LStemplate.php:309
msgid "LStemplate : Template %{file} not found." msgid "LStemplate : Template %{file} not found."
msgstr "LStemplate : le template %{file} est introuvable." msgstr "LStemplate : le template %{file} est introuvable."
@ -1609,7 +1609,7 @@ msgstr "Cliquer pour supprimer cette photo."
msgid "Chat with this person." msgid "Chat with this person."
msgstr "Discuter avec cette personne." msgstr "Discuter avec cette personne."
#: includes/class/class.LSattr_html_select_list.php:282 #: includes/class/class.LSattr_html_select_list.php:366
msgid "" msgid ""
"LSattr_html_select_list : Configuration data are missing to generate the " "LSattr_html_select_list : Configuration data are missing to generate the "
"select list of the attribute %{attr}." "select list of the attribute %{attr}."
@ -1617,6 +1617,38 @@ msgstr ""
"LSattr_html_select_list : Des données de configuration sont manquantes pour " "LSattr_html_select_list : Des données de configuration sont manquantes pour "
"générer la liste de sélection de l'attribut %{attr}." "générer la liste de sélection de l'attribut %{attr}."
#: includes/class/class.LSattr_html_select_list.php:369
msgid ""
"LSattr_html_select_list : Invalid attribute %{attr} reference as "
"OTHER_ATTRIBUTE possible values."
msgstr ""
"LSattr_html_select_list : Référence invalide à l'attribut %{attr} comme "
"valeurs possibles (OTHER_ATTRIBUTE)."
#: includes/class/class.LSattr_html_select_list.php:372
msgid ""
"LSattr_html_select_list : Attribute %{attr} referenced as OTHER_ATTRIBUTE "
"possible values is not a jsonCompositeAttribute."
msgstr ""
"LSattr_html_select_list : L'attribute %{attr} référencé comme valeurs "
"possibles (OTHER_ATTRIBUTE) n'est pas du type jsonCompositeAttribute."
#: includes/class/class.LSattr_html_select_list.php:375
msgid ""
"LSattr_html_select_list : Fail to decode the following attribute %{attr} "
"value as JSON : %{value}"
msgstr ""
"LSattr_html_select_list : Impossible de décodé la valeur JSON suivante de "
"l'attribut %{attr} : %{value}"
#: includes/class/class.LSattr_html_select_list.php:378
msgid ""
"LSattr_html_select_list : No component %{component} found in the following "
"attribute %{attr} JSON value : %{value}"
msgstr ""
"LSattr_html_select_list : Le composant %{component} n'a pas été trouvé dans "
"la valeur JSON de l'attribut %{attr} : %{value}"
#: includes/class/class.LSformRule_inarray.php:56 #: includes/class/class.LSformRule_inarray.php:56
msgid "" msgid ""
"LSformRule_inarray : Possible values has not been configured to validate " "LSformRule_inarray : Possible values has not been configured to validate "
@ -1625,6 +1657,19 @@ msgstr ""
"LSformRule_inarray : Les valeurs possibles n'ont pas été configurées pour " "LSformRule_inarray : Les valeurs possibles n'ont pas été configurées pour "
"valider les données." "valider les données."
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:249
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:262
msgid "Invalid value \"%{value}\" for component %{component}."
msgstr "Valeur invalide pour le composant %{component} : \"%{value}\""
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:267
msgid "Can't validate value of component %{c}."
msgstr "Impossible de valider la valeur du composant %{c}."
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:281
msgid "Component %{c} must be defined"
msgstr "Le composant %{c} est obligatoire."
#: includes/class/class.LSformRule_date.php:59 #: includes/class/class.LSformRule_date.php:59
msgid "LSformRule_date : No date format specify." msgid "LSformRule_date : No date format specify."
msgstr "LSformRule_date : Aucun format de date spécifié." msgstr "LSformRule_date : Aucun format de date spécifié."

View file

@ -32,6 +32,8 @@ require_once('conf/config.inc.php');
$withoutselectlist=False; $withoutselectlist=False;
$copyoriginalvalue=False; $copyoriginalvalue=False;
$interactive=False;
$output=False;
$additionalfileformat=False; $additionalfileformat=False;
$lang=False; $lang=False;
$encoding=False; $encoding=False;
@ -46,16 +48,19 @@ if ($argc > 1) {
$translations[$msg]=$trans; $translations[$msg]=$trans;
} }
} }
elseif($argv[$i]=='--without-select-list') { elseif($argv[$i]=='--without-select-list' || $argv[$i]=='-W') {
$withoutselectlist=True; $withoutselectlist=True;
} }
elseif($argv[$i]=='--copy-original-value') { elseif($argv[$i]=='--copy-original-value' || $argv[$i]=='-c') {
$copyoriginalvalue=True; $copyoriginalvalue=True;
} }
elseif($argv[$i]=='--additional-file-format') { elseif($argv[$i]=='--interactive' || $argv[$i]=='-i') {
$interactive=True;
}
elseif($argv[$i]=='--additional-file-format' || $argv[$i]=='-a') {
$additionalfileformat=True; $additionalfileformat=True;
} }
elseif($argv[$i]=='--lang') { elseif($argv[$i]=='--lang' || $argv[$i]=='-l') {
$i++; $i++;
$parse_lang=explode('.',$argv[$i]); $parse_lang=explode('.',$argv[$i]);
if (count($parse_lang)==2) { if (count($parse_lang)==2) {
@ -66,12 +71,18 @@ if ($argc > 1) {
die("Invalid --lang parameter. Must be compose in format : [lang].[encoding]\n"); die("Invalid --lang parameter. Must be compose in format : [lang].[encoding]\n");
} }
} }
elseif($argv[$i]=='--output' || $argv[$i]=='-o') {
$i++;
$output = $argv[$i];
}
elseif($argv[$i]=='-h') { elseif($argv[$i]=='-h') {
echo "Usage : ".$argv[0]." [file1] [file2] [-h] [options]\n"; echo "Usage : ".$argv[0]." [file1] [file2] [-h] [options]\n";
echo " --without-select-list Don't add possibles values of select list\n"; echo " -W/--without-select-list Don't add possibles values of select list\n";
echo " --copy-original-value Copy original value as translated value when no translated value exists\n"; echo " -c/--copy-original-value Copy original value as translated value when no translated value exists\n";
echo " --additional-file-format Additional file format output\n"; echo " -i/--interactive Interactive mode : ask user to enter translated on each translation needed\n";
echo " --lang Load this specify lang (format : [lang].[encoding])\n"; echo " -a/--additional-file-format Additional file format output\n";
echo " -l/--lang Load this specify lang (format : [lang].[encoding])\n";
echo " -o/--output Output file (default : stdout)\n";
exit(0); exit(0);
} }
} }
@ -82,9 +93,37 @@ $data=array();
function add($msg) { function add($msg) {
if ($msg!='' && _($msg) == "$msg") { if ($msg!='' && _($msg) == "$msg") {
global $data, $translations; global $data, $translations, $interactive, $copyoriginalvalue;
if (array_key_exists($msg, $data)) {
return True;
}
elseif (array_key_exists($msg, $translations)) {
$data[$msg]=$translations[$msg]; $data[$msg]=$translations[$msg];
} }
elseif ($interactive) {
if ($copyoriginalvalue) {
fwrite(STDERR, "\"$msg\"\n\n => Please enter translated string (or leave empty to copy original string) : ");
$in = trim(fgets(STDIN));
if ($in)
$data[$msg]=$in;
else
$data[$msg]=$msg;
}
else {
fwrite(STDERR, "\"$msg\"\n\n => Please enter translated string (or 'c' to copy original message, leave empty to pass) : ");
$in = trim(fgets(STDIN));
if ($in) {
if ($in=="c")
$data[$msg]=$msg;
else
$data[$msg]=$in;
}
}
}
else {
$data[$msg]="";
}
}
} }
// Initialize session // Initialize session
@ -185,9 +224,21 @@ if (loadDir(LS_OBJECTS_DIR) && loadDir(LS_LOCAL_DIR.LS_OBJECTS_DIR)) {
if (is_array($pname['possible_values'])) { if (is_array($pname['possible_values'])) {
foreach($pname['possible_values'] as $pk => $pn) { foreach($pname['possible_values'] as $pk => $pn) {
if ($pk == 'OTHER_OBJECT') continue; if ($pk == 'OTHER_OBJECT') continue;
add($pn); elseif ($pk == 'OTHER_ATTRIBUTE') {
if (is_array($pn) && ! isset($pn['attr'])) {
foreach($pn as $pattr => $plabel)
add($plabel);
} }
} }
else add($pn);
}
}
}
elseif ($pkey == 'OTHER_ATTRIBUTE') {
if (is_array($pname) && ! isset($pname['attr'])) {
foreach($pname as $pattr => $plabel)
add($plabel);
}
} }
elseif ($pkey != 'OTHER_OBJECT') { elseif ($pkey != 'OTHER_OBJECT') {
add($pname); add($pname);
@ -202,10 +253,18 @@ if (loadDir(LS_OBJECTS_DIR) && loadDir(LS_LOCAL_DIR.LS_OBJECTS_DIR)) {
} }
} }
// LSattr_html_labeledValue
if (is_array($attr['html_options']['labels'])) {
foreach($attr['html_options']['labels'] as $klabel => $plabel) {
add($plabel);
}
}
// LSattr_html_jsonCompositeAttribute // LSattr_html_jsonCompositeAttribute
if (is_array($attr['html_options']['components'])) { if (is_array($attr['html_options']['components'])) {
foreach($attr['html_options']['components'] as $c => $cconfig) { foreach($attr['html_options']['components'] as $c => $cconfig) {
add($cconfig['label']); add($cconfig['label']);
add($cconfig['help_info']);
// Component type select_list // Component type select_list
if (is_array($cconfig['options']['possible_values'])) { if (is_array($cconfig['options']['possible_values'])) {
@ -215,9 +274,21 @@ if (loadDir(LS_OBJECTS_DIR) && loadDir(LS_LOCAL_DIR.LS_OBJECTS_DIR)) {
if (is_array($pname['possible_values'])) { if (is_array($pname['possible_values'])) {
foreach($pname['possible_values'] as $pk => $pn) { foreach($pname['possible_values'] as $pk => $pn) {
if ($pk == 'OTHER_OBJECT') continue; if ($pk == 'OTHER_OBJECT') continue;
add($pn); elseif ($pk == 'OTHER_ATTRIBUTE') {
if (is_array($pn) && ! isset($pn['attr'])) {
foreach($pn as $pattr => $plabel)
add($plabel);
} }
} }
else add($pn);
}
}
}
elseif ($pkey == 'OTHER_ATTRIBUTE') {
if (is_array($pname) && ! isset($pname['attr'])) {
foreach($pname as $pattr => $plabel)
add($plabel);
}
} }
elseif ($pkey != 'OTHER_OBJECT') { elseif ($pkey != 'OTHER_OBJECT') {
add($pname); add($pname);
@ -343,9 +414,25 @@ find_and_parse_addon_file(LS_LOCAL_DIR.LS_ADDONS_DIR);
ksort($data); ksort($data);
echo "<?php\n\n"; if ($output) {
try {
$fd = fopen($output, 'w');
}
catch(Exception $e) {
fwrite(STDERR, 'Error occured opening output file : '.$e->getMessage(), "\n");
}
if (!$fd) {
fwrite(STDERR, "Use stdout out instead.\n");
$fd = STDOUT;
$output = false;
}
}
else
$fd = STDOUT;
if (!$additionalfileformat) print "\$GLOBALS['LSlang'] = array (\n"; fwrite($fd, "<?php\n\n");
if (!$additionalfileformat) fwrite($fd, "\$GLOBALS['LSlang'] = array (\n");
foreach($data as $key => $val) { foreach($data as $key => $val) {
if ($copyoriginalvalue && $val=="") { if ($copyoriginalvalue && $val=="") {
@ -354,13 +441,14 @@ foreach($data as $key => $val) {
$key=str_replace('"','\\"',$key); $key=str_replace('"','\\"',$key);
$val=str_replace('"','\\"',$val); $val=str_replace('"','\\"',$val);
if ($additionalfileformat) { if ($additionalfileformat) {
print "\$GLOBALS['LSlang'][\"$key\"] = \"$val\";\n"; fwrite($fd, "\$GLOBALS['LSlang'][\"$key\"] = \"$val\";\n");
} }
else { else {
print "\n\"$key\" =>\n \"$val\",\n"; fwrite($fd, "\n\"$key\" =>\n \"$val\",\n");
} }
} }
if (!$additionalfileformat) echo "\n);\n"; if (!$additionalfileformat) fwrite($fd, "\n);\n");
?> if ($output)
fclose($fd);

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-02-08 18:12+0100\n" "POT-Creation-Date: 2018-04-26 11:39+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -388,7 +388,7 @@ msgstr ""
msgid "Unknown type" msgid "Unknown type"
msgstr "" msgstr ""
#: includes/class/class.LSformElement_valueWithUnit.php:190 #: includes/class/class.LSformElement_valueWithUnit.php:200
msgid "" msgid ""
"LSformElement_valueWithUnit : Units configuration data are missing for the " "LSformElement_valueWithUnit : Units configuration data are missing for the "
"attribute %{attr}." "attribute %{attr}."
@ -435,11 +435,11 @@ msgstr ""
msgid "LStemplate : Smarty version not recognized." msgid "LStemplate : Smarty version not recognized."
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:129 #: includes/class/class.LStemplate.php:130
msgid "LStemplate : Can't load Smarty." msgid "LStemplate : Can't load Smarty."
msgstr "" msgstr ""
#: includes/class/class.LStemplate.php:302 #: includes/class/class.LStemplate.php:309
msgid "LStemplate : Template %{file} not found." msgid "LStemplate : Template %{file} not found."
msgstr "" msgstr ""
@ -1385,18 +1385,55 @@ msgstr ""
msgid "Chat with this person." msgid "Chat with this person."
msgstr "" msgstr ""
#: includes/class/class.LSattr_html_select_list.php:282 #: includes/class/class.LSattr_html_select_list.php:366
msgid "" msgid ""
"LSattr_html_select_list : Configuration data are missing to generate the " "LSattr_html_select_list : Configuration data are missing to generate the "
"select list of the attribute %{attr}." "select list of the attribute %{attr}."
msgstr "" msgstr ""
#: includes/class/class.LSattr_html_select_list.php:369
msgid ""
"LSattr_html_select_list : Invalid attribute %{attr} reference as "
"OTHER_ATTRIBUTE possible values."
msgstr ""
#: includes/class/class.LSattr_html_select_list.php:372
msgid ""
"LSattr_html_select_list : Attribute %{attr} referenced as OTHER_ATTRIBUTE "
"possible values is not a jsonCompositeAttribute."
msgstr ""
#: includes/class/class.LSattr_html_select_list.php:375
msgid ""
"LSattr_html_select_list : Fail to decode the following attribute %{attr} "
"value as JSON : %{value}"
msgstr ""
#: includes/class/class.LSattr_html_select_list.php:378
msgid ""
"LSattr_html_select_list : No component %{component} found in the following "
"attribute %{attr} JSON value : %{value}"
msgstr ""
#: includes/class/class.LSformRule_inarray.php:56 #: includes/class/class.LSformRule_inarray.php:56
msgid "" msgid ""
"LSformRule_inarray : Possible values has not been configured to validate " "LSformRule_inarray : Possible values has not been configured to validate "
"data." "data."
msgstr "" msgstr ""
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:249
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:262
msgid "Invalid value \"%{value}\" for component %{component}."
msgstr ""
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:267
msgid "Can't validate value of component %{c}."
msgstr ""
#: includes/class/class.LSformElement_jsonCompositeAttribute.php:281
msgid "Component %{c} must be defined"
msgstr ""
#: includes/class/class.LSformRule_date.php:59 #: includes/class/class.LSformRule_date.php:59
msgid "LSformRule_date : No date format specify." msgid "LSformRule_date : No date format specify."
msgstr "" msgstr ""

View file

@ -1,6 +1,4 @@
<div id='LSjsConfig'> <div id='LSjsConfig'>{$LSjsConfig}</div>
{$LSjsConfig}
</div>
<div id='LSinfos_txt'>{$LSinfos}</div> <div id='LSinfos_txt'>{$LSinfos}</div>

View file

@ -2,35 +2,73 @@
{if isset($parseValue)} {if isset($parseValue)}
{foreach $components as $c => $cconf} {foreach $components as $c => $cconf}
{if !isset($parseValue[$c])}{continue}{/if} {if !isset($parseValue[$c])}{continue}{/if}
<p> <div>
<label>{tr msg=$cconf.label} : </label> <label>{tr msg=$cconf.label} : </label>
<span title="{$parseValue[$c].value}">{$parseValue[$c].translated}</span> <ul>
</p> {if $cconf.multiple && is_array($parseValue[$c])}
{foreach from=$parseValue[$c] item=cval}
<li><span title="{$cval.value}">{$cval.translated}</span></li>
{/foreach}
{else}
<li><span title="{$parseValue[$c].value}">{$parseValue[$c].translated}</span></li>
{/if}
</ul>
</div>
{/foreach} {/foreach}
{else} {else}
{$noValueTxt} {$noValueTxt}
{/if} {/if}
{else} {else}
{foreach $components as $c => $cconf} {uniqid var="uuid"}
<p data-component="{$c}"> <input type='hidden' name="{$attr_name}__values_uuid[]" value="{$uuid}" />
<label>{tr msg=$cconf.label}{if $cconf.required}*{/if} :</label> {foreach from=$components key=c item=cconf name=components}
<div data-component="{$c}" data-uuid="{$uuid}">
<label>
{tr msg=$cconf.label}{if $cconf.required}*{/if}
{if $cconf.help_info}<img class='LStips' src="{img name='help'}" alt='?' title="{$cconf.help_info}"/>{/if}
:
</label>
{if $cconf.type=='select_list'} {if $cconf.type=='select_list'}
<select name='{$attr_name}__{$c}[]'> <select name='{$attr_name}__{$c}__{$uuid}[]' {if $cconf.multiple}multiple{/if}>
{foreach from=$cconf.possible_values key=key item=label} {foreach from=$cconf.possible_values key=key item=label}
{if is_array($label)} {if is_array($label)}
{if count($label.possible_values)>0} {if count($label.possible_values)>0}
<optgroup label="{$label.label}"> <optgroup label="{$label.label}">
{if $cconf.multiple && is_array($parseValue[$c])}
{html_options options=$label.possible_values selected=$parseValue[$c]}
{else}
{html_options options=$label.possible_values selected=$parseValue[$c].value} {html_options options=$label.possible_values selected=$parseValue[$c].value}
{/if}
</optgroup> </optgroup>
{/if} {/if}
{else} {else}
<option value="{$key}" {if $key == $parseValue[$c].value}selected{/if}>{$label}</option> {assign var="selected" value=0}
{if $cconf.multiple && is_array($parseValue[$c])}
{foreach from=$parseValue[$c] item=cval}
{if $key==$cval.value}{assign var="selected" value=1}{/if}
{/foreach}
{else}
{if $key == $parseValue[$c].value}
{assign var="selected" value=1}
{/if}
{/if}
<option value="{$key}" {if $selected == 1}selected{/if}>{$label}</option>
{/if} {/if}
{/foreach} {/foreach}
</select> </select>
{else} {else}
<input type='text' name='{$attr_name}__{$c}[]' value="{if $parseValue and $parseValue[$c]}{$parseValue[$c].value}{/if}"/> <ul>
{if $cconf.multiple && is_array($parseValue[$c])}
{foreach from=$parseValue[$c] item=cval}
<li><input type='text' name='{$attr_name}__{$c}__{$uuid}[]' value='{$cval.value|escape:"quotes"}'/></li>
{foreachelse}
<li><input type='text' name='{$attr_name}__{$c}__{$uuid}[]' value=''/></li>
{/foreach}
{else}
<li><input type='text' name='{$attr_name}__{$c}__{$uuid}[]' value='{if $parseValue and $parseValue[$c]}{$parseValue[$c].value|escape:"quotes"}{/if}'/></li>
{/if} {/if}
</p> </ul>
{/if}
</div>
{/foreach} {/foreach}
{/if} {/if}

View file

@ -0,0 +1,7 @@
<ul class='LSform {if $multiple && !$freeze} LSformElement_multiple{/if} LSformElement_labeledValue' id='{$attr_name}' data-fieldType="{$fieldType}">
{foreach from=$parseValues item=parseValue}
<li>{include file="ls:$fieldTemplate"}</li>
{foreachelse}
<li {if $freeze}class='noValue'{/if}>{include file="ls:$fieldTemplate"}</li>
{/foreach}
</ul>

View file

@ -0,0 +1,21 @@
{if $freeze}
{if isset($parseValue)}
{if $parseValue.label}
{if $parseValue.translated_label}
<span title='[{$parseValue.label|escape:'quotes'}]'>{$parseValue.translated_label}</span>
{else}
<span>{$parseValue.label} {$unrecognizedLabelTxt}</span>
{/if}
: <span>{$parseValue.value}</span>
{else}
<span>{$parseValue.raw_value}</span> {$unrecognizedValueTxt}
{/if}
{else}
{$noValueTxt}
{/if}
{else}
<select name='{$attr_name}_labels[]' class='LSformElement_labeledValue'>
{html_options options=$labels selected=$parseValue.label}
</select>
<input type="text" name='{$attr_name}_values[]' class='LSformElement_labeledValue' value='{if $parseValue.value}{$parseValue.value|escape:'quotes'}{else}{$parseValue.raw_value|escape:'quotes'}{/if}'/>
{/if}

View file

@ -1,3 +1,3 @@
*.tpl.php *.php
*.tmp *.tmp
*.log *.log