Nikerabbit has uploaded a new change for review.
https://gerrit.wikimedia.org/r/67636
Change subject: Rewrite storage to get rid of multiple issues
......................................................................
Rewrite storage to get rid of multiple issues
Change-Id: I540886ca642dcdaa2cdcaf7d89866394dbcf228e
---
M InviteSignup.php
A InviteStore.php
M SpecialInviteSignup.php
A sql/invitesignup.sql
4 files changed, 137 insertions(+), 80 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/InviteSignup
refs/changes/36/67636/1
diff --git a/InviteSignup.php b/InviteSignup.php
index 0c81f9e..caa51a5 100644
--- a/InviteSignup.php
+++ b/InviteSignup.php
@@ -7,7 +7,7 @@
* @ingroup Extensions
*
* @author Niklas Laxström
- * @copyright Copyright © 2012 Lost in Translations Inc.
+ * @copyright Copyright © 2012-2013 Lost in Translations Inc.
* @license GPL 2.0 or later
*/
@@ -20,10 +20,11 @@
);
$dir = __DIR__;
-$wgSpecialPages['InviteSignup'] = 'SpecialInviteSignup';
+$wgAutoloadClasses['InviteStore'] = "$dir/InviteStore.php";
$wgAutoloadClasses['SpecialInviteSignup'] = "$dir/SpecialInviteSignup.php";
$wgExtensionMessagesFiles['InviteSignupAlias'] = "$dir/InviteSignup.alias.php";
$wgExtensionMessagesFiles['InviteSignup'] = "$dir/InviteSignup.i18n.php";
+$wgSpecialPages['InviteSignup'] = 'SpecialInviteSignup';
$wgAvailableRights[] = 'invitesignup';
$wgInviteSignupHash = null;
@@ -45,8 +46,9 @@
$hash = $request->getVal( 'invite', $request->getCookie( 'invite' ) );
if ( $hash ) {
- $invite = SpecialInviteSignup::getInvite( $hash );
- if ( $invite && $invite['used'] === false ) {
+ $store = new InviteStore( wfGetDB( DB_SLAVE ), 'invitesignup' );
+ $invite = $store->getInvite( $hash );
+ if ( $invite && $invite['used'] === null ) {
global $wgInviteSignupHash;
$wgInviteSignupHash = $hash;
$request->response()->setCookie( 'invite', $hash );
@@ -82,7 +84,10 @@
if ( $wgInviteSignupHash === null ) {
return true;
}
- $invite = SpecialInviteSignup::getInvite( $wgInviteSignupHash );
+
+ $store = new InviteStore( wfGetDB( DB_MASTER ), 'invitesignup' );
+
+ $invite = $store->getInvite( $wgInviteSignupHash );
$user->setOption( 'is-inviter', $invite['inviter'] );
$user->setEmail( $invite['email'] );
$user->confirmEmail();
@@ -90,8 +95,14 @@
$user->addGroup( $group );
}
$user->saveSettings();
- SpecialInviteSignup::addSignupDate( $user, $wgInviteSignupHash );
+ $store->addSignupDate( $user, $wgInviteSignupHash );
global $wgRequest;
$wgRequest->response()->setCookie( 'invite', '', time() - 86400 );
return true;
};
+
+$wgHooks['LoadExtensionSchemaUpdates'][] = function ( DatabaseUpdater $updater
) {
+ $dir = __DIR__ . '/sql';
+ $updater->addExtensionTable( 'invitesignup', "$dir/invitesignup.sql" );
+ return true;
+};
diff --git a/InviteStore.php b/InviteStore.php
new file mode 100644
index 0000000..980a8a0
--- /dev/null
+++ b/InviteStore.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * Storage abstraction for invites.
+ *
+ * @file
+ * @ingroup Extensions
+ *
+ * @author Niklas Laxström
+ * @copyright Copyright © 2013 Lost in Translations Inc.
+ */
+
+/**
+ * InviteStore which uses database as storage.
+ */
+class InviteStore {
+ protected $db;
+ protected $dbTable;
+
+ public function __construct( DatabaseBase $db, $table ) {
+ $this->db = $db;
+ $this->dbTable = $table;
+ }
+
+ public function getInvites() {
+ $fields = array( '*' );
+ $conds = array();
+ $res = $this->db->select( $this->dbTable, $fields, $conds,
__METHOD__ );
+ $invites = array();
+ foreach ( $res as $row ) {
+ $invites[] = $this->rowToArray( $row );
+ }
+ return $invites;
+ }
+
+ public function addInvite( User $inviter, $email, $groups ) {
+ global $wgSecretKey;
+ $hash = sha1( $inviter->getId() . $wgSecretKey . $email .
wfTimestamp( TS_UNIX ) );
+
+ $data = array(
+ 'is_inviter' => $inviter->getId(),
+ 'is_email' => $email,
+ 'is_when' => wfTimestamp( TS_UNIX ),
+ 'is_hash' => $hash,
+ 'is_groups' => serialize( $groups ),
+ );
+
+ $this->db->insert( $this->dbTable, $data, __METHOD__ );
+
+ return $hash;
+ }
+
+
+ public function deleteInvite( $hash ) {
+ $conds = array( 'is_hash' => $hash );
+ $this->db->delete( $this->dbTable, $conds, __METHOD__ );
+ }
+
+ public function getInvite( $hash ) {
+ $fields = array( '*' );
+ $conds = array( 'is_hash' => $hash );
+ $res = $this->db->selectRow( $this->dbTable, $fields, $conds,
__METHOD__ );
+ return $this->rowToArray( $res );
+ }
+
+ public function addSignupDate( User $user, $hash ) {
+ $conds = array( 'is_hash' => $hash );
+ $data = array(
+ 'is_used' => wfTimestamp( TS_UNIX ),
+ 'is_invitee' => $user->getId(),
+ );
+ $this->db->update( $this->dbTable, $data, $conds, __METHOD__ );
+ }
+
+ protected function rowToArray( $row ) {
+ $array = array();
+ if ( $row === false ) {
+ return null;
+ }
+
+ foreach ( $row as $key => $value ) {
+ if ( $key === 'is_groups' ) {
+ $value = unserialize( $value );
+ }
+ $array[substr( $key, 3 )] = $value;
+ }
+ return $array;
+ }
+}
diff --git a/SpecialInviteSignup.php b/SpecialInviteSignup.php
index bf39992..4f23bbd 100644
--- a/SpecialInviteSignup.php
+++ b/SpecialInviteSignup.php
@@ -6,16 +6,28 @@
* @ingroup Extensions
*
* @author Niklas Laxström
- * @copyright Copyright © 2012 Lost in Translations Inc.
+ * @copyright Copyright © 2012-2013 Lost in Translations Inc.
*/
class SpecialInviteSignup extends SpecialPage {
protected $groups;
+ protected $store;
public function __construct() {
parent::__construct( 'InviteSignup', 'invitesignup' );
global $wgISGroups;
$this->groups = $wgISGroups;
+ }
+
+ public function setStore( InviteStore $store ) {
+ $this->store = $store;
+ }
+
+ protected function getStore() {
+ if ( $this->store === null ) {
+ $this->store = new InviteStore( wfGetDB( DB_MASTER ),
'invitesignup' );
+ }
+ return $this->store;
}
public function execute( $par ) {
@@ -26,10 +38,12 @@
$out = $this->getOutput();
$this->setHeaders();
+ $store = $this->getStore();
+
$token = $request->getVal( 'token' );
if ( $request->wasPosted() && $user->matchEditToken( $token,
'is' ) ) {
if ( $request->getVal( 'do' ) === 'delete' ) {
- self::deleteInvite( $request->getVal( 'hash' )
);
+ $store->deleteInvite( $request->getVal( 'hash'
) );
}
if ( $request->getVal( 'do' ) === 'add' ) {
$email = $request->getVal( 'email' );
@@ -45,15 +59,13 @@
$groups[] = $group;
}
}
- self::addInvite( $user, $email, $groups
);
+ $hash = $store->addInvite( $user,
$email, $groups );
+ self::sendInviteEmail( $user, $email,
$hash );
}
}
}
- $invites = self::getInvites();
- uasort( $invites, function ( $a, $b ) {
- return $a['when'] < $b['when'];
- } );
+ $invites = $store->getInvites();
$lang = $this->getLanguage();
$out->addHtml(
@@ -78,12 +90,12 @@
$inviteeUser = User::newFromId(
$invite['userid'] );
$name = $inviteeUser->getName();
$email = "$name <$email>";
- $groups = $inviteeUser->getGroups();
}
foreach ( $groups as $i => $g ) {
$groups[$i] = User::getGroupMember( $g );
}
+
$groups = $lang->commaList( $groups );
$out->addHtml(
@@ -149,48 +161,6 @@
return $row;
}
- public static function getInvites() {
- $dbw = wfGetDB( DB_MASTER );
- $table = 'objectcache';
- $fields = array( 'keyname' );
- $conds = array(
- 'keyname' . $dbw->buildLike( wfMemcKey( 'invitesignup'
), $dbw->anyString() ),
- );
- $res = $dbw->select( $table, $fields, $conds, __METHOD__ );
-
- $keys = array();
- foreach ( $res as $row ) {
- $keys[] = $row->keyname;
- }
-
- $cache = self::getCache();
- $invites = array();
- foreach ( $cache->getMulti( $keys ) as $item ) {
- $invites[] = $item;
- }
-
- return $invites;
- }
-
- public static function addInvite( User $inviter, $email, $groups ) {
- global $wgSecretKey;
- $hash = sha1( $inviter->getId() . $wgSecretKey . $email );
- $memckey = wfMemcKey( 'invitesignup', $hash );
- $data = array(
- 'inviter' => $inviter->getId(),
- 'email' => $email,
- 'when' => wfTimestamp(),
- 'used' => false,
- 'hash' => $hash,
- 'groups' => $groups,
- );
-
- $cache = self::getCache();
- $cache->set( $memckey, $data );
-
- self::sendInviteEmail( $inviter, $email, $hash );
- }
-
public static function sendInviteEmail( User $inviter, $email, $hash ) {
$url = Title::newFromText( 'Special:Userlogin/signup'
)->getCanonicalUrl( array( 'invite' => $hash, 'returnto' => 'Special:Dashboard'
) );
@@ -212,28 +182,4 @@
$job->run();
}
- public static function deleteInvite( $hash ) {
- $memckey = wfMemcKey( 'invitesignup', $hash );
- $cache = self::getCache();
- $cache->delete( $memckey );
- }
-
- public static function getInvite( $hash ) {
- $memckey = wfMemcKey( 'invitesignup', $hash );
- $cache = self::getCache();
- return $cache->get( $memckey );
- }
-
- public static function getCache() {
- return wfGetCache( CACHE_DB );
- }
-
- public static function addSignupDate( User $user, $hash ) {
- $invite = self::getInvite( $hash );
- $invite['used'] = wfTimestamp();
- $invite['userid'] = $user->getId();
- $cache = self::getCache();
- $memckey = wfMemcKey( 'invitesignup', $hash );
- $cache->set( $memckey, $invite );
- }
}
diff --git a/sql/invitesignup.sql b/sql/invitesignup.sql
new file mode 100644
index 0000000..0dc4e95
--- /dev/null
+++ b/sql/invitesignup.sql
@@ -0,0 +1,12 @@
+-- Invite signup signups
+CREATE TABLE /*$wgDBprefix*/invitesignup (
+ is_inviter int unsigned NOT NULL,
+ is_invitee int unsigned,
+ is_email varchar(255) binary NOT NULL,
+ is_when varbinary(14) NOT NULL,
+ is_used varbinary(14),
+ is_hash varbinary(40) NOT NULL,
+ is_groups mediumblob,
+
+ PRIMARY KEY (is_hash)
+) /*$wgDBTableOptions*/;
--
To view, visit https://gerrit.wikimedia.org/r/67636
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I540886ca642dcdaa2cdcaf7d89866394dbcf228e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/InviteSignup
Gerrit-Branch: master
Gerrit-Owner: Nikerabbit <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits