Extension talk:EmailArticle.php/Updated

From Organic Design wiki
Revision as of 21:21, 22 May 2008 by Nad (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

<?php

  1. Extension:EmailArticleTemplate:Php
  2. - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
  3. - Author: User:Nad
  4. - See http://www.mediawiki.org/wiki/Extension:EmailArticle for installation and usage details
  5. - 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.8, 2007-09-28');

$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' => '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 );

  1. If form has been posted, include the phpmailer class

if (isset($_REQUEST['ea_send'])) require_once($wgPhpMailerClass);

  1. 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("

  • <a href=\"$url\">$wgEmailArticleToolboxLink
  • ");

    } 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; } }


    1. 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,$wgEmailArticleSimple; $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('

    '); # 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("\n");

    }

    # Allow selection of a group $groups = '<option/>'; if($wgEmailArticleSimple!=true) { foreach (array_keys($wgGroupPermissions) as $group) if ($group != '*') { $selected = $group == $this->group ? ' selected' : ; if ($wgEmailArticleAllowAllUsers || $group != 'user') $groups .= "<option$selected>$group</option>"; }

    $wgOut->addHTML("\n");

    }

    $wgOut->addHTML('
    From category:<select name=\"ea_cat\"><option/>$cats</select>
    A group:<select name=\"ea_group\">$groups</select>

    ');

    # Addition of named list if($wgEmailArticleSimple!=true) $wgOut->addWikiText(wfMsg('ea_selectlist'));

    $wgOut->addHTML("<textarea name=\"ea_list\" rows=\"5\">{$this->list}</textarea>
    \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>
    \n");

    # CSS $page = $db->tableName('page'); $csss = ; $result = $db->query("SELECT page_id FROM $page WHERE page_title REGEXP('\\.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'))));

    if($wgEmailArticleSimple!=true) { $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: You probably need to log in to use this feature.')); 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 = "$head

    $message

    ";

    }

    # 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*$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; }

    }

    1. 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' => "Emailing article", 'ea_heading' => "Article name: $1", '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 recipients ===", 'ea_error' => "There was a problem: $2", 'ea_sent' => "Article $1 sent successfully to $2 recipients by $3.", 'ea_selectrecipients' => "Send to", 'ea_compose' => "Subject and message", '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 email", '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()); } ?>