From a4242faef06ec228d34bdbc17da1eaf32d16847e Mon Sep 17 00:00:00 2001 From: Fil <fil@rezo.net> Date: Mon, 24 Mar 2008 22:29:21 +0000 Subject: [PATCH] Plusieurs changements qui permettent d'ajouter un champ a n'importe quelle table (y compris les tables 'officielles') et d'avoir tout de suite la balise #TOTO, et les crayons correspondants (mais pas encore l'interface dans l'espace prive): - on fait confiance a sql_showtable() pour nous indiquer les champs, plutot qu'a la version php de tables_principales etc - inc/modifier troque sa liste limitative de champs autorises contre une liste de champs interdits --- ecrire/action/editer_article.php | 87 ++++++++++------------ ecrire/action/instituer_mot.php | 11 ++- ecrire/action/legender.php | 3 +- ecrire/base/trouver_table.php | 23 ++++-- ecrire/inc/forum_insert.php | 17 +++-- ecrire/inc/modifier.php | 120 ++++++++++++++++++++----------- ecrire/public/balises.php | 3 +- ecrire/public/references.php | 47 +----------- 8 files changed, 159 insertions(+), 152 deletions(-) diff --git a/ecrire/action/editer_article.php b/ecrire/action/editer_article.php index 71806e41cd..78e51b7502 100644 --- a/ecrire/action/editer_article.php +++ b/ecrire/action/editer_article.php @@ -46,17 +46,37 @@ function action_editer_article_dist() { // Appelle toutes les fonctions de modification d'un article // $err est de la forme '&trad_err=1' // http://doc.spip.org/@articles_set -function articles_set($id_article, $c=false) { +function articles_set($id_article) { $err = ''; - // Edition du contenu ? - $err .= revisions_articles($id_article, $c); + // unifier $texte en cas de texte trop long + trop_longs_articles(); + + $c = array(); + foreach (array( + 'surtitre', 'titre', 'soustitre', 'descriptif', + 'nom_site', 'url_site', 'chapo', 'texte', 'ps' + ) as $champ) + $c[$champ] = _request($champ); + + if (_request('changer_virtuel') == 'oui') { + $r = _request('virtuel'); + $c['chapo'] = (strlen($r) ? '='.$r : ''); + } + + include_spip('inc/modifier'); + revision_article($id_article, $c); // Modification de statut, changement de rubrique ? + $c = array(); + foreach (array( + 'date', 'statut', 'id_parent' + ) as $champ) + $c[$champ] = _request($champ); $err .= instituer_article($id_article, $c); // Un lien de trad a prendre en compte - $err .= article_referent($id_article, $c); + $err .= article_referent($id_article, _request('id_trad')); return $err; } @@ -110,44 +130,6 @@ function insert_article($id_rubrique) { return $id_article; } -// Enregistre une revision d'article -// $c est un contenu (par defaut on prend le contenu via _request()) -// http://doc.spip.org/@revisions_articles -function revisions_articles ($id_article, $c=false) { - include_spip('inc/modifier'); - - // unifier $texte en cas de texte trop long (sur methode POST seulement) - if (!is_array($c)) trop_longs_articles(); - - // Si l'article est publie, invalider les caches et demander sa reindexation - $t = sql_getfetsel("statut", "spip_articles", "id_article=$id_article"); - if ($t == 'publie') { - $invalideur = "id='id_article/$id_article'"; - $indexation = true; - } - - if (_request('changer_virtuel') == 'oui') { - $r = _request('virtuel'); - if ($r) $r = "=$r"; - set_request('chapo', $r); - } - - modifier_contenu('article', $id_article, - array( - 'champs' => array( - 'surtitre', 'titre', 'soustitre', 'descriptif', - 'nom_site', 'url_site', 'chapo', 'texte', 'ps','date','date_redac' - ), - 'nonvide' => array('titre' => _T('info_sans_titre')), - 'invalideur' => $invalideur, - 'indexation' => $indexation, - 'date_modif' => 'date_modif' // champ a mettre a NOW() s'il y a modif - ), - $c); - - return ''; // pas d'erreur -} - // $c est un array ('statut', 'id_parent' = changement de rubrique) // @@ -164,9 +146,9 @@ function instituer_article($id_article, $c, $calcul_rub=true) { $id_rubrique = $row['id_rubrique']; $statut_ancien = $statut = $row['statut']; $champs = array(); - $date = _request('date', $c); + $date = $c['date']; - $s = _request('statut', $c); + $s = $c['statut']; // cf autorisations dans inc/instituer_article if ($s AND $s != $statut) { @@ -184,7 +166,7 @@ function instituer_article($id_article, $c, $calcul_rub=true) { OR ($champs['statut'] == 'prop' AND !in_array($statut_ancien, array('publie', 'prop')) )) { - if ($date) + if (!is_null($date)) $champs['date'] = $date; else { # on prend la date de MySQL pour eviter un decalage cf. #975 @@ -196,7 +178,7 @@ function instituer_article($id_article, $c, $calcul_rub=true) { // Verifier que la rubrique demandee existe et est differente // de la rubrique actuelle - if ($id_parent = _request('id_parent', $c) + if ($id_parent = $c['id_parent'] AND $id_parent != $id_rubrique AND (sql_fetsel('1', "spip_rubriques", "id_rubrique=$id_parent"))) { $champs['id_rubrique'] = $id_parent; @@ -306,9 +288,9 @@ function trop_longs_articles() { // Poser un lien de traduction vers un article de reference // http://doc.spip.org/@article_referent -function article_referent ($id_article, $c) { +function article_referent ($id_article, $lier_trad) { - if (!$lier_trad = intval(_request('lier_trad', $c))) return; + if (!$lier_trad = intval($c['lier_trad'])) return; // selectionner l'article cible, qui doit etre different de nous-meme, // et quitter s'il n'existe pas @@ -336,4 +318,13 @@ function article_referent ($id_article, $c) { } + +// obsolete, utiliser revision_article dans inc/modifier +// http://doc.spip.org/@revisions_articles +function revisions_articles ($id_article, $c=false) { + include_spip('inc/modifier'); + return revision_article($id_article,$c); +} + + ?> diff --git a/ecrire/action/instituer_mot.php b/ecrire/action/instituer_mot.php index ef5b07c3b7..72ad81133b 100644 --- a/ecrire/action/instituer_mot.php +++ b/ecrire/action/instituer_mot.php @@ -41,10 +41,17 @@ function action_instituer_mot_post($r) // modifier le contenu via l'API include_spip('inc/modifier'); - revision_mot($id_mot); + + $c = array(); + foreach (array( + 'titre', 'descriptif', 'texte', 'id_groupe', 'type', 'id_groupe' + ) as $champ) + $c[$champ] = _request($champ); + + revision_mot($id_mot, $c); if ($redirect = _request('redirect')) redirige_par_entete(parametre_url(urldecode($redirect), - 'id_mot', $id_mot, '&')); + 'id_mot', $id_mot, '&')); } diff --git a/ecrire/action/legender.php b/ecrire/action/legender.php index 8714902d7d..3d5aede413 100644 --- a/ecrire/action/legender.php +++ b/ecrire/action/legender.php @@ -69,7 +69,8 @@ function action_legender_post($r) $modifs['descriptif'] = $t; include_spip('inc/modifier'); - revision_document($id_document, $modifs); + } + ?> diff --git a/ecrire/base/trouver_table.php b/ecrire/base/trouver_table.php index 34d0b2cac0..1e2ef7d11e 100644 --- a/ecrire/base/trouver_table.php +++ b/ecrire/base/trouver_table.php @@ -35,9 +35,12 @@ function base_trouver_table_dist($nom, $serveur='') $nom_sql = $nom; if (preg_match('/\.(.*)$/', $nom, $s)) $nom_sql = $s[1]; - else $nom_sql = $nom; + else + $nom_sql = $nom; + $desc = ''; $connexion = $GLOBALS['connexions'][$serveur ? $serveur : 0]; + // base sous SPIP: gerer les abreviations des noms de table if ($connexion['spip_connect_version']) { include_spip('public/interfaces'); @@ -46,7 +49,7 @@ function base_trouver_table_dist($nom, $serveur='') $nom_sql = 'spip_' . $t; if (!isset($connexion['tables'][$nom_sql])) { include_spip('base/serial'); - $desc = $tables_principales[$nom_sql]; + $fdesc = $tables_principales[$nom_sql]; $nom = $t; } } else { @@ -54,18 +57,25 @@ function base_trouver_table_dist($nom, $serveur='') if (isset($tables_auxiliaires['spip_' .$nom])) { $nom_sql = 'spip_' . $nom; if (!isset($connexion['tables'][$nom_sql])) { - $desc = $tables_auxiliaires[$nom_sql]; + $fdesc = $tables_auxiliaires[$nom_sql]; } } # table locale a cote de SPIP, comme non SPIP: } } + if (!isset($connexion['tables'][$nom_sql])) { - if (!$desc) { + // La *vraie* base a la priorite + if (true /* !$bdesc OR !$bdesc['field'] */) { $t = ($nom_sql != $nom); $desc = sql_showtable($nom_sql, $t, $serveur); if (!$desc OR !$desc['field']) { - spip_log("table inconnue $serveur $nom"); - return null; + if (!$fdesc) { + spip_log("table inconnue $serveur $nom"); + return null; + } + // on ne sait pas lire la structure de la table : + // on retombe sur la description donnee dans les fichiers spip + $desc = $fdesc; } } $desc['table']= $nom_sql; @@ -73,6 +83,7 @@ function base_trouver_table_dist($nom, $serveur='') $desc['connexion']= $serveur; $connexion['tables'][$nom_sql] = $desc; } + return $connexion['tables'][$nom_sql]; } ?> diff --git a/ecrire/inc/forum_insert.php b/ecrire/inc/forum_insert.php index a803c0541e..f859ac3573 100644 --- a/ecrire/inc/forum_insert.php +++ b/ecrire/inc/forum_insert.php @@ -192,14 +192,19 @@ function inc_forum_insert_dist($force_statut = NULL) { // Entree du contenu et invalidation des caches // include_spip('inc/modifier'); - // Injecter les bonnes valeurs dans le contexte $c - $auteur = sinon($GLOBALS['visiteur_session']['nom'], + + $c = array(); + foreach (array( + 'titre', 'texte', 'nom_site', 'url_site' + ) as $champ) + $c[$champ] = _request($champ); + + $c['auteur'] = sinon($GLOBALS['visiteur_session']['nom'], $GLOBALS['visiteur_session']['session_nom']); - $email_auteur = sinon($GLOBALS['visiteur_session']['email'], + $c['email_auteur'] = sinon($GLOBALS['visiteur_session']['email'], $GLOBALS['visiteur_session']['session_email']); - set_request('auteur', $auteur); - set_request('email_auteur', $email_auteur); - revision_forum($id_message); + + revision_forum($id_message, $c); // Notification if ($notifications = charger_fonction('notifications', 'inc')) diff --git a/ecrire/inc/modifier.php b/ecrire/inc/modifier.php index 2fe3034e65..725b87f817 100644 --- a/ecrire/inc/modifier.php +++ b/ecrire/inc/modifier.php @@ -16,37 +16,59 @@ if (!defined("_ECRIRE_INC_VERSION")) return; // Une fonction generique pour l'API de modification de contenu // $options est un array() avec toutes les options // -// Pour l'instant fonctionne pour les types : -// article, auteur, document, forum // renvoie false si rien n'a ete modifie, true sinon // +// Attention, pour eviter des hacks on interdit les champs +// (statut, id_secteur, id_rubrique, id_parent), +// mais la securite doit etre assuree en amont +// // http://doc.spip.org/@modifier_contenu -function modifier_contenu($type, $id, $options, $c=false) { +function modifier_contenu($type, $id, $options, $c=false, $serveur='') { include_spip('inc/filtres'); $table_objet = table_objet($type); $id_table_objet = id_table_objet($type); + $trouver_table = charger_fonction('trouver_table', 'base'); + $desc = $trouver_table($table_objet, $serveur); + + // Appels incomplets (sans $c) + if (!is_array($c)) { + spip_log('erreur appel modifier_contenu('.$type.'), manque $c'); + return false; + } + + // Securite : certaines variables ne sont jamais acceptees ici + // car elles ne relevent pas de autoriser(article, modifier) ; + // il faut passer par instituer_XX() + // TODO: faut-il passer ces variables interdites + // dans un fichier de description separe ? + unset($c['statut']); + unset($c['id_parent']); + unset($c['id_rubrique']); + unset($c['id_secteur']); // Gerer les champs non vides if (is_array($options['nonvide'])) - foreach ($options['nonvide'] as $champ => $sinon) { - if (_request($champ, $c) === '') { - $c = set_request($champ, $sinon, $c); - } - } + foreach ($options['nonvide'] as $champ => $sinon) + if ($c[$champ] === '') + $c[$champ] = $sinon; + + // N'accepter que les champs qui existent + // TODO: ici aussi on peut valider les contenus + // en fonction du type $champs = array(); - if (is_array($options['champs'])) - foreach ($options['champs'] as $champ) { - $val = _request($champ, $c); - if ($val !== NULL) - $champs[$champ] = corriger_caracteres($val); - } + foreach($desc['field'] as $champ => $ignore) + if (isset($c[$champ])) + $champs[$champ] = $c[$champ]; + + // Nettoyer les valeurs + $champs = array_map('corriger_caracteres', $champs); // recuperer les extras if ($GLOBALS['champs_extra']) { include_spip('inc/extra'); - if ($extra = extra_update($table_objet, $id, $c)) + if ($extra = extra_update($table_objet, $id, $champs)) $champs['extra'] = $extra; } @@ -80,18 +102,21 @@ function modifier_contenu($type, $id, $options, $c=false) { $verifier = array(); foreach ($champs as $ch => $val) $verifier[] = $ch.'='.$val; + $verifier = "$id_table_objet=$id AND NOT (".join(' AND ', $verifier).')'; - if (!sql_countsel("spip_$table_objet", $verifier)) + if (!sql_countsel("spip_$table_objet", $verifier, + null,null,null, null, $serveur)) return false; // la modif peut avoir lieu // faut-il ajouter date_modif ? - if ($options['date_modif']) + if ($options['date_modif'] + AND !isset($champs[$options['date_modif']])) $champs[$options['date_modif']] = 'NOW()'; // allez on commit la modif - sql_update("spip_$table_objet", $champs, "$id_table_objet=$id"); + sql_update("spip_$table_objet", $champs, "$id_table_objet=$id", $serveur); // Invalider les caches if ($options['invalideur']) { @@ -149,13 +174,35 @@ function marquer_doublons_documents($champs,$id,$id_table_objet,$table_objet){ } } +// Enregistre une revision d'article +// http://doc.spip.org/@revision_article +function revision_article ($id_article, $c=false) { + + // Si l'article est publie, invalider les caches et demander sa reindexation + $t = sql_getfetsel("statut", "spip_articles", "id_article=$id_article"); + if ($t == 'publie') { + $invalideur = "id='id_article/$id_article'"; + $indexation = true; + } + + modifier_contenu('article', $id_article, + array( + 'nonvide' => array('titre' => _T('info_sans_titre')), + 'invalideur' => $invalideur, + 'indexation' => $indexation, + 'date_modif' => 'date_modif' // champ a mettre a NOW() s'il y a modif + ), + $c); + + return ''; // pas d'erreur +} + // http://doc.spip.org/@revision_document function revision_document($id_document, $c=false) { return modifier_contenu('document', $id_document, array( - 'champs' => array('titre', 'descriptif', 'date', 'largeur', 'hauteur') - //,'nonvide' => array('titre' => _T('info_sans_titre')) + // 'nonvide' => array('titre' => _T('info_sans_titre')) ), $c); } @@ -165,7 +212,6 @@ function revision_signature($id_signature, $c=false) { return modifier_contenu('signature', $id_signature, array( - 'champs' => array('nom_email', 'ad_email', 'nom_site', 'url_site', 'message'), 'nonvide' => array('nom_email' => _T('info_sans_titre')) ), $c); @@ -177,7 +223,6 @@ function revision_auteur($id_auteur, $c=false) { modifier_contenu('auteur', $id_auteur, array( - 'champs' => array('nom', 'bio', 'pgp', 'nom_site', 'url_site', 'email', 'login'), 'nonvide' => array('nom' => _T('ecrire:item_nouvel_auteur')) ), $c); @@ -188,19 +233,16 @@ function revision_auteur($id_auteur, $c=false) { function revision_mot($id_mot, $c=false) { // regler le groupe - if (NULL !== ($id_groupe = _request('id_groupe',$c)) - OR NULL !== ($type = _request('type',$c))) { - $result = sql_select("titre", "spip_groupes_mots", "id_groupe=".sql_quote($id_groupe)); + if (isset($c['id_groupe']) OR isset($c['type'])) { + $result = sql_select("titre", "spip_groupes_mots", "id_groupe=".intval($id_groupe)); if ($row = sql_fetch($result)) - $type = $row['titre']; + $c['type'] = $row['titre']; else - $type = NULL; - $c = set_request('type', $type, $c); + unset($c['type']); } modifier_contenu('mot', $id_mot, array( - 'champs' => array('titre', 'descriptif', 'texte', 'id_groupe', 'type'), 'nonvide' => array('titre' => _T('info_sans_titre')) ), $c); @@ -210,9 +252,7 @@ function revision_mot($id_mot, $c=false) { function revision_petition($id_article, $c=false) { modifier_contenu('petition', $id_article, - array( - 'champs' => array('texte') - ), + array(), $c); } @@ -243,27 +283,23 @@ function revision_forum($id_forum, $c=false) { $invalideur = ''; // Supprimer 'http://' tout seul - $u = _request('url_site', $c); - if ($u !== NULL) { + if (isset($c['url_site'])) { include_spip('inc/filtres'); - $c = set_request('url_site', vider_url($u, false), $c); + $c['url_site'] = vider_url($c['url_site'], false); } $r = modifier_contenu('forum', $id_forum, array( - 'champs' => array('titre', 'texte', 'auteur', 'email_auteur', 'nom_site', 'url_site'), 'nonvide' => array('titre' => _T('info_sans_titre')), 'invalideur' => $invalideur ), $c); - // Modification des id_article etc: ce n'est pas autorise en standard - // mais ca peut servir pour des crayons ; du coup on teste ici que - // la donnee provient bien de $c, pour eviter tout hack lors d'un envoi - // normal de forum ; et on deplace tout le thread {sauf les originaux}. - if (is_array($c) - AND count($cles = array_intersect(array_keys($c), + // Modification des id_article etc + // (non autorise en standard mais utile pour des crayons) + // on deplace tout le thread {sauf les originaux}. + if (count($cles = array_intersect(array_keys($c), array('id_article', 'id_rubrique', 'id_syndic', 'id_breve'))) ) { $thread = sql_fetsel("id_thread", "spip_forum", "id_forum=$id_forum"); diff --git a/ecrire/public/balises.php b/ecrire/public/balises.php index 331513b520..6d5c8a1d75 100644 --- a/ecrire/public/balises.php +++ b/ecrire/public/balises.php @@ -924,7 +924,8 @@ function balise_EVAL_dist($p) { // http://doc.spip.org/@balise_CHAMP_SQL_dist function balise_CHAMP_SQL_dist($p){ $p->code = ''; - if (isset($p->param[0][1][0]) AND $champ = ($p->param[0][1][0]->texte)) + if (isset($p->param[0][1][0]) + AND $champ = ($p->param[0][1][0]->texte)) $p->code = champ_sql($champ, $p); #$p->interdire_scripts = true; diff --git a/ecrire/public/references.php b/ecrire/public/references.php index fc48e1fbdb..b5a5cff660 100644 --- a/ecrire/public/references.php +++ b/ecrire/public/references.php @@ -42,6 +42,7 @@ function index_pile($idb, $nom_champ, &$boucles, $explicite='') { // il y a incoherences qu'il vaut mieux eviter while (isset($boucles[$idb])) { list ($t, $c) = index_tables_en_pile($idb, $nom_champ, $boucles); + if ($t) { if (!in_array($t, $boucles[$idb]->select)) { $boucles[$idb]->select[] = $t; @@ -205,52 +206,6 @@ function calculer_balise($nom, $p) { return $p; } -/* - -L'appel direct de #ARTICLE_TRADUCTIONS devient #MODELE{article_traductions} - -// fonction speciale d'appel a un modele modeles/truc.html pour la balise #TRUC -// exemples : #TRADUCTIONS, #DOC, #IMG... -// http://doc.spip.org/@calculer_balise_modele_dist -function calculer_balise_modele_dist($p){ - $nom = strtolower($p->nom_champ); - $contexte = array(); - - if (isset($p->param[0])){ - while (count($p->param[0])>2){ - $p->param[]=array($p->param[0][0],array_pop($p->param[0])); - } - } -print_r($p->param); - $champ = phraser_arguments_inclure($p, true); - // a priori true - // si false, le compilo va bloquer sur des syntaxes avec un filtre sans argument qui suit la balise - // si true, les arguments simples (sans truc=chose) vont degager - $code_contexte = argumenter_inclure($champ, $p->descr, $p->boucles, $p->id_boucle, false); - - // Si le champ existe dans la pile, on le met dans le contexte - // (a priori c'est du code mort ; il servait pour #LESAUTEURS dans - // le cas spip_syndic_articles) - #$code_contexte[] = "'$nom='.".champ_sql($nom, $p); - - // Reserver la cle primaire de la boucle courante - if ($primary = $p->boucles[$p->id_boucle]->primary) { - $id = champ_sql($primary, $p); - $code_contexte[] = "'$primary='.".$id; - } - -#print_r($code_contexte); - - $p->code = "( ((\$recurs=(isset(\$Pile[0]['recurs'])?\$Pile[0]['recurs']:0))<5)? - recuperer_fond('modeles/".$nom."', - creer_contexte_de_modele(array(".join(',', $code_contexte).",'recurs='.++\$recurs, \$GLOBALS['spip_lang']))):'')"; - $p->interdire_scripts = false; // securite assuree par le squelette - -print $p->code."\n<hr/>\n"; - - return $p; -} -*/ // // Traduction des balises dynamiques, notamment les "formulaire_*" -- GitLab