* @author Trevor Parscal
*/
+use Psr\Log\LoggerAwareInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\NullLogger;
+
/**
* Dynamic JavaScript and CSS resource loading system.
*
* Most of the documentation is on the MediaWiki documentation wiki starting at:
* https://www.mediawiki.org/wiki/ResourceLoader
*/
-class ResourceLoader {
+class ResourceLoader implements LoggerAwareInterface {
/** @var int */
protected static $filterCacheVersion = 7;
*/
protected $blobStore;
+ /**
+ * @var LoggerInterface
+ */
+ private $logger;
+
/**
* Load information stored in the database about modules.
*
}
if ( !in_array( $filter, array( 'minify-js', 'minify-css' ) ) ) {
- wfDebugLog( 'resourceloader', __METHOD__ . ": Invalid filter: $filter" );
+ $this->logger->warning( 'Invalid filter {filter}', array(
+ 'filter' => $filter
+ ) );
return $data;
}
if ( !$options['cache'] ) {
$result = $this->applyFilter( $filter, $data );
} else {
- // Use CACHE_ANYTHING since filtering is very slow compared to DB queries
$key = wfMemcKey( 'resourceloader', 'filter', $filter, self::$filterCacheVersion, md5( $data ) );
- $cache = wfGetCache( CACHE_ANYTHING );
+ $cache = wfGetCache( wfIsHHVM() ? CACHE_ACCEL : CACHE_ANYTHING );
$cacheEntry = $cache->get( $key );
if ( is_string( $cacheEntry ) ) {
- wfIncrStats( "rl-$filter-cache-hits" );
+ wfIncrStats( "resourceloader_cache.$filter.hit" );
return $cacheEntry;
}
$result = '';
try {
- wfIncrStats( "rl-$filter-cache-misses" );
+ wfIncrStats( "resourceloader_cache.$filter.miss" );
$result = $this->applyFilter( $filter, $data );
if ( $options['cacheReport'] ) {
$result .= "\n/* cache key: $key */";
$cache->set( $key, $result );
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
- wfDebugLog( 'resourceloader', __METHOD__ . ": minification failed: $e" );
+ $this->logger->warning( 'Minification failed: {exception}', array(
+ 'exception' => $e
+ ) );
$this->errors[] = self::formatExceptionNoComment( $e );
}
}
* Register core modules and runs registration hooks.
* @param Config|null $config
*/
- public function __construct( Config $config = null ) {
+ public function __construct( Config $config = null, LoggerInterface $logger = null ) {
global $IP;
- if ( $config === null ) {
- wfDebug( __METHOD__ . ' was called without providing a Config instance' );
- $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+ if ( !$logger ) {
+ $logger = new NullLogger();
}
+ $this->setLogger( $logger );
+ if ( !$config ) {
+ $this->logger->debug( __METHOD__ . ' was called without providing a Config instance' );
+ $config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
+ }
$this->config = $config;
// Add 'local' source first
return $this->config;
}
+ public function setLogger( LoggerInterface $logger ) {
+ $this->logger = $logger;
+ }
+
/**
* @param MessageBlobStore $blobStore
* @since 1.25
// Do not allow private modules to be loaded from the web.
// This is a security issue, see bug 34907.
if ( $module->getGroup() === 'private' ) {
- wfDebugLog( 'resourceloader', __METHOD__ . ": request for private module '$name' denied" );
+ $this->logger->debug( "Request for private module '$name' denied" );
$this->errors[] = "Cannot show private module \"$name\"";
continue;
}
$this->preloadModuleInfo( array_keys( $modules ), $context );
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
- wfDebugLog( 'resourceloader', __METHOD__ . ": preloading module info failed: $e" );
+ $this->logger->warning( 'Preloading module info failed: {exception}', array(
+ 'exception' => $e
+ ) );
$this->errors[] = self::formatExceptionNoComment( $e );
}
$versionHash = $this->getCombinedVersion( $context, array_keys( $modules ) );
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
- wfDebugLog( 'resourceloader', __METHOD__ . ": calculating version hash failed: $e" );
+ $this->logger->warning( 'Calculating version hash failed: {exception}', array(
+ 'exception' => $e
+ ) );
$this->errors[] = self::formatExceptionNoComment( $e );
}
// sending the 304.
wfResetOutputBuffers( /* $resetGzipEncoding = */ true );
- header( 'HTTP/1.0 304 Not Modified' );
- header( 'Status: 304 Not Modified' );
+ HttpStatus::header( 304 );
$this->sendResponseHeaders( $context, $etag, false );
return true;
$blobs = $this->blobStore->get( $this, $modules, $context->getLanguage() );
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
- wfDebugLog(
- 'resourceloader',
- __METHOD__ . ": pre-fetching blobs from MessageBlobStore failed: $e"
- );
+ $this->logger->warning( 'Prefetching MessageBlobStore failed: {exception}', array(
+ 'exception' => $e
+ ) );
$this->errors[] = self::formatExceptionNoComment( $e );
}
} else {
}
} catch ( Exception $e ) {
MWExceptionHandler::logException( $e );
- wfDebugLog( 'resourceloader', __METHOD__ . ": generating module package failed: $e" );
+ $this->logger->warning( 'Generating module package failed: {exception}', array(
+ 'exception' => $e
+ ) );
$this->errors[] = self::formatExceptionNoComment( $e );
// Respond to client with error-state instead of module implementation