Difference between revisions of "Extension:EmailPage"

From Organic Design wiki
m
({{svn}})
Line 1: Line 1:
<?php
+
{{svn}}
# Extension:EmailArticle{{Category:Extensions|EmailArticle}}{{php}}
 
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
 
# - Author: [http://www.organicdesign.co.nz/nad User:Nad]{{Category:Extensions created with Template:SpecialPage|EmailArticle}}
 
# - See http://www.mediawiki.org/wiki/Extension:EmailArticle for installation and usage details
 
# - Started: 2007-05-25 (based on http://www.organicdesign.co.nz/email-article.php from XmlWiki)
 
 
 
if (!defined('MEDIAWIKI')) die('Not an entry point.');
 
 
 
define('EMAILARTICLE_VERSION','1.0.9, 2008-01-19');
 
 
 
$wgEmailArticleGroup          = 'sysop';            # Users must belong to this group to send emails (empty string means anyone can send)
 
$wgEmailArticleContactsCat    = '';                # This specifies the name of a category containing categories of contact articles
 
$wgEmailArticleCss            = 'EmailArticle.css'; # A minimal CSS article to embed in the email (eg. monobook/main.css without portlets, actions etc)
 
$wgEmailArticleAllowRemoteAddr = array($_SERVER['SERVER_ADDR'],'127.0.0.1'); # Allow anonymous sending from these addresses
 
$wgEmailArticleAllowAllUsers  = false;              # Whether to allow sending to all users (the "user" group)
 
$wgEmailArticleToolboxLink    = 'Send to email';    # Link title for toolbox link (set to "" to not have any link in toolbox)
 
$wgEmailArticleActionLink      = 'email';            # Link title for action link (set to "" to not have any action link)
 
$wgPhpMailerClass              = dirname(__FILE__).'/phpmailer/class.phpmailer.php'; # From http://phpmailer.sourceforge.net/
 
 
 
if ($wgEmailArticleGroup) $wgGroupPermissions['sysop'][$wgEmailArticleGroup] = true;
 
 
 
$wgExtensionFunctions[] = 'wfSetupEmailArticle';
 
 
 
$wgExtensionCredits['specialpage'][] = array(
 
'name'        => 'Special:EmailArticle',
 
'author'      => '[http://www.organicdesign.co.nz/nad User:Nad]',
 
'description' => 'Send rendered article to an email address or list of addresses',
 
'url'        => 'http://www.mediawiki.org/wiki/Extension:EmailArticle',
 
'version'    => EMAILARTICLE_VERSION
 
);
 
 
 
# If form has been posted, include the phpmailer class
 
if (isset($_REQUEST['ea_send'])) require_once($wgPhpMailerClass);
 
 
 
# Add toolbox and action links
 
if ($wgEmailArticleToolboxLink) {
 
$wgHooks['MonoBookTemplateToolboxEnd'][] = 'wfEmailArticleToolboxLink';
 
function wfEmailArticleToolboxLink() {
 
global $wgEmailArticleToolboxLink,$wgTitle;
 
if (is_object($wgTitle)) {
 
$url = Title::makeTitle(NS_SPECIAL,'EmailArticle')->getLocalURL('ea_title='.$wgTitle->getPrefixedText());
 
echo("<li><a href=\"$url\">$wgEmailArticleToolboxLink</li>");
 
}
 
return true;
 
}
 
}
 
if ($wgEmailArticleActionLink) {
 
$wgHooks['SkinTemplateTabs'][] = 'wfEmailArticleActionLink';
 
function wfEmailArticleActionLink(&$skin,&$actions) {
 
global $wgEmailArticleActionLink,$wgTitle;
 
if (is_object($wgTitle)) {
 
$url = Title::makeTitle(NS_SPECIAL,'EmailArticle')->getLocalURL('ea_title='.$wgTitle->getPrefixedText());
 
$actions['email'] = array('text' => $wgEmailArticleActionLink, 'class' => false, 'href' => $url);
 
}
 
return true;
 
}
 
}
 
 
 
 
 
# Define a new class based on the SpecialPage class
 
require_once("$IP/includes/SpecialPage.php");
 
