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