]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Added contrib/web/php-moderation (Thomas Goirand)
authormortenp <none@none>
Wed, 4 Mar 2009 20:08:29 +0000 (07:08 +1100)
committermortenp <none@none>
Wed, 4 Mar 2009 20:08:29 +0000 (07:08 +1100)
ChangeLog
contrib/web/php-moderation/build-translations.sh [new file with mode: 0755]
contrib/web/php-moderation/mlmmj-moderation.php [new file with mode: 0644]
contrib/web/php-moderation/mlmmj.css [new file with mode: 0644]
contrib/web/php-moderation/translations/dot.htaccess [new file with mode: 0644]
contrib/web/php-moderation/translations/fr_FR.po [new file with mode: 0644]

index b98d8325db346ef642e0b840c360d29dd979e2ae..c348708df64c0894cb0bcf252168ea008d1cd2d6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+ o Added contrib/web/php-moderation (Thomas Goirand)
 1.2.16
  o Fixed injection in contrib/web/perl-user (Gerd von Egidy)
 1.2.16-RC1
diff --git a/contrib/web/php-moderation/build-translations.sh b/contrib/web/php-moderation/build-translations.sh
new file mode 100755 (executable)
index 0000000..8a4c11a
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# Build script for generating the MLMMJ moderation web interface locales
+#
+
+set -e
+
+LOCALE_TRANS=fr_FR
+WEB_SCRIPT_FILES=mlmmj-moderation.php
+
+if [ ! -d translations ]; then
+       echo "Wrong working directory." >&2
+       exit 1
+fi
+
+echo "===> Managing internationalizations and localizations"
+
+echo "=> Extracting strings from sources"
+xgettext $WEB_SCRIPT_FILES -o translations/templates.pot
+
+echo "=> Merging in every language .po file:"
+for i in $LOCALE_TRANS; do
+       echo -n "$i "
+       msgmerge -s -U "translations/$i.po" translations/templates.pot
+done
+
+echo "=> Creating l10n folders"
+for i in $LOCALE_TRANS; do
+       mkdir -p "translations/locale/$i/LC_MESSAGES"
+done
+
+echo "=> Creating binary formats of language files:"
+for i in $LOCALE_TRANS; do
+       echo -n $i" "
+       msgfmt -c -v -o "translations/locale/$i/LC_MESSAGES/messages.mo" \
+               "translations/$i.po"
+done
diff --git a/contrib/web/php-moderation/mlmmj-moderation.php b/contrib/web/php-moderation/mlmmj-moderation.php
new file mode 100644 (file)
index 0000000..b463bea
--- /dev/null
@@ -0,0 +1,277 @@
+<?php
+
+/*
+The MIT License
+
+Copyright (C) 2009, Thomas Goirand <thomas@goirand.fr>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+// These are the configuration variables for your list
+$mod_dir = "/some/path/to/your/listname/moderation";
+$list_name = "listname";
+$list_domain = "example.com";
+$delimiter = "+";
+$from_addr = "user@example.com";
+
+// Manage accepted language and cookies
+$txt_default_lang = "en";
+session_register("lang");
+if(isset($_SESSION["lang"]) && !is_string($_SESSION["lang"])){
+       unset($lang);
+}
+if(isset($_SESSION["lang"])){
+       $lang = $_SESSION["lang"];
+}
+
+// TODO: Add some web stuffs to change the language manually on the web interface...
+// ...HERE...
+//
+
+// $lang = "fr_FR";
+
+// The following code keeps the lang in sessions, so it can be changed manually above with lang=XX
+// and if there's nothing in session yet, then it will parse the language set in the browser
+if(isset($lang)){
+       $_SESSION["lang"] = $lang;
+}
+if (!isset($lang)){
+       if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]) && $_SERVER["HTTP_ACCEPT_LANGUAGE"]) {
+               $all_languages = strtok($_SERVER["HTTP_ACCEPT_LANGUAGE"],";");
+               $langaccept = explode(",", $all_languages);
+               for ($i = 0; $i < sizeof($langaccept); $i++) {
+                       $tmplang = trim($langaccept[$i]);
+                       $tmplang2 = substr($tmplang,0,2);
+                       if (!isset($lang) && isset($txt_langname[$tmplang]) && $txt_langname[$tmplang]) {
+                               $lang = $tmplang;
+                       }elseif (!isset($lang) && isset($txt_langname[$tmplang2])) {
+                               $lang = $tmplang2;
+                       }
+               }
+       }
+       if (!isset($lang)) {
+               $lang = $txt_default_lang;
+       }
+       $_SESSION["lang"] = $lang;
+}
+header("Content-type: text/html; charset=UTF-8");
+switch($lang){
+case "fr_FR":
+case "fr":
+       $gettext_lang = "fr_FR.UTF-8";
+       break;
+default:
+       $gettext_lang = "en_US.UTF-8";
+       break;
+}
+if(FALSE === putenv("LC_ALL=$gettext_lang")){
+       echo "Failed to putenv LC_ALL=$gettext_lang<br>";
+}
+if(FALSE === putenv("LANG=$gettext_lang")){
+       echo "Failed to putenv LANG=$gettext_lang<br>";
+}
+if(FALSE === setlocale(LC_ALL, $gettext_lang)){
+       echo "Failed to setlocale(LC_ALL,$gettext_lang)<br>";
+}
+$pathname = bindtextdomain("messages", dirname(__FILE__) ."/translations/locale");
+$message_domain = textdomain("messages");
+
+// This comes from the Mail_Mime PEAR package, under Debian, you need
+// the php-mail-mime package to have this script work.
+require_once 'Mail/mimeDecode.php';
+
+// Email header parsing
+function decodeEmail($input){
+       $params['include_bodies'] = true;
+       $params['decode_bodies']  = true;
+       $params['decode_headers'] = true;
+
+       $decoder = new Mail_mimeDecode($input);
+       $structure = $decoder->decode($params);
+       return $structure;
+}
+
+// Reading of all the messages from the moderation folder
+function getMessageList(){
+       global $mod_dir;
+       $all_msg = array();
+       // Read all files from the directory.
+       if (is_dir($mod_dir)) {
+               if ($dh = opendir($mod_dir)) {
+                       while (($file = readdir($dh)) !== false) {
+                               $full_path = $mod_dir . "/" . $file;
+                               if(filetype($full_path) == "file"){
+                                       if(FALSE === ($input = file_get_contents($full_path))){
+                                               echo "<span class=\"errorMessages\">"._("Warning: could not read")." $full_path</span><br>";
+                                       }else{
+                                               $struct = decodeEmail($input);
+                                               $my_msg = array();
+                                               $my_msg["headers"] = $struct->headers;
+                                               $my_msg["body"] = $struct->body;
+                                               $my_msg["filename"] = $file;
+                                               $all_msg[] = $my_msg;
+                                       }
+                               }
+                       }
+                       closedir($dh);
+               }
+       }
+       return $all_msg;
+}
+
+// Printing of the list of messages to be displayed (the big table)
+function printAllMessages($all_msg){
+       $n = sizeof($all_msg);
+       $out = "<table cellspacing=\"4\" cellpadding=\"4\" border=\"0\">\n";
+       $th = " class=\"tableTitle\" ";
+       $out .= "<tr><th$th><input onClick=\"checkscript();\" type=\"submit\" value=\""._("Inverse selection")."\"></th><th$th>"._("Date")."</th><th$th>"._("Subject")."</th><th$th>"._("From")."</th></tr>\n";
+       $out .= "<form id=\"zeForm\" name=\"zeForm\" action=\"". $_SERVER["PHP_SELF"] ."\">";
+       for($i=0;$i<$n;$i++){
+               if($i % 2){
+                       $cls = " class=\"alternatecolorline\" ";
+               }else{
+                       $cls = " class=\"alternatecolorline2\" ";
+               }
+               $out .= "<tr>";
+               $out .= "<td $cls>" . "<input type=\"checkbox\" name=\"msg_id[]\" value=\"". $all_msg[$i]["filename"] ."\">" . "</td>";
+               $out .= "<td $cls>" . htmlspecialchars($all_msg[$i]["headers"]["date"]) . "</td>";
+               if( strlen($all_msg[$i]["headers"]["subject"]) == 0){
+                       $subject = _("No subject");
+               }else{
+                       $subject = $all_msg[$i]["headers"]["subject"];
+               }
+               $out .= "<td $cls><a href=\"". $_SERVER["PHP_SELF"] ."?action=show_message&msgid=". $all_msg[$i]["filename"] ."\">" . htmlspecialchars($subject) . "</a></td>";
+               $out .= "<td $cls>" . htmlspecialchars($all_msg[$i]["headers"]["from"]) . "</td>";
+               $out .= "</tr>\n";
+       }
+       $out .= "</table>\n";
+       $out .= _("For the selection:")." ";
+       $out .= "<input type=\"submit\" name=\"validate\" value=\""._("Validate")."\">";
+       $out .= "<input type=\"submit\" name=\"delete\" value=\""._("Delete")."\">";
+       return $out;
+}
+
+// Deletion and validation of messages
+if( isset($_REQUEST["validate"]) || isset($_REQUEST["delete"])){
+       if( !isset($_REQUEST["msg_id"]) ){
+               echo "<span class=\"errorMessages\">"._("No message selected!")."</span><br>";
+       }else{
+               $n = sizeof($_REQUEST["msg_id"]);
+               for($i=0;$i<$n;$i++){
+                       if( !ereg("^([0-9a-f]+)\$",$_REQUEST["msg_id"][$i]) ){
+                               echo "<span class=\"errorMessages\">".("Moderation ID format is wrong: will ignore this one!")."</span>";
+                               continue;
+                       }
+                       $fullpath = $mod_dir . "/" . $_REQUEST["msg_id"][$i];
+                       if(!file_exists($fullpath)){
+                               echo "<span class=\"errorMessages\">"._("Moderation ID not found in the moderation folder!")."</span>";
+                               continue;
+                       }
+                       // TODO: Check if message is there!
+                       if( isset($_REQUEST["validate"]) ){
+//                             echo "Validating message ".$_REQUEST["msg_id"][$i]."<br>";
+                               $to_addr = $list_name . $delimiter . "moderate-" . $_REQUEST["msg_id"][$i] . "@" . $list_domain;
+                               $headers = "From: ".$from_addr;
+                               mail($to_addr,"MLMMJ Web interface moderation","MLMMJ Web interface moderation",$headers);
+                       }else{
+//                             echo "Deleting message ".$_REQUEST["msg_id"][$i]."<br>";
+                               unlink($mod_dir . "/" . $_REQUEST["msg_id"][$i]);
+                       }
+               }
+       }
+}
+
+// A bit of javascript to do the checkboxes inversion.
+echo "<html>
+<head>
+<link REL=\"stylesheet\" TYPE=\"text/css\" href=\"mlmmj.css\">
+<script language=\"JavaScript\" type=\"text/javascript\">
+function getObj(name){
+       if (document.getElementById){
+               this.obj = document.getElementById(name);
+               this.style = document.getElementById(name).style;
+       }else if (document.all){
+               this.obj = document.all[name];
+               this.style = document.all[name].style;
+       }else if (document.layers){
+               this.obj = document.layers[name];
+               this.style = document.layers[name];
+       }
+}
+function checkscript(){
+       var frm = document.forms['zeForm'];
+       var n = frm.elements.length;
+       for(i=0;i<n;i++){
+               if(frm.elements[i].type == 'checkbox'){
+                       if(frm.elements[i].checked == true){
+                               frm.elements[i].checked = false;
+                       }else{
+                               frm.elements[i].checked = true;
+                       }
+               }
+       }
+}
+</script>
+</head>
+<body>
+<h3>MLMMJ "._("moderation web interface")."</h3>
+<a href=\"".$_SERVER["PHP_SELF"]."\">"._("Refresh page")."</a>";
+
+if( isset($_REQUEST["action"]) && $_REQUEST["action"] == show_message){
+       if( !ereg("^([0-9a-f]+)\$",$_REQUEST["msgid"]) ){
+               echo "<span class=\"errorMessages\">"._("Message ID format is wrong: can't display!")."</span>";
+       }else{
+               $full_path = $mod_dir . "/" . $_REQUEST["msgid"];
+               if( !file_exists($full_path) ){
+                       echo "<span class=\"errorMessages\">".("Message does not exists!")."</span>";
+               }else{
+                       if(FALSE === ($input = file_get_contents($full_path))){
+                               echo "<span class=\"errorMessages\">"._("Error: could not read")." $full_path </span><br>";
+                       }else{
+                               $struct = decodeEmail($input);
+                               echo "<a href=\"". $_SERVER["PHP_SELF"] ."\">"._("Back to messages list")."</a><br><br>";
+                               echo "<b>"._("From:")." </b>" . htmlspecialchars($struct->headers["from"])."<br>";
+                               echo "<b>"._("Date:")." </b>" . htmlspecialchars($struct->headers["date"])."<br>";
+                               echo "<b>"._("To:")." </b>" . htmlspecialchars($struct->headers["to"])."<br>";
+                               echo "<b>"._("Subject:")." </b>" . htmlspecialchars($struct->headers["subject"])."<br>";
+                               echo "<b>"._("Message body:")."</b><br><br>" . nl2br(htmlspecialchars($struct->body));
+                       }
+               }
+       }
+}else{
+       $all_msg = getMessageList();
+       echo printAllMessages($all_msg);
+}
+
+echo '
+<div class="footer">
+<a href="http://www.mlmmj.org">MLMMJ</a>: Mailing List Manager Make it Joyfull<br />
+<span class="italics">
+MLMMJ PHP moderator code done by:
+<a target="_blank" href="http://thomas.goirand.fr">Thomas GOIRAND</a>, released under the therms of the
+MIT license. Please visit GPLHost\'s leading
+<a target="_blank" href="http://www.gplhost.com/hosting-vps.html">VPS hosting</a> service, and
+<a target="_blank" href="http://www.gplhost.com/software-dtc.html">DTC GPL control panel home</a>
+if you want hosting with MLMMJ support.
+</span>
+</div>
+</body></html>';
+
+?>
\ No newline at end of file
diff --git a/contrib/web/php-moderation/mlmmj.css b/contrib/web/php-moderation/mlmmj.css
new file mode 100644 (file)
index 0000000..478b88c
--- /dev/null
@@ -0,0 +1,46 @@
+.alternatecolorline2 {
+        background-color: #E3f9ff;
+       font-size: 10px;
+        }
+
+.alternatecolorline {
+        background-color: #bcd0d6;
+       font-size: 10px;
+        }
+
+.tableTitle {
+       text-align: center;
+       color: #547074;
+       font-size: 12px;
+       background-color: #dbe9ed;
+}
+
+.errorMessages {
+       color: #FF0000;
+       font-size: 14px;
+       font-weight: bold;
+}
+
+a:link{color:#105278;text-decoration: none;}
+a:visited{color:#105278;text-decoration: none;}
+a:hover{color:#000000;text-decoration: underline;}
+a:active{color:#000000;text-decoration: none;}
+
+html{height:100%; margin:4;}
+body{height:100%;margin:4;      font: 12px Arial, Helvetica, sans-serif; color: #000000;}
+
+/* Forms fields definitions */
+input,select,textarea {
+        font-family: arial;
+        font-size: 12px;
+        color: #000000;
+        background-color: #F6F6F2;
+        border-color: #ECEEE5 #F6F6F2 #F6F6F2 #ECEEE5;
+}
+
+h3 {
+       text-align: center;
+       font-size: 20px;
+}
+
+.footer{width:98%; text-align:center; position:absolute; bottom:0; padding:1%; }
diff --git a/contrib/web/php-moderation/translations/dot.htaccess b/contrib/web/php-moderation/translations/dot.htaccess
new file mode 100644 (file)
index 0000000..c3c2d19
--- /dev/null
@@ -0,0 +1,2 @@
+Order Deny,Allow
+Deny from all
diff --git a/contrib/web/php-moderation/translations/fr_FR.po b/contrib/web/php-moderation/translations/fr_FR.po
new file mode 100644 (file)
index 0000000..aba8fe4
--- /dev/null
@@ -0,0 +1,100 @@
+# MLMMJ moderation web interface templates.
+# Copyright (C) 2009 Thomas GOIRAND <thomas@goirand.fr>
+# This file is distributed under the same license as MLMMJ package.
+# Thomas Goirand <thomas@goirand.fr>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2009-02-08 11:46+0000\n"
+"PO-Revision-Date: 2009-02-08 11:15+0000\n"
+"Last-Translator: Thomas Goirand <thomas@goirand.fr>\n"
+"Language-Team: Thomas Goirand <thomas@goirand.fr>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: mlmmj-moderation.php:249
+msgid "Back to messages list"
+msgstr "Retour a la liste des messages"
+
+#: mlmmj-moderation.php:144
+msgid "Date"
+msgstr "Date"
+
+#: mlmmj-moderation.php:251
+msgid "Date:"
+msgstr "Date :"
+
+#: mlmmj-moderation.php:167
+msgid "Delete"
+msgstr "Effacer"
+
+#: mlmmj-moderation.php:246
+msgid "Error: could not read"
+msgstr "Erreur: impossible de lire"
+
+#: mlmmj-moderation.php:165
+msgid "For the selection:"
+msgstr "Pour la selection :"
+
+#: mlmmj-moderation.php:144
+msgid "From"
+msgstr "De"
+
+#: mlmmj-moderation.php:250
+msgid "From:"
+msgstr "De:"
+
+#: mlmmj-moderation.php:144
+msgid "Inverse selection"
+msgstr "Inverser la selection"
+
+#: mlmmj-moderation.php:239
+msgid "Message ID format is wrong: can't display!"
+msgstr "Le format de l'ID du message est faux: affichage impossible !"
+
+#: mlmmj-moderation.php:254
+msgid "Message body:"
+msgstr "Corp du message :"
+
+#: mlmmj-moderation.php:184
+msgid "Moderation ID not found in the moderation folder!"
+msgstr "ID de moderation non trouve dans le dossier de moderation!"
+
+#: mlmmj-moderation.php:174
+msgid "No message selected!"
+msgstr "Pas de message selectionne !"
+
+#: mlmmj-moderation.php:156
+msgid "No subject"
+msgstr "Pas de sujet"
+
+#: mlmmj-moderation.php:235
+msgid "Refresh page"
+msgstr "Rafraichir la page"
+
+#: mlmmj-moderation.php:144
+msgid "Subject"
+msgstr "Sujet"
+
+#: mlmmj-moderation.php:253
+msgid "Subject:"
+msgstr "Sujet :"
+
+#: mlmmj-moderation.php:252
+msgid "To:"
+msgstr "Pour :"
+
+#: mlmmj-moderation.php:166
+msgid "Validate"
+msgstr "Valider"
+
+#: mlmmj-moderation.php:122
+msgid "Warning: could not read"
+msgstr "Warning : impossible de lire"
+
+#: mlmmj-moderation.php:234
+msgid "moderation web interface"
+msgstr "interface web de moderation"