r68383 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r68382‎ | r68383 | r68384 >
Date:22:27, 21 June 2010
Author:catrope
Status:deferred
Tags:
Comment:
resourceloader: Near-complete implementation of MessageBlobStore, just need to handle concurrency now.
Modified paths:
  • /branches/resourceloader/phase3/includes/ResourceLoader.php (modified) (history)
  • /branches/resourceloader/phase3/load.php (modified) (history)
  • /branches/resourceloader/phase3/maintenance/archives/patch-msg_resource.sql (added) (history)
  • /branches/resourceloader/phase3/maintenance/tables.sql (modified) (history)
  • /branches/resourceloader/phase3/maintenance/updaters.inc (modified) (history)

Diff [purge]

Index: branches/resourceloader/phase3/maintenance/archives/patch-msg_resource.sql
@@ -0,0 +1,22 @@
 2+-- Table for storing JSON message blobs for the resource loader
 3+CREATE TABLE /*_*/msg_resource (
 4+ -- Resource name
 5+ mr_resource varchar(255) NOT NULL,
 6+ -- Language code
 7+ mr_lang varbinary(32) NOT NULL,
 8+ -- JSON blob. This is an incomplete JSON object, i.e. without the wrapping {}
 9+ mr_blob mediumblob NOT NULL,
 10+ -- Timestamp of last update
 11+ mr_timestamp binary(14) NOT NULL
 12+) /*$wgDBTableOptions*/;
 13+CREATE UNIQUE INDEX /*i*/mr_resource_lang(mr_resource, mr_lang);
 14+
 15+-- Table for administering which message is contained in which resource
 16+CREATE TABLE /*_*/msg_resource_links (
 17+ mrl_resource varchar(255) NOT NULL,
 18+ -- Language code
 19+ mrl_lang varbinary(32) NOT NULL,
 20+ -- Message key
 21+ mrl_message varchar(255) NOT NULL
 22+) /*$wgDBTableOptions*/;
 23+CREATE UNIQUE INDEX /*i*/mrl_lang_message_resource(mrl_lang, mrl_message, mrl_resource);
Index: branches/resourceloader/phase3/maintenance/updaters.inc
@@ -176,6 +176,7 @@
177177 // 1.17
178178 array( 'add_table', 'iwlinks', 'patch-iwlinks.sql' ),
179179 array( 'add_index', 'iwlinks', 'iwl_prefix_from_title', 'patch-rename-iwl_prefix.sql' ),
 180+ array( 'add_table', 'msg_resource', 'patch-msg_resource.sql' ),
180181 ),
181182
182183 'sqlite' => array(
Index: branches/resourceloader/phase3/maintenance/tables.sql
@@ -1369,4 +1369,27 @@
13701370 ) /*$wgDBTableOptions*/;
13711371 CREATE INDEX /*i*/lc_lang_key ON /*_*/l10n_cache (lc_lang, lc_key);
13721372
 1373+-- Table for storing JSON message blobs for the resource loader
 1374+CREATE TABLE /*_*/msg_resource (
 1375+ -- Resource name
 1376+ mr_resource varchar(255) NOT NULL,
 1377+ -- Language code
 1378+ mr_lang varbinary(32) NOT NULL,
 1379+ -- JSON blob. This is an incomplete JSON object, i.e. without the wrapping {}
 1380+ mr_blob mediumblob NOT NULL,
 1381+ -- Timestamp of last update
 1382+ mr_timestamp binary(14) NOT NULL
 1383+) /*$wgDBTableOptions*/;
 1384+CREATE UNIQUE INDEX /*i*/mr_lang_resource(mr_lang, mr_resource);
 1385+
 1386+-- Table for administering which message is contained in which resource
 1387+CREATE TABLE /*_*/msg_resource_links (
 1388+ mrl_resource varchar(255) NOT NULL,
 1389+ -- Language code
 1390+ mrl_lang varbinary(32) NOT NULL,
 1391+ -- Message key
 1392+ mrl_message varchar(255) NOT NULL
 1393+) /*$wgDBTableOptions*/;
 1394+CREATE UNIQUE INDEX /*i*/mrl_lang_message_resource(mrl_lang, mrl_message, mrl_resource);
 1395+
13731396 -- vim: sw=2 sts=2 et
Index: branches/resourceloader/phase3/includes/ResourceLoader.php
@@ -50,7 +50,13 @@
5151 private $useCSSMin = true;
5252 private $useCSSJanus = true;
5353
 54+ private $lang;
5455
 56+ public function __construct( $lang ) {
 57+ $this->lang = $lang;
 58+ }
 59+
 60+
