[Devel] r331 - trunk

svn at agendadulibre.org svn at agendadulibre.org
Jeu 8 Mai 19:25:17 CEST 2008


Author: thomas
Date: Thu May  8 19:23:57 2008
New Revision: 331

Log:
Nouvelle interface de modération, plus pratique.

 * calendar.css:

  - Nouvelles classes CSS utilisées dans l'interface de modération

 * rejectevent.php, validateevent.php, editevent.php:

  - Nouveaux scripts traitant respectivement le rejet, la validation
    et l'édition d'un évènement. Par rapport à l'ancienne interface,
    de nouvelles fonctionnalités sont disponibles. Tout d'abord, lors
    du refus, on peut préciser une raison personnalisée, en plus des
    raisons prédéfinies. Dans l'interface d'édition, on peut
    prévisualiser l'évènement avant de valider sa sauvegarde.

 * bd-private.inc.php.template, bd.inc.php:

   - Renommage des variables host, user, pass et bdd and db_host,
     db_user, db_pass et db_bdd, pour ne pas entrer en conflit avec le
     nom d'autres variables.

 * user.inc.php:

   - Nouvelle classe s'occupant de l'authentification d'un utilisateur
     et de l'affichage d'une boîte de login le cas échéant.

 * moderate.php:

   - Suppression de l'ancienne interface de modération.

 * moderation.php:

   - Point d'entrée de l'interface de modération. Ne fait que lister
     les évènements, et pointer vers les scripts d'édition, de
     validation et de rejet.

 * funcs.inc.php:

   - Nouvelles fonctions *_mysql2humanreadable().

   - Ajout d'un paramètre global debugaddress qui peut être positionné
     lors du développement pour éviter l'envoi de mails aux
     soumetteurs d'évènements.



Added:
   trunk/editevent.php
   trunk/moderation.php
   trunk/rejectevent.php
   trunk/user.inc.php
   trunk/validateevent.php
Removed:
   trunk/moderate.php
Modified:
   trunk/bd-private.inc.php.template
   trunk/bd.inc.php
   trunk/calendar.css
   trunk/funcs.inc.php

Modified: trunk/bd-private.inc.php.template
==============================================================================
--- trunk/bd-private.inc.php.template	(original)
+++ trunk/bd-private.inc.php.template	Thu May  8 19:23:57 2008
@@ -7,16 +7,16 @@
  */
 
 /** Where the database is hosted */
-$host = "host";
+$db_host = "host";
 
 /** Username needed to connect to the database */
-$user = "user";
+$db_user = "user";
 
 /** Password needed to connect to the database */
-$pass = "password";
+$db_pass = "password";
 
 /** Database name */
-$bdd  = "bdd";
+$db_bdd  = "bdd";
 
 /** Root URL of the libre agenda, without leading slash */
 $root = "http://dummy.url.org";
@@ -24,4 +24,9 @@
 /** Mailing-list of moderators */
 $moderatorlist = "moderators at your.domain.org";
 
+/** Debug address. When not empty, all the e-mails are sent to this
+    address, instead of the event submitter addresses. Useful during
+    development. */
+$debugaddress = "";
+
 ?>

