r93131 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r93130‎ | r93131 | r93132 >
Date:21:58, 25 July 2011
Author:catrope
Status:ok
Tags:
Comment:
1.17wmf1: Add EditPageTracking and MoodBar extensions from trunk
Modified paths:
  • /branches/wmf/1.17wmf1/extensions/EditPageTracking (added) (history)
  • /branches/wmf/1.17wmf1/extensions/MoodBar (added) (history)

Diff [purge]

Index: branches/wmf/1.17wmf1/extensions/EditPageTracking/edit_page_tracking.sql
@@ -0,0 +1,14 @@
 2+-- Tables for EditPageTracking extension
 3+-- Note: Rows are deliberately not always unique, because we might want to track more than one event
 4+CREATE TABLE /*_*/edit_page_tracking (
 5+ -- User ID
 6+ ept_user bigint unsigned not null,
 7+ -- Timestamp when the edit form was viewed
 8+ ept_timestamp varbinary(14) not null,
 9+ -- Page that the edit form was viewed for
 10+ -- Not used at the moment, but useful for statistics
 11+ ept_namespace int not null,
 12+ ept_title varbinary(255) not null
 13+) /*$wgDBTableOptions*/;
 14+
 15+CREATE INDEX /*i*/user_timestamp ON /*_*/edit_page_tracking (ept_user, ept_timestamp);
Property changes on: branches/wmf/1.17wmf1/extensions/EditPageTracking/edit_page_tracking.sql
___________________________________________________________________
Added: svn:eol-style
116 + native
Index: branches/wmf/1.17wmf1/extensions/EditPageTracking/EditPageTracking.i18n.php
@@ -0,0 +1,88 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for EditPageTracking extension.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Andrew Garrett
 14+ */
 15+
 16+$messages['en'] = array(
 17+ 'editpagetracking-desc' => 'Records the first time each user views the edit page',
 18+);
 19+
 20+/** Message documentation (Message documentation)
 21+ * @author Purodha
 22+ */
 23+$messages['qqq'] = array(
 24+ 'editpagetracking-desc' => '{{desc}}',
 25+);
 26+
 27+/** Belarusian (Taraškievica orthography) (‪Беларуская (тарашкевіца)‬)
 28+ * @author Wizardist
 29+ */
 30+$messages['be-tarask'] = array(
 31+ 'editpagetracking-desc' => 'Захоўвае першае наведваньне старонкі рэдагаваньня ўдзельнікам',
 32+);
 33+
 34+/** German (Deutsch)
 35+ * @author Kghbln
 36+ */
 37+$messages['de'] = array(
 38+ 'editpagetracking-desc' => 'Ermöglicht die Aufzeichnung des erstens Besuchs einer Bearbeitungsseite durch einen Benutzer',
 39+);
 40+
 41+/** Hebrew (עברית)
 42+ * @author Amire80
 43+ */
 44+$messages['he'] = array(
 45+ 'editpagetracking-desc' => 'שמירת הפעם הראשונה שעל משתמש רואה את דך העריכה',
 46+);
 47+
 48+/** Interlingua (Interlingua)
 49+ * @author McDutchie
 50+ */
 51+$messages['ia'] = array(
 52+ 'editpagetracking-desc' => 'Registra le prime vice que cata usator visualisa le pagina de modification',
 53+);
 54+
 55+/** Colognian (Ripoarisch)
 56+ * @author Purodha
 57+ */
 58+$messages['ksh'] = array(
 59+ 'editpagetracking-desc' => 'Deiht et eezde Mohl faß hallde, wann ene Metmaacher op en Sigg för et Ändere kütt.',
 60+);
 61+
 62+/** Luxembourgish (Lëtzebuergesch)
 63+ * @author Robby
 64+ */
 65+$messages['lb'] = array(
 66+ 'editpagetracking-desc' => "Enregistréiert déi éischte Kéier wann e Benotzer d'Ännerungssäit kuckt",
 67+);
 68+
 69+/** Macedonian (Македонски)
 70+ * @author Bjankuloski06
 71+ */
 72+$messages['mk'] = array(
 73+ 'editpagetracking-desc' => 'Ја евидентира првата посета (погледнување) на страницата за уредување на секој корисник',
 74+);
 75+
 76+/** Norwegian (bokmål)‬ (‪Norsk (bokmål)‬)
 77+ * @author Event
 78+ */
 79+$messages['no'] = array(
 80+ 'editpagetracking-desc' => 'Det blir registrert første gang hver bruker ser på redigeringssiden',
 81+);
 82+
 83+/** Portuguese (Português)
 84+ * @author Hamilton Abreu
 85+ */
 86+$messages['pt'] = array(
 87+ 'editpagetracking-desc' => 'Regista a primeira vez que cada utilizador visita a página de edição',
 88+);
 89+
Property changes on: branches/wmf/1.17wmf1/extensions/EditPageTracking/EditPageTracking.i18n.php
___________________________________________________________________
Added: svn:eol-style
190 + native
Index: branches/wmf/1.17wmf1/extensions/EditPageTracking/EditPageTracking.php
@@ -0,0 +1,131 @@
 2+<?php
 3+/**
 4+ * EditPageTracking extension
 5+ * Allows tracking when users first click on "edit page"
 6+ */
 7+
 8+$wgExtensionCredits['other'][] = array(
 9+ 'author' => array( 'Andrew Garrett' ),
 10+ 'descriptionmsg' => 'editpagetracking-desc',
 11+ 'name' => 'EditPageTracking',
 12+ 'url' => 'http://www.mediawiki.org/wiki/Extension:EditPageTracking',
 13+ 'version' => '0.1',
 14+ 'path' => __FILE__,
 15+);
 16+
 17+$wgExtensionMessagesFiles['EditPageTracking'] = dirname(__FILE__).'/EditPageTracking.i18n.php';
 18+
 19+$wgHooks['LoadExtensionSchemaUpdates'][] = 'EditPageTracking::doSchemaUpdates';
 20+$wgHooks['EditPage::showEditForm:initial'][] = 'EditPageTracking::onEditForm';
 21+
 22+/** Configuration **/
 23+
 24+/** The registration cutoff for recording this data **/
 25+$wgEditPageTrackingRegistrationCutoff = null;
 26+
 27+abstract class EditPageTracking {
 28+
 29+ /**
 30+ * Applies EditPageTracking schema updates.
 31+ *
 32+ * @param $updater DatabaseUpdater
 33+ */
 34+ public static function doSchemaUpdates( $updater = null ) {
 35+ $updater->addExtensionUpdate( array( 'addTable', 'edit_page_tracking',
 36+ dirname(__FILE__).'/edit_page_tracking.sql', true ) );
 37+
 38+ return true;
 39+ }
 40+
 41+ /**
 42+ * Monitors edit page usage
 43+ */
 44+ public static function onEditForm( EditPage $editPage ) {
 45+ global $wgUser, $wgEditPageTrackingRegistrationCutoff, $wgMemc;
 46+
 47+ // Anonymous users
 48+ if ( $wgUser->isAnon() ) {
 49+ return true;
 50+ }
 51+
 52+ if ( $wgEditPageTrackingRegistrationCutoff &&
 53+ $wgUser->getRegistration() < $wgEditPageTrackingRegistrationCutoff )
 54+ {
 55+ // User registered before the cutoff
 56+ return true;
 57+ }
 58+
 59+ if ( EditPageTracking::getFirstEditPage( $wgUser ) ) {
 60+ // Already stored.
 61+ return true;
 62+ }
 63+
 64+ // Record it
 65+ $dbw = wfGetDB( DB_MASTER );
 66+
 67+ $title = $editPage->getArticle()->getTitle();
 68+ $timestamp = wfTimestampNow();
 69+
 70+ $row = array(
 71+ 'ept_user' => $wgUser->getId(),
 72+ 'ept_namespace' => $title->getNamespace(),
 73+ 'ept_title' => $title->getDBkey(),
 74+ 'ept_timestamp' => $dbw->timestamp( $timestamp ),
 75+ );
 76+
 77+ $dbw->insert( 'edit_page_tracking', $row, __METHOD__ );
 78+
 79+ $wgUser->mFirstEditPage = $timestamp;
 80+
 81+ $cacheKey = wfMemcKey( 'first-edit-page', $wgUser->getId() );
 82+ $wgMemc->set($cacheKey, $timestamp, 86400);
 83+
 84+ return true;
 85+ }
 86+
 87+ /**
 88+ * Gets the first time a user opened an edit page
 89+ * @param $user User The User to check.
 90+ * @return The timestamp of the first time the user opened an edit page.
 91+ * false for an anonymous user, null for a user who has never opened an edit page.
 92+ */
 93+ public static function getFirstEditPage( $user ) {
 94+ global $wgMemc;
 95+
 96+ if ( isset($user->mFirstEditPage) ) {
 97+ return $user->mFirstEditPage;
 98+ }
 99+
 100+ if ( $user->isAnon() ) {
 101+ return false;
 102+ }
 103+
 104+ $cacheKey = wfMemcKey( 'first-edit-page', $user->getId() );
 105+ $cacheVal = $wgMemc->get($cacheKey);
 106+
 107+ if ( $cacheVal !== false ) {
 108+ $user->mFirstEditPage = $cacheVal;
 109+ return $cacheVal;
 110+ }
 111+
 112+ $dbr = wfGetDB( DB_SLAVE );
 113+
 114+ $res = $dbr->select( 'edit_page_tracking', 'ept_timestamp',
 115+ array( 'ept_user' => $user->getID() ),
 116+ __METHOD__, array( 'ORDER BY' => 'ept_timestamp asc' ) );
 117+
 118+ if ( $dbr->numRows($res) == 0 ) {
 119+ $user->mFirstEditPage = null;
 120+ $wgMemc->set( $cacheKey, null, 86400 );
 121+ return null;
 122+ }
 123+
 124+ $row = $dbr->fetchObject( $res );
 125+
 126+ $user->mFirstEditPage = wfTimestamp( TS_MW, $row->ept_timestamp );
 127+ $wgMemc->set($cacheKey, $user->mFirstEditPage, 86400);
 128+
 129+ return $user->mFirstEditPage;
 130+ }
 131+
 132+}
