ResourceLoaderModule.php

Go to the documentation of this file.
00001 <?php
00028 abstract class ResourceLoaderModule {
00029 
00030         # Type of resource
00031         const TYPE_SCRIPTS = 'scripts';
00032         const TYPE_STYLES = 'styles';
00033         const TYPE_MESSAGES = 'messages';
00034         const TYPE_COMBINED = 'combined';
00035 
00036         # sitewide core module like a skin file or jQuery component
00037         const ORIGIN_CORE_SITEWIDE = 1;
00038 
00039         # per-user module generated by the software
00040         const ORIGIN_CORE_INDIVIDUAL = 2;
00041 
00042         # sitewide module generated from user-editable files, like MediaWiki:Common.js, or
00043         # modules accessible to multiple users, such as those generated by the Gadgets extension.
00044         const ORIGIN_USER_SITEWIDE = 3;
00045 
00046         # per-user module generated from user-editable files, like User:Me/vector.js
00047         const ORIGIN_USER_INDIVIDUAL = 4;
00048 
00049         # an access constant; make sure this is kept as the largest number in this group
00050         const ORIGIN_ALL = 10;
00051 
00052         # script and style modules form a hierarchy of trustworthiness, with core modules like
00053         # skins and jQuery as most trustworthy, and user scripts as least trustworthy.  We can
00054         # limit the types of scripts and styles we allow to load on, say, sensitive special
00055         # pages like Special:UserLogin and Special:Preferences
00056         protected $origin = self::ORIGIN_CORE_SITEWIDE;
00057 
00058         /* Protected Members */
00059 
00060         protected $name = null;
00061 
00062         // In-object cache for file dependencies
00063         protected $fileDeps = array();
00064         // In-object cache for message blob mtime
00065         protected $msgBlobMtime = array();
00066 
00067         /* Methods */
00068 
00075         public function getName() {
00076                 return $this->name;
00077         }
00078 
00085         public function setName( $name ) {
00086                 $this->name = $name;
00087         }
00088 
00096         public function getOrigin() {
00097                 return $this->origin;
00098         }
00099 
00106         public function setOrigin( $origin ) {
00107                 $this->origin = $origin;
00108         }
00109 
00114         public function getFlip( $context ) {
00115                 global $wgContLang;
00116 
00117                 return $wgContLang->getDir() !== $context->getDirection();
00118         }
00119 
00127         public function getScript( ResourceLoaderContext $context ) {
00128                 // Stub, override expected
00129                 return '';
00130         }
00131 
00146         public function getScriptURLsForDebug( ResourceLoaderContext $context ) {
00147                 $url = ResourceLoader::makeLoaderURL(
00148                         array( $this->getName() ),
00149                         $context->getLanguage(),
00150                         $context->getSkin(),
00151                         $context->getUser(),
00152                         $context->getVersion(),
00153                         true, // debug
00154                         'scripts', // only
00155                         $context->getRequest()->getBool( 'printable' ),
00156                         $context->getRequest()->getBool( 'handheld' )
00157                 );
00158                 return array( $url );
00159         }
00160 
00167         public function supportsURLLoading() {
00168                 return true;
00169         }
00170 
00177         public function getStyles( ResourceLoaderContext $context ) {
00178                 // Stub, override expected
00179                 return array();
00180         }
00181 
00191         public function getStyleURLsForDebug( ResourceLoaderContext $context ) {
00192                 $url = ResourceLoader::makeLoaderURL(
00193                         array( $this->getName() ),
00194                         $context->getLanguage(),
00195                         $context->getSkin(),
00196                         $context->getUser(),
00197                         $context->getVersion(),
00198                         true, // debug
00199                         'styles', // only
00200                         $context->getRequest()->getBool( 'printable' ),
00201                         $context->getRequest()->getBool( 'handheld' )
00202                 );
00203                 return array( 'all' => array( $url ) );
00204         }
00205 
00213         public function getMessages() {
00214                 // Stub, override expected
00215                 return array();
00216         }
00217 
00223         public function getGroup() {
00224                 // Stub, override expected
00225                 return null;
00226         }
00227 
00233         public function getSource() {
00234                 // Stub, override expected
00235                 return 'local';
00236         }
00237 
00245         public function getPosition() {
00246                 return 'bottom';
00247         }
00248 
00256         public function isRaw() {
00257                 return false;
00258         }
00259 
00265         public function getLoaderScript() {
00266                 // Stub, override expected
00267                 return false;
00268         }
00269 
00285         public function getDependencies() {
00286                 // Stub, override expected
00287                 return array();
00288         }
00289 
00297         public function getFileDependencies( $skin ) {
00298                 // Try in-object cache first
00299                 if ( isset( $this->fileDeps[$skin] ) ) {
00300                         return $this->fileDeps[$skin];
00301                 }
00302 
00303                 $dbr = wfGetDB( DB_SLAVE );
00304                 $deps = $dbr->selectField( 'module_deps', 'md_deps', array(
00305                                 'md_module' => $this->getName(),
00306                                 'md_skin' => $skin,
00307                         ), __METHOD__
00308                 );
00309                 if ( !is_null( $deps ) ) {
00310                         $this->fileDeps[$skin] = (array) FormatJson::decode( $deps, true );
00311                 } else {
00312                         $this->fileDeps[$skin] = array();
00313                 }
00314                 return $this->fileDeps[$skin];
00315         }
00316 
00323         public function setFileDependencies( $skin, $deps ) {
00324                 $this->fileDeps[$skin] = $deps;
00325         }
00326 
00333         public function getMsgBlobMtime( $lang ) {
00334                 if ( !isset( $this->msgBlobMtime[$lang] ) ) {
00335                         if ( !count( $this->getMessages() ) )
00336                                 return 0;
00337 
00338                         $dbr = wfGetDB( DB_SLAVE );
00339                         $msgBlobMtime = $dbr->selectField( 'msg_resource', 'mr_timestamp', array(
00340                                         'mr_resource' => $this->getName(),
00341                                         'mr_lang' => $lang
00342                                 ), __METHOD__
00343                         );
00344                         // If no blob was found, but the module does have messages, that means we need
00345                         // to regenerate it. Return NOW
00346                         if ( $msgBlobMtime === false ) {
00347                                 $msgBlobMtime = wfTimestampNow();
00348                         }
00349                         $this->msgBlobMtime[$lang] = wfTimestamp( TS_UNIX, $msgBlobMtime );
00350                 }
00351                 return $this->msgBlobMtime[$lang];
00352         }
00353 
00360         public function setMsgBlobMtime( $lang, $mtime ) {
00361                 $this->msgBlobMtime[$lang] = $mtime;
00362         }
00363 
00364         /* Abstract Methods */
00365 
00380         public function getModifiedTime( ResourceLoaderContext $context ) {
00381                 // 0 would mean now
00382                 return 1;
00383         }
00384 
00394         public function isKnownEmpty( ResourceLoaderContext $context ) {
00395                 return false;
00396         }
00397 
00398 
00400         private static $jsParser;
00401         private static $parseCacheVersion = 1;
00402 
00411         protected function validateScriptFile( $fileName, $contents ) {
00412                 global $wgResourceLoaderValidateJS;
00413                 if ( $wgResourceLoaderValidateJS ) {
00414                         // Try for cache hit
00415                         // Use CACHE_ANYTHING since filtering is very slow compared to DB queries
00416                         $key = wfMemcKey( 'resourceloader', 'jsparse', self::$parseCacheVersion, md5( $contents ) );
00417                         $cache = wfGetCache( CACHE_ANYTHING );
00418                         $cacheEntry = $cache->get( $key );
00419                         if ( is_string( $cacheEntry ) ) {
00420                                 return $cacheEntry;
00421                         }
00422 
00423                         $parser = self::javaScriptParser();
00424                         try {
00425                                 $parser->parse( $contents, $fileName, 1 );
00426                                 $result = $contents;
00427                         } catch (Exception $e) {
00428                                 // We'll save this to cache to avoid having to validate broken JS over and over...
00429                                 $err = $e->getMessage();
00430                                 $result = "throw new Error(" . Xml::encodeJsVar("JavaScript parse error: $err") . ");";
00431                         }
00432 
00433                         $cache->set( $key, $result );
00434                         return $result;
00435                 } else {
00436                         return $contents;
00437                 }
00438         }
00439 
00443         protected static function javaScriptParser() {
00444                 if ( !self::$jsParser ) {
00445                         self::$jsParser = new JSParser();
00446                 }
00447                 return self::$jsParser;
00448         }
00449 
00450 }
Generated on Thu Sep 20 00:00:58 2012 for MediaWiki by  doxygen 1.6.3