[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * 5 * Created on Dec 27, 2012 6 * 7 * Copyright © 2012 Yuri Astrakhan "<Firstname><Lastname>@gmail.com" 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 * http://www.gnu.org/copyleft/gpl.html 23 * 24 * @file 25 * @since 1.21 26 */ 27 28 /** 29 * This class holds a list of modules and handles instantiation 30 * 31 * @since 1.21 32 * @ingroup API 33 */ 34 class ApiModuleManager extends ContextSource { 35 36 /** 37 * @var ApiBase 38 */ 39 private $mParent; 40 /** 41 * @var ApiBase[] 42 */ 43 private $mInstances = array(); 44 /** 45 * @var null[] 46 */ 47 private $mGroups = array(); 48 /** 49 * @var array[] 50 */ 51 private $mModules = array(); 52 53 /** 54 * Construct new module manager 55 * @param ApiBase $parentModule Parent module instance will be used during instantiation 56 */ 57 public function __construct( ApiBase $parentModule ) { 58 $this->mParent = $parentModule; 59 } 60 61 /** 62 * Add a list of modules to the manager. Each module is described 63 * by a module spec. 64 * 65 * Each module spec is an associative array containing at least 66 * the 'class' key for the module's class, and optionally a 67 * 'factory' key for the factory function to use for the module. 68 * 69 * That factory function will be called with two parameters, 70 * the parent module (an instance of ApiBase, usually ApiMain) 71 * and the name the module was registered under. The return 72 * value must be an instance of the class given in the 'class' 73 * field. 74 * 75 * For backward compatibility, the module spec may also be a 76 * simple string containing the module's class name. In that 77 * case, the class' constructor will be called with the parent 78 * module and module name as parameters, as described above. 79 * 80 * Examples for defining module specs: 81 * 82 * @code 83 * $modules['foo'] = 'ApiFoo'; 84 * $modules['bar'] = array( 85 * 'class' => 'ApiBar', 86 * 'factory' => function( $main, $name ) { ... } 87 * ); 88 * $modules['xyzzy'] = array( 89 * 'class' => 'ApiXyzzy', 90 * 'factory' => array( 'XyzzyFactory', 'newApiModule' ) 91 * ); 92 * @endcode 93 * 94 * @param array $modules A map of ModuleName => ModuleSpec; The ModuleSpec 95 * is either a string containing the module's class name, or an associative 96 * array (see above for details). 97 * @param string $group Which group modules belong to (action,format,...) 98 */ 99 public function addModules( array $modules, $group ) { 100 101 foreach ( $modules as $name => $moduleSpec ) { 102 if ( is_array( $moduleSpec ) ) { 103 $class = $moduleSpec['class']; 104 $factory = ( isset( $moduleSpec['factory'] ) ? $moduleSpec['factory'] : null ); 105 } else { 106 $class = $moduleSpec; 107 $factory = null; 108 } 109 110 $this->addModule( $name, $group, $class, $factory ); 111 } 112 } 113 114 /** 115 * Add or overwrite a module in this ApiMain instance. Intended for use by extending 116 * classes who wish to add their own modules to their lexicon or override the 117 * behavior of inherent ones. 118 * 119 * @param string $name The identifier for this module. 120 * @param string $group Name of the module group 121 * @param string $class The class where this module is implemented. 122 * @param callable|null $factory Callback for instantiating the module. 123 * 124 * @throws InvalidArgumentException 125 */ 126 public function addModule( $name, $group, $class, $factory = null ) { 127 if ( !is_string( $name ) ) { 128 throw new InvalidArgumentException( '$name must be a string' ); 129 } 130 131 if ( !is_string( $group ) ) { 132 throw new InvalidArgumentException( '$group must be a string' ); 133 } 134 135 if ( !is_string( $class ) ) { 136 throw new InvalidArgumentException( '$class must be a string' ); 137 } 138 139 if ( $factory !== null && !is_callable( $factory ) ) { 140 throw new InvalidArgumentException( '$factory must be a callable (or null)' ); 141 } 142 143 $this->mGroups[$group] = null; 144 $this->mModules[$name] = array( $group, $class, $factory ); 145 } 146 147 /** 148 * Get module instance by name, or instantiate it if it does not exist 149 * 150 * @param string $moduleName Module name 151 * @param string $group Optionally validate that the module is in a specific group 152 * @param bool $ignoreCache If true, force-creates a new instance and does not cache it 153 * 154 * @return ApiBase|null The new module instance, or null if failed 155 */ 156 public function getModule( $moduleName, $group = null, $ignoreCache = false ) { 157 if ( !isset( $this->mModules[$moduleName] ) ) { 158 return null; 159 } 160 161 list( $moduleGroup, $moduleClass, $moduleFactory ) = $this->mModules[$moduleName]; 162 163 if ( $group !== null && $moduleGroup !== $group ) { 164 return null; 165 } 166 167 if ( !$ignoreCache && isset( $this->mInstances[$moduleName] ) ) { 168 // already exists 169 return $this->mInstances[$moduleName]; 170 } else { 171 // new instance 172 $instance = $this->instantiateModule( $moduleName, $moduleClass, $moduleFactory ); 173 174 if ( !$ignoreCache ) { 175 // cache this instance in case it is needed later 176 $this->mInstances[$moduleName] = $instance; 177 } 178 179 return $instance; 180 } 181 } 182 183 /** 184 * Instantiate the module using the given class or factory function. 185 * 186 * @param string $name The identifier for this module. 187 * @param string $class The class where this module is implemented. 188 * @param callable|null $factory Callback for instantiating the module. 189 * 190 * @throws MWException 191 * @return ApiBase 192 */ 193 private function instantiateModule( $name, $class, $factory = null ) { 194 if ( $factory !== null ) { 195 // create instance from factory 196 $instance = call_user_func( $factory, $this->mParent, $name ); 197 198 if ( !$instance instanceof $class ) { 199 throw new MWException( "The factory function for module $name did not return an instance of $class!" ); 200 } 201 } else { 202 // create instance from class name 203 $instance = new $class( $this->mParent, $name ); 204 } 205 206 return $instance; 207 } 208 209 /** 210 * Get an array of modules in a specific group or all if no group is set. 211 * @param string $group Optional group filter 212 * @return array List of module names 213 */ 214 public function getNames( $group = null ) { 215 if ( $group === null ) { 216 return array_keys( $this->mModules ); 217 } 218 $result = array(); 219 foreach ( $this->mModules as $name => $grpCls ) { 220 if ( $grpCls[0] === $group ) { 221 $result[] = $name; 222 } 223 } 224 225 return $result; 226 } 227 228 /** 229 * Create an array of (moduleName => moduleClass) for a specific group or for all. 230 * @param string $group Name of the group to get or null for all 231 * @return array Name=>class map 232 */ 233 public function getNamesWithClasses( $group = null ) { 234 $result = array(); 235 foreach ( $this->mModules as $name => $grpCls ) { 236 if ( $group === null || $grpCls[0] === $group ) { 237 $result[$name] = $grpCls[1]; 238 } 239 } 240 241 return $result; 242 } 243 244 /** 245 * Returns the class name of the given module 246 * 247 * @param string $module Module name 248 * @return string|bool class name or false if the module does not exist 249 * @since 1.24 250 */ 251 public function getClassName( $module ) { 252 if ( isset( $this->mModules[$module] ) ) { 253 return $this->mModules[$module][1]; 254 } 255 256 return false; 257 } 258 259 /** 260 * Returns true if the specific module is defined at all or in a specific group. 261 * @param string $moduleName Module name 262 * @param string $group Group name to check against, or null to check all groups, 263 * @return bool True if defined 264 */ 265 public function isDefined( $moduleName, $group = null ) { 266 if ( isset( $this->mModules[$moduleName] ) ) { 267 return $group === null || $this->mModules[$moduleName][0] === $group; 268 } 269 270 return false; 271 } 272 273 /** 274 * Returns the group name for the given module 275 * @param string $moduleName 276 * @return string Group name or null if missing 277 */ 278 public function getModuleGroup( $moduleName ) { 279 if ( isset( $this->mModules[$moduleName] ) ) { 280 return $this->mModules[$moduleName][0]; 281 } 282 283 return null; 284 } 285 286 /** 287 * Get a list of groups this manager contains. 288 * @return array 289 */ 290 public function getGroups() { 291 return array_keys( $this->mGroups ); 292 } 293 }
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 |