class SpecialEmailArticle extends SpecialPage {
 
 
 
var $recipients = array();
 
var $title;
 
var $subject;
 
var $header;
 
var $cat;
 
var $group;
 
var $list;
 
var $textonly;
 
var $css;
 
 
 
# Constructor
 
function SpecialEmailArticle() {
 
global $wgEmailArticleGroup;
 
SpecialPage::SpecialPage('EmailArticle',$wgEmailArticleGroup);
 
}
 
 
 
 
 
# Override SpecialPage::execute($param = '')
 
function execute($param) {
 
global $wgOut,$wgUser,$wgEmailArticleContactsCat,$wgGroupPermissions,$wgSitename,$wgEmailArticleCss,$wgEmailArticleAllowAllUsers;
 
$db =& wfGetDB(DB_SLAVE);
 
$param = str_replace('_',' ',$param);
 
$this->setHeaders();
 
 
 
# Get info from request or set to defaults
 
$this->title    = isset($_REQUEST['ea_title'])    ? $_REQUEST['ea_title']    : $param;
 
$this->subject  = isset($_REQUEST['ea_subject'])  ? $_REQUEST['ea_subject']  : "\"{$this->title}\" article sent from $wgSitename";
 
$this->header  = isset($_REQUEST['ea_header'])  ? $_REQUEST['ea_header']  : '';
 
$this->cat      = isset($_REQUEST['ea_cat'])      ? $_REQUEST['ea_cat']      : '';
 
$this->group    = isset($_REQUEST['ea_group'])    ? $_REQUEST['ea_group']    : '';
 
$this->list    = isset($_REQUEST['ea_list'])    ? $_REQUEST['ea_list']    : '';
 
$this->textonly = isset($_REQUEST['ea_textonly']) ? $_REQUEST['ea_textonly'] : false;
 
$this->css      = isset($_REQUEST['ea_css'])      ? $_REQUEST['ea_css']      : $wgEmailArticleCss;
 
 
 
# Bail if no article title to send has been specified
 
if ($this->title) $wgOut->addWikiText(wfMsg('ea_heading',$this->title));
 
else return $wgOut->addWikiText(wfMsg('ea_noarticle'));
 
 
 
# If the send button was clicked, attempt to send and exit
 
if (isset($_REQUEST['ea_send'])) return $this->send();
 
 
 
# Render form
 
$special = Title::makeTitle(NS_SPECIAL,'EmailArticle');
 
$wgOut->addHTML(wfElement('form',array(
 
'class'  => 'EmailArticle',
 
'action' => $special->getLocalURL('action=submit'),
 
'method' => 'POST'
 
),null));
 
$wgOut->addHTML('<fieldset><legend>'.wfMsg('ea_selectrecipients').'</legend>');
 
$wgOut->addHTML('<table style="padding:0;margin:0;border:none;">');
 
 
 
# If $wgEmailArticleContactsCat is set, create a select list of all categories
 
if ($wgEmailArticleContactsCat) {
 
$cl = $db->tableName('categorylinks');
 
$cats = '';
 
$result = $db->query("SELECT cl_from FROM $cl WHERE cl_to = '$wgEmailArticleContactsCat' ORDER BY cl_sortkey");
 
if ($result instanceof ResultWrapper) $result = $result->result;
 
if ($result) while ($row = $db->fetchRow($result)) {
 
$t = Title::newFromID($row[0]);
 
if ($t->getNamespace() == NS_CATEGORY) {
 
$cat = $t->getText();
 
$selected = $cat == $this->cat ? ' selected' : '';
 
$cats .= "<option$selected>$cat</option>";
 
}
 
}
 
if ($cats) $wgOut->addHTML("<tr><td>From category:</td><td><select name=\"ea_cat\"><option/>$cats</select></td></tr>\n");
 
}
 
 
 
# Allow selection of a group
 
$groups = '<option/>';
 
foreach (array_keys($wgGroupPermissions) as $group) if ($group != '*') {
 
$selected = $group == $this->group ? ' selected' : '';
 
if ($wgEmailArticleAllowAllUsers || $group != 'user') $groups .= "<option$selected>$group</option>";
 
}
 
$wgOut->addHTML("<tr><td>From group:</td><td><select name=\"ea_group\">$groups</select></td></tr>\n");
 
$wgOut->addHTML('</table>');
 
 
 
# Addition of named list
 
$wgOut->addWikiText(wfMsg('ea_selectlist'));
 
$wgOut->addHTML("<textarea name=\"ea_list\" rows=\"5\">{$this->list}</textarea><br />\n");
 
$wgOut->addHTML('</fieldset>');
 
 
 
$wgOut->addHTML('<fieldset><legend>'.wfMsg('ea_compose').'</legend>');
 
 
 
# Subject
 
$wgOut->addWikiText(wfMsg('ea_subject'));
 
$wgOut->addHTML(wfElement('input',array('type' => 'text', 'name' => 'ea_subject', 'value' => $this->subject, 'style' => "width:100%")));
 
 
 
# Header
 
$wgOut->addWikiText(wfMsg('ea_header'));
 
$wgOut->addHTML("<textarea name=\"ea_header\" rows=\"5\">{$this->header}</textarea><br />\n");
 
 
 
# CSS
 
$page = $db->tableName('page');
 
$csss = '';
 
$result = $db->query("SELECT page_id FROM $page WHERE page_title LIKE '%.css' ORDER BY page_title");
 
if ($result instanceof ResultWrapper) $result = $result->result;
 
if ($result) while ($row = $db->fetchRow($result)) {
 
$t = Title::newFromID($row[0])->getPrefixedText();
 
$selected = $t == $this->css ? ' selected' : '';
 
$csss .= "<option$selected>$t</option>";
 
}
 
if ($csss) {
 
$wgOut->addWikiText(wfMsg('ea_selectcss'));
 
$wgOut->addHTML("<select name=\"ea_css\"><option/>$csss</select>\n");
 
}
 
 
 
$wgOut->addHTML("</fieldset>");
 
 
 
# Submit buttons & hidden values
 
$wgOut->addHTML(wfElement('input',array('type' => 'submit','name' => 'ea_send', 'value' => wfMsg('ea_send'))));
 
$wgOut->addHTML(wfElement('input',array('type' => 'submit','name' => 'ea_show', 'value' => wfMsg('ea_show'))));
 
$wgOut->addHTML(wfElement('input',array('type' => 'hidden','name' => 'ea_title','value' => $this->title)));
 
 
 
$wgOut->addHTML('</form>');
 
 
 
# If the show button was clicked, render the list
 
if (isset($_REQUEST['ea_show'])) return $this->send(false);
 
}
 
 
 
 
 
# Send the message to the recipients (or just list them if arg = false)
 
function send($send = true) {
 
global $wgOut,$wgUser,$wgParser,$wgServer,$wgScript,$wgArticlePath,$wgScriptPath,
 
$wgEmailArticleCss,$wgEmailArticleGroup,$wgEmailArticleAllowRemoteAddr,$wgEmailArticleAllowAllUsers;
 
 
 
# Set error and bail if user not in postmaster group, and request not from trusted address
 
if ($wgEmailArticleGroup && !in_array($wgEmailArticleGroup,$wgUser->getGroups()) && !in_array($_SERVER['REMOTE_ADDR'],$wgEmailArticleAllowRemoteAddr)) {
 
$wgOut->addWikiText(wfMsg('ea_error',$this->title,'Permission denied'));
 
return false;
 
}
 
 
 
$db      = &wfGetDB(DB_SLAVE);
 
$title    = Title::newFromText($this->title);
 
$opt      = new ParserOptions;
 
 
 
# Get contact article titles from selected cat
 
if ($this->cat) {
 
$cl    = $db->tableName('categorylinks');
 
$result = $db->query("SELECT cl_from FROM $cl WHERE cl_to = '{$this->cat}' ORDER BY cl_sortkey");
 
while ($row = mysql_fetch_row($result)) $this->addRecipient(Title::newFromID($row[0]));
 
}
 
 
 
# Get email addresses from users in selected group
 
if ($this->group && ($wgEmailArticleAllowAllUsers || $this->group != 'user')) {
 
$u  = str_replace('`','',$db->tableName('user'));
 
$ug = str_replace('`','',$db->tableName('user_groups'));
 
if ($this->group == 'user') $sql = "SELECT user_email FROM $u WHERE user_email != ''";
 
else $sql = "SELECT $u.user_email FROM $u,$ug WHERE $ug.ug_user = $u.user_id AND $ug.ug_group = '{$this->group}'";
 
$result = $db->query($sql);
 
if ($result instanceof ResultWrapper) $result = $result->result;
 
while ($row = $db->fetchRow($result)) $this->addRecipient($row[0]);
 
}
 
 
 
# Recipients from list (expand templates in wikitext)
 
$list = $wgParser->preprocess($this->list,$title,$opt);
 
foreach (preg_split("/[\\x00-\\x1f,;*]+/",$list) as $item) $this->addRecipient($item);
 
 
 
# Compose the wikitext content of the article to send
 
$article = new Article($title);
 
$message = $article->getContent();
 
if ($this->header) $message = "{$this->header}\n\n$message";
 
 
 
# Convert the message text to html unless textonly
 
if ($this->textonly == '') {
 
 
 
# Parse the wikitext using absolute URL's for local article links
 
$tmp          = array($wgArticlePath,$wgScriptPath,$wgScript);
 
$wgArticlePath = $wgServer.$wgArticlePath;
 
$wgScriptPath  = $wgServer.$wgScriptPath;
 
$wgScript      = $wgServer.$wgScript;
 
$message      = $wgParser->parse($message,$title,$opt,true,true)->getText();
 
list($wgArticlePath,$wgScriptPath,$wgScript) = $tmp;
 
 
 
# Get CSS content if any
 
if ($this->css) {
 
$article = new Article(Title::newFromText($this->css));
 
$css = '<style type="text/css">'.$article->getContent().'</style>';
 
}
 
 
 
# Create a html wrapper for the message
 
$head    = "<head>$css</head>";
 
$message = "<html>$head<body style=\"margin:10px\"><div id=\"#bodyContent\">$message</div></body></html>";
 
 
 
}
 
 
# Send message or list recipients
 
$count = count($this->recipients);
 
if ($count > 0) {
 
 
 
# Set up new mailer instance if sending
 
if ($send) {
 
$mail          = new PHPMailer();
 
$mail->From    = $wgUser->isValidEmailAddr($wgUser->getEmail()) ? $wgUser->getEmail() : "wiki@$wgServer";
 
$mail->FromName = User::whoIsReal($wgUser->getId());
 
$mail->Subject  = $this->subject;
 
$mail->Body    = $message;
 
$mail->IsHTML(!$this->textonly);
 
}
 
else $msg = wfMsg('ea_listrecipients',$count);
 
 
# Loop through recipients sending or adding to list
 
foreach ($this->recipients as $recipient) $send ? $mail->AddAddress($recipient) : $msg .= "\n*[mailto:$recipient $recipient]";
 
 
if ($send) {
 
if ($state = $mail->Send()) $msg = wfMsg('ea_sent',$this->title,$count,$wgUser->getName());
 
else $msg = wfMsg('ea_error',$this->title,$mail->ErrorInfo);
 
}
 
else $state = $count;
 
}
 
else $msg = wfMsg('ea_error',$this->title,wfMsg('ea_norecipients'));
 
 
 
$wgOut->addWikiText($msg);
 
return $state;
 
}
 
 
 
# Add a recipient the list
 
# - accepts title objects for article containing email address, or string of actual address
 
function addRecipient($recipient) {
 
if (is_object($recipient) && $recipient->exists()) {
 
$article = new Article($recipient);
 
if (preg_match('/[a-z0-9_.-]+@[a-z0-9_.-]+/i',$article->getContent(),$emails)) $recipient = $emails[0];
 
else $recipient = '';
 
}
 
if ($valid = User::isValidEmailAddr($recipient)) $this->recipients[] = $recipient;
 
return $valid;
 
}
 
 
 
}
 
 
 
