MediaWiki
REL1_24
|
00001 <?php 00002 00029 class SkinFactory { 00030 00035 private $factoryFunctions = array(); 00042 private $displayNames = array(); 00049 private $legacySkins = array(); 00050 00054 private static $self; 00055 00056 public static function getDefaultInstance() { 00057 if ( !self::$self ) { 00058 self::$self = new self; 00059 } 00060 00061 return self::$self; 00062 } 00063 00077 public function register( $name, $displayName, $callback ) { 00078 if ( !is_callable( $callback ) ) { 00079 throw new InvalidArgumentException( 'Invalid callback provided' ); 00080 } 00081 $this->factoryFunctions[$name] = $callback; 00082 $this->displayNames[$name] = $displayName; 00083 } 00084 00088 private function getLegacySkinNames() { 00089 static $skinsInitialised = false; 00090 00091 if ( !$skinsInitialised || !count( $this->legacySkins ) ) { 00092 # Get a list of available skins 00093 # Build using the regular expression '^(.*).php$' 00094 # Array keys are all lower case, array value keep the case used by filename 00095 # 00096 wfProfileIn( __METHOD__ . '-init' ); 00097 00098 global $wgStyleDirectory; 00099 00100 $skinDir = dir( $wgStyleDirectory ); 00101 00102 if ( $skinDir !== false && $skinDir !== null ) { 00103 # while code from www.php.net 00104 while ( false !== ( $file = $skinDir->read() ) ) { 00105 // Skip non-PHP files, hidden files, and '.dep' includes 00106 $matches = array(); 00107 00108 if ( preg_match( '/^([^.]*)\.php$/', $file, $matches ) ) { 00109 $aSkin = $matches[1]; 00110 00111 // Explicitly disallow loading core skins via the autodiscovery mechanism. 00112 // 00113 // They should be loaded already (in a non-autodicovery way), but old files might still 00114 // exist on the server because our MW version upgrade process is widely documented as 00115 // requiring just copying over all files, without removing old ones. 00116 // 00117 // This is one of the reasons we should have never used autodiscovery in the first 00118 // place. This hack can be safely removed when autodiscovery is gone. 00119 if ( in_array( $aSkin, array( 'CologneBlue', 'Modern', 'MonoBook', 'Vector' ) ) ) { 00120 wfLogWarning( 00121 "An old copy of the $aSkin skin was found in your skins/ directory. " . 00122 "You should remove it to avoid problems in the future." . 00123 "See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for details." 00124 ); 00125 continue; 00126 } 00127 00128 wfLogWarning( 00129 "A skin using autodiscovery mechanism, $aSkin, was found in your skins/ directory. " . 00130 "The mechanism will be removed in MediaWiki 1.25 and the skin will no longer be recognized. " . 00131 "See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for information how to fix this." 00132 ); 00133 $this->legacySkins[strtolower( $aSkin )] = $aSkin; 00134 } 00135 } 00136 $skinDir->close(); 00137 } 00138 $skinsInitialised = true; 00139 wfProfileOut( __METHOD__ . '-init' ); 00140 } 00141 return $this->legacySkins; 00142 00143 } 00144 00151 public function getSkinNames() { 00152 return array_merge( 00153 $this->getLegacySkinNames(), 00154 $this->displayNames 00155 ); 00156 } 00157 00164 private function getLegacySkin( $name ) { 00165 $skinNames = $this->getLegacySkinNames(); 00166 if ( !isset( $skinNames[$name] ) ) { 00167 return false; 00168 } 00169 $skinName = $skinNames[$name]; 00170 $className = "Skin{$skinName}"; 00171 00172 # Grab the skin class and initialise it. 00173 if ( !class_exists( $className ) ) { 00174 global $wgStyleDirectory; 00175 require_once "{$wgStyleDirectory}/{$skinName}.php"; 00176 00177 # Check if we got it 00178 if ( !class_exists( $className ) ) { 00179 # DO NOT die if the class isn't found. This breaks maintenance 00180 # scripts and can cause a user account to be unrecoverable 00181 # except by SQL manipulation if a previously valid skin name 00182 # is no longer valid. 00183 return false; 00184 } 00185 } 00186 $skin = new $className( $name ); 00187 return $skin; 00188 00189 } 00190 00198 public function makeSkin( $name ) { 00199 if ( !isset( $this->factoryFunctions[$name] ) ) { 00200 // Check the legacy autodiscovery method of skin loading 00201 $legacy = $this->getLegacySkin( $name ); 00202 if ( $legacy ) { 00203 return $legacy; 00204 } 00205 throw new SkinException( "No registered builder available for $name." ); 00206 } 00207 $skin = call_user_func( $this->factoryFunctions[$name], $name ); 00208 if ( $skin instanceof Skin ) { 00209 return $skin; 00210 } else { 00211 throw new UnexpectedValueException( "The builder for $name returned a non-Skin object." ); 00212 } 00213 } 00214 }