http://www.mediawiki.org/wiki/Special:Code/MediaWiki/90043

Revision: 90043
Author:   werdna
Date:     2011-06-14 13:43:05 +0000 (Tue, 14 Jun 2011)
Log Message:
-----------
First pass at http://www.mediawiki.org/wiki/MoodBar backend.

Added Paths:
-----------
    trunk/extensions/MoodBar/
    trunk/extensions/MoodBar/ApiMoodBar.php
    trunk/extensions/MoodBar/FeedbackItem.php
    trunk/extensions/MoodBar/Messages.php
    trunk/extensions/MoodBar/MoodBar.php
    trunk/extensions/MoodBar/moodbar.sql

Added: trunk/extensions/MoodBar/ApiMoodBar.php
===================================================================
--- trunk/extensions/MoodBar/ApiMoodBar.php                             (rev 0)
+++ trunk/extensions/MoodBar/ApiMoodBar.php     2011-06-14 13:43:05 UTC (rev 
90043)
@@ -0,0 +1,83 @@
+<?php
+
+class ApiMoodBar extends ApiBase {
+       public function execute() {
+               $params = $this->extractRequestParams();
+               
+               $params['page'] = Title::newFromText( $params['page'] );
+               
+               // Params are deliberately named the same as the properties,
+               //  just slurp them through.
+               $item = MBFeedbackItem::create( $params );
+               
+               $item->save();
+               
+               $result = array( 'result' => 'success' );
+               $this->getResult()->addValue( null, $this->getModuleName(), 
+       }
+       
+       public function needsToken() {
+               return true;
+       }
+
+       public function getTokenSalt() {
+               return '';
+       }
+
+       public function getAllowedParams() {
+               return array(
+                       'page' => array(
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'type' => array(
+                               ApiBase::PARAM_REQUIRED => true,
+                               ApiBase::PARAM_TYPE => 
MBFeedbackItem::getValidTypes(),
+                       ),
+                       'comment' => array(
+                               ApiBase::PARAM_REQUIRED => true,
+                       ),
+                       'anonymize' => array(
+                               ApiBase::PARAM_TYPE => 'boolean',
+                       ),
+                       'editmode' => array(
+                               ApiBase::PARAM_TYPE => 'boolean',
+                       ),
+                       'useragent' => null,
+                       'system' => null,
+                       'locale' => null,
+                       'bucket' => null,
+               );
+       }
+
+       public function mustBePosted() {
+               return true;
+       }
+
+       public function isWriteMode() {
+               return true;
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id: ApiThreadAction.php 88574 2011-05-22 
13:31:30Z werdna $';
+       }
+       
+       public function getPossibleErrors() {
+               return array_merge( parent::getPossibleErrors(), array(
+                       
+               ) );
+       }
+       
+       public function getParamDescription() {
+               return array(
+                       'page' => 'The page the feedback is on',
+                       'type' => 'The type of feedback being provided',
+                       'comment' => 'The feedback text',
+                       'anonymize' => 'Whether to hide user information',
+                       'editmode' => 'Whether or not the feedback context is 
in edit mode',
+                       'bucket' => 'The testing bucket, if any',
+                       'useragent' => 'The User-Agent header of the browser',
+                       'system' => 'The operating system being used',
+                       'locale' => 'The locale in use',
+               );
+       }
+}

Added: trunk/extensions/MoodBar/FeedbackItem.php
===================================================================
--- trunk/extensions/MoodBar/FeedbackItem.php                           (rev 0)
+++ trunk/extensions/MoodBar/FeedbackItem.php   2011-06-14 13:43:05 UTC (rev 
90043)
@@ -0,0 +1,237 @@
+<?php
+
+/**
+ * This class represents a single piece of MoodBar feedback.
+ */
+class MBFeedbackItem {
+       /** Container for the data **/
+       protected $data;
+       /** Valid data keys **/
+       protected $validMembers = array(
+                       // Feedback essentials
+                       'id', // ID in the database
+                       'comment', // The feedback itself
+                       'page', // The page where it was submitted
+                       'type',
+                       
+                       // Housekeeping
+                       'timestamp',
+                       'user', // User object who submitted the feedback
+                       'anonymize',
+                       
+                       // Statistics
+                       'useragent',
+                       'system',
+                       'locale',
+                       'editmode',
+                       'bucket',
+               );
+       
+       /** Valid values for the 'type' parameter. **/
+       protected static $validTypes = array( 'happy', 'sad', 'confused' );
+               
+       /**
+        * Default constructor.
+        * Don't use this, use either MBFeedbackItem::newFromRow or 
MBFeedbackItem::create
+        */
+       protected function __construct() {
+               $this->data = array_fill_keys( $this->validMembers, null );
+               
+               // Non-nullable boolean fields
+               $this->setProperty('anonymize', false);
+               $this->setProperty('editmode', false);
+       }
+       
+       /**
+        * Factory function to create a new MBFeedbackItem
+        * @param $info Associative array of values
+        * Valid keys: type, user, comment, page, flags, timestamp,
+        *             useragent, system, locale, bucket, anonymize
+        * @return MBFeedback object.
+        */
+       public static function create( $info ) {
+               $newObject = new self();
+               $newObject->initialiseNew( $info );
+               return $newObject;
+       }
+       
+       /**
+        * Initialiser for new MBFeedbackItems
+        * @param $info Associative array of values
+        * @see MBFeedbackItem::create
+        */
+       protected function initialiseNew( $info ) {
+               global $wgUser;
+               
+               $template = array(
+                       'user' => $wgUser,
+                       'timestamp' => wfTimestampNow(),
+               );
+               
+               $this->setProperties( $template );
+               $this->setProperties( $info );
+       }
+       
+       /**
+        * Factory function to load an MBFeedbackItem from a DB row.
+        * @param $row A row, from DatabaseBase::fetchObject
+        * @return MBFeedback object.
+        */
+       public static function load( $row ) {
+               $newObject = new self();
+               $newObject->initialiseFromRow( $row );
+               return $newObject;
+       }
+       
+       /**
+        * Initialiser for MBFeedbackItems loaded from the database
+        * @param $row A row object from DatabaseBase::fetchObject
+        * @see MBFeedbackItem::load
+        */
+       protected function initialiseFromRow( $row ) {
+               $properties = array(
+                       'id' => $row->mbf_id,
+                       'type' => $row->mbf_type,
+                       'comment' => $row->mbf_comment,
+                       'timestamp' => $row->mbf_timestamp,
+                       'anonymize' => $row->mbf_anonymous,
+                       'useragent' => $row->mbf_user_agent,
+                       'system' => $row->mbf_system_type,
+                       'locale' => $row->mbf_locale,
+                       'bucket' => $row->mbf_bucket,
+                       'editmode' => $row->mbf_editing,
+               );
+               
+               $properties['page'] = Title::makeTitleSafe( 
$row->mbf_namespace, $row->mbf_title );
+               
+               if ( $row->mbf_user_id > 0 ) {
+                       $properties['user'] = User::newFromId( 
$row->mbf_user_id );
+               } else {
+                       $properties['user'] = User::newFromName( 
$row->mbf_user_ip );
+               }
+               
+               $this->setProperties( $properties );
+       }
+       
+       /**
+        * Set a group of properties. Throws an exception on invalid property.
+        * @param $values An associative array of properties to set.
+        */
+       public function setProperties( $values ) {
+               foreach( $values as $key => $value ) {
+                       if ( ! $this->isValidKey($key) ) {
+                               throw new MWException( "Attempt to set invalid 
property $key" );
+                       }
+                       
+                       if ( ! $this->validatePropertyValue($key, $value) ) {
+                               throw new MWException( "Attempt to set invalid 
value for $key" );
+                       }
+                       
+                       $this->data[$key] = $value;
+               }
+       }
+       
+       /**
+        * Set a group of values.
+        * @param $key The property to set.
+        * @param $value The value to give it.
+        */
+       public function setProperty( $key, $value ) {
+               $this->setProperties( array( $key => $value ) );
+       }
+       
+       /**
+        * Get a property.
+        * @param $key The property to get
+        * @return The property value.
+        */
+       public function getProperty( $key ) {
+               if ( ! $this->isValidKey($key) ) {
+                       throw new MWException( "Attempt to get invalid property 
$key" );
+               }
+               
+               return $this->data[$key];
+       }
+       
+       /**
+        * Check a property key for validity.
+        * If a property key is valid, it will be prefilled to NULL.
+        * @param $key The property key to check.
+        */
+       public function isValidKey( $key ) {
+               return in_array( $key, $this->validMembers );
+       }
+       
+       /**
+        * Check if a property value is valid for that property
+        * @param $key The key of the property to check.
+        * @param $value The value to check
+        * @return Boolean
+        */
+       public function validatePropertyValue( $key, $value ) {
+               if ( $key == 'user' ) {
+                       return $value instanceof User || $value instanceof 
StubUser;
+               } elseif ( $key == 'page' ) {
+                       return $value instanceof Title || $value instanceof 
StubTitle;
+               } elseif ( $key == 'type' ) {
+                       return in_array( $value, self::$validTypes );
+               }
+               
+               return true;
+       }
+       
+       /**
+        * Writes this MBFeedbackItem to the database.
+        * Throws an exception if this it is already in the database.
+        * @return The MBFeedbackItem's new ID.
+        */
+       public function save() {
+       
+               if ( $this->getProperty('id') != null ) {
+                       throw new MWException( "This ".__CLASS__." is already 
in the database." );
+               }
+               
+               $dbw = wfGetDB( DB_MASTER );
+               
+               $row = array(
+                       'mbf_id' => $dbw->nextSequenceValue( 
'moodbar_feedback_mbf_id' ),
+                       'mbf_type' => $this->getProperty('type'),
+                       'mbf_comment' => $this->getProperty('comment'),
+                       'mbf_timestamp' => 
$dbw->timestamp($this->getProperty('timestamp')),
+                       'mbf_anonymous' => $this->getProperty('anonymize'),
+                       'mbf_user_agent' => $this->getProperty('useragent'),
+                       'mbf_system_type' => $this->getProperty('system'),
+                       'mbf_locale' => $this->getProperty('locale'),
+                       'mbf_bucket' => $this->getProperty('bucket'),
+                       'mbf_editing' => $this->getProperty('editmode'),
+               );
+               
+               $user = $this->getProperty('user');
+               if ( $user->isAnon() ) {
+                       $row['mbf_user_id'] = 0;
+                       $row['mbf_user_ip'] = $user->getName();
+               } else {
+                       $row['mbf_user_id'] = $user->getId();
+               }
+               
+               $page = $this->getProperty('page');
+               if ( $page ) {
+                       $row['mbf_namespace'] = $page->getNamespace();
+                       $row['mbf_title'] = $page->getDBkey();
+               }
+               
+               $dbw->insert( 'moodbar_feedback', $row, __METHOD__ );
+               
+               $this->setProperty( 'id', $dbw->insertId() );
+               
+               return $this->getProperty('id');
+       }
+       
+       /**
+        * Gets the valid types of a feedback item.
+        */
+       public static function getValidTypes() {
+               return self::$validTypes;
+       }
+       
+}

Added: trunk/extensions/MoodBar/Messages.php
===================================================================
--- trunk/extensions/MoodBar/Messages.php                               (rev 0)
+++ trunk/extensions/MoodBar/Messages.php       2011-06-14 13:43:05 UTC (rev 
90043)
@@ -0,0 +1,5 @@
+<?php
+
+$messages['en'] = array(
+       'moodbar-desc' => 'Allows specified users to send their "mood" back to 
the site operator.",
+);

Added: trunk/extensions/MoodBar/MoodBar.php
===================================================================
--- trunk/extensions/MoodBar/MoodBar.php                                (rev 0)
+++ trunk/extensions/MoodBar/MoodBar.php        2011-06-14 13:43:05 UTC (rev 
90043)
@@ -0,0 +1,37 @@
+<?php
+/**
+ * MoodBar extension
+ * Allows specified users to send their "mood" back to the site operator.
+ */
+
+$wgExtensionCredits['other'][] = array(
+       'author' => array( 'Andrew Garrett', 'Timo Tijhof' ),
+       'descriptionmsg' => 'moodbar-desc',
+       'name' => 'MoodBar',
+       'url' => 'http://www.mediawiki.org/wiki/MoodBar',
+       'version' => '0.1',
+       'path' => __FILE__,
+);
+
+// Object model
+$wgAutoloadClasses['MBFeedbackItem'] = dirname(__FILE__).'/FeedbackItem.php';
+
+// API
+$wgAutoloadClasses['ApiMoodBar'] = dirname(__FILE__).'/ApiMoodBar.php';
+$wgAPIModules['moodbar'] = 'ApiMoodBar';
+
+// Internationalisation
+$wgExtensionMessagesFiles = dirname(__FILE__).'/Messages.php';
+
+// Resources
+$mbResourceTemplate = array(
+       'localBasePath' => dirname(__FILE__),
+       'remoteExtPath' => 'MoodBar'
+);
+
+$wgResourceModules['ext.moodBar'] = $mbResourceTemplate + array(
+       'styles' => array(  ),
+       'scripts' => array(  ),
+       'dependencies' => array(  ),
+       'messages' => array( ),
+);

Added: trunk/extensions/MoodBar/moodbar.sql
===================================================================
--- trunk/extensions/MoodBar/moodbar.sql                                (rev 0)
+++ trunk/extensions/MoodBar/moodbar.sql        2011-06-14 13:43:05 UTC (rev 
90043)
@@ -0,0 +1,30 @@
+CREATE TABLE /*_*/moodbar_feedback (
+       mbf_id int unsigned NOT NULL PRIMARY KEY auto_increment, -- Primary key
+       mbf_type varchar(32) binary NOT NULL, -- Type of feedback
+       
+       -- User who provided the feedback
+       mbf_user_id int unsigned NOT NULL, -- User ID, or zero
+       mbf_user_ip varchar(255) binary NULL, -- If anonymous, user's IP address
+       
+       -- Page where the feedback was received
+       -- Nullable.
+       mbf_namespace int,
+       mbf_title varchar(255) binary,
+       
+       -- The feedback itself
+       mbf_comment varchar(255) binary,
+       
+       -- Options and context
+       mbf_anonymous tinyint unsigned not null default 0, -- Anonymity
+       mbf_timestamp varchar(14) binary not null, -- When feedback was received
+       mbf_system_type varchar(64) binary null, -- Operating System
+       mbf_user_agent varchar(255) binary null, -- User-Agent header
+       mbf_locale varchar(32) binary null, -- The locale of the user's browser
+       mbf_editing tinyint unsigned not null, -- Whether or not the user was 
editing
+       mbf_bucket varchar(128) binary null -- Bucket, for A/B testing
+) /*$wgDBtableOptions*/;
+
+-- A little overboard with the indexes perhaps, but we want to be able to dice 
this data a lot!
+CREATE INDEX /*i*/type_timestamp ON /*_*/moodbar_feedback 
(mbf_type,mbf_timestamp);
+CREATE INDEX /*i*/user_timestamp ON /*_*/moodbar_feedback 
(mbf_user_id,mbf_user_ip,mbf_timestamp);
+CREATE INDEX /*i*/title_type ON /*_*/moodbar_feedback 
(mbf_namespace,mbf_title,mbf_type,mbf_timestamp);


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to