Modified: trunk/bd.inc.php
==============================================================================
--- trunk/bd.inc.php	(original)
+++ trunk/bd.inc.php	Thu May  8 19:23:57 2008
@@ -33,18 +33,18 @@
 {
   function db()
   {
-    global $host;
-    global $user;
-    global $pass;
-    global $bdd;
+    global $db_host;
+    global $db_user;
+    global $db_pass;
+    global $db_name;
 
-    if(mysql_connect($host,$user,$pass)==FALSE)
+    if(mysql_connect($db_host,$db_user,$db_pass)==FALSE)
       {
 	echo "Probleme de connexion à la base de données sur $host.\n";
 	return 0;
       }
 
-    if(mysql_select_db($bdd) == FALSE)
+    if(mysql_select_db($db_name) == FALSE)
       {
 	echo "Probleme de selection de la base de données $bdd sur $host.\n";
 	return 0;

Modified: trunk/calendar.css
==============================================================================
--- trunk/calendar.css	(original)
+++ trunk/calendar.css	Thu May  8 19:23:57 2008
@@ -432,3 +432,17 @@
 #advises a:hover {
 	color : #543a1f;
 }
+
+/* Moderation interface specific definitions */
+p.moderationheader {
+           background: #cccccc;
+           margin-left: 5em;
+           margin-right: 5em;
+}
+
+div.moderationbox {
+          background: #cccccc;
+          width: 70%;
+          padding: 1em;
+          margin: auto;
+}
\ No newline at end of file

Added: trunk/editevent.php
==============================================================================
--- (empty file)
+++ trunk/editevent.php	Thu May  8 19:23:57 2008
@@ -0,0 +1,194 @@
+<?php
+
+/* Copyright 2008
+ * - Thomas Petazzoni <thomas POINT petazzoni CHEZ enix POINT org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+include("bd.inc.php");
+include("funcs.inc.php");
+include("session.inc.php");
+include("user.inc.php");
+include("diff.inc.php");
+
+function save_event ($db, $user, $id, $title, $start, $end, $description, $city,
+		     $region, $locality, $url, $contact, $submitter, $tags)
+{
+  global $moderatorlist;
+
+  $sql = "SELECT * FROM events WHERE id=" . $db->quote_smart($id);
+  $ret = $db->query($sql);
+  if ($ret == FALSE)
+    {
+      error ("La requête <i>" . $sql . "</i> a échoué");
+      return -1;
+    }
+
+  $oldevent = mysql_fetch_object ($ret);
+
+  $sql = "UPDATE events SET " .
+    "title=" .       $db->quote_smart ($title)                        . ", " .
+    "start_time=" .  $db->quote_smart (date_timestamp2mysql ($start)) . ", ".
+    "end_time=" .    $db->quote_smart (date_timestamp2mysql ($end))   . ", ".
+    "description=" . $db->quote_smart ($description)                  . ", ".
+    "city=" .        $db->quote_smart ($city)                         . ", ".
+    "region=" .      $db->quote_smart ($region)                       . ", ".
+    "locality=" .    $db->quote_smart ($locality)                     . ", ".
+    "url=" .         $db->quote_smart ($url)                          . ", ".
+    "contact=" .     $db->quote_smart ($contact)                      . ", ".
+    "submitter=" .   $db->quote_smart ($submitter)                    . ", ".
+    "tags=" .        $db->quote_smart ($tags)                         . "  ".
+    "where id=" .    $db->quote_smart ($id);
+
+  $ret = $db->query ($sql);
+
+  if ($ret == FALSE)
+    {
+      error ("La requête <i>" . $sql . "</i> a échoué");
+      return -1;
+    }
+
+  $oldevent_str =
+    format_ascii_event ($db, $oldevent->title, date_mysql2timestamp($oldevent->start_time),
+			date_mysql2timestamp($oldevent->end_time),
+			$oldevent->description, $oldevent->city, $oldevent->region, $oldevent->locality,
+			$oldevent->url, $oldevent->contact, $oldevent->submitter, $oldevent->tags);
+  $newevent_str =
+    format_ascii_event ($db, $title, $start, $end,
+			$description, $city, $region, $locality,
+			$url, $contact, $submitter, $tags);
+
+  $diff = arr_diff (split ("\n", $oldevent_str), split ("\n", $newevent_str), 1);
+
+  calendar_mail ($moderatorlist, "",
+		 "Édition de l'évènement '" . $title . "'",
+		 "Bonjour,\n\n" .
+		 "L'évènement '" . stripslashes($title) . "' a été modifié par " . $user->get_login() . ".\n".
+		 "Modifications apportées:\n\n" .
+		 $diff . "\n\n".
+		 "Bonne journée\n\n".
+		 "-- L'équipe de modération");
+
+  return 0;
+}
+
+$db = new db();
+$user = new user($db);
+
+$id = get_safe_integer('id', 0);
+
+if ($_POST['__event_save'])
+{
+  $ret = save_event ($db, $user, $id,
+		     $_POST['__event_title'],
+		     mktime($_POST['__event_start_hour'],
+			    $_POST['__event_start_minute'],
+			    0,
+			    $_POST['__event_start_month'],
+			    $_POST['__event_start_day'],
+			    $_POST['__event_start_year']),
+		     mktime($_POST['__event_end_hour'],
+			    $_POST['__event_end_minute'],
+			    0,
+			    $_POST['__event_end_month'],
+			    $_POST['__event_end_day'],
+			    $_POST['__event_end_year']),
+		     $_POST['__event_description'],
+		     $_POST['__event_city'],
+		     $_POST['__event_region'],
+		     $_POST['__event_locality'],
+		     $_POST['__event_url'],
+		     $_POST['__event_contact'],
+		     $_POST['__event_submitter'],
+		     $_POST['__event_tags']);
+  header("Location: moderation.php");
+}
+
+put_header("Édition d'un évènement");
+
+$event = fetch_event($db, $id);
+if (! $event)
+{
+  echo "<p>Pas d'évènement avec cet ID</p>";
+  put_footer();
+  exit;
+}
+
+if ($_POST['__event_preview'])
+{
+  $title       = $_POST['__event_title'];
+  $start       = mktime($_POST['__event_start_hour'],
+			$_POST['__event_start_minute'],
+			0,
+			$_POST['__event_start_month'],
+			$_POST['__event_start_day'],
+			$_POST['__event_start_year']);
+  $end         = mktime($_POST['__event_end_hour'],
+			$_POST['__event_end_minute'],
+			0,
+			$_POST['__event_end_month'],
+			$_POST['__event_end_day'],
+			$_POST['__event_end_year']);
+  $description = $_POST['__event_description'];
+  $city        = $_POST['__event_city'];
+  $region      = $_POST['__event_region'];
+  $locality    = $_POST['__event_locality'];
+  $url         = $_POST['__event_url'];
+  $contact     = $_POST['__event_contact'];
+  $submitter   = $_POST['__event_submitter'];
+  $tags        = $_POST['__event_tags'];
+}
+else
+{
+  $title       = $event->title;
+  $start       = strtotime($event->start_time);
+  $end         = strtotime($event->end_time);
+  $description = $event->description;
+  $city        = $event->city;
+  $region      = $event->region;
+  $locality    = $event->locality;
+  $url         = $event->url;
+  $contact     = $event->contact;
+  $submitter   = $event->submitter;
+  $tags        = $event->tags;
+}
+
+echo '<p class="moderationheader">';
+echo "<a href=\"moderation.php\">Modération</a>&nbsp;&gt;&gt;&gt&nbsp;Prévisualisation de l'évènement";
+echo "</p>";
+
+echo '<div class="moderationbox">';
+echo format_event ($db, $title, $start, $end, $description, $city,
+		   $region, $locality, $url, $contact, $submitter,
+		   $tags);
+echo '</div>';
+
+echo '<p class="moderationheader">';
+echo "<a href=\"moderation.php\">Modération</a>&nbsp;&gt;&gt;&gt&nbsp;Édition de l'évènement";
+echo "</p>";
+
+echo '<div class="moderationbox">';
+echo "<form action=\"?id=".$id."\" method=\"post\">\n";
+edit_event ($db, $title, $start, $end, $description, $city,
+	    $region, $locality, $url, $contact, $submitter,
+	    $tags, TRUE);
+echo "</form>\n";
+echo '</div>';
+
+put_footer();
+
+?>

Modified: trunk/funcs.inc.php
==============================================================================
--- trunk/funcs.inc.php	(original)
+++ trunk/funcs.inc.php	Thu May  8 19:23:57 2008
@@ -20,6 +20,8 @@
  * 02111-1307, USA.
  */
 
+require_once("bd-private.inc.php");
+
 /*
  * Compute an absolute URL for the website
  *
@@ -106,7 +108,7 @@
 ?>
 </div>
 <div class="footer">
-<p><a href="submit.php">Proposer un évènement</a> - <a href="rsslist.php">Flux RSS</a> - <a href="icallist.php">Calendriers iCal</a> - <a href="map.php">Carte</a> - <a href="tags.php">Tags</a> - <a href="infos.php">Informations</a> - <a href="stats.php">Statistiques</a> - <a href="mailto:moderateurs CHEZ agendadulibre POINT org">Contact</a></p>
+<p><a href="submit.php">Proposer un évènement</a> - <a href="rsslist.php">Flux RSS</a> - <a href="icallist.php">Calendriers iCal</a> - <a href="map.php">Carte</a> - <a href="tags.php">Tags</a> - <a href="infos.php">Informations</a> - <a href="stats.php">Statistiques</a> - <a href="mailto:moderateurs CHEZ agendadulibre POINT org">Contact</a> - <a href="moderation.php">Modération</a></p>
 </div>
 </body>
 </html>
@@ -137,7 +139,7 @@
 
 function date_mysql2humanreadable ($mysql_date)
 {
-  return strftime ("<b>%A %d %B %Y</b> %Hh%M", date_mysql2timestamp($mysql_date));
+  return strftime ("%A %d %B %Y %Hh%M", date_mysql2timestamp($mysql_date));
 }
 
 function date_timestamp2humanreadable($timestamp)
@@ -155,16 +157,31 @@
   return strftime ("%Hh%M", $timestamp);
 }
 
+function onlyday_mysql2humanreadable($mysqldate)
+{
+  return strftime ("%A %d %B %Y", date_mysql2timestamp($mysqldate));
+}
+
+function onlyhour_mysql2humanreadable($mysqldate)
+{
+  return strftime ("%Hh%M", date_mysql2timestamp($mysqldate));
+}
+
 function date_month2string($month)
 {
   return strftime("%B", mktime(0,0,0,$month,1));
 }
 
-function calendar_mail ($recv, $cc, $title, $contents)
+function calendar_mail ($to, $cc, $title, $contents)
 {
+  global $debugaddress;
+
   $title = '=?iso8859-1?B?'.base64_encode("[Agenda du Libre] " . $title).'?=';
 
-  return mail($recv, $title, $contents,
+  if (isset($debugaddress) && $debugaddress != "")
+    $to = $debugaddress;
+
+  return mail($to, $title, $contents,
 	      /* Message headers */
 	      "From: moderateurs at agendadulibre.org\n" .
 	      "Reply-To: moderateurs at agendadulibre.org\n" .

Added: trunk/moderation.php
==============================================================================
--- (empty file)
+++ trunk/moderation.php	Thu May  8 19:23:57 2008
@@ -0,0 +1,90 @@
+<?php
+
+/* Copyright 2008
+ * - Thomas Petazzoni <thomas POINT petazzoni CHEZ enix POINT org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+include("bd.inc.php");
+include("funcs.inc.php");
+include("session.inc.php");
+include("user.inc.php");
+
+$db = new db();
+$user = new user($db);
+
+put_header("Modération");
+
+echo "<h2>Évènements à modérer</h2>\n";
+
+$ret = $db->query ("select id, title, start_time, end_time, city, region from events where moderated=0 order by start_time");
+
+if ($ret == FALSE)
+{
+  echo "<p class=\"error\">Requête SQL invalide</p>";
+  put_footer();
+  exit;
+}
+
+echo "<table style=\"text-align: center; width: 100%\" class=\"stats\">\n";
+
+echo "<tr>\n";
+echo "<td><b>Titre</b></td>\n";
+echo "<td><b>Date</b></td>\n";
+echo "<td><b>Ville</b></td>\n";
+echo "<td><b>Région</b></td>\n";
+echo "<td><b>Actions</b></td>\n";
+echo "</tr>";
+
+$i = 0;
+while ($row = mysql_fetch_object($ret))
+{
+  if ($i % 2)
+    $class = "odd";
+  else
+    $class = "even";
+
+  $start_day = onlyday_mysql2humanreadable($row->start_time);
+  if ($start_day == onlyday_mysql2humanreadable($row->end_time)) {
+    $date = "Le " .  $start_day . ", de "
+      . onlyhour_mysql2humanreadable($row->start_time) . " à "
+      . onlyhour_mysql2humanreadable($row->end_time);
+  } else {
+    $date = "Du " . date_mysql2humanreadable($row->start_time)
+      . " au " . date_mysql2humanreadable($row->end_time);
+  }
+
+  echo "<tr class=\"" . $class . "\">\n";
+  echo "<td  style=\"padding-top: 0.5em; padding-bottom: 0.5em\">" . stripslashes($row->title) . "</td>\n";
+  echo "<td>" . $date . "</td>\n";
+  echo "<td>" . stripslashes($row->city) . "</td>\n";
+  echo "<td>" . stripslashes(region_find($db, $row->region)) . "</td>\n";
+  echo "<td>";
+  echo "<a href=\"editevent.php?id=" . $row->id . "\">Éditer</a>&nbsp;-&nbsp;";
+  echo "<a href=\"validateevent.php?id=" . $row->id . "\">Valider</a>&nbsp;-&nbsp;";
+  echo "<a href=\"rejectevent.php?id=" . $row->id . "\">Refuser</a>";
+  echo "</td>\n";
+  echo "</tr>\n";
+
+  $i = $i + 1;
+}
+
+echo "</table>\n";
+
+put_footer();
+
+?>
\ No newline at end of file

Added: trunk/rejectevent.php
==============================================================================
--- (empty file)
+++ trunk/rejectevent.php	Thu May  8 19:23:57 2008
@@ -0,0 +1,135 @@
+<?php
+
+/* Copyright 2008
+ * - Thomas Petazzoni <thomas POINT petazzoni CHEZ enix POINT org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+include("bd.inc.php");
+include("funcs.inc.php");
+include("session.inc.php");
+include("user.inc.php");
+
+$db = new db();
+$user = new user($db);
+
+if ($_POST['__event_rejection_cancel'])
+{
+  header("Location: moderation.php");
+  exit;
+}
+else if ($_POST['__event_rejection_confirm'])
+{
+  $id = get_safe_integer('id', 0);
+
+  if ($_POST['reason'] == "out-of-subject")
+    $reason = wordwrap("Toutefois, l'évènement proposé n'a pour l'instant pas retenu l'attention des modérateurs. En effet, l'évènement proposé ne concerne pas le Logiciel Libre, ou bien le lien avec le Logiciel Libre n'est pas évident dans la formulation actuelle, ou alors il s'agit d'un évènement ou d'une formation payante et coûteuse. Si l'évènement concerne vraiment le Logiciel Libre et qu'il ne s'agit pas d'une formation payante, n'hésitez pas à le soumettre à nouveau avec une description plus claire.");
+  else if ($_POST['reason'] == "not-enough-infos")
+    $reason = wordwrap("Votre évènement a tout à fait sa place dans l'Agenda du Libre, mais les modérateurs trouvent que la description de celui-ci n'est pas assez complète pour être validée.\n\nLa description doit être compréhensible par un nouveau venu dans le monde du Libre, et doit donc préciser le principe de la rencontre, le public visé, la rôle du ou des Logiciels Libres qui seront exposés, la date et le lieu précis de la rencontre. Même si il s'agit d'une rencontre régulière, n'hésitez pas à répéter à chaque fois ces informations, elles sont importantes.\n\nNous vous invitons donc vivement à soumettre à nouveau cet évènement avec une description plus complète.");
+  else if ($_POST['reason'] == "duplicate")
+    $reason = wordwrap("Votre évènement a tout à fait sa place dans l'Agenda du Libre, mais il est déjà enregistré dans celui-ci.");
+  else if ($_POST['reason'] == "custom")
+    $reason = wordwrap("Toutefois, votre évènement n'a pour le moment pas retenu l'attention des modérateurs, pour la raison suivante: " . stripslashes($_POST['customtext']));
+
+  $sql = "select * from events where id=" . $db->quote_smart($id);
+  $ret = $db->query ($sql);
+  if ($ret == FALSE)
+    {
+      error ("La requête <i>" . $sql . "</i> a échoué");
+      return -1;
+    }
+
+  $row = mysql_fetch_object($ret);
+
+  $sql = "delete from events where id=" . $db->quote_smart($id);
+
+  $ret = $db->query ($sql);
+  if ($ret == FALSE)
+    {
+      error ("La requête <i>" . $sql . "</i> a échoué");
+      return -1;
+    }
+
+  /* Send email */
+  calendar_mail ($row->submitter, $moderatorlist, "Évènement '" . $row->title . "' refusé",
+		 "Bonjour,\n\n" .
+		 "Vous avez soumis l'évènement suivant dans l'Agenda du Libre, et nous\n" .
+		 "vous remercions de cette contribution.\n\n" .
+		 $reason .
+		 "\n\nPour rappel, voici le contenu de votre évènement:\n" .
+		 "=====================================================\n" .
+		 format_ascii_event ($db, $row->title, date_mysql2timestamp($row->start_time),
+				     date_mysql2timestamp($row->end_time),
+				     $row->description, $row->city, $row->region, $row->locality,
+				     $row->url, $row->contact, $row->submitter, $row->tags) . "\n" .
+		 "=====================================================\n\n" .
+		 "Merci de votre contribution !\n\n" .
+		 "-- \nL'équipe de modération");
+
+  header("Location: moderation.php");
+  exit;
+}
+
+$id = get_safe_integer('id', 0);
+
+put_header("Rejet d'un évènement");
+
+$event = fetch_event($db, $id);
+if (! $event)
+{
+  echo "<p>Pas d'évènement avec cet ID</p>";
+  put_footer();
+  exit;
+}
+
+if ($event->moderated)
+{
+  echo "<p>Évènement déjà modéré</p>";
+  put_footer();
+  exit;
+}
+
+echo '<p class="moderationheader">';
+echo "<a href=\"moderation.php\">Modération</a>&nbsp;&gt;&gt;&gt&nbsp;Rejet de l'évènement";
+echo "</p>";
+
+echo '<div class="moderationbox">';
+echo '<form action="rejectevent.php?id=' . $id . '" method="post">';
+echo '<p style="text-align: center;">Quel motif souhaitez-vous associer au rejet de cet évènement&nbsp;?</p>';
+echo '<p>';
+echo '<input type="radio" name="reason" value="out-of-subject" onClick="document.getElementById(\'customtext\').style.display = \'none\';">Hors sujet</input><br/>';
+echo '<input type="radio" name="reason" value="not-enough-infos" onClick="document.getElementById(\'customtext\').style.display = \'none\';">Pas assez d\'informations</input><br/>';
+echo '<input type="radio" name="reason" value="duplicate" onClick="document.getElementById(\'customtext\').style.display = \'none\';">Évènement déjà enregistré</input><br/>';
+echo '<input type="radio" name="reason" value="custom" onClick="document.getElementById(\'customtext\').style.display = \'block\';">Raison spécifique (précisez)</input><br/>';
+echo '<textarea id="customtext" style="display: none;" cols="80" rows="10" name="customtext"></textarea>';
+echo '</p>';
+echo '<input name="__event_rejection_confirm" type="submit" value="Rejeter"/>&nbsp;';
+echo '<input name="__event_rejection_cancel" type="submit" value="Annuler"/>';
+echo '</form>';
+echo '</div>';
+
+echo '<div class="moderationbox">';
+echo format_event ($db, $event->title, strtotime($event->start_time),
+		   strtotime($event->end_time), $event->description,
+		   $event->city, $event->region, $event->locality,
+		   $event->url, $event->contact, $event->submitter,
+		   $event->tags);
+echo '</div>';
+
+put_footer();
+
+?>
\ No newline at end of file

Added: trunk/user.inc.php
==============================================================================
--- (empty file)
+++ trunk/user.inc.php	Thu May  8 19:23:57 2008
@@ -0,0 +1,96 @@
+<?php
+
+class user
+{
+  var $session;
+  var $db;
+
+  /*
+   * Returns a positive ID if user identified, -1 otherwise
+   */
+  function identify ($login, $password)
+  {
+    $sql =
+      "SELECT id FROM users WHERE login=" . $this->db->quote_smart($login) .
+      " AND password=" . $this->db->quote_smart(md5($password));
+    $ret = $this->db->query ($sql);
+    if ($ret == FALSE)
+      {
+	error ("Erreur lors de la requête <i>" . $sql . "</i>");
+	return -1;
+      }
+
+    if (mysql_num_rows ($ret) != 1)
+      {
+	return -1;
+      }
+
+    $row = mysql_fetch_object($ret);
+
+    return $row->id;
+  }
+
+  function get()
+  {
+    return $this->session->value("agenda_libre_id");
+  }
+
+  function get_login()
+  {
+    $sql = "select login from users where id=" . $this->db->quote_smart($this->session->value("agenda_libre_id"));
+    $ret = $this->db->query($sql);
+    if ($ret == FALSE)
+      {
+	error("Erreur lors de la requête <i>" . $sql . "</i>");
+	return -1;
+      }
+
+    if (mysql_num_rows($ret) != 1)
+      return -1;
+
+    $row = mysql_fetch_object($ret);
+    return $row->login;
+  }
+
+  function user($db)
+  {
+    $this->session = new session();
+    $this->db = $db;
+
+    if (! $this->session->exists("agenda_libre_id"))
+      {
+	if (! $_POST['__user_identify'])
+	  {
+	    put_header("Modération");
+
+	    echo "<h2>Identification</h2>";
+	    echo "<table align=\"center\">";
+	    echo "<form method=\"post\">\n";
+	    echo "<tr><td>Login:</td><td><input type=\"text\" name=\"__user_login\" size=\"20\"/></td></tr>";
+	    echo "<tr><td>Mot de passe:</td><td><input type=\"password\" name=\"__user_password\" size=\"20\"/></td></tr>";
+	    echo "<tr><td></td><td><input type=\"submit\" name=\"__user_identify\" value=\"Identifier\"></td></tr>";
+	    echo "</form>";
+	    echo "</table>";
+
+	    put_footer();
+	    exit;
+	  }
+	else
+	  {
+	    if (($ret = $this->identify ($_POST['__user_login'], $_POST['__user_password'])) > 0)
+	      {
+		$this->session->set("agenda_libre_id", $ret);
+	      }
+	    else
+	      {
+		put_header("Modération");
+		echo "Mauvais login/pass";
+		put_footer();
+		exit;
+	      }
+	  }
+      }
+  }
+}
+
+?>
\ No newline at end of file

Added: trunk/validateevent.php
==============================================================================
--- (empty file)
+++ trunk/validateevent.php	Thu May  8 19:23:57 2008
@@ -0,0 +1,125 @@
+<?php
+
+/* Copyright 2008
+ * - Thomas Petazzoni <thomas POINT petazzoni CHEZ enix POINT org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+include("bd.inc.php");
+include("funcs.inc.php");
+include("session.inc.php");
+include("user.inc.php");
+
+$db = new db();
+$user = new user($db);
+
+if ($_POST['__event_validation_cancel'])
+{
+  header("Location: moderation.php");
+  exit;
+}
+else if ($_POST['__event_validation_confirm'])
+{
+  $id = get_safe_integer('id', 0);
+
+  /* Fetch contact email, in order to be able to send a confirmation
+     mail */
+  $sql = "select * from events where id=" . $db->quote_smart($id);
+  $ret = $db->query ($sql);
+  if ($ret == FALSE)
+    {
+      error ("La requête <i>" . $sql . "</i> a échoué");
+      exit;
+    }
+
+  $row = mysql_fetch_object($ret);
+  $email = $row->contact;
+  $title = $row->title;
+  $link = calendar_absolute_url("showevent.php?id=".$id);
+
+  /* Accept event */
+  $sql = "update events set moderated=1 where id=" . $db->quote_smart($id);
+  $ret = $db->query ($sql);
+  if ($ret == FALSE)
+    {
+      error ("La requête <i>" . $sql . "</i> a échoué");
+      exit;
+    }
+
+  /* Send email */
+  calendar_mail ($row->submitter, $moderatorlist,
+		 "Évènement '" . $row->title . "' modéré",
+		 "Bonjour,\n\n" .
+		 "L'évènement que vous avez soumis a été modéré par " . $user->get_login() .
+		 ".\nIl est maintenant visible dans l'Agenda à l'adresse\n" . $link . "\n\n" .
+		 "Si vous souhaitez modifier cet évènement ultérieurement, merci de contacter\n" .
+		 "l'équipe de modération à l'adresse moderateurs at agendadulibre.org\n\n" .
+		 "=====================================================\n" .
+		 format_ascii_event ($db, $row->title, date_mysql2timestamp($row->start_time),
+				     date_mysql2timestamp($row->end_time),
+				     $row->description, $row->city, $row->region, $row->locality,
+				     $row->url, $row->contact, $row->submitter, $row->tags) . "\n" .
+		 "=====================================================\n\n" .
+		 "Merci de votre contribution à l'Agenda du Libre et à bientôt !\n\n".
+		 "-- \nL'équipe de modération");
+
+  header("Location: moderation.php");
+  exit;
+}
+
+$id = get_safe_integer('id', 0);
+
+put_header("Validation d'un évènement");
+
+$event = fetch_event($db, $id);
+if (! $event)
+{
+  echo "<p>Pas d'évènement avec cet ID</p>";
+  put_footer();
+  exit;
+}
+
+if ($event->moderated)
+{
+  echo "<p>Évènement déjà modéré</p>";
+  put_footer();
+  exit;
+}
+
+echo '<p class="moderationheader">';
+echo "<a href=\"moderation.php\">Modération</a>&nbsp;&gt;&gt;&gt&nbsp;Validation de l'évènement";
+echo "</p>";
+
+echo '<div class="moderationbox">';
+echo '<form action="validateevent.php?id=' . $id . '" method="post">';
+echo '<p style="text-align: center;">Confirmez-vous la validation de cet évènement&nbsp;?</p>';
+echo '<input name="__event_validation_confirm" type="submit" value="Oui"/>&nbsp;';
+echo '<input name="__event_validation_cancel" type="submit" value="Non"/>';
+echo '</form>';
+echo '</div>';
+
+echo '<div class="moderationbox">';
+echo format_event ($db, $event->title, strtotime($event->start_time),
+		   strtotime($event->end_time), $event->description,
+		   $event->city, $event->region, $event->locality,
+		   $event->url, $event->contact, $event->submitter,
+		   $event->tags);
+echo '</div>';
+
+put_footer();
+
+?>
\ No newline at end of file


Plus d'informations sur la liste de diffusion Devel