MediaWiki  REL1_21
ResourceLoaderWikiModule.php
Go to the documentation of this file.
00001 <?php
00032 abstract class ResourceLoaderWikiModule extends ResourceLoaderModule {
00033 
00034         /* Protected Members */
00035 
00036         # Origin is user-supplied code
00037         protected $origin = self::ORIGIN_USER_SITEWIDE;
00038 
00039         // In-object cache for title mtimes
00040         protected $titleMtimes = array();
00041 
00042         /* Abstract Protected Methods */
00043 
00060         abstract protected function getPages( ResourceLoaderContext $context );
00061 
00062         /* Protected Methods */
00063 
00075         protected function getDB() {
00076                 return wfGetDB( DB_SLAVE );
00077         }
00078 
00083         protected function getContent( $title ) {
00084                 if ( !$title->isCssJsSubpage() && !$title->isCssOrJsPage() ) {
00085                         return null;
00086                 }
00087                 $revision = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
00088                 if ( !$revision ) {
00089                         return null;
00090                 }
00091 
00092                 $content = $revision->getContent( Revision::RAW );
00093 
00094                 if ( !$content ) {
00095                         wfDebug( __METHOD__ . "failed to load content of JS/CSS page!\n" );
00096                         return null;
00097                 }
00098 
00099                 $model = $content->getModel();
00100 
00101                 if ( $model !== CONTENT_MODEL_CSS && $model !== CONTENT_MODEL_JAVASCRIPT ) {
00102                         wfDebug( __METHOD__ . "bad content model $model for JS/CSS page!\n" );
00103                         return null;
00104                 }
00105 
00106                 return $content->getNativeData(); //NOTE: this is safe, we know it's JS or CSS
00107         }
00108 
00109         /* Methods */
00110 
00115         public function getScript( ResourceLoaderContext $context ) {
00116                 $scripts = '';
00117                 foreach ( $this->getPages( $context ) as $titleText => $options ) {
00118                         if ( $options['type'] !== 'script' ) {
00119                                 continue;
00120                         }
00121                         $title = Title::newFromText( $titleText );
00122                         if ( !$title || $title->isRedirect() ) {
00123                                 continue;
00124                         }
00125                         $script = $this->getContent( $title );
00126                         if ( strval( $script ) !== '' ) {
00127                                 $script = $this->validateScriptFile( $titleText, $script );
00128                                 if ( strpos( $titleText, '*/' ) === false ) {
00129                                         $scripts .= "/* $titleText */\n";
00130                                 }
00131                                 $scripts .= $script . "\n";
00132                         }
00133                 }
00134                 return $scripts;
00135         }
00136 
00141         public function getStyles( ResourceLoaderContext $context ) {
00142                 global $wgScriptPath;
00143 
00144                 $styles = array();
00145                 foreach ( $this->getPages( $context ) as $titleText => $options ) {
00146                         if ( $options['type'] !== 'style' ) {
00147                                 continue;
00148                         }
00149                         $title = Title::newFromText( $titleText );
00150                         if ( !$title || $title->isRedirect() ) {
00151                                 continue;
00152                         }
00153                         $media = isset( $options['media'] ) ? $options['media'] : 'all';
00154                         $style = $this->getContent( $title );
00155                         if ( strval( $style ) === '' ) {
00156                                 continue;
00157                         }
00158                         if ( $this->getFlip( $context ) ) {
00159                                 $style = CSSJanus::transform( $style, true, false );
00160                         }
00161                         $style = CSSMin::remap( $style, false, $wgScriptPath, true );
00162                         if ( !isset( $styles[$media] ) ) {
00163                                 $styles[$media] = array();
00164                         }
00165                         if ( strpos( $titleText, '*/' ) === false ) {
00166                                 $style = "/* $titleText */\n" . $style;
00167                         }
00168                         $styles[$media][] = $style;
00169                 }
00170                 return $styles;
00171         }
00172 
00177         public function getModifiedTime( ResourceLoaderContext $context ) {
00178                 $modifiedTime = 1; // wfTimestamp() interprets 0 as "now"
00179                 $mtimes = $this->getTitleMtimes( $context );
00180                 if ( count( $mtimes ) ) {
00181                         $modifiedTime = max( $modifiedTime, max( $mtimes ) );
00182                 }
00183                 $modifiedTime = max( $modifiedTime, $this->getMsgBlobMtime( $context->getLanguage() ) );
00184                 return $modifiedTime;
00185         }
00186 
00191         public function isKnownEmpty( ResourceLoaderContext $context ) {
00192                 return count( $this->getTitleMtimes( $context ) ) == 0;
00193         }
00194 
00201         protected function getTitleMtimes( ResourceLoaderContext $context ) {
00202                 $dbr = $this->getDB();
00203                 if ( !$dbr ) {
00204                         // We're dealing with a subclass that doesn't have a DB
00205                         return array();
00206                 }
00207 
00208                 $hash = $context->getHash();
00209                 if ( isset( $this->titleMtimes[$hash] ) ) {
00210                         return $this->titleMtimes[$hash];
00211                 }
00212 
00213                 $this->titleMtimes[$hash] = array();
00214                 $batch = new LinkBatch;
00215                 foreach ( $this->getPages( $context ) as $titleText => $options ) {
00216                         $batch->addObj( Title::newFromText( $titleText ) );
00217                 }
00218 
00219                 if ( !$batch->isEmpty() ) {
00220                         $res = $dbr->select( 'page',
00221                                 array( 'page_namespace', 'page_title', 'page_touched' ),
00222                                 $batch->constructSet( 'page', $dbr ),
00223                                 __METHOD__
00224                         );
00225                         foreach ( $res as $row ) {
00226                                 $title = Title::makeTitle( $row->page_namespace, $row->page_title );
00227                                 $this->titleMtimes[$hash][$title->getPrefixedDBkey()] =
00228                                         wfTimestamp( TS_UNIX, $row->page_touched );
00229                         }
00230                 }
00231                 return $this->titleMtimes[$hash];
00232         }
00233 }