5561 /**
5662 * Add a module to the output. This includes the module's
5763 * JS itself, its style and its messages.
@@ -95,9 +101,16 @@
96102 }
97103
98104 private function getMessagesJS( $modules ) {
99 - return "mw.addMessages( {\n" .
100 - implode( ",\n", array_map( array( 'MessageBlobStore', 'get' ), $modules ) ) .
101 - "\n} );";
 105+ $blobs = array();
 106+ $dbr = wfGetDB( DB_SLAVE );
 107+ $res = $dbr->select( 'msg_resource', 'msg_blob',
 108+ array( 'msg_resource' => $modules, 'msg_lang' => $this->lang ),
 109+ __METHOD__
 110+ );
 111+ foreach ( $res as $row ) {
 112+ $blobs[] = $row->msg_blob;
 113+ }
 114+ return "mw.addMessages( {\n" . implode( ",\n", $blobs ) . "\n} );";
102115 }
103116
104117 public function getOutput() {
@@ -152,12 +165,63 @@
153166
154167 class MessageBlobStore {
155168 /**
156 - * Get the message blob for a module
157 - * @param $module string Module name
158 - * @return string An incomplete JSON object (i.e. without the {} ) with messages keys and their values.
 169+ * Get the message blobs for a set of modules
 170+ * @param $lang string Language code
 171+ * @param $modules array Array of module names
 172+ * @return array An array of incomplete JSON objects (i.e. without the {} ) with messages keys and their values.
159173 */
160 - public static function get( $module ) {
161 - // TODO: Implement
162 - return '';
 174+ public static function get( $lang, $modules ) {
 175+ // Try getting from the DB first
 176+ $blobs = self::getFromDB( $lang, $modules );
 177+
 178+ // Generate blobs for any missing modules and store them in the DB
 179+ $missing = array_diff( $modules, array_keys( $blobs ) );
 180+ foreach ( $missing as $module ) {
 181+ $blob = self::generateMessageBlob( $lang, $module );
 182+ if ( $blob ) {
 183+ self::set( $lang, $module, $blob );
 184+ $blobs[$module] = $blob;
 185+ }
 186+ }
 187+ return implode( ",\n", $blobs );
163188 }
 189+
 190+ public static function set( $lang, $module, $blob ) {
 191+ $dbw = wfGetDb( DB_MASTER );
 192+ // TODO: Timestamp stuff to handle concurrency
 193+ $dbw->replace( 'msg_resource', array( array( 'mr_lang', 'mr_resource' ) ),
 194+ array( array(
 195+ 'mr_lang' => $lang,
 196+ 'mr_module' => $module,
 197+ 'mr_blob' => $blob,
 198+ 'mr_timestamp' => wfTimestampNow(),
 199+ ) )
 200+ );
 201+ }
 202+
 203+ private static function getFromDB( $lang, $modules ) {
 204+ $retval = array();
 205+ $dbr = wfGetDB( DB_SLAVE );
 206+ $res = $dbr->select( 'msg_resource', array( 'mr_blob', 'mr_resource' ),
 207+ array( 'mr_resource' => $modules, 'mr_lang' => $this->lang ),
 208+ __METHOD__
 209+ );
 210+ foreach ( $res as $row ) {
 211+ $retval[$row->mr_resource] = $row->mr_blob;
 212+ }
 213+ return $retval;
 214+ }
 215+
 216+ private static function generateMessageBlob( $lang, $module ) {
 217+ if ( !isset ( ResourceLoader::$modules[$module]['messages'] ) ) {
 218+ return false;
 219+ }
 220+ $messages = array();
 221+ foreach ( ResourceLoader::$modules[$module]['messages'] as $key ) {
 222+ $encKey = Xml::escapeJsString( $key );
 223+ $encValue = Xml::escapeJsString( wfMsg( $key ) ); // TODO: Use something rawer than wfMsg()?
 224+ $messages[] = "'$encKey': '$encValue'";
 225+ }
 226+ return implode( ",", $messages );
 227+ }
164228 }
\ No newline at end of file
Index: branches/resourceloader/phase3/load.php
@@ -32,11 +32,10 @@
3333 //
3434 // See RawPage.php for details; summary is that MSIE can override the
3535 // Content-Type if it sees a recognized extension on the URL, such as
36 -// might be appended via PATH_INFO after 'api.php'.
 36+// might be appended via PATH_INFO after 'load.php'.
3737 //
38 -// Some data formats can end up containing unfiltered user-provided data
39 -// which will end up triggering HTML detection and execution, hence
40 -// XSS injection and all that entails.
 38+// Some resources can contain HTML-like strings (e.g. in messages)
 39+// which will end up triggering HTML detection and execution.
4140 //
4241 if ( $wgRequest->isPathInfoBad() ) {
4342 wfHttpError( 403, 'Forbidden',
@@ -47,7 +46,7 @@
4847 // Was taken from api.php so I guess it's maybe OK but it doesn't look good.
4948 }
5049
51 -$loader = new ResourceLoader();
 50+$loader = new ResourceLoader( $wgRequest->getVal( 'lang', 'en' ) );
5251 $moduleParam = $wgRequest->getVal( 'modules' );
5352 $modules = $moduleParam ? explode( '|', $moduleParam ) : array();
5453 foreach ( $modules as $module ) {
@@ -55,6 +54,7 @@
5655 }
5756
5857 // TODO: Cache-Control header
 58+header( 'Content-Type', 'text/javascript' );
5959 echo $loader->getOutput();
6060
6161 wfProfileOut( 'loader.php' );

Follow-up revisions

RevisionCommit summaryAuthorDate
r69677resourceloader: Merge to r68383 through HEAD from trunkcatrope13:23, 21 July 2010
r69679resourceloader: Redo the updaters.inc part of r68383 because the updaters wer...catrope13:28, 21 July 2010

Status & tagging log