* consistuent messages or the resource itself is changed.
*/
class MessageBlobStore {
+
/**
* Get the message blobs for a set of modules
+ *
+ * @param $resourceLoader ResourceLoader object
* @param $modules array Array of module objects keyed by module name
* @param $lang string Language code
* @return array An array mapping module names to message blobs
*/
- public static function get( $modules, $lang ) {
- // TODO: Invalidate blob when module touched
+ public static function get( ResourceLoader $resourceLoader, $modules, $lang ) {
wfProfileIn( __METHOD__ );
if ( !count( $modules ) ) {
wfProfileOut( __METHOD__ );
return array();
}
// Try getting from the DB first
- $blobs = self::getFromDB( array_keys( $modules ), $lang );
+ $blobs = self::getFromDB( $resourceLoader, array_keys( $modules ), $lang );
// Generate blobs for any missing modules and store them in the DB
$missing = array_diff( array_keys( $modules ), array_keys( $blobs ) );
* Generate and insert a new message blob. If the blob was already
* present, it is not regenerated; instead, the preexisting blob
* is fetched and returned.
- * @param $module string Module name
- * @param $lang string Language code
+ *
+ * @param $name String: module name
+ * @param $module ResourceLoaderModule object
+ * @param $lang String: language code
* @return mixed Message blob or false if the module has no messages
*/
public static function insertMessageBlob( $name, ResourceLoaderModule $module, $lang ) {
- $blob = self::generateMessageBlob( $name, $module, $lang );
+ $blob = self::generateMessageBlob( $module, $lang );
if ( !$blob ) {
return false;
/**
* Update all message blobs for a given module.
- * @param $module string Module name
- * @param $lang string Language code (optional)
- * @return mixed If $lang is set, the new message blob for that language is
+ *
+ * @param $name String: module name
+ * @param $module ResourceLoaderModule object
+ * @param $lang String: language code (optional)
+ * @return Mixed: if $lang is set, the new message blob for that language is
* returned if present. Otherwise, null is returned.
*/
public static function updateModule( $name, ResourceLoaderModule $module, $lang = null ) {
foreach ( $res as $row ) {
$oldBlob = $row->mr_blob;
- $newBlob = self::generateMessageBlob( $name, $module, $row->mr_lang );
+ $newBlob = self::generateMessageBlob( $module, $row->mr_lang );
if ( $row->mr_lang === $lang ) {
$retval = $newBlob;
/**
* Update a single message in all message blobs it occurs in.
- * @param $key string Message key
+ *
+ * @param $key String: message key
*/
public static function updateMessage( $key ) {
$dbw = wfGetDB( DB_MASTER );
/**
* Create an update queue for updateMessage()
- * @param $key string Message key
- * @param $prevUpdates array Updates queue to refresh or null to build a fresh update queue
- * @return array Updates queue
+ *
+ * @param $key String: message key
+ * @param $prevUpdates Array: updates queue to refresh or null to build a fresh update queue
+ * @return Array: updates queue
*/
private static function getUpdatesForMessage( $key, $prevUpdates = null ) {
$dbw = wfGetDB( DB_MASTER );
/**
* Reencode a message blob with the updated value for a message
- * @param $blob string Message blob (JSON object)
- * @param $key string Message key
- * @param $lang string Language code
+ *
+ * @param $blob String: message blob (JSON object)
+ * @param $key String: message key
+ * @param $lang String: language code
* @return Message blob with $key replaced with its new value
*/
private static function reencodeBlob( $blob, $key, $lang ) {
$decoded = FormatJson::decode( $blob, true );
$decoded[$key] = wfMsgExt( $key, array( 'language' => $lang ) );
- return FormatJson::encode( $decoded );
+ return FormatJson::encode( (object)$decoded );
}
/**
* Get the message blobs for a set of modules from the database.
* Modules whose blobs are not in the database are silently dropped.
- * @param $modules array Array of module names
- * @param $lang string Language code
+ *
+ * @param $resourceLoader ResourceLoader object
+ * @param $modules Array of module names
+ * @param $lang String: language code
* @return array Array mapping module names to blobs
*/
- private static function getFromDB( $modules, $lang ) {
+ private static function getFromDB( ResourceLoader $resourceLoader, $modules, $lang ) {
+ global $wgCacheEpoch;
$retval = array();
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( 'msg_resource',
);
foreach ( $res as $row ) {
- $module = ResourceLoader::getModule( $row->mr_resource );
+ $module = $resourceLoader->getModule( $row->mr_resource );
if ( !$module ) {
// This shouldn't be possible
throw new MWException( __METHOD__ . ' passed an invalid module name' );
}
- if ( array_keys( FormatJson::decode( $row->mr_blob, true ) ) !== $module->getMessages() ) {
- $retval[$row->mr_resource] = self::updateModule( $row->mr_resource, $lang );
+ // Update the module's blobs if the set of messages changed or if the blob is
+ // older than $wgCacheEpoch
+ if ( array_keys( FormatJson::decode( $row->mr_blob, true ) ) !== $module->getMessages() ||
+ wfTimestamp( TS_MW, $row->mr_timestamp ) <= $wgCacheEpoch ) {
+ $retval[$row->mr_resource] = self::updateModule( $row->mr_resource, $module, $lang );
} else {
$retval[$row->mr_resource] = $row->mr_blob;
}
/**
* Generate the message blob for a given module in a given language.
- * @param $module string Module name
- * @param $lang string Language code
- * @return string JSON object
+ *
+ * @param $module ResourceLoaderModule object
+ * @param $lang String: language code
+ * @return String: JSON object
*/
- private static function generateMessageBlob( $name, ResourceLoaderModule $module, $lang ) {
+ private static function generateMessageBlob( ResourceLoaderModule $module, $lang ) {
$messages = array();
foreach ( $module->getMessages() as $key ) {
$messages[$key] = wfMsgExt( $key, array( 'language' => $lang ) );
}
- return FormatJson::encode( $messages );
+ return FormatJson::encode( (object)$messages );
}
}