[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Copyright 2014 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License along 17 * with this program; if not, write to the Free Software Foundation, Inc., 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 * http://www.gnu.org/copyleft/gpl.html 20 * 21 * @file 22 */ 23 24 /** 25 * Factory class to create Skin objects 26 * 27 * @since 1.24 28 */ 29 class SkinFactory { 30 31 /** 32 * Map of name => callback 33 * @var array 34 */ 35 private $factoryFunctions = array(); 36 /** 37 * Map of name => fallback human-readable name, used when the 'skinname-<skin>' message is not 38 * available 39 * 40 * @var array 41 */ 42 private $displayNames = array(); 43 /** 44 * Map of name => class name without "Skin" prefix, for legacy skins using the autodiscovery 45 * mechanism 46 * 47 * @var array 48 */ 49 private $legacySkins = array(); 50 51 /** 52 * @var SkinFactory 53 */ 54 private static $self; 55 56 public static function getDefaultInstance() { 57 if ( !self::$self ) { 58 self::$self = new self; 59 } 60 61 return self::$self; 62 } 63 64 /** 65 * Register a new Skin factory function. 66 * 67 * Will override if it's already registered. 68 * 69 * @param string $name Internal skin name. Should be all-lowercase (technically doesn't have 70 * to be, but doing so would change the case of i18n message keys). 71 * @param string $displayName For backwards-compatibility with old skin loading system. This is 72 * the text used as skin's human-readable name when the 'skinname-<skin>' message is not 73 * available. It should be the same as the skin name provided in $wgExtensionCredits. 74 * @param callable $callback Callback that takes the skin name as an argument 75 * @throws InvalidArgumentException If an invalid callback is provided 76 */ 77 public function register( $name, $displayName, $callback ) { 78 if ( !is_callable( $callback ) ) { 79 throw new InvalidArgumentException( 'Invalid callback provided' ); 80 } 81 $this->factoryFunctions[$name] = $callback; 82 $this->displayNames[$name] = $displayName; 83 } 84 85 /** 86 * @return array 87 */ 88 private function getLegacySkinNames() { 89 static $skinsInitialised = false; 90 91 if ( !$skinsInitialised || !count( $this->legacySkins ) ) { 92 # Get a list of available skins 93 # Build using the regular expression '^(.*).php$' 94 # Array keys are all lower case, array value keep the case used by filename 95 # 96 wfProfileIn( __METHOD__ . '-init' ); 97 98 global $wgStyleDirectory; 99 100 $skinDir = dir( $wgStyleDirectory ); 101 102 if ( $skinDir !== false && $skinDir !== null ) { 103 # while code from www.php.net 104 while ( false !== ( $file = $skinDir->read() ) ) { 105 // Skip non-PHP files, hidden files, and '.dep' includes 106 $matches = array(); 107 108 if ( preg_match( '/^([^.]*)\.php$/', $file, $matches ) ) { 109 $aSkin = $matches[1]; 110 111 // Explicitly disallow loading core skins via the autodiscovery mechanism. 112 // 113 // They should be loaded already (in a non-autodicovery way), but old files might still 114 // exist on the server because our MW version upgrade process is widely documented as 115 // requiring just copying over all files, without removing old ones. 116 // 117 // This is one of the reasons we should have never used autodiscovery in the first 118 // place. This hack can be safely removed when autodiscovery is gone. 119 if ( in_array( $aSkin, array( 'CologneBlue', 'Modern', 'MonoBook', 'Vector' ) ) ) { 120 wfLogWarning( 121 "An old copy of the $aSkin skin was found in your skins/ directory. " . 122 "You should remove it to avoid problems in the future." . 123 "See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for details." 124 ); 125 continue; 126 } 127 128 wfLogWarning( 129 "A skin using autodiscovery mechanism, $aSkin, was found in your skins/ directory. " . 130 "The mechanism will be removed in MediaWiki 1.25 and the skin will no longer be recognized. " . 131 "See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for information how to fix this." 132 ); 133 $this->legacySkins[strtolower( $aSkin )] = $aSkin; 134 } 135 } 136 $skinDir->close(); 137 } 138 $skinsInitialised = true; 139 wfProfileOut( __METHOD__ . '-init' ); 140 } 141 return $this->legacySkins; 142 143 } 144 145 /** 146 * Returns an associative array of: 147 * skin name => human readable name 148 * 149 * @return array 150 */ 151 public function getSkinNames() { 152 return array_merge( 153 $this->getLegacySkinNames(), 154 $this->displayNames 155 ); 156 } 157 158 /** 159 * Get a legacy skin which uses the autodiscovery mechanism. 160 * 161 * @param string $name 162 * @return Skin|bool False if the skin couldn't be constructed 163 */ 164 private function getLegacySkin( $name ) { 165 $skinNames = $this->getLegacySkinNames(); 166 if ( !isset( $skinNames[$name] ) ) { 167 return false; 168 } 169 $skinName = $skinNames[$name]; 170 $className = "Skin{$skinName}"; 171 172 # Grab the skin class and initialise it. 173 if ( !class_exists( $className ) ) { 174 global $wgStyleDirectory; 175 require_once "{$wgStyleDirectory}/{$skinName}.php"; 176 177 # Check if we got it 178 if ( !class_exists( $className ) ) { 179 # DO NOT die if the class isn't found. This breaks maintenance 180 # scripts and can cause a user account to be unrecoverable 181 # except by SQL manipulation if a previously valid skin name 182 # is no longer valid. 183 return false; 184 } 185 } 186 $skin = new $className( $name ); 187 return $skin; 188 189 } 190 191 /** 192 * Create a given Skin using the registered callback for $name. 193 * @param string $name Name of the skin you want 194 * @throws SkinException If a factory function isn't registered for $name 195 * @throws UnexpectedValueException If the factory function returns a non-Skin object 196 * @return Skin 197 */ 198 public function makeSkin( $name ) { 199 if ( !isset( $this->factoryFunctions[$name] ) ) { 200 // Check the legacy autodiscovery method of skin loading 201 $legacy = $this->getLegacySkin( $name ); 202 if ( $legacy ) { 203 return $legacy; 204 } 205 throw new SkinException( "No registered builder available for $name." ); 206 } 207 $skin = call_user_func( $this->factoryFunctions[$name], $name ); 208 if ( $skin instanceof Skin ) { 209 return $skin; 210 } else { 211 throw new UnexpectedValueException( "The builder for $name returned a non-Skin object." ); 212 } 213 } 214 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |