Au taff, je bosse sur un forum qui sera réalisé avec ce bon vieux petit Drupal. Le truc génial, c'est qu'on trouve presque tout ce qu'il faut pour faire ça avec les modules existants déjà.
Sauf une chose que je n'ai pas trouvé en fait : fermer les réponses a un thread du forum. Oui, ça semble tellement gros que je pense qu'en réalité, j'ai juste mal cherché ^_^
Mais tant pis, ca permet de se faire la mains avec un petit module pas compliqué à réaliser.
Premièrement, avant de se soucier d'un quelconque module, encore faut-il savoir comment on pourrait fermer les réponses d'un sujet précis.
Pour ceci, c'est assez simple, c'est déjà prévu. En effet, dans la base de données, dans la table "node", on retrouve un champ "comment" qui peut prendre 3 valeurs différentes :
0 : les commentaires sont fermés et ne sont plus affichés
1 : les commentaires sont fermés mais restent affichés
2 : les commentaires sont ouverts et on peut répondre.
Sachant cela, il suffit de changer ce champ pour un noeud donné, et c'est gagné.
Pour commencer, on va d'abord rajouter un lien, sous chaque message, pour pouvoir acceder a la page permettant de les fermer
Pour cela, on va utiliser le hook_link(), qui definit les liens en question.
* Implementation of hook_link().
*
* Permet de rajouter un lien dans la variable $links
*/
function closecomment_link($type, $node) {
if ($type != 'comment') {
$links = array();
$links[] = array('href' => 'closecomment/'.$node->nid,
'title' => variable_get('closecomment_text', 'on ferme !'),
'html' => $format['html']);
return $links;
}
}
Décortiquons un peu ça :
Tout d'abord, on vérifie qu'on ne se trouve pas sur un commentaire. Ce n'est pas indispensable, mais ça évite d'avoir le lien autant de fois qu'il y a de réponses sur la page.
Ensuite, on rajoute un élément dans le tableau $links[], en y passant :
- href : qui indique que c'est un lien qui pointe vers /closecomment/n°_du_noeud
- title : l'intitulé du lien en question (on reviendra sur le variable_get() plus tard)
On a notre lien maintenant. Seulement voila, le lien pointe vers un /closecomment/17 (par exemple), mais Drupal ne sait pas quoi afficher sur cette page, d'ailleurs, il ne sait même pas que les pages /closecomment/ sont sensé exister !
Remédions a cela grâce a au hook hook_menu
$items[] = array(
'path' => 'closecomment',
'title' => t('On Ferme'),
'callback' => 'fermeture_commentaire',
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK
);
return $items;
}
En surchargeant le hook_menu, on peut indiquer a Drupal la manière de gérer des "nouvelles" pages. En l'occurrence, ici, on parle de la page "path" = closecomment.
Le callback correspond à la fonction qui sera exécuté lors de l'accès a cette page (on parlera de cette fonction juste après).
On défini aussi un "acces" qui est limité aux personnes ayant les droit d'administration du site, parce que ça serait bête que tous le monde puissent jouer avec l'ouverture ou la fermeture des commentaire de votre site, non ? ^_^
Le "type", ici MENU_CALLBACK indique que la page ne doit pas être lister parmis les liens des menus. (ceci mériterais d'être plus étoffé, je le sais, mais ce n'est pas le but ici)
Donc, on parlais de la fonction "fermeture_commentaire()", voyons a quoi elle ressemble :
* Contenu de la page consécutive au clic sur le lien
* On chope le formulaire construit avant aussi
*/
function fermeture_commentaire() {
$output .= drupal_get_form('fermeture_commentaire_form');
return $output;
}
Pas grand chose en fait, elle ne fait qu'appeler, et intégrer le résultat de la fonction "fermeture_commentaire_form()"
$query = db_query("SELECT {comment} FROM {node} WHERE {nid} = %d", arg(1));
$nid = db_fetch_object($query);
$form['fermeture_commentaire'] = array(
'#type' => 'select',
'#title' => 'Champs bdd sur',
'#options' => range(0, 2),
'#default_value' => $nid->comment,
'#description' => t('0 = Les commentaires ne sont pas affichés <br />1 = Commentaires fermés <br />2 = Everything is open !'),
);
/**
* system_settings_form() rajoute les boutons de validation/annulation sur un formulaire
*/
return system_settings_form($form);
}
On commence par une jolie requête SQL afin de récupérer la valeur courante du champ "comment" de la table "node". A noter l'utilisation de placeholders pour passer les variables dans la requête. Ceux qui ont déjà fait du C ne seront pas dépaysés. C'est pareil. Un %d indique une variable, qui est passé a la fin, en argument. (le but de cette manipulation est d'éviter les injections SQL)
Le formulaire est ensuite construit en utilisant l'api form de Drupal. Cette partie mériterais a elle seule des dizaines de page d'explication, c'est pourquoi je ne rentrerais pas dans les détails ici. (je pense que pour ce qui est présenté ici, une lecture simple suffit a comprendre)
On a notre formulaire (joie !), mais ... une fois validé, on arrivé où ? Comment on exécute des choses a la validation d'un formulaire ?
Simple ! on reprend le nom de notre fonction qui génère le formulaire, et on lui rajoute un _submit dans le nom. Ce qui donne donc fermeture_commentaire_form_submit($form, $form_values)
* suite de la fonction juste au dessus. Soumission du formulaire
* Traitement des données
*/
function fermeture_commentaire_form_submit($form_id, $form_values) {
db_query("UPDATE {node}
SET comment = %d WHERE {nid} = %d", $form_values['fermeture_commentaire'], arg(1));
drupal_set_message('Parametre mis a jour. <br />La nouvelle valeur est : '.$form_values['fermeture_commentaire'], status);
}
Une simple requête SQL pour mettre a jour le champs "comment" de la base de données. On remarque aussi que les nom des champs sont entre {}, ceci car Drupal gère les préfix sur les nom des tables. Le fait de mettre les champs entre {} permet de ne pas avoir a se soucier des préfix, Drupal se charge de les rajouter tout seul.
Les valeurs du formulaire précèdent sont récupère via les variable $form_values['nom_du_form']
A partir de là, on a déjà quelque chose de sympa. Il manque quand même une petite interface d'administration qui nous permettrait, par exemple, de changer l'intitulé du liens sur laquelle on clic pour accéder a la page de gestion d'ouverture ou de fermeture des commentaires.
Pour cela, il faut "déclarer" la nouvelle page, dans l'administration. On reprend donc notre hook_menu (closecomment_menu pour nous) pour y rajouter des petites choses sympathique dedans.
function closecomment_menu($may_cache) {
$items[] = array(
'path' => 'admin/settings/closecomment',
'title' => t('Close Comment'),
'description' => t('Fermeture des commentaire.'),
'callback' => 'drupal_get_form',
'callback arguments' => 'closecomment_settings',
'access' => user_access('administer site configuration'),
);
// la page de gestion d'etat des commentaires pour un sujet donné
$items[] = array(
'path' => 'closecomment',
'title' => t('On Ferme'),
'callback' => 'fermeture_commentaire',
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK
);
return $items;
}
On voit donc qu'on rajoute une page /admin/settings/closecomment/, qui appelle la fonction callback "drupal_get_form". Drupal_get_form n'est pas une fonction comme on a pu les voir avant, c'est une fonction qui appelle juste un formulaire en fait. Mais on voir qu'on a également un "callback argument" qui nous permet de passer en meme temps un argument a "callback" (donc a "drupal_get_form"), qui sera dans notre cas le formulaire "closecomment_settings"
*
* On defini un formulaire qui permet de spécifier la chaine de caractere
* qui sera affichée dans les $links
* Cette chaine est stocké dans la table "variable" de la bdd
*
*/
function closecomment_settings() {
$form['closecomment_admin'] = array(
'#type' => 'textfield',
'#title' => 'Texte',
'#size' => 40,
'#maxlenght' => 40,
'#default_value' => variable_get('closecomment_text', 'on ferme !'),
);
return system_settings_form($form);
}
/**
* Enregistrement dans la base de données de la chaine de caractere defini juste au dessus
*/
function closecomment_settings_submit($form_id, $form_values) {
variable_set('closecomment_text', $form_values['closecomment_admin']);
}
Si vous avez compris tout jusqu'ici, j'ai normalement même pas besoin d'expliquer ce qui est réalisé ici, c'est assez trivial.
On peut juste s'attarder sur les fonctions "variable_set()" et "variable_get()". Ces deux fonctions permettent de sauvegarder, et de retrouver, des variables qui seront enregistré dans la base de données de Drupal. On y enregistre donc, dans notre cas, la valeur de la chaîne de caractère qui est affiché pour le lien pour gérer les commentaires.
je mets ici le contenu complet du module, avec quelques changements mineurs dedans, a vous de les trouver :D
/* $Id: closecomment.info,v 1.0 2008/01/28 14:00:00 nmeyer Exp $ */
/**
* closecomment.module
*/
// la page d'admin
function closecomment_menu($may_cache) {
$items[] = array(
'path' => 'admin/settings/closecomment',
'title' => t('Close Comment'),
'description' => t('Fermeture des commentaire.'),
'callback' => 'drupal_get_form',
'callback arguments' => 'closecomment_settings',
'access' => user_access('administer site configuration'),
);
// la page de gestion d'etat des commentaires pour un sujet donné
$items[] = array(
'path' => 'closecomment',
'title' => t('On Ferme'),
'callback' => 'fermeture_commentaire',
'access' => user_access('administer site configuration'),
'type' => MENU_CALLBACK
);
return $items;
}
/**
*
* On defini un formulaire qui permet de spécifier la chaine de caractere
* qui sera affichée dans les $links
* Cette chaine est stocké dans la table "variable" de la bdd
*
*/
function closecomment_settings() {
$form['closecomment_admin'] = array(
'#type' => 'textfield',
'#title' => 'Texte',
'#size' => 40,
'#maxlenght' => 40,
'#default_value' => variable_get('closecomment_text', 'on ferme !'),
);
return system_settings_form($form);
}
/**
* Enregistrement dans la base de données de la chaine de caractere defini juste au dessus
*/
function closecomment_settings_submit($form_id, $form_values) {
variable_set('closecomment_text', $form_values['closecomment_admin']);
}
/**
* Implementation of hook_link().
*
* Permet de rajouter un lien dans la variable $links
*/
function closecomment_link($type, $node) {
if ($type != 'comment' && user_access('administer site configuration')) {
$links = array();
$links[] = array('href' => 'closecomment/'.$node->nid,
'title' => variable_get('closecomment_text', 'on ferme !'),
'html' => $format['html'],
'access' => user_access('administer site configuration'),
);
return $links;
}
}
/**
* On construit le formulaire qui permet d'ouvrir ou non les commentaires
* 0 = les commentaires ne sont plus affichés
* 1 = Les commentaires restent affichés mais il n'est plus possible d'en rajouter
* 2 = Commentaires affichés et ouvert aux nouvelles soumissions
*
* TODO : changer le nom de la variable $minidou ^^
* TODO : changer les textes
*/
function fermeture_commentaire_form() {
$minidou = db_query("SELECT {comment} FROM {node} WHERE {nid} = %d", arg(1));
$nid = db_fetch_object($minidou);
$form['fermeture_commentaire'] = array(
'#type' => 'select',
'#title' => 'Champs bdd sur',
'#options' => range(0, 2),
'#default_value' => $nid->comment,
'#description' => t('0 = Les commentaires ne sont pas affichés <br />1 = Commentaires fermés <br />2 = Everything is open !'),
);
/**
* system_settings_form() rajoute les boutons de validation/annulation sur un formulaire
*/
return system_settings_form($form);
}
/**
* suite de la fonction juste au dessus. Soumission du formulaire
* Traitement des données
*/
function fermeture_commentaire_form_submit($form_id, $form_values) {
db_query("UPDATE {node}
SET comment = %d WHERE {nid} = %d", $form_values['fermeture_commentaire'], arg(1));
drupal_set_message('Parametre mis a jour. <br />La nouvelle valeur est : '.$form_values['fermeture_commentaire'], status);
}
/**
* Contenu de la page consécutive au clic sur le lien
* On chope le formulaire construit avant aussi
*/
function fermeture_commentaire() {
$output .= drupal_get_form('fermeture_commentaire_form');
return $output;
}
Poster un nouveau commentaire