Server : Apache System : Linux webd348.cluster026.gra.hosting.ovh.net 5.15.148-ovh-vps-grsec-zfs-classid #1 SMP Thu Feb 8 09:41:04 UTC 2024 x86_64 User : hednacluml ( 122243) PHP Version : 8.3.9 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl Directory : /home/hednacluml/france/plugins-dist/forum/formulaires/ |
<?php /***************************************************************************\ * SPIP, Système de publication pour l'internet * * * * Copyright © avec tendresse depuis 2001 * * Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James * * * * Ce programme est un logiciel libre distribué sous licence GNU/GPL. * \***************************************************************************/ if (!defined('_ECRIRE_INC_VERSION')) { return; } include_spip('inc/forum'); /** * Identification du formulaire poste : ne pas tenir compte de la previsu et du retour * * @param $objet * @param $id_objet * @param $id_forum * @param $ajouter_mot * @param $ajouter_groupe * @param $afficher_previsu * @param $retour * @return array */ function formulaires_forum_identifier_dist( $objet, $id_objet, $id_forum, $ajouter_mot, $ajouter_groupe, $afficher_previsu, $retour ) { return [$objet, $id_objet, $id_forum, $ajouter_mot, $ajouter_groupe]; } /** * Charger l'env du squelette de #FORMULAIRE_FORUM * * @param string $objet * @param int $id_objet * @param int $id_forum * @param int|array $ajouter_mot * mots ajoutés cochés par defaut * @param $ajouter_groupe * groupes ajoutables * @param $forcer_previsu * forcer la previsualisation du message oui ou non * @param $retour * url de retour * @return array|bool */ function formulaires_forum_charger_dist( $objet, $id_objet, $id_forum, $ajouter_mot, $ajouter_groupe, $forcer_previsu, $retour ) { if (!function_exists($f = 'forum_recuperer_titre')) { $f = 'forum_recuperer_titre_dist'; } if (!$titre = $f($objet, $id_objet, $id_forum)) { return false; } // ca s'apparenterait presque a une autorisation... // si on n'avait pas a envoyer la valeur $accepter_forum au formulaire $accepter_forum = controler_forum($objet, $id_objet); if ($accepter_forum == 'non') { return false; } $primary = id_table_objet($objet); // table a laquelle sont associes les mots : if ($GLOBALS['meta']['mots_cles_forums'] != 'oui') { $table = ''; } else { $table = table_objet($objet); } // exiger l'authentification des posteurs pour les forums sur abo if ($accepter_forum == 'abo') { if (!isset($GLOBALS['visiteur_session']['statut']) or !$GLOBALS['visiteur_session']['statut']) { return [ 'action' => '', #ne sert pas dans ce cas, on la vide pour mutualiser le cache 'editable' => false, 'login_forum_abo' => ' ', 'inscription' => generer_url_public('identifiants', 'lang=' . $GLOBALS['spip_lang']), 'oubli' => generer_url_public('spip_pass', 'lang=' . $GLOBALS['spip_lang'], true), ]; } } // Tableau des valeurs servant au calcul d'une signature de securite. // Elles seront placees en Input Hidden pour que inc/forum_insert // recalcule la meme chose et verifie l'identite des resultats. // Donc ne pas changer la valeur de ce tableau entre le calcul de // la signature et la fabrication des Hidden // Faire attention aussi a 0 != '' $ids = []; $ids[$primary] = ($x = intval($id_objet)) ? $x : ''; $ids['id_objet'] = ($x = intval($id_objet)) ? $x : ''; $ids['objet'] = $objet; $ids['id_forum'] = ($x = intval($id_forum)) ? $x : ''; // par défaut, on force la prévisualisation du message avant de le poster if (($forcer_previsu == 'non') or (empty($forcer_previsu) and $GLOBALS['meta']['forums_forcer_previsu'] == 'non')) { $forcer_previsu = 'non'; } else { $forcer_previsu = 'oui'; } if (_request('formulaire_action')) { $arg = forum_fichier_tmp(join('', $ids)); $securiser_action = charger_fonction('securiser_action', 'inc'); // on sait que cette fonction est dans le fichier associe $hash = calculer_action_auteur("ajout_forum-$arg"); } else { $arg = $hash = ''; } // pour les hidden $script_hidden = ''; foreach ($ids as $id => $v) { $script_hidden .= "<input type='hidden' name='$id' value='$v' />"; } $script_hidden .= "<input type='hidden' name='arg' value='$arg' />"; $script_hidden .= "<input type='hidden' name='hash' value='$hash' />"; $script_hidden .= "<input type='hidden' name='verif_$hash' value='ok' />"; if ($formats = forum_documents_acceptes()) { include_spip('inc/securiser_action'); $cle = calculer_cle_action('ajouter-document-' . $objet . '-' . $id_objet); } else { $cle = null; } // Valeurs par defaut du formulaire // si le formulaire a ete sauvegarde, restituer les valeurs de session $vals = [ 'titre' => $titre, 'texte' => '', 'nom_site' => '', 'url_site' => '' ]; return array_merge($vals, [ 'modere' => (($accepter_forum != 'pri') ? '' : ' '), 'table' => $table, 'config' => ['afficher_barre' => ($GLOBALS['meta']['forums_afficher_barre'] != 'non' ? ' ' : '')], '_hidden' => $script_hidden, # pour les variables hidden qui seront inserees dans le form et dans le form de previsu 'cle_ajouter_document' => $cle, 'formats_documents_forum' => trim($GLOBALS['meta']['formats_documents_forum']) == '*' ? _T('forum:extensions_autorisees_toutes') : forum_documents_acceptes(), 'ajouter_document' => $_FILES['ajouter_document']['name'] ?? '', 'nobot' => ($cle ? _request($cle) : _request('nobot')), 'ajouter_groupe' => $ajouter_groupe, 'ajouter_mot' => (is_array($ajouter_mot) ? $ajouter_mot : [$ajouter_mot]), 'forcer_previsu' => $forcer_previsu, 'id_forum' => $id_forum, // passer id_forum au formulaire pour lui permettre d'afficher a quoi l'internaute repond '_sign' => implode('_', $ids), '_autosave_id' => $ids, ]); } /** * Une securite qui nous protege contre : * - les doubles validations de forums (derapages humains ou des brouteurs) * - les abus visant a mettre des forums malgre nous sur un article (??) * On installe un fichier temporaire dans _DIR_TMP (et pas _DIR_CACHE * afin de ne pas bugguer quand on vide le cache) * Le lock est leve au moment de l'insertion en base (inc-messforum) * Ce systeme n'est pas fonctionnel pour les forums sans previsu (notamment * si $forcer_previsu = 'non') * * @param $arg * @return int */ function forum_fichier_tmp($arg) { $f = null; # astuce : random_int pour autoriser les hits simultanes while ( ($alea = time() + random_int(0, mt_getrandmax())) + intval($arg) and @file_exists($f = _DIR_TMP . "forum_$alea.lck") ) { }; spip_touch($f); # et maintenant on purge les locks de forums ouverts depuis > 4 h if ($dh = opendir(_DIR_TMP)) { while (($file = @readdir($dh)) !== false) { if ( preg_match('/^forum_([0-9]+)\.lck$/', $file) and (time() - @filemtime(_DIR_TMP . $file) > 4 * 3600) ) { spip_unlink(_DIR_TMP . $file); } } } return $alea; } /** * Verifier la saisie de #FORMULAIRE_FORUM * * @param string $objet * @param int $id_objet * @param int $id_forum * @param int|array $ajouter_mot * mots ajoutés cochés par defaut * @param $ajouter_groupe * groupes ajoutables * @param $forcer_previsu * forcer la previsualisation du message oui ou non * @param $retour * url de retour * @return array|bool */ function formulaires_forum_verifier_dist( $objet, $id_objet, $id_forum, $ajouter_mot, $ajouter_groupe, $forcer_previsu, $retour ) { $meta = null; include_spip('inc/acces'); include_spip('inc/texte'); include_spip('inc/session'); include_spip('base/abstract_sql'); // par défaut, on force la prévisualisation du message avant de le poster if (($forcer_previsu == 'non') or (empty($forcer_previsu) and $GLOBALS['meta']['forums_forcer_previsu'] == 'non')) { $forcer_previsu = 'non'; } else { $forcer_previsu = 'oui'; } $erreurs = []; $doc = []; // desactiver id_rubrique si un id_article ou autre existe dans le contexte // if ($id_article OR $id_breve OR $id_forum OR $id_syndic) // $id_rubrique = 0; // stocker un eventuel document dans un espace temporaire // portant la cle du formulaire ; et ses metadonnees avec if ( isset($_FILES['ajouter_document']) and $_FILES['ajouter_document']['tmp_name'] ) { $acceptes = forum_documents_acceptes(); if ( // si on a poste un $_FILES mais que l'option n'est pas active : cas produit par les bots qui spamment automatiquement !count($acceptes) // securite : // verifier si on possede la cle (ie on est autorise a poster) // (sinon tant pis) ; cf. charger.php pour la definition de la cle or _request('cle_ajouter_document') != calculer_cle_action($a = "ajouter-document-$objet-$id_objet") ) { $erreurs['document_forum'] = _T('forum:documents_interdits_forum'); unset($_FILES['ajouter_document']); } else { if (!isset($GLOBALS['visiteur_session']['tmp_forum_document'])) { session_set('tmp_forum_document', sous_repertoire(_DIR_TMP, 'documents_forum') . md5(uniqid(random_int(0, mt_getrandmax())))); } $tmp = $GLOBALS['visiteur_session']['tmp_forum_document']; $doc = &$_FILES['ajouter_document']; include_spip('inc/joindre_document'); include_spip('action/ajouter_documents'); [$extension, $doc['name']] = fixer_extension_document($doc); if (!in_array($extension, $acceptes)) { $erreurs['document_forum'] = _T('public:formats_acceptes', ['formats' => join(', ', $acceptes)]); } else { include_spip('inc/getdocument'); if (!deplacer_fichier_upload($doc['tmp_name'], $tmp . '.bin')) { $erreurs['document_forum'] = _T('copie_document_impossible'); } # else if (...) # verifier le type_document autorise # retailler eventuellement les photos } // si ok on stocke les meta donnees, sinon on efface if (isset($erreurs['document_forum'])) { spip_unlink($tmp . '.bin'); unset($_FILES['ajouter_document']); } else { $doc['tmp_name'] = $tmp . '.bin'; ecrire_fichier($tmp . '.txt', serialize($doc)); } } } // restaurer/supprimer le document eventuellement uploade au tour precedent elseif ( isset($GLOBALS['visiteur_session']['tmp_forum_document']) and $tmp = $GLOBALS['visiteur_session']['tmp_forum_document'] and file_exists($tmp . '.bin') ) { if (_request('supprimer_document_ajoute')) { spip_unlink($tmp . '.bin'); spip_unlink($tmp . '.txt'); } elseif (lire_fichier($tmp . '.txt', $meta)) { $doc = &$_FILES['ajouter_document']; $doc = @unserialize($meta); } } $min_length = (defined('_FORUM_LONGUEUR_MINI') ? _FORUM_LONGUEUR_MINI : 10); if ( strlen($texte = _request('texte')) < $min_length and !$ajouter_mot and $GLOBALS['meta']['forums_texte'] == 'oui' ) { $erreurs['texte'] = _T( $min_length == 10 ? 'forum:forum_attention_dix_caracteres' : 'forum:forum_attention_nb_caracteres_mini', ['min' => $min_length] ); } elseif ( defined('_FORUM_LONGUEUR_MAXI') and _FORUM_LONGUEUR_MAXI > 0 and strlen($texte) > _FORUM_LONGUEUR_MAXI ) { $erreurs['texte'] = _T( 'forum:forum_attention_trop_caracteres', [ 'compte' => strlen($texte), 'max' => _FORUM_LONGUEUR_MAXI ] ); } if (array_reduce($_POST, 'reduce_strlen', (20 * 1024)) < 0) { $erreurs['erreur_message'] = _T('forum:forum_message_trop_long'); } else { // Ne pas autoriser d'envoi hacke si forum sur abonnement if ( controler_forum($objet, $id_objet) == 'abo' and !test_espace_prive() ) { if ( !isset($GLOBALS['visiteur_session']) or !isset($GLOBALS['visiteur_session']['statut']) ) { $erreurs['erreur_message'] = _T('forum_non_inscrit'); } elseif ($GLOBALS['visiteur_session']['statut'] == '5poubelle') { $erreurs['erreur_message'] = _T('forum:forum_acces_refuse'); } } } if ( strlen($titre = _request('titre')) < 3 and $GLOBALS['meta']['forums_titre'] == 'oui' ) { $erreurs['titre'] = _T('forum:forum_attention_trois_caracteres'); } if (!count($erreurs) and !_request('confirmer_previsu_forum')) { if (!_request('envoyer_message') or $forcer_previsu <> 'non') { $previsu = inclure_previsu( $texte, $titre, _request('url_site'), _request('nom_site'), _request('ajouter_mot'), $doc, $objet, $id_objet, $id_forum ); $erreurs['previsu'] = $previsu; $erreurs['message_erreur'] = ''; // on ne veut pas du message_erreur automatique } } // Si forum avec previsu sans bon hash de securite, echec if (!count($erreurs)) { if ( !test_espace_prive() and $forcer_previsu <> 'non' and forum_insert_noprevisu() ) { $erreurs['erreur_message'] = _T('forum:forum_acces_refuse'); } } return $erreurs; } /** * Lister les formats de documents joints acceptes dans les forum * * @return array */ function forum_documents_acceptes() { $formats = trim($GLOBALS['meta']['formats_documents_forum']); if (!$formats) { return []; } if ($formats !== '*') { $formats = array_filter(preg_split(',[^a-zA-Z0-9/+_],', $formats)); } else { include_spip('base/typedoc'); $formats = array_keys($GLOBALS['tables_mime']); } sort($formats); return $formats; } /** * Preparer la previsu d'un message de forum * * @param string $texte * @param string $titre * @param string $url_site * @param string $nom_site * @param array $ajouter_mot * @param array $doc * @param string $objet * @param int $id_objet * @param int $id_forum * @return string */ function inclure_previsu( $texte, $titre, $url_site, $nom_site, $ajouter_mot, $doc, $objet, $id_objet, $id_forum ) { global $table_des_traitements; $bouton = _T('forum:forum_message_definitif'); include_spip('public/assembler'); include_spip('public/composer'); // appliquer les traitements de #TEXTE a la previsu // comme on voit c'est complique... y a peut-etre plus simple ? // recuperer les filtres eventuels de 'mes_fonctions.php' sur les balises include_spip('public/parametrer'); $tmptexte = ''; $evaltexte = $table_des_traitements['TEXTE']['forums'] ?? $table_des_traitements['TEXTE'][0]; $evaltexte = '$tmptexte = ' . str_replace('%s', '$texte', $evaltexte) . ';'; // evaluer... // [fixme] // $connect et $Pile ne sont pas definis ici :/ // mais font souvent partie des variables appelees par les traitements $connect = ''; $Pile = [0 => []]; eval($evaltexte); // supprimer les <form> de la previsualisation // (sinon on ne peut pas faire <cadre>...</cadre> dans les forums) return preg_replace( "@<(/?)form\b@ism", '<\1div', inclure_balise_dynamique( [ 'formulaires/inc-forum_previsu', 0, [ 'titre' => safehtml(typo($titre)), 'texte' => $tmptexte, 'notes' => safehtml(calculer_notes()), 'url_site' => vider_url($url_site), 'nom_site' => safehtml(typo($nom_site)), 'ajouter_mot' => (is_array($ajouter_mot) ? $ajouter_mot : [$ajouter_mot]), 'ajouter_document' => $doc, #'erreur' => $erreur, // non definie ? 'bouton' => $bouton, 'objet' => $objet, 'id_objet' => $id_objet, 'id_forum' => $id_forum ] ], false ) ); } /** * Traiter la saisie de #FORMULAIRE_FORUM * tout est delegue a inc_forum_insert() * * @param string $objet * @param int $id_objet * @param int $id_forum * @param int|array $ajouter_mot * mots ajoutes coches par defaut * @param $ajouter_groupe * groupes ajoutables * @param $forcer_previsu * forcer la previsualisation du message oui ou non * @param $retour * url de retour * @return array|bool */ function formulaires_forum_traiter_dist( $objet, $id_objet, $id_forum, $ajouter_mot, $ajouter_groupe, $forcer_previsu, $retour ) { $forum_insert = charger_fonction('forum_insert', 'inc'); // Antispam basique : // si l'input invisible a ete renseigne, ca ne peut etre qu'un bot if (strlen(_request(_request('cle_ajouter_document')) ?? '')) { tracer_erreur_forum('champ interdit (nobot) rempli'); return ['message_erreur' => _T('forum:erreur_enregistrement_message')]; } if ( defined('_FORUM_AUTORISER_POST_ID_FORUM') and _FORUM_AUTORISER_POST_ID_FORUM and _request('id_forum') ) { $id_forum = _request('id_forum'); } $id_reponse = $forum_insert($objet, $id_objet, $id_forum); if ($id_reponse) { // En cas de retour sur (par exemple) {#SELF}, on ajoute quand // meme #forum12 a la fin de l'url, sauf si un #ancre est explicite if ($retour) { if (!strpos($retour, '#')) { $retour .= '#forum' . $id_reponse; } } else { // le retour par defaut envoie sur le thread, ce qui permet // de traiter elegamment le cas des forums moderes a priori. // Cela assure aussi qu'on retrouve son message dans le thread // dans le cas des forums moderes a posteriori, ce qui n'est // pas plus mal. if (function_exists('generer_url_forum')) { $retour = generer_url_forum($id_reponse); } else { $thread = sql_fetsel('id_thread', 'spip_forum', 'id_forum=' . $id_reponse); spip_log('id_thread=' . $thread['id_thread'], 'forum'); $retour = generer_objet_url($thread['id_thread'], 'forum'); } } $res = ['redirect' => $retour, 'id_forum' => $id_reponse]; } else { $res = ['message_erreur' => _T('forum:erreur_enregistrement_message')]; } return $res; }