Index: trunk/extensions/EmailCapture/EmailCapture.i18n.php |
— | — | @@ -0,0 +1,27 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Internationalisation for EmailCapture extension |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + */ |
| 9 | + |
| 10 | +$messages = array(); |
| 11 | + |
| 12 | +/** English |
| 13 | + * @author Trevor Parscal |
| 14 | + */ |
| 15 | +$messages['en'] = array( |
| 16 | + 'emailcapture' => 'Email Capture', |
| 17 | + 'emailcapture-desc' => 'Capture email addresses, and allow users to verify them through email', |
| 18 | + 'emailcapture-response-subject' => '{{SITENAME}} Email Verification', |
| 19 | + 'emailcapture-response-body' => 'To verify your email address, following this link: |
| 20 | + $1 |
| 21 | + |
| 22 | +You can also visit: |
| 23 | + $2 |
| 24 | +and enter the following verification code: |
| 25 | + $3 |
| 26 | + |
| 27 | +Thank you for verifying your email address.', |
| 28 | +); |
Index: trunk/extensions/EmailCapture/sql/CreateEmailCaptureTable.sql |
— | — | @@ -0,0 +1,13 @@ |
| 2 | +-- Captured email addresses |
| 3 | +CREATE TABLE IF NOT EXISTS /*_*/email_capture ( |
| 4 | + -- Email address |
| 5 | + ec_email tinytext NOT NULL, |
| 6 | + -- Additional information |
| 7 | + ec_info blob NOT NULL, |
| 8 | + -- Verification code |
| 9 | + ec_code varbinary(32) NOT NULL DEFAULT '', |
| 10 | + -- Verified |
| 11 | + ec_verified boolean DEFAULT 0 |
| 12 | +) /*$wgDBTableOptions*/; |
| 13 | +CREATE UNIQUE INDEX /*i*/ac_email_key ON /*_*/email_capture (ec_email); |
| 14 | +CREATE INDEX /*i*/ac_code_verified_key ON /*_*/email_capture (ec_code, ec_verified); |
Index: trunk/extensions/EmailCapture/EmailCapture.php |
— | — | @@ -0,0 +1,45 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * EmailCapture extension |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Extensions |
| 8 | + * |
| 9 | + * @author Trevor Parscal <trevor@wikimedia.org> |
| 10 | + * @license GPL v2 or later |
| 11 | + * @version 0.3.0 |
| 12 | + */ |
| 13 | + |
| 14 | +/* Configuration */ |
| 15 | + |
| 16 | +$wgEmailCaptureSendAutoResponse = true; |
| 17 | +$wgEmailCaptureAutoResponse = array( |
| 18 | + 'from' => $wgPasswordSender, |
| 19 | + 'subject-msg' => 'emailcapture-response-subject', |
| 20 | + 'body-msg' => 'emailcapture-response-body', |
| 21 | + 'reply-to' => null, |
| 22 | + 'content-type' => null, |
| 23 | +); |
| 24 | + |
| 25 | +/* Setup */ |
| 26 | + |
| 27 | +$wgExtensionCredits['other'][] = array( |
| 28 | + 'path' => __FILE__, |
| 29 | + 'name' => 'EmailCapture', |
| 30 | + 'author' => array( 'Trevor Parscal' ), |
| 31 | + 'version' => '0.3.0', |
| 32 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:EmailCapture', |
| 33 | + 'descriptionmsg' => 'emailcapture-desc', |
| 34 | +); |
| 35 | +$dir = dirname( __FILE__ ) . '/'; |
| 36 | +$wgExtensionMessagesFiles['EmailCapture'] = $dir . 'EmailCapture.i18n.php'; |
| 37 | +// API |
| 38 | +$wgAutoloadClasses['ApiEmailCapture'] = $dir . 'api/ApiEmailCapture.php'; |
| 39 | +$wgAPIModules['emailcapture'] = 'ApiEmailCapture'; |
| 40 | +// Schema |
| 41 | +$wgAutoloadClasses['EmailCaptureHooks'] = $dir . 'EmailCaptureHooks.php'; |
| 42 | +$wgHooks['LoadExtensionSchemaUpdates'][] = 'EmailCaptureHooks::loadExtensionSchemaUpdates'; |
| 43 | +$wgHooks['ParserTestTables'][] = 'EmailCaptureHooks::parserTestTables'; |
| 44 | +// SpecialPage |
| 45 | +$wgAutoloadClasses['SpecialEmailCapture'] = $dir . "SpecialEmailCapture.php"; |
| 46 | +$wgSpecialPages['EmailCapture'] = 'SpecialEmailCapture'; |
Index: trunk/extensions/EmailCapture/SpecialEmailCapture.php |
— | — | @@ -0,0 +1,25 @@ |
| 2 | +<?php |
| 3 | +class SpecialEmailCapture extends SpecialPage { |
| 4 | + |
| 5 | + function __construct() { |
| 6 | + parent::__construct( 'EmailCapture', 'emailcapture' ); |
| 7 | + } |
| 8 | + |
| 9 | + function execute( $par ) { |
| 10 | + global $wgOut, $wgRequest; |
| 11 | + |
| 12 | + $this->setHeaders(); |
| 13 | + |
| 14 | + $code = $wgRequest->getVal( 'verify' ); |
| 15 | + if ( $verify !== null ) { |
| 16 | + // $affectedRows = ( UPDATE email_capture SET (ec_veified = 1) WHERE ec_code = $code ) |
| 17 | + // if ( $affectedRows ) { |
| 18 | + // show success |
| 19 | + // } else { |
| 20 | + // show failure |
| 21 | + // } |
| 22 | + // exit |
| 23 | + } |
| 24 | + // Show simple form for submitting verification code |
| 25 | + } |
| 26 | +} |
Index: trunk/extensions/EmailCapture/EmailCaptureHooks.php |
— | — | @@ -0,0 +1,41 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Hooks for EmailCapture extension |
| 5 | + * |
| 6 | + * @author tparscal |
| 7 | + */ |
| 8 | +class EmailCaptureHooks { |
| 9 | + /** |
| 10 | + * LoadExtensionSchemaUpdates hook |
| 11 | + */ |
| 12 | + public static function loadExtensionSchemaUpdates( $updater = null ) { |
| 13 | + if ( $updater === null ) { |
| 14 | + global $wgExtNewTables; |
| 15 | + $wgExtNewTables[] = array( |
| 16 | + 'email_capture', |
| 17 | + dirname( __FILE__ ) . '/sql/CreateEmailCaptureTable.sql' |
| 18 | + ); |
| 19 | + } else { |
| 20 | + $dir = dirname( __FILE__ ); |
| 21 | + $db = $updater->getDB(); |
| 22 | + if ( !$db->tableExists( 'article_feedback' ) ) { |
| 23 | + // Initial install tables |
| 24 | + $updater->addExtensionUpdate( array( |
| 25 | + 'addTable', |
| 26 | + 'email_capture', |
| 27 | + $dir . '/sql/CreateEmailCaptureTable.sql', |
| 28 | + true |
| 29 | + ) ); |
| 30 | + } |
| 31 | + } |
| 32 | + return true; |
| 33 | + } |
| 34 | + |
| 35 | + /** |
| 36 | + * ParserTestTables hook |
| 37 | + */ |
| 38 | + public static function parserTestTables( &$tables ) { |
| 39 | + $tables[] = 'email_capture'; |
| 40 | + return true; |
| 41 | + } |
| 42 | +} |
Index: trunk/extensions/EmailCapture/api/ApiEmailCapture.php |
— | — | @@ -0,0 +1,109 @@ |
| 2 | +<?php |
| 3 | +class ApiEmailCapture extends ApiBase { |
| 4 | + public function __construct( $query, $moduleName ) { |
| 5 | + parent::__construct( $query, $moduleName, '' ); |
| 6 | + } |
| 7 | + |
| 8 | + public function execute() { |
| 9 | + $params = $this->extractRequestParams(); |
| 10 | + |
| 11 | + // Validation |
| 12 | + if ( !isset( $params['email'] ) ) { |
| 13 | + $this->dieUsageMsg( array( 'missingparam', 'email' ) ); |
| 14 | + } else if ( !User:isValidEmailAddr( $params['email'] ) ) { |
| 15 | + $this->dieUsage( 'The email address does not appear to be valid', 'invalidemail' ); |
| 16 | + } |
| 17 | + |
| 18 | + // Verification code |
| 19 | + $code = md5( 'EmailCapture' . time() . $params['email'] . $params['info'] ) |
| 20 | + |
| 21 | + // Insert |
| 22 | + $dbw = wfGetDB( DB_MASTER ); |
| 23 | + $affectedRows = $dbw->insert( |
| 24 | + 'email_capture', |
| 25 | + array( |
| 26 | + 'ec_email' => $params['email'], |
| 27 | + 'ec_info' => isset( $params['info'] ) ? $params['email'] : null, |
| 28 | + 'ec_code' => $code, |
| 29 | + ) |
| 30 | + ); |
| 31 | + |
| 32 | + // Send auto-response |
| 33 | + global $wgUser, $wgEmailCaptureSendAutoResponse, $wgEmailCaptureAutoResponse; |
| 34 | + $link = $wgUser->getSkin()->link( 'Special:EmailCapture' ); |
| 35 | + $fullLink = $wgUser->getSkin()->link( |
| 36 | + 'Special:EmailCapture', null, array(), array( 'verify' => $code ) |
| 37 | + ); |
| 38 | + if ( $wgEmailCaptureSendAutoResponse ) { |
| 39 | + UserMailer::send( |
| 40 | + $params['email'], |
| 41 | + $wgEmailCaptureAutoResponse['from'], |
| 42 | + wfMsg( $wgEmailCaptureAutoResponse['subject-msg'] ), |
| 43 | + wfMsg( $wgEmailCaptureAutoResponse['body-msg'], $link, $code, $fullLink ), |
| 44 | + $wgEmailCaptureAutoResponse['reply-to'], |
| 45 | + $wgEmailCaptureAutoResponse['content-type'], |
| 46 | + ); |
| 47 | + } |
| 48 | + |
| 49 | + // Result |
| 50 | + if ( $affectedRows === 0 ) { |
| 51 | + $r = array( 'result' => 'Failure', 'message' => 'Duplicate email address' ); |
| 52 | + } else { |
| 53 | + $r = array( 'result' => 'Success' ); |
| 54 | + } |
| 55 | + $this->getResult()->addValue( null, $this->getModuleName(), $r ); |
| 56 | + } |
| 57 | + |
| 58 | + public function getAllowedParams() { |
| 59 | + return array( |
| 60 | + 'email' => array( |
| 61 | + ApiBase::PARAM_REQUIRED => true, |
| 62 | + ApiBase::PARAM_TYPE => 'string', |
| 63 | + ), |
| 64 | + 'info' => array( |
| 65 | + ApiBase::PARAM_TYPE => 'string', |
| 66 | + ), |
| 67 | + ); |
| 68 | + } |
| 69 | + |
| 70 | + public function getParamDescription() { |
| 71 | + return array( |
| 72 | + 'email' => 'Email address to capture', |
| 73 | + 'info' => 'Extra information to log, usually JSON encoded structured information', |
| 74 | + ); |
| 75 | + } |
| 76 | + |
| 77 | + public function getDescription() { |
| 78 | + return array( |
| 79 | + 'Capture email addresses' |
| 80 | + ); |
| 81 | + } |
| 82 | + |
| 83 | + public function mustBePosted() { |
| 84 | + return true; |
| 85 | + } |
| 86 | + |
| 87 | + public function isWriteMode() { |
| 88 | + return true; |
| 89 | + } |
| 90 | + |
| 91 | + public function getPossibleErrors() { |
| 92 | + return array_merge( parent::getPossibleErrors(), array( |
| 93 | + array( 'missingparam', 'email' ), |
| 94 | + array( |
| 95 | + 'code' => 'invalidemail', |
| 96 | + 'info' => 'The email address does not appear to be valid' |
| 97 | + ), |
| 98 | + ) ); |
| 99 | + } |
| 100 | + |
| 101 | + protected function getExamples() { |
| 102 | + return array( |
| 103 | + 'api.php?action=emailcapture' |
| 104 | + ); |
| 105 | + } |
| 106 | + |
| 107 | + public function getVersion() { |
| 108 | + return __CLASS__ . ': $Id: ApiEmailCapture.php 85276 2011-04-03 20:32:25Z reedy $'; |
| 109 | + } |
| 110 | +} |