'', #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 .= ""; } $script_hidden .= ""; $script_hidden .= ""; $script_hidden .= ""; 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