--- /dev/null
+<?php\r
+\r
+/**\r
+ * Gestion de l'affichage des saisies\r
+ *\r
+ * @return SPIP\Saisies\Afficher\r
+**/\r
+\r
+// Sécurité\r
+if (!defined('_ECRIRE_INC_VERSION')) return;\r
+\r
+/**\r
+ * Indique si une saisie peut être affichée.\r
+ * \r
+ * On s'appuie sur l'éventuelle clé "editable" du $champ.\r
+ * Si editable vaut :\r
+ * - absent : le champ est éditable\r
+ * - 1, le champ est éditable\r
+ * - 0, le champ n'est pas éditable\r
+ * - -1, le champ est éditable s'il y a du contenu dans le champ (l'environnement)\r
+ * ou dans un de ses enfants (fieldsets)\r
+ *\r
+ * @param array $champ\r
+ * Tableau de description de la saisie\r
+ * @param array $env\r
+ * Environnement transmis à la saisie, certainement l'environnement du formulaire\r
+ * @param bool $utiliser_editable\r
+ * - false pour juste tester le cas -1\r
+ * \r
+ * @return bool\r
+ * Retourne un booléen indiquant l'état éditable ou pas :\r
+ * - true si la saisie est éditable (peut être affichée)\r
+ * - false sinon\r
+ */\r
+function saisie_editable($champ, $env, $utiliser_editable=true) {\r
+ if ($utiliser_editable) {\r
+ // si le champ n'est pas éditable, on sort.\r
+ if (!isset($champ['editable'])) {\r
+ return true;\r
+ }\r
+ $editable = $champ['editable'];\r
+\r
+ if ($editable > 0) {\r
+ return true;\r
+ }\r
+ if ($editable == 0) {\r
+ return false;\r
+ }\r
+ }\r
+\r
+ // cas -1\r
+ // name de la saisie\r
+ if (isset($champ['options']['nom'])) {\r
+ // si on a le name dans l'environnement, on le teste\r
+ $nom = $champ['options']['nom'];\r
+ if (isset($env[$nom])) {\r
+ return $env[$nom] ? true : false ;\r
+ }\r
+ }\r
+ // sinon, si on a des sous saisies\r
+ if (isset($champ['saisies']) and is_array($champ['saisies'])) {\r
+ foreach($champ['saisies'] as $saisie) {\r
+ if (saisie_editable($saisie, $env, false)) {\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ \r
+ // aucun des paramètres demandés n'avait de contenu\r
+ return false;\r
+}\r
+\r
+/**\r
+ * Génère une saisie à partir d'un tableau la décrivant et de l'environnement\r
+ *\r
+ * @param array $champ\r
+ * Description de la saisie.\r
+ * Le tableau doit être de la forme suivante :\r
+ * array(\r
+ * 'saisie' => 'input',\r
+ * 'options' => array(\r
+ * 'nom' => 'le_name',\r
+ * 'label' => 'Un titre plus joli',\r
+ * 'obligatoire' => 'oui',\r
+ * 'explication' => 'Remplissez ce champ en utilisant votre clavier.'\r
+ * )\r
+ * )\r
+ * @param array $env\r
+ * Environnement du formulaire\r
+ * Permet de savoir les valeurs actuelles des contenus des saisies,\r
+ * les erreurs eventuelles présentes...\r
+ * @return string\r
+ * Code HTML des saisies de formulaire\r
+ */\r
+function saisies_generer_html($champ, $env=array()){\r
+ // Si le parametre n'est pas bon, on genere du vide\r
+ if (!is_array($champ))\r
+ return '';\r
+\r
+ // Si la saisie n'est pas editable, on sort aussi.\r
+ if (!saisie_editable($champ, $env)) {\r
+ return '';\r
+ }\r
+ \r
+ $contexte = array();\r
+ \r
+ // On sélectionne le type de saisie\r
+ $contexte['type_saisie'] = $champ['saisie'];\r
+ // Identifiant unique de saisie, si present\r
+ if (isset($champ['identifiant'])) {\r
+ $contexte['id_saisie'] = $champ['identifiant'];\r
+ }\r
+\r
+ // Peut-être des transformations à faire sur les options textuelles\r
+ $options = $champ['options'];\r
+ foreach ($options as $option => $valeur){\r
+ if ($option == 'datas') {\r
+ // exploser une chaine datas en tableau (applique _T_ou_typo sur chaque valeur)\r
+ $options[$option] = saisies_chaine2tableau($valeur);\r
+ } else {\r
+ $options[$option] = _T_ou_typo($valeur, 'multi');\r
+ }\r
+ }\r
+ \r
+ // On ajoute les options propres à la saisie\r
+ $contexte = array_merge($contexte, $options);\r
+\r
+ // Si env est définie dans les options ou qu'il y a des enfants, on ajoute tout l'environnement\r
+ if (isset($contexte['env']) or (isset($champ['saisies']) AND is_array($champ['saisies']))) {\r
+ unset($contexte['env']);\r
+\r
+ // on sauve l'ancien environnement\r
+ // car les sous-saisies ne doivent pas être affectees\r
+ // par les modification sur l'environnement servant à generer la saisie mère\r
+ $contexte['_env'] = $env;\r
+ \r
+ // À partir du moment où on passe tout l'environnement, il faut enlever certains éléments qui ne doivent absolument provenir que des options\r
+ unset($env['inserer_debut']);\r
+ unset($env['inserer_fin']);\r
+ $saisies_disponibles = saisies_lister_disponibles();\r
+ if (isset($saisies_disponibles[$contexte['type_saisie']]) and is_array($saisies_disponibles[$contexte['type_saisie']]['options'])) {\r
+ $options_a_supprimer = saisies_lister_champs($saisies_disponibles[$contexte['type_saisie']]['options']);\r
+ foreach ($options_a_supprimer as $option_a_supprimer){\r
+ unset($env[$option_a_supprimer]);\r
+ }\r
+ }\r
+ \r
+ $contexte = array_merge($env, $contexte);\r
+ }\r
+ // Sinon on ne sélectionne que quelques éléments importants\r
+ else{\r
+ // On récupère la liste des erreurs\r
+ $contexte['erreurs'] = $env['erreurs'];\r
+ // On ajoute toujours le bon self\r
+ $contexte['self'] = self();\r
+ }\r
+\r
+ // Dans tous les cas on récupère de l'environnement la valeur actuelle du champ\r
+ // Si le nom du champ est un tableau indexé, il faut parser !\r
+ if (preg_match('/([\w]+)((\[[\w]+\])+)/', $contexte['nom'], $separe)){\r
+ $contexte['valeur'] = $env[$separe[1]];\r
+ preg_match_all('/\[([\w]+)\]/', $separe[2], $index);\r
+ // On va chercher au fond du tableau\r
+ foreach($index[1] as $cle){\r
+ $contexte['valeur'] = isset($contexte['valeur'][$cle]) ? $contexte['valeur'][$cle] : null;\r
+ }\r
+ }\r
+ // Sinon la valeur est juste celle du nom\r
+ else {\r
+ $contexte['valeur'] = (isset($env[$contexte['nom']]) ? $env[$contexte['nom']] : null);\r
+ }\r
+\r
+ // Si ya des enfants on les remonte dans le contexte\r
+ if (isset($champ['saisies']) and is_array($champ['saisies']))\r
+ $contexte['saisies'] = $champ['saisies'];\r
+ \r
+ // On génère la saisie\r
+ return recuperer_fond(\r
+ 'saisies/_base',\r
+ $contexte\r
+ );\r
+}\r
+\r
+/**\r
+ * Génère une vue d'une saisie à partir d'un tableau la décrivant\r
+ *\r
+ * @see saisies_generer_html()\r
+ * @param array $saisie\r
+ * Tableau de description d'une saisie\r
+ * @param array $env\r
+ * L'environnement, contenant normalement la réponse à la saisie\r
+ * @param array $env_obligatoire\r
+ * ???\r
+ * @return string\r
+ * Code HTML de la vue de la saisie\r
+ */\r
+function saisies_generer_vue($saisie, $env=array(), $env_obligatoire=array()){\r
+ // Si le paramètre n'est pas bon, on génère du vide\r
+ if (!is_array($saisie))\r
+ return '';\r
+\r
+ $contexte = array();\r
+ \r
+ // On sélectionne le type de saisie\r
+ $contexte['type_saisie'] = $saisie['saisie'];\r
+ \r
+ // Peut-être des transformations à faire sur les options textuelles\r
+ $options = $saisie['options'];\r
+ foreach ($options as $option => $valeur){\r
+ if ($option == 'datas') {\r
+ // exploser une chaine datas en tableau (applique _T_ou_typo sur chaque valeur)\r
+ $options[$option] = saisies_chaine2tableau($valeur);\r
+ } else {\r
+ $options[$option] = _T_ou_typo($valeur, 'multi');\r
+ }\r
+ }\r
+ \r
+ // On ajoute les options propres à la saisie\r
+ $contexte = array_merge($contexte, $options);\r
+\r
+ // Si env est définie dans les options ou qu'il y a des enfants, on ajoute tout l'environnement\r
+ if (isset($contexte['env']) or (isset($saisie['saisies']) AND is_array($saisie['saisies']))){\r
+ unset($contexte['env']);\r
+\r
+ // on sauve l'ancien environnement\r
+ // car les sous-saisies ne doivent pas être affectees\r
+ // par les modification sur l'environnement servant à generer la saisie mère\r
+ $contexte['_env'] = $env;\r
+\r
+ // À partir du moment où on passe tout l'environnement, il faut enlever \r
+ // certains éléments qui ne doivent absolument provenir que des options\r
+ $saisies_disponibles = saisies_lister_disponibles();\r
+ if (is_array($saisies_disponibles[$contexte['type_saisie']]['options'])){\r
+ $options_a_supprimer = saisies_lister_champs($saisies_disponibles[$contexte['type_saisie']]['options']);\r
+ foreach ($options_a_supprimer as $option_a_supprimer){\r
+ unset($env[$option_a_supprimer]);\r
+ }\r
+ }\r
+ \r
+ $contexte = array_merge($env, $contexte);\r
+ }\r
+\r
+ // Dans tous les cas on récupère de l'environnement la valeur actuelle du champ\r
+ \r
+ // On regarde en priorité s'il y a un tableau listant toutes les valeurs\r
+ if ($env['valeurs'] and is_array($env['valeurs']) and isset($env['valeurs'][$contexte['nom']])){\r
+ $contexte['valeur'] = $env['valeurs'][$contexte['nom']];\r
+ }\r
+ // Si le nom du champ est un tableau indexé, il faut parser !\r
+ elseif (preg_match('/([\w]+)((\[[\w]+\])+)/', $contexte['nom'], $separe)){\r
+ $contexte['valeur'] = $env[$separe[1]];\r
+ preg_match_all('/\[([\w]+)\]/', $separe[2], $index);\r
+ // On va chercher au fond du tableau\r
+ foreach($index[1] as $cle){\r
+ $contexte['valeur'] = $contexte['valeur'][$cle];\r
+ }\r
+ }\r
+ // Sinon la valeur est juste celle du nom\r
+ else {\r
+ // certains n'ont pas de nom (fieldset)\r
+ $contexte['valeur'] = isset($env[$contexte['nom']]) ? $env[$contexte['nom']] : '';\r
+ }\r
+\r
+ // Si ya des enfants on les remonte dans le contexte\r
+ if (isset($saisie['saisies']) AND is_array($saisie['saisies']))\r
+ $contexte['saisies'] = $saisie['saisies'];\r
+\r
+ if (is_array($env_obligatoire)) {\r
+ $contexte = array_merge($contexte, $env_obligatoire);\r
+ }\r
+\r
+ // On génère la saisie\r
+ return recuperer_fond(\r
+ 'saisies-vues/_base',\r
+ $contexte\r
+ );\r
+}\r
+\r
+/**\r
+ * Génère, à partir d'un tableau de saisie le code javascript ajouté à la fin de #GENERER_SAISIES\r
+ * pour produire un affichage conditionnel des saisies ayant une option afficher_si.\r
+ *\r
+ * @param array $saisies\r
+ * Tableau de descriptions des saisies\r
+ * @param string $id_form\r
+ * Identifiant unique pour le formulaire\r
+ * @return text\r
+ * Code javascript\r
+ */\r
+function saisies_generer_js_afficher_si($saisies,$id_form){\r
+ $i = 0;\r
+ $saisies = saisies_lister_par_nom($saisies,true);\r
+ $code = '';\r
+ $code .= '(function($){';\r
+ $code .= '$(document).ready(function(){';\r
+ $code .= 'verifier_saisies_'.$id_form.' = function(form){';\r
+ foreach ($saisies as $saisie) {\r
+ // on utilise comme selecteur l'identifiant de saisie en priorite s'il est connu\r
+ // parce que li_class = 'tableau[nom][option]' ne fonctionne evidement pas\r
+ // lorsque le name est un tableau\r
+ if (isset($saisie['options']['afficher_si'])) {\r
+ $i++;\r
+ // retrouver la classe css probable\r
+ switch ($saisie['saisie']) {\r
+ case 'fieldset':\r
+ $class_li = 'fieldset_'.$saisie['options']['nom'];\r
+ break;\r
+ case 'explication':\r
+ $class_li = 'explication_'.$saisie['options']['nom'];\r
+ break;\r
+ default:\r
+ $class_li = 'editer_'.$saisie['options']['nom'];\r
+ }\r
+ $condition = $saisie['options']['afficher_si'];\r
+ // retrouver l'identifiant\r
+ $identifiant = '';\r
+ if (isset($saisie['identifiant']) and $saisie['identifiant']) {\r
+ $identifiant = $saisie['identifiant'];\r
+ }\r
+ // On gère le cas @plugin:non_plugin@\r
+ preg_match_all('#@plugin:(.+)@#U', $condition, $matches);\r
+ foreach ($matches[1] as $plug) {\r
+ if (defined('_DIR_PLUGIN_'.strtoupper($plug)))\r
+ $condition = preg_replace('#@plugin:'.$plug.'@#U', 'true', $condition);\r
+ else\r
+ $condition = preg_replace('#@plugin:'.$plug.'@#U', 'false', $condition);\r
+ }\r
+ // On gère le cas @config:plugin:meta@ suivi d'un test\r
+ preg_match_all('#@config:(.+):(.+)@#U', $condition, $matches);\r
+ foreach ($matches[1] as $plugin) {\r
+ $config = lire_config($plugin);\r
+ $condition = preg_replace('#@config:'.$plugin.':'.$matches[2][0].'@#U', '"'.$config[$matches[2][0]].'"', $condition);\r
+ }\r
+ // On transforme en une condition valide\r
+ preg_match_all('#@(.+)@#U', $condition, $matches);\r
+ foreach ($matches[1] as $nom) {\r
+ switch($saisies[$nom]['saisie']) {\r
+ case 'radio':\r
+ case 'oui_non':\r
+ $condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']:checked").val()', $condition);\r
+ break;\r
+ case 'case':\r
+ $condition = preg_replace('#@'.preg_quote($nom).'@#U', '($(form).find("[name=\''.$nom.'\']").is(":checked") ? $(form).find("[name=\''.$nom.'\']").val() : "")', $condition);\r
+ break;\r
+ default:\r
+ $condition = preg_replace('#@'.preg_quote($nom).'@#U', '$(form).find("[name=\''.$nom.'\']").val()', $condition);\r
+ }\r
+ }\r
+ if ($identifiant) {\r
+ $sel = "li[data-id='$identifiant']";\r
+ } else {\r
+ $sel = "li.$class_li";\r
+ }\r
+ $code .= 'if ('.$condition.') {$(form).find("'.$sel.'").show(400);} ';\r
+ $code .= 'else {$(form).find("'.$sel.'").hide(400).css("display", "none");} ';\r
+ }\r
+ }\r
+ $code .= '};';\r
+ $code .= '$("li#afficher_si_'.$id_form.'").parents("form").each(function(){verifier_saisies_'.$id_form.'(this);});';\r
+ $code .= '$("li#afficher_si_'.$id_form.'").parents("form").change(function(){verifier_saisies_'.$id_form.'(this);});';\r
+ $code .= '});';\r
+ $code .= '})(jQuery);';\r
+ return $i>0 ? $code : '';\r
+}\r
+\r
+/**\r
+ * Lorsque l'on affiche les saisies (#VOIR_SAISIES), les saisies ayant une option afficher_si\r
+ * et dont les conditions ne sont pas remplies doivent être retirées du tableau de saisies.\r
+ * \r
+ * Cette fonction sert aussi lors de la vérification des saisies avec saisies_verifier().\r
+ * À ce moment là, les saisies non affichées sont retirées de _request\r
+ * (on passe leur valeur à NULL).\r
+ *\r
+ * @param array $saisies\r
+ * Tableau de descriptions de saisies\r
+ * @param array|null $env\r
+ * Tableau d'environnement transmis dans inclure/voi_saisies.html,\r
+ * NULL si on doit rechercher dans _request (pour saisies_verifier()).\r
+ * @return array\r
+ * Tableau de descriptions de saisies\r
+ */\r
+function saisies_verifier_afficher_si($saisies, $env=NULL) {\r
+ // eviter une erreur par maladresse d'appel :)\r
+ if (!is_array($saisies)) {\r
+ return array();\r
+ }\r
+ foreach ($saisies as $cle => $saisie) {\r
+ if (isset($saisie['options']['afficher_si'])) {\r
+ $condition = $saisie['options']['afficher_si'];\r
+ // On gère le cas @plugin:non_plugin@\r
+ preg_match_all('#@plugin:(.+)@#U', $condition, $matches);\r
+ foreach ($matches[1] as $plug) {\r
+ if (defined('_DIR_PLUGIN_'.strtoupper($plug)))\r
+ $condition = preg_replace('#@plugin:'.$plug.'@#U', 'true', $condition);\r
+ else\r
+ $condition = preg_replace('#@plugin:'.$plug.'@#U', 'false', $condition);\r
+ }\r
+ // On gère le cas @config:plugin:meta@ suivi d'un test\r
+ preg_match_all('#@config:(.+):(.+)@#U', $condition, $matches);\r
+ foreach ($matches[1] as $plugin) {\r
+ $config = lire_config($plugin);\r
+ $condition = preg_replace('#@config:'.$plugin.':'.$matches[2][0].'@#U', '"'.$config[$matches[2][0]].'"', $condition);\r
+ }\r
+ // On transforme en une condition valide\r
+ if (is_null($env))\r
+ $condition = preg_replace('#@(.+)@#U', '_request(\'$1\')', $condition);\r
+ else\r
+ $condition = preg_replace('#@(.+)@#U', '$env["valeurs"][\'$1\']', $condition);\r
+ eval('$ok = '.$condition.';');\r
+ if (!$ok) {\r
+ unset($saisies[$cle]);\r
+ if (is_null($env)) set_request($saisie['options']['nom'],NULL);\r
+ }\r
+ }\r
+ if (isset($saisies[$cle]['saisies'])) // S'il s'agit d'un fieldset ou equivalent, verifier les sous-saisies\r
+ $saisies[$cle]['saisies'] = saisies_verifier_afficher_si($saisies[$cle]['saisies'], $env);\r
+ }\r
+ return $saisies;\r
+}\r
+\r
+?>\r