# Called from $wgExtensionFunctions array when initialising extensions
 
function wfSetupEmailArticle() {
 
global $wgLanguageCode,$wgMessageCache;
 
 
 
# Add the messages used by the specialpage
 
if ($wgLanguageCode == 'en') {
 
$wgMessageCache->addMessages(array(
 
'emailarticle'        => "EmailArticle",
 
'ea_heading'          => "=== Emailing [[$1]] article ===",
 
'ea_noarticle'        => "Please specify an article to send, for example [[Special:EmailArticle/Main Page]].",
 
'ea_norecipients'    => "No valid email addresses found!",
 
'ea_listrecipients'  => "=== List of $1 {{PLURAL:$1|recipient|recipients}} ===",
 
'ea_error'            => "'''Error sending [[$1]]:''' ''$2''",
 
'ea_sent'            => "Article [[$1]] sent successfully to '''$2''' {{PLURAL:$2|recipient|recipients}} by [[User:$3|$3]].",
 
'ea_selectrecipients' => "Select recipients",
 
'ea_compose'          => "Compose content",
 
'ea_selectlist'      => "Additional recipients as article titles or email addresses\n"
 
                      . "*''separate items with , ; * \\n\n"
 
                      . "*''list can contain templates and parser-functions''",
 
'ea_show'            => "Show recipients",
 
'ea_send'            => "Send!",
 
'ea_subject'          => "Enter a subject line for the email",
 
'ea_header'          => "Prepend content with optional message (wikitext)",
 
'ea_selectcss'        => "Select a CSS stylesheet"
 
));
 
}
 
 
 
# Add the specialpage to the environment
 
SpecialPage::addPage(new SpecialEmailArticle());
 
}
 

Revision as of 10:03, 17 May 2008

Info.svg This code is in our Git repository here.

Note: If there is no information in this page about this code and it's a MediaWiki extension, there may be something at mediawiki.org.