<?php
/**
- * Abstraction for resource loader modules.
+ * Abstraction for ResourceLoader modules.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* @author Roan Kattouw
*/
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
/**
- * Abstraction for resource loader modules, with name registration and maxage functionality.
+ * Abstraction for ResourceLoader modules, with name registration and maxage functionality.
*/
-abstract class ResourceLoaderModule {
+abstract class ResourceLoaderModule implements LoggerAwareInterface {
# Type of resource
const TYPE_SCRIPTS = 'scripts';
const TYPE_STYLES = 'styles';
// In-object cache for file dependencies
protected $fileDeps = array();
- // In-object cache for message blob mtime
- protected $msgBlobMtime = array();
+ // In-object cache for message blob (keyed by language)
+ protected $msgBlobs = array();
// In-object cache for version hash
protected $versionHash = array();
// In-object cache for module content
protected $contents = array();
- // Whether the position returned by getPosition() is defined in the module configuration
- // and not a default value
- protected $isPositionDefined = false;
-
/**
* @var Config
*/
protected $config;
+ /**
+ * @var LoggerInterface
+ */
+ protected $logger;
+
/* Methods */
/**
$this->config = $config;
}
+ /**
+ * @since 1.27
+ * @param LoggerInterface $logger
+ * @return null
+ */
+ public function setLogger( LoggerInterface $logger ) {
+ $this->logger = $logger;
+ }
+
+ /**
+ * @since 1.27
+ * @return LoggerInterface
+ */
+ protected function getLogger() {
+ if ( !$this->logger ) {
+ $this->logger = new NullLogger();
+ }
+ return $this->logger;
+ }
+
/**
* Get the URL or URLs to load for this module's JS in debug mode.
* The default behavior is to return a load.php?only=scripts URL for
return 'bottom';
}
- /**
- * Whether the position returned by getPosition() is a default value or comes from the module
- * definition. This method is meant to be short-lived, and is only useful until classes added
- * via addModuleStyles with a default value define an explicit position. See getModuleStyles()
- * in OutputPage for the related migration warning.
- *
- * @return bool
- * @since 1.26
- */
- public function isPositionDefault() {
- return !$this->isPositionDefined;
- }
-
/**
* Whether this module's JS expects to work without the client-side ResourceLoader module.
* Returning true from this function will prevent mw.loader.state() call from being
return false;
}
- /**
- * Get the loader JS for this module, if set.
- *
- * @return mixed JavaScript loader code as a string or boolean false if no custom loader set
- */
- public function getLoaderScript() {
- // Stub, override expected
- return false;
- }
-
/**
* Get a list of modules this module depends on.
*
* Dependency information is taken into account when loading a module
* on the client side.
*
- * To add dependencies dynamically on the client side, use a custom
- * loader script, see getLoaderScript()
- *
* Note: It is expected that $context will be made non-optional in the near
* future.
*
* This is used to retrieve data in batches. See ResourceLoader::preloadModuleInfo().
* To save the data, use saveFileDependencies().
*
- * @param string $skin Skin name
- * @param array $deps Array of file names
+ * @param ResourceLoaderContext $context
+ * @param string[] $files Array of file names
*/
public function setFileDependencies( ResourceLoaderContext $context, $files ) {
$vary = $context->getSkin() . '|' . $context->getLanguage();
}
/**
- * Get the last modification timestamp of the messages in this module for a given language.
- * @param string $lang Language code
- * @return int UNIX timestamp
+ * Get the hash of the message blob.
+ *
+ * @since 1.27
+ * @param ResourceLoaderContext $context
+ * @return string|null JSON blob or null if module has no messages
*/
- public function getMsgBlobMtime( $lang ) {
- if ( !isset( $this->msgBlobMtime[$lang] ) ) {
- if ( !count( $this->getMessages() ) ) {
- return 1;
- }
-
- $dbr = wfGetDB( DB_SLAVE );
- $msgBlobMtime = $dbr->selectField( 'msg_resource',
- 'mr_timestamp',
- array(
- 'mr_resource' => $this->getName(),
- 'mr_lang' => $lang
- ),
- __METHOD__
- );
- // If no blob was found, but the module does have messages, that means we need
- // to regenerate it. Return NOW
- if ( $msgBlobMtime === false ) {
- $msgBlobMtime = wfTimestampNow();
- }
- $this->msgBlobMtime[$lang] = wfTimestamp( TS_UNIX, $msgBlobMtime );
+ protected function getMessageBlob( ResourceLoaderContext $context ) {
+ if ( !$this->getMessages() ) {
+ // Don't bother consulting MessageBlobStore
+ return null;
+ }
+ // Message blobs may only vary language, not by context keys
+ $lang = $context->getLanguage();
+ if ( !isset( $this->msgBlobs[$lang] ) ) {
+ $this->getLogger()->warning( 'Message blob for {module} should have been preloaded', array(
+ 'module' => $this->getName(),
+ ) );
+ $store = $context->getResourceLoader()->getMessageBlobStore();
+ $this->msgBlobs[$lang] = $store->getBlob( $this, $lang );
}
- return $this->msgBlobMtime[$lang];
+ return $this->msgBlobs[$lang];
}
/**
- * Set in-object cache for message blob time.
+ * Set in-object cache for message blobs.
*
- * This is used to retrieve data in batches. See ResourceLoader::preloadModuleInfo().
+ * Used to allow fetching of message blobs in batches. See ResourceLoader::preloadModuleInfo().
*
+ * @since 1.27
+ * @param string|null $blob JSON blob or null
* @param string $lang Language code
- * @param int $mtime UNIX timestamp
*/
- public function setMsgBlobMtime( $lang, $mtime ) {
- $this->msgBlobMtime[$lang] = $mtime;
+ public function setMessageBlob( $blob, $lang ) {
+ $this->msgBlobs[$lang] = $blob;
}
/**
}
// Messages
- $blobs = $rl->getMessageBlobStore()->get(
- $rl,
- array( $this->getName() => $this ),
- $context->getLanguage()
- );
- if ( isset( $blobs[$this->getName()] ) ) {
- $content['messagesBlob'] = $blobs[$this->getName()];
+ $blob = $this->getMessageBlob( $context );
+ if ( $blob ) {
+ $content['messagesBlob'] = $blob;
}
$templates = $this->getTemplates();
* A number of utility methods are available to help you gather data. These are not
* called by default and must be included by the subclass' getDefinitionSummary().
*
- * - getMsgBlobMtime()
+ * - getMessageBlob()
*
* @since 1.23
* @param ResourceLoaderContext $context
protected function validateScriptFile( $fileName, $contents ) {
if ( $this->getConfig()->get( 'ResourceLoaderValidateJS' ) ) {
// Try for cache hit
- $cache = ObjectCache::getLocalClusterInstance();
+ $cache = ObjectCache::getMainWANInstance();
$key = $cache->makeKey(
'resourceloader',
'jsparse',