Property changes on: branches/wmf/1.17wmf1/extensions/EditPageTracking/EditPageTracking.php
___________________________________________________________________
Added: svn:eol-style
1133 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/sql/MoodBar.sql
@@ -0,0 +1,30 @@
 2+CREATE TABLE /*_*/moodbar_feedback (
 3+ mbf_id int unsigned NOT NULL PRIMARY KEY auto_increment, -- Primary key
 4+ mbf_type varchar(32) binary NOT NULL, -- Type of feedback
 5+
 6+ -- User who provided the feedback
 7+ mbf_user_id int unsigned NOT NULL, -- User ID, or zero
 8+ mbf_user_ip varchar(255) binary NULL, -- If anonymous, user's IP address
 9+ mbf_user_editcount int unsigned NOT NULL, -- Edit count of the user
 10+
 11+ -- Page where the feedback was received
 12+ -- Nullable.
 13+ mbf_namespace int,
 14+ mbf_title varchar(255) binary,
 15+
 16+ -- The feedback itself
 17+ mbf_comment varchar(255) binary,
 18+
 19+ -- Options and context
 20+ mbf_anonymous tinyint unsigned not null default 0, -- Anonymity
 21+ mbf_timestamp varchar(14) binary not null, -- When feedback was received
 22+ mbf_system_type varchar(64) binary null, -- Operating System
 23+ mbf_user_agent varchar(255) binary null, -- User-Agent header
 24+ mbf_locale varchar(32) binary null, -- The locale of the user's browser
 25+ mbf_editing tinyint unsigned not null, -- Whether or not the user was editing
 26+ mbf_bucket varchar(128) binary null -- Bucket, for A/B testing
 27+) /*$wgDBtableOptions*/;
 28+
 29+-- A little overboard with the indexes perhaps, but we want to be able to dice this data a lot!
 30+CREATE INDEX /*i*/type_timestamp ON /*_*/moodbar_feedback (mbf_type,mbf_timestamp);
 31+CREATE INDEX /*i*/title_type ON /*_*/moodbar_feedback (mbf_namespace,mbf_title,mbf_type,mbf_timestamp);
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/sql/MoodBar.sql
___________________________________________________________________
Added: svn:eol-style
132 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/sql/mbf_user_editcount.sql
@@ -0,0 +1,2 @@
 2+-- Adds the mbf_user_editcount
 3+ALTER TABLE /*_*/moodbar_feedback ADD COLUMN mbf_user_editcount int unsigned NOT NULL;
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/sql/mbf_user_editcount.sql
___________________________________________________________________
Added: svn:eol-style
14 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/ApiMoodBar.php
@@ -0,0 +1,92 @@
 2+<?php
 3+
 4+class ApiMoodBar extends ApiBase {
 5+ public function execute() {
 6+ $params = $this->extractRequestParams();
 7+
 8+ $params['page'] = Title::newFromText( $params['page'] );
 9+
 10+ // Params are deliberately named the same as the properties,
 11+ // just slurp them through.
 12+ $item = MBFeedbackItem::create( array() );
 13+
 14+ $setParams = array();
 15+ foreach( $params as $key => $value ) {
 16+ if ( $item->isValidKey( $key ) ) {
 17+ $setParams[$key] = $value;
 18+ }
 19+ }
 20+
 21+ $item->setProperties( $setParams );
 22+
 23+ $item->save();
 24+
 25+ $result = array( 'result' => 'success' );
 26+ $this->getResult()->addValue( null, $this->getModuleName(), $result );
 27+ }
 28+
 29+ public function needsToken() {
 30+ return true;
 31+ }
 32+
 33+ public function getTokenSalt() {
 34+ return '';
 35+ }
 36+
 37+ public function getAllowedParams() {
 38+ return array(
 39+ 'page' => array(
 40+ ApiBase::PARAM_REQUIRED => true,
 41+ ),
 42+ 'type' => array(
 43+ ApiBase::PARAM_REQUIRED => true,
 44+ ApiBase::PARAM_TYPE => MBFeedbackItem::getValidTypes(),
 45+ ),
 46+ 'comment' => array(
 47+ ApiBase::PARAM_REQUIRED => true,
 48+ ),
 49+ 'anonymize' => array(
 50+ ApiBase::PARAM_TYPE => 'boolean',
 51+ ),
 52+ 'editmode' => array(
 53+ ApiBase::PARAM_TYPE => 'boolean',
 54+ ),
 55+ 'useragent' => null,
 56+ 'system' => null,
 57+ 'locale' => null,
 58+ 'bucket' => null,
 59+ 'token' => null,
 60+ );
 61+ }
 62+
 63+ public function mustBePosted() {
 64+ return true;
 65+ }
 66+
 67+ public function isWriteMode() {
 68+ return true;
 69+ }
 70+
 71+ public function getVersion() {
 72+ return __CLASS__ . ': $Id$';
 73+ }
 74+
 75+ public function getParamDescription() {
 76+ return array(
 77+ 'page' => 'The page the feedback is on',
 78+ 'type' => 'The type of feedback being provided',
 79+ 'comment' => 'The feedback text',
 80+ 'anonymize' => 'Whether to hide user information',
 81+ 'editmode' => 'Whether or not the feedback context is in edit mode',
 82+ 'bucket' => 'The testing bucket, if any',
 83+ 'useragent' => 'The User-Agent header of the browser',
 84+ 'system' => 'The operating system being used',
 85+ 'locale' => 'The locale in use',
 86+ 'token' => 'An edit token',
 87+ );
 88+ }
 89+
 90+ public function getDescription() {
 91+ return 'Allows users to submit feedback about their experiences on the site';
 92+ }
 93+}
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/ApiMoodBar.php
___________________________________________________________________
Added: svn:keywords
194 + Id
Added: svn:eol-style
295 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/MoodBar.i18n.php
@@ -0,0 +1,596 @@
 2+<?php
 3+/**
 4+ * Internationalisation file for MoodBar extension.
 5+ *
 6+ * @file
 7+ * @ingroup Extensions
 8+ */
 9+
 10+$messages = array();
 11+
 12+/** English
 13+ * @author Andrew Garrett
 14+ */
 15+
 16+$messages['en'] = array(
 17+ 'moodbar-desc' => 'Allows specified users to send their "mood" back to the site operator',
 18+ // Portlet link
 19+ 'moodbar-trigger-feedback' => 'Feedback about editing',
 20+ 'moodbar-trigger-share' => 'Share your experience',
 21+ 'moodbar-trigger-editing' => 'Editing $1...',
 22+ 'tooltip-p-moodbar-trigger-feedback' => '',
 23+ 'tooltip-p-moodbar-trigger-share' => '',
 24+ 'tooltip-p-moodbar-trigger-editing' => '',
 25+ // Overlay
 26+ 'moodbar-close' => '(close)',
 27+ 'moodbar-intro-feedback' => 'Editing $1 made me... ',
 28+ 'moodbar-intro-share' => 'My experience on $1 made me...',
 29+ 'moodbar-intro-editing' => 'Editing $1 made me...',
 30+ 'moodbar-type-happy-title' => 'Happy',
 31+ 'moodbar-type-sad-title' => 'Sad',
 32+ 'moodbar-type-confused-title' => 'Confused',
 33+ 'tooltip-moodbar-what' => 'Learn more about this feature',
 34+ 'moodbar-what-target' => 'http://www.mediawiki.org/wiki/MoodBar',
 35+ 'moodbar-what-label' => 'What is this?',
 36+ 'moodbar-what-collapsed' => '▶', // Ignore, do not translate. &#x25BC;
 37+ 'moodbar-what-expanded' => '▼', // Ignore, do not translate. &#x25B6;
 38+ 'moodbar-what-content' => 'This feature is designed to help the Wikipedia community understand the experience of people editing the encyclopedia.
 39+For more information, please visit the $1.',
 40+ 'moodbar-what-link' => 'feature page',
 41+ 'moodbar-privacy' => 'By submitting, you agree to transparency under these $1.',
 42+ 'moodbar-privacy-link' => 'terms',
 43+ 'moodbar-disable-link' => "I'm not interested. Please disable this feature.",
 44+ 'moodbar-form-title' => 'Because...',
 45+ 'moodbar-form-note' => '140 character maximum',
 46+ 'moodbar-form-note-dynamic' => '$1 characters remaining',
 47+ 'moodbar-form-submit' => 'Share Feedback',
 48+ 'moodbar-form-policy-text' => 'By submitting, $1',
 49+ 'moodbar-form-policy-label' => 'our policy',
 50+ 'moodbar-loading-title' => 'Sharing...',
 51+ 'moodbar-success-title' => 'Thanks!',
 52+ 'moodbar-error-title' => 'Oops!',
 53+ 'moodbar-loading-subtitle' => 'We are sharing your feedback…',
 54+ 'moodbar-success-subtitle' => 'Sharing your editing experience helps us improve $1.',
 55+ 'moodbar-error-subtitle' => 'Something went wrong! Please try sharing your mood again later.',
 56+ // Special:MoodBar
 57+ 'right-moodbar-view' => 'View and export MoodBar feedback',
 58+ 'moodbar-admin-title' => 'MoodBar feedback',
 59+ 'moodbar-admin-intro' => 'This page allows you to view feedback submitted with the MoodBar.',
 60+ 'moodbar-admin-empty' => 'No results',
 61+ 'moodbar-header-id' => 'Feedback ID',
 62+ 'moodbar-header-timestamp' => 'Timestamp',
 63+ 'moodbar-header-type' => 'Type',
 64+ 'moodbar-header-page' => 'Page',
 65+ 'moodbar-header-usertype' => 'User type',
 66+ 'moodbar-header-user' => 'User',
 67+ 'moodbar-header-editmode' => 'Edit mode',
 68+ 'moodbar-header-bucket' => 'Testing bucket',
 69+ 'moodbar-header-system' => 'System type',
 70+ 'moodbar-header-locale' => 'Locale',
 71+ 'moodbar-header-useragent' => 'User-Agent',
 72+ 'moodbar-header-comment' => 'Comments',
 73+ 'moodbar-header-user-editcount' => 'User edit count',
 74+ 'moodbar-header-namespace' => 'Namespace',
 75+ 'moodbar-header-own-talk' => 'Own talk page',
 76+ // Mood types
 77+ 'moodbar-type-happy' => 'Happy',
 78+ 'moodbar-type-sad' => 'Sad',
 79+ 'moodbar-type-confused' => 'Confused',
 80+ // User types
 81+ 'moodbar-user-anonymized' => 'Anonymized',
 82+ 'moodbar-user-ip' => 'IP Address',
 83+ 'moodbar-user-user' => 'Registered user',
 84+);
 85+
 86+/** Message documentation (Message documentation)
 87+ * @author Krinkle
 88+ * @author SPQRobin
 89+ */
 90+
 91+$messages['qqq'] = array(
 92+ 'moodbar-desc' => 'This is a feature in development. See [[mw:MoodBar 0.1/Design]] for background information.',
 93+ 'moodbar-trigger-editing' => "Link text of the MoodBar overlay trigger. \$1 is the SITENAME. The implied sentence is ''\"Using [Sitename] made me happy/sad/...\"''. See [[mw:MoodBar 0.1/Design]] for background development information.",
 94+ 'moodbar-trigger-feedback' => 'Link text of the MoodBar overlay trigger. $1 is the SITENAME.',
 95+ 'moodbar-intro-editing' => 'Intro title of the MoodBar overlay trigger. $1 is the SITENAME.',
 96+ 'moodbar-intro-feedback' => 'Intro title of the MoodBar overlay trigger. $1 is the SITENAME.',
 97+ 'moodbar-close' => 'Link text of the close-button. Make sure to include parentheses.
 98+
 99+See also:
 100+* {{msg|parentheses}}',
 101+ 'tooltip-moodbar-what' => 'Tooltip displayed when hovering the What-link.
 102+
 103+See also:
 104+* {{msg|moodbar-what-label}}',
 105+ 'moodbar-what-target' => 'Complete URL (including http://) or article name where more info can be found.',
 106+ 'moodbar-what-label' => 'Link text for the page where more info abut MoodBar can be found.',
 107+ 'moodbar-form-policy-text' => 'Text displayed below the input area.
 108+
 109+See also:
 110+* {{msg|moodbar-form-policy-label}}',
 111+ 'moodbar-form-policy-label' => 'Label text for the link to the privacy policy,.
 112+
 113+See also:
 114+* {{msg|moodbar-form-policy-text}}',
 115+ 'moodbar-loading-title' => 'Title of the screen when the widget is loading.',
 116+ 'moodbar-success-title' => 'Title of the screen after the feedback was successfullyully submitted.',
 117+ 'moodbar-error-title' => 'Title of the screen when after an error occurred and submission aborted.',
 118+ 'moodbar-loading-subtitle' => 'Subtitle of Loading-screen. $1 is the SITENAME',
 119+ 'moodbar-success-subtitle' => 'Subtitle of screen when feedback was successfullyully submitted. $1 is the SITENAME',
 120+ 'moodbar-error-subtitle' => 'Subtitle of screen when an error occurred. $1 is the SITENAME',
 121+);
 122+
 123+/** Message documentation (Message documentation)
 124+ * @author Purodha
 125+ * @author Raymond
 126+ * @author SPQRobin
 127+ */
 128+$messages['qqq'] = array(
 129+ 'moodbar-desc' => '{{desc}}
 130+This is a feature in development. See [[mw:MoodBar 0.1/Design]] for background information.',
 131+ 'moodbar-trigger-feedback' => 'Link text of the MoodBar overlay trigger. $1 is the SITENAME.',
 132+ 'moodbar-trigger-editing' => "Link text of the MoodBar overlay trigger. \$1 is the SITENAME. The implied sentence is ''\"Using [Sitename] made me happy/sad/...\"''. See [[mw:MoodBar 0.1/Design]] for background development information.",
 133+ 'moodbar-close' => 'Link text of the close-button. Make sure to include parentheses.
 134+
 135+See also:
 136+* {{msg|parentheses}}',
 137+ 'moodbar-intro-feedback' => 'Intro title of the MoodBar overlay trigger. $1 is the SITENAME.',
 138+ 'moodbar-intro-editing' => '[[File:MoodBar-Step-1.png|right|200px]]
 139+Intro title of the MoodBar overlay trigger. $1 is the SITENAME.',
 140+ 'tooltip-moodbar-what' => 'Tooltip displayed when hovering the What-link.
 141+
 142+See also:
 143+* {{msg|moodbar-what-label}}',
 144+ 'moodbar-what-label' => 'Link text for the page where more info abut MoodBar can be found.',
 145+ 'moodbar-privacy' => 'Parameters:
 146+*$1 - a link having the anchor text {{msg-mw|moodbar-privacy-link}}',
 147+ 'moodbar-privacy-link' => 'This is the anchor text being used in the link replacing $1 in the message {{msg-mw|moodbar-privacy}}',
 148+);
 149+
 150+/** Afrikaans (Afrikaans)
 151+ * @author Naudefj
 152+ */
 153+$messages['af'] = array(
 154+ 'moodbar-desc' => 'Laat spesifieke gebruikers toe om hulle gemoedstoestand aan die webwerf se operateur terug te stuur',
 155+);
 156+
 157+/** Belarusian (Taraškievica orthography) (‪Беларуская (тарашкевіца)‬)
 158+ * @author EugeneZelenko
 159+ */
 160+$messages['be-tarask'] = array(
 161+ 'moodbar-desc' => 'Дазваляе вызначаным удзельнікам дасылаць іх «настрой» апэратару сайта',
 162+ 'moodbar-trigger-editing' => 'Выкарыстоўваючы $1…',
 163+ 'moodbar-trigger-feedback' => 'Водгук',
 164+);
 165+
 166+/** German (Deutsch)
 167+ * @author Kghbln
 168+ * @author Purodha
 169+ */
 170+$messages['de'] = array(
 171+ 'moodbar-desc' => 'Ermöglicht es Benutzern dem Betreiber des Wikis ihre Stimmung bezüglich des Bearbeitens von Seiten mitzuteilen',
 172+ 'moodbar-trigger-feedback' => 'Rückmeldung zum Bearbeiten',
 173+ 'moodbar-trigger-share' => 'Teile uns deinen Eindruck mit',
 174+ 'moodbar-trigger-editing' => 'Bearbeite $1 …',
 175+ 'moodbar-close' => '(schließen)',
 176+ 'moodbar-intro-feedback' => 'Rückmeldung:',
 177+ 'moodbar-intro-editing' => '$1 zu bearbeiten macht mich …',
 178+ 'moodbar-type-happy-title' => 'Glücklich',
 179+ 'moodbar-type-sad-title' => 'Traurig',
 180+ 'moodbar-type-confused-title' => 'Verwirrt',
 181+ 'tooltip-moodbar-what' => 'Mehr zu dieser Funktion in Erfahrung bringen',
 182+ 'moodbar-what-label' => 'Worum handelt es sich?',
 183+ 'moodbar-what-content' => 'Diese Funktion wurde entwickelt, damit man eine Rückmeldung geben kann, wie man sich beim Bearbeiten von Seiten in der Wikipedia fühlt.
 184+Weitere Informationen hierzu sind an der folgenden Stelle zu finden: $1.',
 185+ 'moodbar-what-link' => 'Seite zu den Funktionen',
 186+ 'moodbar-privacy' => 'Mit dem Speichern erklärst du dich mit diesen $1 einverstanden.',
 187+ 'moodbar-privacy-link' => 'Bedingungen',
 188+ 'moodbar-disable-link' => 'Ich bin nicht interessiert. Bitte diese Funktion deaktivieren.',
 189+ 'moodbar-form-title' => 'Weil …',
 190+ 'moodbar-form-note' => 'Maximal 140 Zeichen',
 191+ 'moodbar-form-note-dynamic' => '$1 Zeichen verbleibend',
 192+ 'moodbar-form-submit' => 'Rückmeldung senden',
 193+ 'moodbar-form-policy-text' => 'Mit dem Senden, $1',
 194+ 'moodbar-form-policy-label' => 'unserer Richtlinie',
 195+ 'moodbar-loading-title' => 'Am senden ...',
 196+ 'moodbar-success-title' => 'Vielen Dank!',
 197+ 'moodbar-error-title' => 'Hoppla!',
 198+ 'moodbar-success-subtitle' => 'Uns deine Stimmung mitzuteilen hilft uns dabei die Wikipedia weiter zu verbessern.',
 199+ 'moodbar-error-subtitle' => 'Etwas ist schief gelaufen. Bitte versuche es später noch einmal uns deine Stimmung mitzuteilen.',
 200+ 'right-moodbar-view' => 'Rückmeldung zur Stimmung ansehen und exportieren',
 201+ 'moodbar-admin-title' => 'Rückmeldung zur Stimmung',
 202+ 'moodbar-admin-intro' => 'Auf dieser Seite können die Rückmeldungen zur Stimmung angesehen werden',
 203+ 'moodbar-admin-empty' => 'Keine Ergebnisse',
 204+ 'moodbar-header-id' => 'Rückmeldungskennung',
 205+ 'moodbar-header-timestamp' => 'Zeitstempel',
 206+ 'moodbar-header-type' => 'Typ',
 207+ 'moodbar-header-page' => 'Seite',
 208+ 'moodbar-header-usertype' => 'Benutzerart',
 209+ 'moodbar-header-user' => 'Benutzer',
 210+ 'moodbar-header-editmode' => 'Bearbeitungsmodus',
 211+ 'moodbar-header-bucket' => 'Testumgebung',
 212+ 'moodbar-header-system' => 'Systemtyp',
 213+ 'moodbar-header-locale' => 'Gebietsschema',
 214+ 'moodbar-header-useragent' => 'Browser',
 215+ 'moodbar-header-comment' => 'Kommentare',
 216+ 'moodbar-header-user-editcount' => 'Bearbeitungszähler',
 217+ 'moodbar-header-namespace' => 'Namensraum',
 218+ 'moodbar-header-own-talk' => 'Eigene Diskussionsseite',
 219+ 'moodbar-type-happy' => 'Glücklich',
 220+ 'moodbar-type-sad' => 'Traurig',
 221+ 'moodbar-type-confused' => 'Verwirrt',
 222+ 'moodbar-user-anonymized' => 'Anonymisiert',
 223+ 'moodbar-user-ip' => 'IP-Adresse',
 224+ 'moodbar-user-user' => 'Registrierter Benutzer',
 225+);
 226+
 227+/** German (formal address) (‪Deutsch (Sie-Form)‬)
 228+ * @author Kghbln
 229+ */
 230+$messages['de-formal'] = array(
 231+ 'moodbar-trigger-share' => 'Teilen Sie uns Ihren Eindruck mit',
 232+ 'moodbar-privacy' => 'Mit dem Speichern erklären Sie sich damit einverstanden, dass wir Ihre Rückmeldung nutzen können, wie wir es in $1 beschrieben haben.',
 233+ 'moodbar-success-subtitle' => 'Uns Ihre Stimmung mitzuteilen hilft uns dabei die Wikipedia weiter zu verbessern.',
 234+ 'moodbar-error-subtitle' => 'Etwas ist schief gelaufen. Bitte versuchen Sie es später noch einmal uns Ihre Stimmung mitzuteilen.',
 235+);
 236+
 237+/** Spanish (Español)
 238+ * @author Fitoschido
 239+ */
 240+$messages['es'] = array(
 241+ 'moodbar-desc' => 'Permite a usuarios específicos enviar su «estado de ánimo» hacia el operador del sitio',
 242+);
 243+
 244+/** French (Français)
 245+ * @author Crochet.david
 246+ */
 247+$messages['fr'] = array(
 248+ 'moodbar-desc' => 'Permet aux utilisateurs spécifiés d’envoyer leur retour d’« humeur » à l’exploitant du site',
 249+);
 250+
 251+/** Franco-Provençal (Arpetan)
 252+ * @author ChrisPtDe
 253+ */
 254+$messages['frp'] = array(
 255+ 'moodbar-header-timestamp' => 'Dâta et hora',
 256+ 'moodbar-header-type' => 'Tipo',
 257+ 'moodbar-header-page' => 'Pâge',
 258+ 'moodbar-header-user' => 'Utilisator',
 259+ 'moodbar-header-useragent' => 'Agent utilisator',
 260+ 'moodbar-header-comment' => 'Comentèros',
 261+ 'moodbar-header-namespace' => 'Èspâço de noms',
 262+ 'moodbar-header-own-talk' => 'Pâge de discussion a sè',
 263+ 'moodbar-type-happy' => 'Herox',
 264+ 'moodbar-type-sad' => 'Tristo',
 265+ 'moodbar-type-confused' => 'Confondu',
 266+ 'moodbar-user-anonymized' => 'Anonimisâ',
 267+ 'moodbar-user-ip' => 'Adrèce IP',
 268+ 'moodbar-user-user' => 'Utilisator encartâ',
 269+);
 270+
 271+/** Galician (Galego)
 272+ * @author Toliño
 273+ */
 274+$messages['gl'] = array(
 275+ 'moodbar-desc' => 'Permite que os usuarios especificados envíen ao operador do sitio o seu "humor"',
 276+ 'moodbar-trigger-editing' => 'Usando $1...',
 277+ 'moodbar-trigger-feedback' => 'Comentarios',
 278+);
 279+
 280+/** Hebrew (עברית)
 281+ * @author Amire80
 282+ */
 283+$messages['he'] = array(
 284+ 'moodbar-desc' => 'מתן אפשרות למשתמשם לשלוח את "מצב הרוח" שלהם למפעיל האתר',
 285+ 'moodbar-trigger-feedback' => 'משוב על עריכה',
 286+ 'moodbar-trigger-editing' => 'עריכה $1...',
 287+ 'moodbar-close' => '(סגירה)',
 288+ 'moodbar-intro-feedback' => 'עריכת $1 גרמה לי ...',
 289+ 'moodbar-intro-editing' => 'עריכת $1 גרמה לי ...',
 290+ 'moodbar-type-happy-title' => 'שמחה',
 291+ 'moodbar-type-sad-title' => 'עצב',
 292+ 'moodbar-type-confused-title' => 'בלבול',
 293+ 'tooltip-moodbar-what' => 'מידע נוסף על התכונה הזאת',
 294+ 'moodbar-what-label' => 'מה זה?',
 295+ 'right-moodbar-view' => 'הצגה וייצוא של של משוב מסרגל מצב הרוח',
 296+ 'moodbar-admin-title' => 'משוב על סרגל מצב הרוח',
 297+ 'moodbar-admin-intro' => 'הדף הזה מאפשר לך לראות משוב שנשלח באמצעות סרגל מצב הרוח',
 298+ 'moodbar-header-id' => 'מזהה משוב',
 299+ 'moodbar-header-timestamp' => 'חותם זמן',
 300+ 'moodbar-header-type' => 'סוג',
 301+ 'moodbar-header-page' => 'דף',
 302+ 'moodbar-header-usertype' => 'סוג משתמש',
 303+ 'moodbar-header-user' => 'משתמש',
 304+ 'moodbar-header-editmode' => 'מצב עריכה',
 305+ 'moodbar-header-bucket' => 'דלי ניסוי',
 306+ 'moodbar-header-system' => 'סוג מערכת',
 307+ 'moodbar-header-locale' => 'אזור',
 308+ 'moodbar-header-useragent' => 'User-Agent (דפדפן)',
 309+ 'moodbar-header-comment' => 'תגובות',
 310+ 'moodbar-header-user-editcount' => 'מספר עריכות',
 311+);
 312+
 313+/** Interlingua (Interlingua)
 314+ * @author McDutchie
 315+ */
 316+$messages['ia'] = array(
 317+ 'moodbar-desc' => 'Permitte al usatores specificate de inviar lor "humor" retro al operator del sito',
 318+ 'moodbar-trigger-feedback' => 'Commentos super le modification',
 319+ 'moodbar-trigger-share' => 'Divider tu experientia',
 320+ 'moodbar-trigger-editing' => 'Modificar $1...',
 321+ 'moodbar-close' => '(clauder)',
 322+ 'moodbar-intro-feedback' => 'Reaction:',
 323+ 'moodbar-intro-editing' => 'Le uso de $1 me rendeva...',
 324+ 'moodbar-type-happy-title' => 'Felice',
 325+ 'moodbar-type-sad-title' => 'Triste',
 326+ 'moodbar-type-confused-title' => 'Confuse',
 327+ 'tooltip-moodbar-what' => 'Lege plus a proposito de iste function',
 328+ 'moodbar-what-label' => 'Que es isto?',
 329+ 'moodbar-what-content' => 'Iste function es designate pro adjutar le communitate de Wikipedia a comprender le experientia del personas qui modifica Wikipedia.
 330+Pro ulterior information, per favor visita le $1.',
 331+ 'moodbar-what-link' => 'pagina de function',
 332+ 'moodbar-privacy' => 'Per submitter, tu te declara de accordo que nos pote usar tu commento como explicate in $1.',
 333+ 'moodbar-privacy-link' => 'nostre politica',
 334+ 'moodbar-disable-link' => 'Isto non me interessa. Per favor disactiva iste function.',
 335+ 'moodbar-form-title' => 'Perque...',
 336+ 'moodbar-form-note' => 'maximo 140 characteres',
 337+ 'moodbar-form-note-dynamic' => 'resta $1 characteres',
 338+ 'moodbar-form-submit' => 'Inviar commento',
 339+ 'moodbar-form-policy-text' => 'Per submitter, $1',
 340+ 'moodbar-form-policy-label' => 'nostre politica',
 341+ 'moodbar-loading-title' => 'Invio in curso...',
 342+ 'moodbar-success-title' => 'Gratias!',
 343+ 'moodbar-error-title' => 'Ups!',
 344+ 'moodbar-success-subtitle' => 'Specificar tu humor nos adjuta a meliorar Wikipedia.',
 345+ 'moodbar-error-subtitle' => 'Un problema ha occurrite! Per favor tenta specificar tu humor de novo plus tarde.',
 346+ 'right-moodbar-view' => 'Vider e exportar reactiones del Barra de Humor',
 347+ 'moodbar-admin-title' => 'Reactiones del Barra de Humor',
 348+ 'moodbar-admin-intro' => 'Iste pagina permitte vider reactiones submittite con le Barra de Humor',
 349+ 'moodbar-admin-empty' => 'Nulle resultato',
 350+ 'moodbar-header-id' => 'ID del reaction',
 351+ 'moodbar-header-timestamp' => 'Data e hora',
 352+ 'moodbar-header-type' => 'Typo',
 353+ 'moodbar-header-page' => 'Pagina',
 354+ 'moodbar-header-usertype' => 'Typo de usator',
 355+ 'moodbar-header-user' => 'Usator',
 356+ 'moodbar-header-editmode' => 'Modo de modification',
 357+ 'moodbar-header-bucket' => 'Situla de test',
 358+ 'moodbar-header-system' => 'Typo de systema',
 359+ 'moodbar-header-locale' => 'Region',
 360+ 'moodbar-header-useragent' => 'Agente usator',
 361+ 'moodbar-header-comment' => 'Commentos',
 362+ 'moodbar-header-user-editcount' => 'Numero de modificationes del usator',
 363+ 'moodbar-header-namespace' => 'Spatio de nomines',
 364+ 'moodbar-header-own-talk' => 'Pagina de discussion proprie',
 365+ 'moodbar-type-happy' => 'Felice',
 366+ 'moodbar-type-sad' => 'Triste',
 367+ 'moodbar-type-confused' => 'Confuse',
 368+ 'moodbar-user-anonymized' => 'Anonymisate',
 369+ 'moodbar-user-ip' => 'Adresse IP',
 370+ 'moodbar-user-user' => 'Usator registrate',
 371+);
 372+
 373+/** Colognian (Ripoarisch)
 374+ * @author Purodha
 375+ */
 376+$messages['ksh'] = array(
 377+ 'moodbar-close' => '(zohmaache)',
 378+ 'moodbar-privacy' => 'Wä heh jät enjitt, moß met dä $1 enverschtande sen, söns moß mer et sennlohße.',
 379+ 'moodbar-privacy-link' => 'Begengonge',
 380+ 'moodbar-success-title' => 'Mer bedanke uns.',
 381+);
 382+
 383+/** Luxembourgish (Lëtzebuergesch)
 384+ * @author Robby
 385+ */
 386+$messages['lb'] = array(
 387+ 'moodbar-desc' => 'Erméiglecht et spezifesche Benotzer fir dem Responsabele vum Site hir Stëmmung ze schécken',
 388+ 'moodbar-trigger-feedback' => "Feedback iwwert d'Änneren",
 389+ 'moodbar-trigger-editing' => 'Ännert $1...',
 390+ 'moodbar-close' => '(zoumaachen)',
 391+ 'moodbar-intro-feedback' => 'Feedback:',
 392+ 'moodbar-type-happy-title' => 'Glécklech',
 393+ 'moodbar-type-sad-title' => 'Traureg',
 394+ 'moodbar-what-label' => 'Wat ass dat?',
 395+ 'moodbar-disable-link' => 'Ech sinn net interesséiert. Schalt dës Fonctioun w.e.g. aus.',
 396+ 'moodbar-form-title' => 'Well...',
 397+ 'moodbar-form-note' => 'Maximal 140 Zeechen',
 398+ 'moodbar-form-policy-label' => 'eis Richtlinnen',
 399+ 'moodbar-success-title' => 'Merci!',
 400+ 'moodbar-error-title' => 'Ups!',
 401+ 'moodbar-admin-empty' => 'Keng Resultater',
 402+ 'moodbar-header-timestamp' => 'Zäitstempel',
 403+ 'moodbar-header-type' => 'Typ',
 404+ 'moodbar-header-page' => 'Säit',
 405+ 'moodbar-header-usertype' => 'Benotzer-Typ',
 406+ 'moodbar-header-user' => 'Benotzer',
 407+ 'moodbar-header-editmode' => 'Ännerungsmodus',
 408+ 'moodbar-header-comment' => 'Bemierkungen',
 409+ 'moodbar-header-user-editcount' => 'Compteur vun den Ännerunge pro Benotzer',
 410+ 'moodbar-header-namespace' => 'Nummraum',
 411+ 'moodbar-header-own-talk' => 'Eegen Diskussiounssäit',
 412+ 'moodbar-type-happy' => 'Glécklech',
 413+ 'moodbar-type-sad' => 'Traureg',
 414+ 'moodbar-user-anonymized' => 'Anonymiséiert',
 415+ 'moodbar-user-ip' => 'IP-Adress',
 416+ 'moodbar-user-user' => 'Registréierte Benotzer',
 417+);
 418+
 419+/** Macedonian (Македонски)
 420+ * @author Bjankuloski06
 421+ */
 422+$messages['mk'] = array(
 423+ 'moodbar-desc' => 'Им овозможува на одредени корисници да му го соопштуваат нивното „расположение“ на операторот на мрежното место',
 424+ 'moodbar-trigger-feedback' => 'Мислења за уредувањето',
 425+ 'moodbar-trigger-share' => 'Споделете го вашето искуство',
 426+ 'moodbar-trigger-editing' => 'Уредување на $1...',
 427+ 'moodbar-close' => '(затвори)',
 428+ 'moodbar-intro-feedback' => 'Мислења',
 429+ 'moodbar-intro-editing' => 'Уредувањето на $1 ме...',
 430+ 'moodbar-type-happy-title' => 'усреќи',
 431+ 'moodbar-type-sad-title' => 'натажи',
 432+ 'moodbar-type-confused-title' => 'збуни',
 433+ 'tooltip-moodbar-what' => 'Дознајте повеќе за оваа функција',
 434+ 'moodbar-what-label' => 'Што е ова?',
 435+ 'moodbar-what-content' => 'Оваа функција е предвидена да ѝ овозможува на заедницата да го осознае искуството на луѓето што ја уредуваат Википедија.
 436+Повеќе информации ќе добиете на $1.',
 437+ 'moodbar-what-link' => 'страница за функцијата',
 438+ 'moodbar-privacy' => 'Поднесувајќи го ова, се согласувате на транспарентност под следниве $1.',
 439+ 'moodbar-privacy-link' => 'услови',
 440+ 'moodbar-disable-link' => 'Не сум заинтересиран. Оневозможи ја функцијава.',
 441+ 'moodbar-form-title' => 'Бидејќи...',
 442+ 'moodbar-form-note' => 'највеќе 140 знаци',
 443+ 'moodbar-form-note-dynamic' => 'Преостануваат $1 знаци',
 444+ 'moodbar-form-submit' => 'Сподели ▶',
 445+ 'moodbar-form-policy-text' => 'Поднесувајќи го ова, $1',
 446+ 'moodbar-form-policy-label' => 'нашите правила',
 447+ 'moodbar-loading-title' => 'Споделувам...',
 448+ 'moodbar-success-title' => 'Благодариме!',
 449+ 'moodbar-error-title' => 'Упс!',
 450+ 'moodbar-success-subtitle' => 'Споделувајќи го вашето расположение ни помагате да ја подобриме Википедија.',
 451+ 'moodbar-error-subtitle' => 'Нешто не е в ред! Обидете се да го споделите вашето расположение подоцна.',
 452+ 'right-moodbar-view' => 'Преглед и извоз на мислења од MoodBar',
 453+ 'moodbar-admin-title' => 'Мислења со MoodBar',
 454+ 'moodbar-admin-intro' => 'Оваа страница служи за преглед на мислења поднесени со MoodBar',
 455+ 'moodbar-admin-empty' => 'Нема резултати',
 456+ 'moodbar-header-id' => 'Назнака (ID) на мислењето',
 457+ 'moodbar-header-timestamp' => 'Време и датум',
 458+ 'moodbar-header-type' => 'Вид',
 459+ 'moodbar-header-page' => 'Страница',
 460+ 'moodbar-header-usertype' => 'Вид на корисник',
 461+ 'moodbar-header-user' => 'Корисник',
 462+ 'moodbar-header-editmode' => 'Уреднички режим',
 463+ 'moodbar-header-bucket' => 'Испробување',
 464+ 'moodbar-header-system' => 'Вид на систем',
 465+ 'moodbar-header-locale' => 'Место',
 466+ 'moodbar-header-useragent' => 'Корисник-вршител',
 467+ 'moodbar-header-comment' => 'Коментари',
 468+ 'moodbar-header-user-editcount' => 'Бр. на кориснички уредувања',
 469+ 'moodbar-header-namespace' => 'Именски простор',
 470+ 'moodbar-header-own-talk' => 'Сопствена страница за разговор',
 471+ 'moodbar-type-happy' => 'Среќен',
 472+ 'moodbar-type-sad' => 'Тажен',
 473+ 'moodbar-type-confused' => 'Збунет',
 474+ 'moodbar-user-anonymized' => 'Анонимизирано',
 475+ 'moodbar-user-ip' => 'IP-адреса',
 476+ 'moodbar-user-user' => 'Регистриран корисник',
 477+);
 478+
 479+/** Dutch (Nederlands)
 480+ * @author SPQRobin
 481+ */
 482+$messages['nl'] = array(
 483+ 'moodbar-desc' => 'Laat bepaalde gebruikers toe hun "gemoedstoestand" naar de sitebeheerders te verzenden',
 484+ 'moodbar-trigger-feedback' => 'Terugkoppeling over het bewerken',
 485+ 'moodbar-trigger-share' => 'Deel uw ervaring',
 486+ 'moodbar-trigger-editing' => 'Het bewerken van $1...',
 487+ 'moodbar-close' => '(sluiten)',
 488+ 'moodbar-intro-feedback' => 'Terugkoppeling:',
 489+ 'moodbar-intro-editing' => 'Het gebruiken van $1 maakte mij...',
 490+ 'moodbar-type-happy-title' => 'Blij',
 491+ 'moodbar-type-sad-title' => 'Triest',
 492+ 'moodbar-type-confused-title' => 'Verward',
 493+ 'tooltip-moodbar-what' => 'Meer informatie over deze functie',
 494+ 'moodbar-what-label' => 'Wat is dit?',
 495+ 'moodbar-what-content' => 'Deze functie is ontworpen om de Wikipedia-gemeenschap de ervaring van mensen die Wikipedia bewerken, te helpen begrijpen.
 496+Voor meer informatie, ga naar de $1.',
 497+ 'moodbar-privacy-link' => 'ons beleid',
 498+ 'moodbar-disable-link' => 'Ik ben niet geïnteresseerd. Schakel deze functie uit.',
 499+ 'moodbar-form-title' => 'Omdat...',
 500+ 'moodbar-form-note' => 'Maximaal 140 tekens',
 501+ 'moodbar-form-note-dynamic' => '$1 tekens resterend',
 502+ 'moodbar-form-submit' => 'Feedback delen ▶',
 503+ 'moodbar-form-policy-label' => 'ons beleid',
 504+ 'moodbar-success-title' => 'Bedankt!',
 505+ 'moodbar-error-title' => 'Oeps!',
 506+ 'right-moodbar-view' => 'MoodBar-terugkoppeling bekijken en exporteren',
 507+ 'moodbar-admin-title' => 'MoodBar-terugkoppeling',
 508+ 'moodbar-admin-intro' => 'Deze pagina laat u toe om terugkoppeling die met de MoodBar is verzonden, te bekijken',
 509+ 'moodbar-admin-empty' => 'Geen resultaten',
 510+ 'moodbar-header-id' => 'Nummer van de terugkoppeling',
 511+ 'moodbar-header-timestamp' => 'Tijdstip',
 512+ 'moodbar-header-type' => 'Type',
 513+ 'moodbar-header-page' => 'Pagina',
 514+ 'moodbar-header-usertype' => 'Gebruikerstype',
 515+ 'moodbar-header-user' => 'Gebruiker',
 516+ 'moodbar-header-editmode' => 'Bewerkingsmodus',
 517+ 'moodbar-header-system' => 'Systeemtype',
 518+ 'moodbar-header-locale' => 'Taalinstelling',
 519+ 'moodbar-header-useragent' => 'User-agent',
 520+ 'moodbar-header-comment' => 'Opmerkingen',
 521+ 'moodbar-header-user-editcount' => 'Aantal bewerkingen van de gebruiker',
 522+ 'moodbar-header-namespace' => 'Naamruimte',
 523+ 'moodbar-header-own-talk' => 'Eigen overlegpagina',
 524+ 'moodbar-type-happy' => 'Blij',
 525+ 'moodbar-type-sad' => 'Triest',
 526+ 'moodbar-type-confused' => 'Verward',
 527+ 'moodbar-user-ip' => 'IP-adres',
 528+ 'moodbar-user-user' => 'Geregistreerde gebruiker',
 529+);
 530+
 531+/** Portuguese (Português)
 532+ * @author Hamilton Abreu
 533+ */
 534+$messages['pt'] = array(
 535+ 'moodbar-desc' => 'Permite que os utilizadores especificados enviem ao operador do site uma indicação do seu estado de espírito',
 536+ 'moodbar-trigger-feedback' => 'Comentários sobre edição',
 537+ 'moodbar-trigger-share' => 'Partilhe a sua experiência',
 538+ 'moodbar-trigger-editing' => 'A editar $1...',
 539+ 'moodbar-close' => '(fechar)',
 540+ 'moodbar-intro-feedback' => 'Comentários:',
 541+ 'moodbar-intro-editing' => 'Usar a $1 tornou-me...',
 542+ 'moodbar-type-happy-title' => 'Feliz',
 543+ 'moodbar-type-sad-title' => 'Triste',
 544+ 'moodbar-type-confused-title' => 'Confuso',
 545+ 'tooltip-moodbar-what' => 'Saiba mais sobre esta funcionalidade',
 546+ 'moodbar-what-label' => 'O que é isto?',
 547+ 'moodbar-what-content' => 'Esta funcionalidade foi concebida para ajudar a comunidade da Wikipédia a compreender a experiência das pessoas que editam a Wikipédia.
 548+Para mais informações, visite $1.',
 549+ 'moodbar-what-link' => 'a página da funcionalidade',
 550+ 'moodbar-privacy' => 'Ao gravar, concorda que os seus comentários podem ser usados tal como explicado $1.',
 551+ 'moodbar-privacy-link' => 'nas nossas normas',
 552+ 'moodbar-disable-link' => 'Não estou interessado. Desactivar esta funcionalidade, por favor.',
 553+ 'moodbar-form-title' => 'Porque...',
 554+ 'moodbar-form-note' => 'máx. 140 caracteres',
 555+ 'moodbar-form-note-dynamic' => 'restam $1 caracteres',
 556+ 'moodbar-form-submit' => 'Partilhar Comentários',
 557+ 'moodbar-form-policy-text' => 'Ao gravar, $1',
 558+ 'moodbar-form-policy-label' => 'as nossas normas',
 559+ 'moodbar-loading-title' => 'A partilhar...',
 560+ 'moodbar-success-title' => 'Obrigado!',
 561+ 'moodbar-error-title' => 'Erro!',
 562+ 'moodbar-success-subtitle' => 'Partilhar connosco o seu estado de espírito ajuda-nos a melhorar a Wikipédia.',
 563+ 'moodbar-error-subtitle' => 'Algo correu mal! Tente novamente mais tarde, por favor.',
 564+ 'right-moodbar-view' => 'Ver e exportar os comentários da MoodBar',
 565+ 'moodbar-admin-title' => 'Comentários da MoodBar',
 566+ 'moodbar-admin-intro' => 'Esta página permite-lhe ver os comentários enviados com a MoodBar',
 567+ 'moodbar-admin-empty' => 'Não foram encontrados resultados',
 568+ 'moodbar-header-id' => 'ID do comentário',
 569+ 'moodbar-header-timestamp' => 'Data e hora',
 570+ 'moodbar-header-type' => 'Tipo',
 571+ 'moodbar-header-page' => 'Página',
 572+ 'moodbar-header-usertype' => 'Tipo de utilizador',
 573+ 'moodbar-header-user' => 'Utilizador',
 574+ 'moodbar-header-editmode' => 'Modo de edição',
 575+ 'moodbar-header-bucket' => 'Zona de testes',
 576+ 'moodbar-header-system' => 'Tipo de sistema',
 577+ 'moodbar-header-locale' => 'Local',
 578+ 'moodbar-header-useragent' => 'User-Agent',
 579+ 'moodbar-header-comment' => 'Comentários',
 580+ 'moodbar-header-user-editcount' => 'Contagem de edições do utilizador',
 581+ 'moodbar-header-namespace' => 'Espaço nominal',
 582+ 'moodbar-header-own-talk' => 'Página de discussão própria',
 583+ 'moodbar-type-happy' => 'Feliz',
 584+ 'moodbar-type-sad' => 'Triste',
 585+ 'moodbar-type-confused' => 'Confuso',
 586+ 'moodbar-user-anonymized' => 'Tornado anónimo',
 587+ 'moodbar-user-ip' => 'Endereço IP',
 588+ 'moodbar-user-user' => 'Utilizador registado',
 589+);
 590+
 591+/** Russian (Русский)
 592+ * @author Александр Сигачёв
 593+ */
 594+$messages['ru'] = array(
 595+ 'moodbar-desc' => 'Позволяет определенным участникам отправлять свои «настроения» обратно на сайт оператора',
 596+);
 597+
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/MoodBar.i18n.php
___________________________________________________________________
Added: svn:eol-style
1598 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/jquery.moodBar/jquery.moodBar.js
@@ -0,0 +1,53 @@
 2+/**
 3+ * jquery.moodbar.js
 4+ * JavaScript interface for the MoodBar backend.
 5+ *
 6+ * @author Andrew Garrett
 7+ */
 8+( function( $ ) {
 9+ $.moodBar = {
 10+ /**
 11+ * Submit a MoodBar feedback item.
 12+ * @param fbProps Object: Properties for the FeedbackItem:
 13+ * - comment: The comments submitted
 14+ * - bucket: A bucket, for A/B testing.
 15+ * - anonymize: Boolean, whether or not to mark as anonymous
 16+ * - callback: A function, accepts a single 'fbProps' parameter, to call when the
 17+ * request completes.
 18+ * - type: A string.
 19+ * @return jqXHR
 20+ */
 21+ 'submit': function( fbProps ) {
 22+ var clientData = $.client.profile(),
 23+ fbProps = $.extend( {
 24+ 'page': mw.config.get( 'wgPageName' ),
 25+ 'editmode': mw.config.get( 'wgAction' ) == 'edit' ? 1 : 0
 26+ }, fbProps ),
 27+ apiRequest = {
 28+ 'action': 'moodbar',
 29+ 'page': fbProps.page,
 30+ 'comment': fbProps.comment,
 31+ 'anonymize': fbProps.anonymize,
 32+ 'useragent': clientData.name + '/' + clientData.versionNumber,
 33+ 'system': clientData.platform,
 34+ 'bucket': fbProps.bucket,
 35+ 'type': fbProps.type,
 36+ 'token': mw.config.get('mbEditToken'),
 37+ 'format': 'json'
 38+ };
 39+
 40+ // API treats any value as true.
 41+ if ( fbProps.editmode ) {
 42+ apiRequest.editmode = true;
 43+ }
 44+
 45+ return $.ajax( {
 46+ type: 'post',
 47+ url: mw.util.wikiScript( 'api' ),
 48+ data: apiRequest,
 49+ success: fbProps.callback,
 50+ dataType: 'json'
 51+ } );
 52+ }
 53+ };
 54+} ) ( jQuery );
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/jquery.moodBar/jquery.moodBar.js
___________________________________________________________________
Added: svn:eol-style
155 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.init.js
@@ -0,0 +1,72 @@
 2+/**
 3+ * Initialization script for the MoodBar MediaWiki extension
 4+ *
 5+ * @author Timo Tijhof, 2011
 6+ */
 7+( function( $ ) {
 8+
 9+ var mb = mw.moodBar = {
 10+
 11+ conf: mw.config.get( 'mbConfig' ),
 12+
 13+ cookiePrefix: function() {
 14+ return 'ext.moodBar@' + mb.conf.bucketConfig.version + '-';
 15+ },
 16+
 17+ isDisabled: function() {
 18+ var cookieDisabled = ($.cookie( mb.cookiePrefix() + 'disabled' ) == '1');
 19+ var browserDisabled = false;
 20+ var clientInfo = $.client.profile();
 21+
 22+ if ( clientInfo.name == 'msie' && clientInfo.versionNumber < 9 ) {
 23+ browserDisabled = true;
 24+ }
 25+
 26+ return cookieDisabled || browserDisabled;
 27+ },
 28+
 29+ ui: {
 30+ // jQuery objects
 31+ pMoodbar: null,
 32+ trigger: null,
 33+ overlay: null
 34+ },
 35+
 36+ init: function() {
 37+ var ui = mb.ui;
 38+
 39+ mb.conf.bucketKey = mw.user.bucket(
 40+ 'moodbar-trigger',
 41+ mb.conf.bucketConfig
 42+ );
 43+
 44+ // Create portlet
 45+ ui.pMoodbar = $( '<div id="p-moodbar"></div>' );
 46+
 47+ // Create trigger
 48+ ui.trigger = $( '<a>' )
 49+ .attr( 'href', '#' )
 50+ .attr( 'title', mw.msg( 'tooltip-p-moodbar-trigger-' + mb.conf.bucketKey ) )
 51+ .text( mw.msg( 'moodbar-trigger-' + mb.conf.bucketKey, mw.config.get( 'wgSiteName' ) ) );
 52+
 53+ // Insert trigger into portlet
 54+ ui.trigger
 55+ .wrap( '<p>' )
 56+ .parent()
 57+ .appendTo( ui.pMoodbar );
 58+
 59+ // Inject portlet into document, when document is ready
 60+ $( mb.inject );
 61+ },
 62+
 63+ inject: function() {
 64+ $( '#mw-head' ).append( mb.ui.pMoodbar );
 65+ }
 66+
 67+ };
 68+
 69+ if ( !mb.isDisabled() ) {
 70+ mb.init();
 71+ }
 72+
 73+} )( jQuery );
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.init.js
___________________________________________________________________
Added: svn:eol-style
174 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.css
@@ -0,0 +1,176 @@
 2+/* Overlay styling */
 3+#mw-moodBar-overlayWrap {
 4+ position: absolute;
 5+ top: 4em;
 6+ left: 10.2em;
 7+ min-width: 100px;
 8+ min-height: 100px;
 9+ background: #fafafa;
 10+ border: 1px solid #0645ad;
 11+ border-radius: 40px;
 12+ box-shadow: 7px 7px 15px rgba(0, 0, 0, 0.5);
 13+ display: none;
 14+}
 15+
 16+#mw-moodBar-overlay {
 17+ margin: 22px 22px;
 18+}
 19+
 20+.mw-moodBar-overlayTitle {
 21+ font-weight: bold;
 22+ white-space: nowrap;
 23+}
 24+
 25+.mw-moodBar-overlayClose {
 26+ float: right;
 27+ font-size: 10px;
 28+}
 29+
 30+.mw-moodBar-types {
 31+ overflow: hidden; /* clear */
 32+ margin: 0 30px;
 33+}
 34+
 35+.mw-moodBar-type {
 36+ float: left;
 37+ min-width: 42px;
 38+ margin: 15px;
 39+ padding: 42px 0 5px 0;
 40+ /* @embed */
 41+ background: transparent url(images/type-unknown.png) center top no-repeat;
 42+ text-align: center;
 43+}
 44+
 45+.mw-moodBar-type {
 46+ cursor: pointer;
 47+}
 48+
 49+.mw-moodBar-typeTitle,
 50+.mw-moodBar-privacy,
 51+.mw-moodBar-overlayWhat {
 52+ font-size: 12px;
 53+}
 54+
 55+.mw-moodBar-form,
 56+.mw-moodBar-overlayWhatContent {
 57+ display: none;
 58+ overflow: hidden;
 59+}
 60+
 61+.mw-moodBar-formNote {
 62+ float: right;
 63+ font-size: 10px;
 64+ color: #7e7e7e;
 65+}
 66+
 67+.mw-moodBar-formTitle {
 68+ font-size: 18px;
 69+}
 70+
 71+.mw-moodBar-formInput {
 72+ width: 100%;
 73+ outline: none;
 74+}
 75+
 76+.mw-moodBar-privacy,
 77+.mw-moodBar-overlayWhatContent {
 78+ font-size: 10px;
 79+}
 80+
 81+.mw-moodBar-formSubmit {
 82+ float: right;
 83+}
 84+
 85+.mw-moodBar-form {
 86+ padding-right: 5px;
 87+}
 88+.mw-moodBar-formInputs {
 89+ padding-left: 1em;
 90+}
 91+
 92+.mw-moodBar-state-loading {
 93+ /* @embed */
 94+ background: url(images/ajax-spinner.gif) left center no-repeat;
 95+ padding: 20px 0 0 90px;
 96+ height: 77px;
 97+}
 98+
 99+.mw-moodBar-state-title {
 100+ font-weight: bold;
 101+ font-size: 25px;
 102+}
 103+
 104+.mw-moodBar-state-subtitle {
 105+ font-size: 14px;
 106+ color: #7e7e7e;
 107+}
 108+
 109+/**
 110+ * Types
 111+ */
 112+
 113+/* Happy */
 114+.mw-moodBar-types .mw-moodBar-type-happy {
 115+ /* @embed */
 116+ background-image: url(images/type-happy-normal.png);
 117+}
 118+.mw-moodBar-types-hover .mw-moodBar-type-happy {
 119+ /* @embed */
 120+ background-image: url(images/type-happy-hoverside.png);
 121+}
 122+.mw-moodBar-types-hover .mw-moodBar-type-happy:hover {
 123+ /* @embed */
 124+ background-image: url(images/type-happy-hovered.png);
 125+}
 126+.mw-moodBar-types-select .mw-moodBar-type-happy {
 127+ /* @embed */
 128+ background-image: url(images/type-happy-dull.png);
 129+}
 130+.mw-moodBar-types-select .mw-moodBar-type-happy.mw-moodBar-selected {
 131+ /* @embed */
 132+ background-image: url(images/type-happy-selected.png);
 133+}
 134+
 135+/* Sad */
 136+.mw-moodBar-types .mw-moodBar-type-sad {
 137+ /* @embed */
 138+ background-image: url(images/type-sad-normal.png);
 139+}
 140+.mw-moodBar-types-hover .mw-moodBar-type-sad {
 141+ /* @embed */
 142+ background-image: url(images/type-sad-hoverside.png);
 143+}
 144+.mw-moodBar-types-hover .mw-moodBar-type-sad:hover {
 145+ /* @embed */
 146+ background-image: url(images/type-sad-hovered.png);
 147+}
 148+.mw-moodBar-types-select .mw-moodBar-type-sad {
 149+ /* @embed */
 150+ background-image: url(images/type-sad-dull.png);
 151+}
 152+.mw-moodBar-types-select .mw-moodBar-type-sad.mw-moodBar-selected {
 153+ /* @embed */
 154+ background-image: url(images/type-sad-selected.png);
 155+}
 156+
 157+/* Confused */
 158+.mw-moodBar-types .mw-moodBar-type-confused {
 159+ /* @embed */
 160+ background-image: url(images/type-confused-normal.png);
 161+}
 162+.mw-moodBar-types-hover .mw-moodBar-type-confused {
 163+ /* @embed */
 164+ background-image: url(images/type-confused-hoverside.png);
 165+}
 166+.mw-moodBar-types-hover .mw-moodBar-type-confused:hover {
 167+ /* @embed */
 168+ background-image: url(images/type-confused-hovered.png);
 169+}
 170+.mw-moodBar-types-select .mw-moodBar-type-confused {
 171+ /* @embed */
 172+ background-image: url(images/type-confused-dull.png);
 173+}
 174+.mw-moodBar-types-select .mw-moodBar-type-confused.mw-moodBar-selected {
 175+ /* @embed */
 176+ background-image: url(images/type-confused-selected.png);
 177+}
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.css
___________________________________________________________________
Added: svn:eol-style
1178 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.js
@@ -0,0 +1,270 @@
 2+/**
 3+ * Front-end scripting core for the MoodBar MediaWiki extension
 4+ *
 5+ * @author Timo Tijhof, 2011
 6+ */
 7+( function( $ ) {
 8+
 9+ var mb = mw.moodBar;
 10+ $.extend( mb, {
 11+
 12+ tpl: {
 13+ overlayBase: '\
 14+ <div id="mw-moodBar-overlayWrap"><div id="mw-moodBar-overlay">\
 15+ <span class="mw-moodBar-overlayClose"><a href="#"><html:msg key="moodbar-close" /></a></span>\
 16+ <div class="mw-moodBar-overlayContent"></div>\
 17+ </div></div>',
 18+ userinput: '\
 19+ <div class="mw-moodBar-overlayTitle"><html:msg key="INTROTITLE" /></div>\
 20+ <div class="mw-moodBar-types"></div>\
 21+ <div class="mw-moodBar-form">\
 22+ <div class="mw-moodBar-formTitle">\
 23+ <span class="mw-moodBar-formNote"><html:msg key="moodbar-form-note" /></span>\
 24+ <html:msg key="moodbar-form-title" />\
 25+ </div>\
 26+ <div class="mw-moodBar-formInputs">\
 27+ <textarea rows="3" maxlength="140" class="mw-moodBar-formInput" /></textarea>\
 28+ <div class="mw-moodBar-privacy"></div>\
 29+ <input type="button" class="mw-moodBar-formSubmit" />\
 30+ </div>\
 31+ </div>\
 32+ <span class="mw-moodBar-overlayWhat">\
 33+ <a href="#" title-msg="tooltip-moodbar-what">\
 34+ <span class="mw-moodBar-overlayWhatTrigger"></span>\
 35+ <span class="mw-moodBar-overlayWhatLabel"><html:msg key="moodbar-what-label" /></span>\
 36+ </a>\
 37+ <div class="mw-moodBar-overlayWhatContent"></div>\
 38+ </span>',
 39+ type: '\
 40+ <div class="mw-moodBar-type mw-moodBar-type-$1" rel="$1">\
 41+ <span class="mw-moodBar-typeTitle"><html:msg key="moodbar-type-$1-title" /></span>\
 42+ </div>',
 43+ loading: '\
 44+ <div class="mw-moodBar-state mw-moodBar-state-loading">\
 45+ <div class="mw-moodBar-state-title"><html:msg key="moodbar-loading-title" /></div>\
 46+ <div class="mw-moodBar-state-subtitle"><html:msg key="moodbar-loading-subtitle" /></div>\
 47+ </div>',
 48+ success: '\
 49+ <div class="mw-moodBar-state mw-moodBar-state-success">\
 50+ <div class="mw-moodBar-state-title"><html:msg key="moodbar-success-title" /></div>\
 51+ <div class="mw-moodBar-state-subtitle"><html:msg key="moodbar-success-subtitle" /></div>\
 52+ </div>',
 53+ error: '\
 54+ <div class="mw-moodBar-state mw-moodBar-state-error">\
 55+ <div class="mw-moodBar-state-title"><html:msg key="moodbar-error-title" /></div>\
 56+ <div class="mw-moodBar-state-subtitle"><html:msg key="moodbar-error-subtitle" /></div>\
 57+ </div>'
 58+ },
 59+
 60+ event: {
 61+ trigger: function( e ) {
 62+ e.preventDefault();
 63+ if ( mb.ui.overlay.is( ':hidden' ) ) {
 64+ mb.swapContent( mb.tpl.userinput );
 65+ mb.ui.overlay.show();
 66+ } else {
 67+ mb.ui.overlay.hide();
 68+ }
 69+ },
 70+
 71+ disable: function( e ) {
 72+ e.preventDefault();
 73+ $.cookie(
 74+ mb.cookiePrefix() + 'disabled',
 75+ '1',
 76+ { 'path': '/', 'expires': Number( mb.conf.disableExpiration ) }
 77+ );
 78+ mb.ui.overlay.fadeOut( 'fast' );
 79+ mb.ui.trigger.fadeOut( 'fast' );
 80+ }
 81+ },
 82+
 83+ feedbackItem: {
 84+ comment: '',
 85+ bucket: mb.conf.bucketKey,
 86+ type: 'unknown',
 87+ callback: function( data ) {
 88+ if ( data && data.moodbar && data.moodbar.result === 'success' ) {
 89+ mb.swapContent( mb.tpl.success );
 90+ setTimeout( function() {
 91+ mb.ui.overlay.fadeOut();
 92+ }, 3000 );
 93+ } else {
 94+ mb.swapContent( mb.tpl.error );
 95+ }
 96+ }
 97+ },
 98+
 99+ prepareUserinputContent: function( overlay ) {
 100+ overlay
 101+ // Populate type selector
 102+ .find( '.mw-moodBar-types' )
 103+ .append( function() {
 104+ var $mwMoodBarTypes = $( this ),
 105+ elems = [];
 106+ $.each( mb.conf.validTypes, function( id, type ) {
 107+ elems.push(
 108+ $( mb.tpl.type.replace( /\$1/g, type ) )
 109+ .localize()
 110+ .click( function( e ) {
 111+ var $el = $( this );
 112+ mb.ui.overlay.find( '.mw-moodBar-form' ).slideDown( 'fast' );
 113+ $mwMoodBarTypes.addClass( 'mw-moodBar-types-select' );
 114+ mb.feedbackItem.type = $el.attr( 'rel' );
 115+ $el.addClass( 'mw-moodBar-selected' );
 116+ $el.parent()
 117+ .find( '.mw-moodBar-selected' )
 118+ .not( $el )
 119+ .removeClass( 'mw-moodBar-selected' );
 120+ } )
 121+ .get( 0 )
 122+ );
 123+ } );
 124+ return elems;
 125+ } )
 126+ .hover( function() {
 127+ $( this ).addClass( 'mw-moodBar-types-hover' );
 128+ }, function() {
 129+ $( this ).removeClass( 'mw-moodBar-types-hover' );
 130+ } )
 131+ .end()
 132+ // Link what-button
 133+ .find( '.mw-moodBar-overlayWhatTrigger' )
 134+ .text( mw.msg( 'moodbar-what-collapsed' ) )
 135+ .end()
 136+ .find( '.mw-moodBar-overlayWhat > a' )
 137+ .click( function( e ) {
 138+ e.preventDefault();
 139+ mb.ui.overlay
 140+ .find( '.mw-moodBar-overlayWhatContent' )
 141+ .each( function() {
 142+ var $el = $( this ),
 143+ $trigger = mb.ui.overlay.find( '.mw-moodBar-overlayWhatTrigger' );
 144+ if ( $el.is( ':visible' ) ) {
 145+ $el.slideUp( 'fast' );
 146+ $trigger.html( mw.msg( 'moodbar-what-collapsed' ) );
 147+ } else {
 148+ $el.slideDown( 'fast' );
 149+ $trigger.html( mw.msg( 'moodbar-what-expanded' ) );
 150+ }
 151+ } )
 152+ } )
 153+ .end()
 154+ .find( '.mw-moodBar-overlayWhatContent' )
 155+ .html(
 156+ function() {
 157+ var message, linkMessage, link,
 158+ disableMsg, disableLink, out;
 159+
 160+ message = mw.msg( 'moodbar-what-content' );
 161+ linkMessage = mw.msg( 'moodbar-what-link' );
 162+ link = mw.html.element( 'a', {
 163+ 'href': mb.conf.infoUrl,
 164+ 'title': linkMessage
 165+ }, linkMessage );
 166+
 167+ out = mw.html.escape( message )
 168+ .replace( /\$1/, link );
 169+ out = mw.html.element( 'p', {},
 170+ new mw.html.Raw( out )
 171+ );
 172+
 173+ disableMsg = mw.msg( 'moodbar-disable-link' )
 174+ disableLink = mw.html.element( 'a', {
 175+ 'href' : '#',
 176+ 'class' : 'mw-moodBar-disable'
 177+ }, disableMsg );
 178+
 179+ out += mw.html.element( 'p', {},
 180+ new mw.html.Raw( disableLink )
 181+ );
 182+
 183+ return out;
 184+ }
 185+ )
 186+ .find('.mw-moodBar-disable')
 187+ .click( mb.event.disable )
 188+ .end()
 189+ .end()
 190+ .find( '.mw-moodBar-privacy' )
 191+ .html(
 192+ function() {
 193+ var message, linkMessage, link;
 194+
 195+ message = mw.msg( 'moodbar-privacy' );
 196+ linkMessage = mw.msg( 'moodbar-privacy-link' );
 197+ link = mw.html.element( 'a', {
 198+ 'href': mb.conf.privacyUrl,
 199+ 'title': linkMessage
 200+ }, linkMessage );
 201+
 202+ return mw.html.escape( message )
 203+ .replace( /\$1/, link );
 204+ }
 205+ )
 206+ .end()
 207+ // Submit
 208+ .find( '.mw-moodBar-formSubmit' )
 209+ .val( mw.msg( 'moodbar-form-submit' ) )
 210+ .click( function() {
 211+ mb.feedbackItem.comment = mb.ui.overlay.find( '.mw-moodBar-formInput' ).val();
 212+ mb.swapContent( mb.tpl.loading );
 213+ $.moodBar.submit( mb.feedbackItem );
 214+ } )
 215+ .end();
 216+ },
 217+
 218+ core: function() {
 219+
 220+ // Create overlay
 221+ mb.ui.overlay = $( mb.tpl.overlayBase )
 222+ .localize()
 223+ // Bind close-toggle
 224+ .find( '.mw-moodBar-overlayClose' )
 225+ .click( mb.event.trigger )
 226+ .end();
 227+ mb.swapContent( mb.tpl.userinput );
 228+
 229+ mb.ui.overlay
 230+ // Inject overlay
 231+ .appendTo( 'body' )
 232+ // Fix the width after the icons and titles are localized and inserted
 233+ .width( function( i, width ) {
 234+ return width + 10;
 235+ } );
 236+
 237+ // Bind triger
 238+ mb.ui.trigger.click( mb.event.trigger );
 239+ },
 240+
 241+ swapContent: function( tpl ) {
 242+ var sitenameParams = [mw.config.get( 'wgSiteName' )], // Cache common params
 243+ msgOptions = {
 244+ keys: {
 245+ INTROTITLE: 'moodbar-intro-' + mb.conf.bucketKey
 246+ },
 247+ params: {
 248+ INTROTITLE: sitenameParams,
 249+ 'moodbar-loading-subtitle': sitenameParams,
 250+ 'moodbar-success-subtitle': sitenameParams,
 251+ 'moodbar-error-subtitle': sitenameParams
 252+ }
 253+ };
 254+
 255+ mb.ui.overlay
 256+ .find( '.mw-moodBar-overlayContent' )
 257+ .html( tpl )
 258+ .localize( msgOptions );
 259+
 260+ if ( tpl == mb.tpl.userinput ) {
 261+ mb.prepareUserinputContent( mb.ui.overlay );
 262+ }
 263+ return true;
 264+ }
 265+ } );
 266+
 267+ if ( !mb.isDisabled() ) {
 268+ mb.core();
 269+ }
 270+
 271+} )( jQuery );
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.core.js
___________________________________________________________________
Added: svn:eol-style
1272 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-dull.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-dull.png
___________________________________________________________________
Added: svn:mime-type
2273 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/speechbubble-icon-rndrectangle-blue.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/speechbubble-icon-rndrectangle-blue.png
___________________________________________________________________
Added: svn:mime-type
3274 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-hoverside.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-hoverside.png
___________________________________________________________________
Added: svn:mime-type
4275 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-normal.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-normal.png
___________________________________________________________________
Added: svn:mime-type
5276 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-selected.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-selected.png
___________________________________________________________________
Added: svn:mime-type
6277 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-selected.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-selected.png
___________________________________________________________________
Added: svn:mime-type
7278 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-normal.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-normal.png
___________________________________________________________________
Added: svn:mime-type
8279 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-hoverside.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-hoverside.png
___________________________________________________________________
Added: svn:mime-type
9280 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-hovered.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-hovered.png
___________________________________________________________________
Added: svn:mime-type
10281 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/ajax-spinner.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/ajax-spinner.gif
___________________________________________________________________
Added: svn:mime-type
11282 + application/octet-stream
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-hovered.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-hovered.png
___________________________________________________________________
Added: svn:mime-type
12283 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-dull.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-confused-dull.png
___________________________________________________________________
Added: svn:mime-type
13284 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-dull.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-sad-dull.png
___________________________________________________________________
Added: svn:mime-type
14285 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-hoverside.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-hoverside.png
___________________________________________________________________
Added: svn:mime-type
15286 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-normal.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-normal.png
___________________________________________________________________
Added: svn:mime-type
16287 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-selected.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-selected.png
___________________________________________________________________
Added: svn:mime-type
17288 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/speechbubble-icon-ellipse-blue.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/speechbubble-icon-ellipse-blue.png
___________________________________________________________________
Added: svn:mime-type
18289 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-hovered.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/images/type-happy-hovered.png
___________________________________________________________________
Added: svn:mime-type
19290 + image/png
Index: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.init.css
@@ -0,0 +1,15 @@
 2+/* Based on p-personal */
 3+#p-moodbar {
 4+ position: absolute;
 5+ left: 10.75em;
 6+ top: 0px;
 7+}
 8+
 9+#p-moodbar p {
 10+ margin-top: 0.5em;
 11+ margin-right: 0.75em;
 12+ font-size: 0.75em;
 13+ white-space: nowrap;
 14+ line-height: 1.125em;
 15+ text-transform: none;
 16+}
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/modules/ext.moodBar/ext.moodBar.init.css
___________________________________________________________________
Added: svn:eol-style
117 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/FeedbackItem.php
@@ -0,0 +1,257 @@
 2+<?php
 3+
 4+/**
 5+ * This class represents a single piece of MoodBar feedback.
 6+ */
 7+class MBFeedbackItem {
 8+ /** Container for the data **/
 9+ protected $data;
 10+ /** Valid data keys **/
 11+ protected $validMembers = array(
 12+ // Feedback essentials
 13+ 'id', // ID in the database
 14+ 'comment', // The feedback itself
 15+ 'page', // The page where it was submitted
 16+ 'type',
 17+
 18+ // Housekeeping
 19+ 'timestamp',
 20+ 'user', // User object who submitted the feedback
 21+ 'anonymize',
 22+
 23+ // Statistics
 24+ 'useragent',
 25+ 'system',
 26+ 'locale',
 27+ 'editmode',
 28+ 'bucket',
 29+ 'user-editcount',
 30+ );
 31+
 32+ /** Valid values for the 'type' parameter. **/
 33+ protected static $validTypes = array( 'happy', 'sad', 'confused' );
 34+
 35+ /**
 36+ * Default constructor.
 37+ * Don't use this, use either MBFeedbackItem::newFromRow or MBFeedbackItem::create
 38+ */
 39+ protected function __construct() {
 40+ $this->data = array_fill_keys( $this->validMembers, null );
 41+
 42+ // Non-nullable boolean fields
 43+ $this->setProperty('anonymize', false);
 44+ $this->setProperty('editmode', false);
 45+ }
 46+
 47+ /**
 48+ * Factory function to create a new MBFeedbackItem
 49+ * @param $info Associative array of values
 50+ * Valid keys: type, user, comment, page, flags, timestamp,
 51+ * useragent, system, locale, bucket, anonymize
 52+ * @return MBFeedbackItem object.
 53+ */
 54+ public static function create( $info ) {
 55+ $newObject = new self();
 56+ $newObject->initialiseNew( $info );
 57+ return $newObject;
 58+ }
 59+
 60+ /**
 61+ * Initialiser for new MBFeedbackItems
 62+ * @param $info Associative array of values
 63+ * @see MBFeedbackItem::create
 64+ */
 65+ protected function initialiseNew( $info ) {
 66+ global $wgUser;
 67+
 68+ $template = array(
 69+ 'user' => $wgUser,
 70+ 'timestamp' => wfTimestampNow(),
 71+ );
 72+
 73+ $this->setProperties( $template );
 74+ $this->setProperties( $info );
 75+ }
 76+
 77+ /**
 78+ * Factory function to load an MBFeedbackItem from a DB row.
 79+ * @param $row A row, from DatabaseBase::fetchObject
 80+ * @return MBFeedback object.
 81+ */
 82+ public static function load( $row ) {
 83+ $newObject = new self();
 84+ $newObject->initialiseFromRow( $row );
 85+ return $newObject;
 86+ }
 87+
 88+ /**
 89+ * Initialiser for MBFeedbackItems loaded from the database
 90+ * @param $row A row object from DatabaseBase::fetchObject
 91+ * @see MBFeedbackItem::load
 92+ */
 93+ protected function initialiseFromRow( $row ) {
 94+ $properties = array(
 95+ 'id' => $row->mbf_id,
 96+ 'type' => $row->mbf_type,
 97+ 'comment' => $row->mbf_comment,
 98+ 'timestamp' => $row->mbf_timestamp,
 99+ 'anonymize' => $row->mbf_anonymous,
 100+ 'useragent' => $row->mbf_user_agent,
 101+ 'system' => $row->mbf_system_type,
 102+ 'locale' => $row->mbf_locale,
 103+ 'bucket' => $row->mbf_bucket,
 104+ 'editmode' => $row->mbf_editing,
 105+ 'user-editcount' => $row->mbf_user_editcount,
 106+ );
 107+
 108+ $properties['page'] = Title::makeTitleSafe( $row->mbf_namespace, $row->mbf_title );
 109+
 110+ if ( !empty($row->user_id) ) {
 111+ $properties['user'] = User::newFromRow( $row );
 112+ } elseif ( $row->mbf_user_id > 0 ) {
 113+ $properties['user'] = User::newFromId( $row->mbf_user_id );
 114+ } else {
 115+ $properties['user'] = User::newFromName( $row->mbf_user_ip );
 116+ }
 117+
 118+ $this->setProperties( $properties );
 119+ }
 120+
 121+ /**
 122+ * Set a group of properties. Throws an exception on invalid property.
 123+ * @param $values An associative array of properties to set.
 124+ */
 125+ public function setProperties( $values ) {
 126+ foreach( $values as $key => $value ) {
 127+ if ( ! $this->isValidKey($key) ) {
 128+ throw new MWException( "Attempt to set invalid property $key" );
 129+ }
 130+
 131+ if ( ! $this->validatePropertyValue($key, $value) ) {
 132+ throw new MWException( "Attempt to set invalid value for $key" );
 133+ }
 134+
 135+ $this->data[$key] = $value;
 136+ }
 137+ }
 138+
 139+ /**
 140+ * Set a group of values.
 141+ * @param $key The property to set.
 142+ * @param $value The value to give it.
 143+ */
 144+ public function setProperty( $key, $value ) {
 145+ $this->setProperties( array( $key => $value ) );
 146+ }
 147+
 148+ /**
 149+ * Get a property.
 150+ * @param $key The property to get
 151+ * @return The property value.
 152+ */
 153+ public function getProperty( $key ) {
 154+ if ( ! $this->isValidKey($key) ) {
 155+ throw new MWException( "Attempt to get invalid property $key" );
 156+ }
 157+
 158+ return $this->data[$key];
 159+ }
 160+
 161+ /**
 162+ * Check a property key for validity.
 163+ * If a property key is valid, it will be prefilled to NULL.
 164+ * @param $key The property key to check.
 165+ */
 166+ public function isValidKey( $key ) {
 167+ return in_array( $key, $this->validMembers );
 168+ }
 169+
 170+ /**
 171+ * Check if a property value is valid for that property
 172+ * @param $key The key of the property to check.
 173+ * @param $value The value to check
 174+ * @return Boolean
 175+ */
 176+ public function validatePropertyValue( $key, $value ) {
 177+ if ( $key == 'user' ) {
 178+ return $value instanceof User;
 179+ } elseif ( $key == 'page' ) {
 180+ return $value instanceof Title;
 181+ } elseif ( $key == 'type' ) {
 182+ return in_array( $value, self::$validTypes );
 183+ } elseif ( $key == 'comment' ) {
 184+ return mb_strlen( $value ) <= 140;
 185+ }
 186+
 187+ return true;
 188+ }
 189+
 190+ /**
 191+ * Writes this MBFeedbackItem to the database.
 192+ * Throws an exception if this it is already in the database.
 193+ * @return The MBFeedbackItem's new ID.
 194+ */
 195+ public function save() {
 196+
 197+ if ( $this->getProperty('id') ) {
 198+ throw new MWException( "This ".__CLASS__." is already in the database." );
 199+ }
 200+
 201+ // Add edit count if necessary
 202+ if ( $this->getProperty('user-editcount') === null &&
 203+ $this->getProperty('user') )
 204+ {
 205+ $value = $this->getProperty('user');
 206+
 207+ if ( $value->isAnon() ) {
 208+ $this->setProperty( 'user-editcount', 0 );
 209+ } else {
 210+ $this->setProperty( 'user-editcount', $value->getEditCount() );
 211+ }
 212+ }
 213+
 214+ $dbw = wfGetDB( DB_MASTER );
 215+
 216+ $row = array(
 217+ 'mbf_id' => $dbw->nextSequenceValue( 'moodbar_feedback_mbf_id' ),
 218+ 'mbf_type' => $this->getProperty('type'),
 219+ 'mbf_comment' => $this->getProperty('comment'),
 220+ 'mbf_timestamp' => $dbw->timestamp($this->getProperty('timestamp')),
 221+ 'mbf_anonymous' => $this->getProperty('anonymize'),
 222+ 'mbf_user_agent' => $this->getProperty('useragent'),
 223+ 'mbf_system_type' => $this->getProperty('system'),
 224+ 'mbf_locale' => $this->getProperty('locale'),
 225+ 'mbf_bucket' => $this->getProperty('bucket'),
 226+ 'mbf_editing' => $this->getProperty('editmode'),
 227+ 'mbf_user_editcount' => $this->getProperty('user-editcount'),
 228+ );
 229+
 230+ $user = $this->getProperty('user');
 231+ if ( $user->isAnon() ) {
 232+ $row['mbf_user_id'] = 0;
 233+ $row['mbf_user_ip'] = $user->getName();
 234+ } else {
 235+ $row['mbf_user_id'] = $user->getId();
 236+ }
 237+
 238+ $page = $this->getProperty('page');
 239+ if ( $page ) {
 240+ $row['mbf_namespace'] = $page->getNamespace();
 241+ $row['mbf_title'] = $page->getDBkey();
 242+ }
 243+
 244+ $dbw->insert( 'moodbar_feedback', $row, __METHOD__ );
 245+
 246+ $this->setProperty( 'id', $dbw->insertId() );
 247+
 248+ return $this->getProperty('id');
 249+ }
 250+
 251+ /**
 252+ * Gets the valid types of a feedback item.
 253+ */
 254+ public static function getValidTypes() {
 255+ return self::$validTypes;
 256+ }
 257+
 258+}
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/FeedbackItem.php
___________________________________________________________________
Added: svn:eol-style
1259 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/Formatter.php
@@ -0,0 +1,92 @@
 2+<?php
 3+
 4+/**
 5+ * Set of utilities for formatting and processing MoodBar output.
 6+ * @author Andrew Garrett
 7+ */
 8+abstract class MoodBarFormatter {
 9+ /**
 10+ * Gets the viewer's representation of $field from $data.
 11+ * @param $data MBFeedbackItem to retrieve the data from.
 12+ * @param $field String name of the field to fill. Valid values in $this->fields
 13+ * @return String HTML for putting in the table.
 14+ */
 15+ public static function getHTMLRepresentation( $data, $field ) {
 16+ switch( $field ) {
 17+ case 'page':
 18+ $title = $data->getProperty('page');
 19+
 20+ global $wgUser;
 21+ $linker = $wgUser->getSkin();
 22+ $outData = $linker->link( $title );
 23+ break;
 24+ case 'timestamp':
 25+ global $wgLang;
 26+ $outData = $wgLang->timeanddate( $data->getProperty('timestamp') );
 27+ $outData = htmlspecialchars($outData);
 28+ break;
 29+ case 'type':
 30+ $internal = self::getInternalRepresentation( $data, $field );
 31+ $outData = wfMessage("moodbar-type-$internal")->parse();
 32+ break;
 33+ case 'usertype':
 34+ $internal = self::getInternalRepresentation( $data, $field );
 35+ $outData = wfMessage("moodbar-user-$internal")->parse();
 36+ break;
 37+ default:
 38+ $outData = self::getInternalRepresentation($data, $field);
 39+ $outData = htmlspecialchars( $outData );
 40+ break;
 41+ }
 42+
 43+ return $outData;
 44+ }
 45+
 46+ /**
 47+ * Gets an internal representation of $field from $data.
 48+ * @param $data MBFeedbackItem to retrieve the data from.
 49+ * @param $field String name of the field to fill. Valid values in $this->fields
 50+ * @return String value appropriate for putting in CSV
 51+ */
 52+ public static function getInternalRepresentation( $data, $field ) {
 53+ $outData = null;
 54+
 55+ switch( $field ) {
 56+ case 'namespace':
 57+ $page = $data->getProperty('page');
 58+ $outData = $page->getNsText();
 59+ break;
 60+ case 'own-talk':
 61+ $page = $data->getProperty('page');
 62+ $user = $data->getProperty('user');
 63+ $userTalk = $user->getUserPage()->getTalkPage();
 64+ $outData = $page->equals( $userTalk );
 65+ break;
 66+ case 'usertype':
 67+ $user = $data->getProperty('user');
 68+ if ( $data->getProperty('anonymize') ) {
 69+ $outData = 'anonymized';
 70+ } else if ( $user->isAnon() ) {
 71+ $outData = 'ip';
 72+ } else {
 73+ $outData = 'user';
 74+ }
 75+ break;
 76+ case 'user':
 77+ $user = $data->getProperty('user');
 78+ if ( $data->getProperty('anonymize') ) {
 79+ $outData = '';
 80+ } else {
 81+ $outData = $user->getName();
 82+ }
 83+ break;
 84+ case 'page':
 85+ $outData = $data->getProperty('page')->getPrefixedText();
 86+ break;
 87+ default:
 88+ $outData = $data->getProperty($field);
 89+ }
 90+
 91+ return $outData;
 92+ }
 93+}
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/Formatter.php
___________________________________________________________________
Added: svn:eol-style
194 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/MoodBar.php
@@ -0,0 +1,142 @@
 2+<?php
 3+/**
 4+ * MoodBar extension
 5+ * Allows specified users to send their "mood" back to the site operator.
 6+ */
 7+
 8+$wgExtensionCredits['other'][] = array(
 9+ 'author' => array( 'Andrew Garrett', 'Timo Tijhof' ),
 10+ 'descriptionmsg' => 'moodbar-desc',
 11+ 'name' => 'MoodBar',
 12+ 'url' => 'http://www.mediawiki.org/wiki/MoodBar',
 13+ 'version' => '0.1',
 14+ 'path' => __FILE__,
 15+);
 16+
 17+// Object model
 18+$wgAutoloadClasses['MBFeedbackItem'] = dirname(__FILE__).'/FeedbackItem.php';
 19+$wgAutoloadClasses['MoodBarFormatter'] = dirname(__FILE__).'/Formatter.php';
 20+
 21+// API
 22+$wgAutoloadClasses['ApiMoodBar'] = dirname(__FILE__).'/ApiMoodBar.php';
 23+$wgAPIModules['moodbar'] = 'ApiMoodBar';
 24+
 25+// Hooks
 26+$wgAutoloadClasses['MoodBarHooks'] = dirname(__FILE__).'/MoodBar.hooks.php';
 27+$wgHooks['BeforePageDisplay'][] = 'MoodBarHooks::onPageDisplay';
 28+$wgHooks['ResourceLoaderGetConfigVars'][] = 'MoodBarHooks::resourceLoaderGetConfigVars';
 29+$wgHooks['MakeGlobalVariablesScript'][] = 'MoodBarHooks::makeGlobalVariablesScript';
 30+$wgHooks['LoadExtensionSchemaUpdates'][] = 'MoodBarHooks::onLoadExtensionSchemaUpdates';
 31+
 32+// Special page
 33+$wgAutoloadClasses['SpecialMoodBar'] = dirname(__FILE__).'/SpecialMoodBar.php';
 34+$wgSpecialPages['MoodBar'] = 'SpecialMoodBar';
 35+
 36+// User rights
 37+$wgAvailableRights[] = 'moodbar-view';
 38+
 39+// Internationalisation
 40+$wgExtensionMessagesFiles['MoodBar'] = dirname(__FILE__).'/MoodBar.i18n.php';
 41+
 42+// Resources
 43+$mbResourceTemplate = array(
 44+ 'localBasePath' => dirname(__FILE__) . '/modules',
 45+ 'remoteExtPath' => 'MoodBar/modules'
 46+);
 47+
 48+$wgResourceModules['ext.moodBar.init'] = $mbResourceTemplate + array(
 49+ 'styles' => 'ext.moodBar/ext.moodBar.init.css',
 50+ 'scripts' => 'ext.moodBar/ext.moodBar.init.js',
 51+ 'messages' => array(
 52+ 'moodbar-trigger-feedback',
 53+ 'moodbar-trigger-share',
 54+ 'moodbar-trigger-editing',
 55+ 'tooltip-p-moodbar-trigger-feedback',
 56+ 'tooltip-p-moodbar-trigger-share',
 57+ 'tooltip-p-moodbar-trigger-editing',
 58+ ),
 59+ 'position' => 'top',
 60+ 'dependencies' => array(
 61+ 'jquery.cookie',
 62+ 'jquery.client',
 63+ ),
 64+);
 65+
 66+$oldVersion = version_compare( $wgVersion, '1.17', '<=' );
 67+
 68+if ( !$oldVersion ) {
 69+ $wgResourceModules['ext.moodBar.init']['dependencies'][] = 'mediawiki.user';
 70+}
 71+
 72+$wgResourceModules['ext.moodBar.core'] = $mbResourceTemplate + array(
 73+ 'styles' => 'ext.moodBar/ext.moodBar.core.css',
 74+ 'scripts' => 'ext.moodBar/ext.moodBar.core.js',
 75+ 'messages' => array(
 76+ 'moodbar-close',
 77+ 'moodbar-intro-feedback',
 78+ 'moodbar-intro-share',
 79+ 'moodbar-intro-editing',
 80+ 'moodbar-type-happy-title',
 81+ 'moodbar-type-sad-title',
 82+ 'moodbar-type-confused-title',
 83+ 'tooltip-moodbar-what',
 84+ 'moodbar-what-target',
 85+ 'moodbar-what-label',
 86+ 'moodbar-what-expanded',
 87+ 'moodbar-what-collapsed',
 88+ 'moodbar-what-content',
 89+ 'moodbar-what-link',
 90+ 'moodbar-form-title',
 91+ 'moodbar-form-note',
 92+ 'moodbar-form-note-dynamic',
 93+ 'moodbar-form-policy-text',
 94+ 'moodbar-form-policy-label',
 95+ 'moodbar-form-submit',
 96+ 'moodbar-privacy',
 97+ 'moodbar-privacy-link',
 98+ 'moodbar-disable-link',
 99+ 'moodbar-loading-title',
 100+ 'moodbar-error-title',
 101+ 'moodbar-success-title',
 102+ 'moodbar-loading-subtitle',
 103+ 'moodbar-error-subtitle',
 104+ 'moodbar-success-subtitle',
 105+ ),
 106+ 'dependencies' => array(
 107+ 'mediawiki.util',
 108+ 'ext.moodBar.init', // just in case
 109+ 'jquery.localize',
 110+ 'jquery.moodBar',
 111+ ),
 112+ 'position' => 'bottom',
 113+);
 114+
 115+
 116+$wgResourceModules['jquery.moodBar'] = $mbResourceTemplate + array(
 117+ 'scripts' => 'jquery.moodBar/jquery.moodBar.js',
 118+ 'dependencies' => array(
 119+ 'mediawiki.util',
 120+ ),
 121+);
 122+
 123+/** Configuration **/
 124+/** The registration time after which users will be shown the MoodBar **/
 125+$wgMoodBarCutoffTime = null;
 126+
 127+/** MoodBar configuration settings **/
 128+$wgMoodBarConfig = array(
 129+ 'bucketConfig' =>
 130+ array(
 131+ 'buckets' =>
 132+ array(
 133+ 'feedback' => 80,
 134+ 'share' => 10,
 135+ 'editing' => 10,
 136+ ),
 137+ 'version' => 3,
 138+ 'expires' => 30,
 139+ ),
 140+ 'infoUrl' => 'http://www.mediawiki.org/wiki/MoodBar',
 141+ 'privacyUrl' => 'about:blank',
 142+ 'disableExpiration' => 365,
 143+);
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/MoodBar.php
___________________________________________________________________
Added: svn:eol-style
1144 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/SpecialMoodBar.php
@@ -0,0 +1,118 @@
 2+<?php
 3+
 4+class SpecialMoodBar extends SpecialPage {
 5+ static $fields = array(
 6+ 'mbf_id' => 'id',
 7+ 'mbf_timestamp' => 'timestamp',
 8+ 'mbf_type' => 'type',
 9+ 'mbf_namespace' => 'namespace',
 10+ 'mbf_title' => 'page',
 11+ 'user-type' => 'usertype',
 12+ 'mbs_user_id' => 'user',
 13+ 'mbf_user_editcount' => 'user-editcount',
 14+ 'mbf_editing' => 'editmode',
 15+ 'mbf_bucket' => 'bucket',
 16+ 'mbf_system_type' => 'system',
 17+ 'mbf_locale' => 'locale',
 18+ 'mbf_user_agent' => 'useragent',
 19+ 'mbf_comment' => 'comment',
 20+ );
 21+
 22+ function __construct() {
 23+ parent::__construct( 'MoodBar', 'moodbar-view' );
 24+ }
 25+
 26+ function execute($par) {
 27+ global $wgUser, $wgOut;
 28+
 29+ if ( !$this->userCanExecute( $wgUser ) ) {
 30+ $this->displayRestrictionError();
 31+ return;
 32+ }
 33+
 34+ $wgOut->setPageTitle( wfMsg( 'moodbar-admin-title' ) );
 35+ $wgOut->addWikiMsg( 'moodbar-admin-intro' );
 36+
 37+ $pager = new MoodBarPager();
 38+
 39+ if ( $pager->getNumRows() > 0 ) {
 40+ $wgOut->addHTML(
 41+ $pager->getNavigationBar() .
 42+ $pager->getBody() .
 43+ $pager->getNavigationBar()
 44+ );
 45+ } else {
 46+ $wgOut->addWikiMsg( 'moodbar-admin-empty' );
 47+ }
 48+ }
 49+}
 50+
 51+class MoodBarPager extends TablePager {
 52+ function getFieldNames() {
 53+ static $headers = null;
 54+
 55+ if ( is_null( $headers ) ) {
 56+ $headers = array();
 57+ foreach( SpecialMoodBar::$fields as $field => $property ) {
 58+ $headers[$field] = wfMessage("moodbar-header-$property")->text();
 59+ }
 60+ }
 61+
 62+ return $headers;
 63+ }
 64+
 65+ // Overridden from TablePager, it's just easier because
 66+ // we're doing things with a proper object model
 67+ function formatRow( $row ) {
 68+ $out = '';
 69+
 70+ $data = MBFeedbackItem::load( $row );
 71+ $outData = null;
 72+
 73+ foreach( SpecialMoodBar::$fields as $field ) {
 74+ $outData = MoodBarFormatter::getHTMLRepresentation( $data, $field );
 75+ $out .= Xml::tags( 'td', null, $outData );
 76+ }
 77+
 78+ $out = Xml::tags( 'tr', $this->getRowAttrs($row), $out ) . "\n";
 79+ return $out;
 80+ }
 81+
 82+ function formatValue( $name, $value ) {
 83+ return '';
 84+ }
 85+
 86+ function getQueryInfo() {
 87+ $info = array(
 88+ 'tables' => array('moodbar_feedback', 'user'),
 89+ 'fields' => '*',
 90+ 'join_conds' => array(
 91+ 'user' => array(
 92+ 'left join',
 93+ 'user_id=mbf_user_id',
 94+ ),
 95+ ),
 96+ );
 97+
 98+ return $info;
 99+ }
 100+
 101+ function getDefaultSort() {
 102+ return 'mbf_id';
 103+ }
 104+
 105+ function isFieldSortable( $name ) {
 106+ $sortable = array(
 107+ 'mbf_id',
 108+ 'mbf_type',
 109+ 'mbf_user_id',
 110+ 'mbf_namespace',
 111+ );
 112+
 113+ return in_array( $name, $sortable );
 114+ }
 115+
 116+ function getTitle() {
 117+ return SpecialPage::getTitleFor( 'MoodBar' );
 118+ }
 119+}
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/SpecialMoodBar.php
___________________________________________________________________
Added: svn:eol-style
1120 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/MoodBar.hooks.php
@@ -0,0 +1,95 @@
 2+<?php
 3+
 4+class MoodBarHooks {
 5+ /**
 6+ * Adds MoodBar JS to the output if appropriate.
 7+ */
 8+ public static function onPageDisplay( &$output, &$skin ) {
 9+ if ( self::shouldShowMoodbar( $output, $skin ) ) {
 10+ $output->addModules( array( 'ext.moodBar.init', 'ext.moodBar.core' ) );
 11+ }
 12+
 13+ return true;
 14+ }
 15+
 16+ /**
 17+ * Determines whether or not we should show the MoodBar.
 18+ */
 19+ public static function shouldShowMoodbar( &$output, &$skin ) {
 20+ // Front-end appends to header elements, which have different
 21+ // locations and IDs in every skin.
 22+ // Untill there is some kind of central registry of element-ids
 23+ // that skins implement, or a fixed name for each of them, just
 24+ // show it in Vector for now.
 25+ if ( $skin->getSkinName() !== 'vector' ) {
 26+ return false;
 27+ }
 28+ global $wgUser;
 29+ $user = $wgUser;
 30+
 31+ if ( $user->isAnon() ) {
 32+ return false;
 33+ }
 34+
 35+ // Only show MoodBar for users registered after a certain time
 36+ global $wgMoodBarCutoffTime;
 37+ if ( $wgMoodBarCutoffTime &&
 38+ $user->getRegistration() < $wgMoodBarCutoffTime )
 39+ {
 40+ return false;
 41+ }
 42+
 43+ if ( class_exists('EditPageTracking') ) {
 44+ return ((bool)EditPageTracking::getFirstEditPage($user));
 45+ }
 46+
 47+ return true;
 48+ }
 49+
 50+ /**
 51+ * ResourceLoaderGetConfigVars hook
 52+ */
 53+ public static function resourceLoaderGetConfigVars( &$vars ) {
 54+ global $wgMoodBarConfig, $wgUser;
 55+ $vars['mbConfig'] = array(
 56+ 'validTypes' => MBFeedbackItem::getValidTypes(),
 57+ 'userBuckets' => MoodBarHooks::getUserBuckets( $wgUser ),
 58+ ) + $wgMoodBarConfig;
 59+ return true;
 60+ }
 61+
 62+ public static function makeGlobalVariablesScript( &$vars ) {
 63+ global $wgUser;
 64+ $vars['mbEditToken'] = $wgUser->editToken();
 65+ return true;
 66+ }
 67+
 68+ /**
 69+ * Runs MoodBar schema updates
 70+ */
 71+ public static function onLoadExtensionSchemaUpdates( $updater = null ) {
 72+ $updater->addExtensionUpdate( array( 'addTable', 'moodbar_feedback',
 73+ dirname(__FILE__).'/sql/MoodBar.sql', true ) );
 74+
 75+ $updater->addExtensionUpdate( array( 'addField', 'moodbar_feedback',
 76+ 'mbf_user_editcount', dirname(__FILE__).'/sql/mbf_user_editcount.sql', true )
 77+ );
 78+
 79+ return true;
 80+ }
 81+
 82+ /**
 83+ * Gets the MoodBar testing bucket that a user is in.
 84+ * @param $user The user to check
 85+ * @return array of bucket names
 86+ */
 87+ public static function getUserBuckets( $user ) {
 88+ $id = $user->getID();
 89+ $buckets = array();
 90+
 91+ // No show-time bucketing yet. This method is a stub.
 92+
 93+ sort($buckets);
 94+ return $buckets;
 95+ }
 96+}
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/MoodBar.hooks.php
___________________________________________________________________
Added: svn:eol-style
197 + native
Index: branches/wmf/1.17wmf1/extensions/MoodBar/exportMoodBar.php
@@ -0,0 +1,94 @@
 2+<?php
 3+
 4+$IP = getenv( 'MW_INSTALL_PATH' );
 5+if ( $IP === false ) {
 6+ $IP = dirname( __FILE__ ) . '/../..';
 7+}
 8+require( "$IP/maintenance/Maintenance.php" );
 9+
 10+class ExportMoodBar extends Maintenance {
 11+ protected $fields = array(
 12+ 'id',
 13+ 'timestamp',
 14+ 'type',
 15+ 'namespace',
 16+ 'page',
 17+ 'own-talk',
 18+ 'usertype',
 19+ 'user',
 20+ 'user-editcount',
 21+ 'editmode',
 22+ 'bucket',
 23+ 'system',
 24+ 'locale',
 25+ 'useragent',
 26+ 'comment',
 27+ );
 28+
 29+ public function __construct() {
 30+ parent::__construct();
 31+ $this->mDescription = "Exports MoodBar feedback";
 32+ $this->addOption( 'since-id', 'Get feedback after this ID' );
 33+ $this->addOption( 'since-time', 'Get feedback after this time' );
 34+ }
 35+
 36+ public function execute() {
 37+ $dbr = wfGetDB( DB_SLAVE );
 38+ $lastRowCount = 1;
 39+ $fh = fopen('php://stdout', 'w');
 40+
 41+ $offsetCond = array( 1 );
 42+
 43+ if ( $this->getOption('since-id') ) {
 44+ $offsetCond[] = 'mbf_id > '.$dbr->addQuotes( $this->getArg('since-id') );
 45+ }
 46+
 47+ if ( $this->getOption('since-time') ) {
 48+ $ts = $dbr->timestamp( $this->getArg('since-id') );
 49+ $offsetCond[] = 'mbf_timestamp > '.$dbr->addQuotes( $ts );
 50+ }
 51+
 52+ fputcsv( $fh, $this->fields );
 53+ $lastId = 0;
 54+
 55+ while ( $lastRowCount > 0 ) {
 56+ $res = $dbr->select(
 57+ array('moodbar_feedback','user'),
 58+ '*',
 59+ $offsetCond,
 60+ __METHOD__,
 61+ array( 'LIMIT' => 500 ),
 62+ array(
 63+ 'user' => array(
 64+ 'left join',
 65+ 'user_id=mbf_user_id'
 66+ )
 67+ )
 68+ );
 69+
 70+ $lastRowCount = $dbr->numRows( $res );
 71+
 72+ foreach( $res as $row ) {
 73+ $this->outputRow( $fh, $row );
 74+ $lastId = $row->mbf_id;
 75+ }
 76+
 77+ $offsetCond = 'mbf_id > ' . $dbr->addQuotes( $lastId );
 78+ }
 79+ }
 80+
 81+ protected function outputRow( $fh, $row ) {
 82+ $item = MBFeedbackItem::load( $row );
 83+ $user = User::newFromRow( $row );
 84+ $outData = array();
 85+
 86+ foreach( $this->fields as $field ) {
 87+ $outData[] = MoodBarFormatter::getInternalRepresentation( $item, $field );
 88+ }
 89+
 90+ fputcsv( $fh, $outData );
 91+ }
 92+}
 93+
 94+$maintClass = "ExportMoodBar";
 95+require_once( DO_MAINTENANCE );
Property changes on: branches/wmf/1.17wmf1/extensions/MoodBar/exportMoodBar.php
___________________________________________________________________
Added: svn:eol-style
196 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r93170Deployed with r93131 on the WMF clusterraymond12:29, 26 July 2011

Status & tagging log