PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/yii-1.1.4/framework/base/CModule.php

https://github.com/sassman/django-benchmark
PHP | 483 lines | 233 code | 35 blank | 215 comment | 36 complexity | 014590fa845b4258c2a5c13308d819a0 MD5 | raw file
  1. <?php
  2. /**
  3. * CModule class file.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2010 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CModule is the base class for module and application classes.
  12. *
  13. * CModule mainly manages application components and sub-modules.
  14. *
  15. * @author Qiang Xue <qiang.xue@gmail.com>
  16. * @version $Id: CModule.php 2094 2010-05-05 00:51:49Z qiang.xue $
  17. * @package system.base
  18. * @since 1.0.4
  19. */
  20. abstract class CModule extends CComponent
  21. {
  22. /**
  23. * @var array the IDs of the application components that should be preloaded.
  24. */
  25. public $preload=array();
  26. /**
  27. * @var array the behaviors that should be attached to the module.
  28. * The behaviors will be attached to the module when {@link init} is called.
  29. * Please refer to {@link CModel::behaviors} on how to specify the value of this property.
  30. */
  31. public $behaviors=array();
  32. private $_id;
  33. private $_parentModule;
  34. private $_basePath;
  35. private $_modulePath;
  36. private $_params;
  37. private $_modules=array();
  38. private $_moduleConfig=array();
  39. private $_components=array();
  40. private $_componentConfig=array();
  41. /**
  42. * Constructor.
  43. * @param string the ID of this module
  44. * @param CModule the parent module (if any)
  45. * @param mixed the module configuration. It can be either an array or
  46. * the path of a PHP file returning the configuration array.
  47. */
  48. public function __construct($id,$parent,$config=null)
  49. {
  50. $this->_id=$id;
  51. $this->_parentModule=$parent;
  52. // set basePath at early as possible to avoid trouble
  53. if(is_string($config))
  54. $config=require($config);
  55. if(isset($config['basePath']))
  56. {
  57. $this->setBasePath($config['basePath']);
  58. unset($config['basePath']);
  59. }
  60. Yii::setPathOfAlias($id,$this->getBasePath());
  61. $this->preinit();
  62. $this->configure($config);
  63. $this->attachBehaviors($this->behaviors);
  64. $this->preloadComponents();
  65. $this->init();
  66. }
  67. /**
  68. * Getter magic method.
  69. * This method is overridden to support accessing application components
  70. * like reading module properties.
  71. * @param string application component or property name
  72. * @return mixed the named property value
  73. */
  74. public function __get($name)
  75. {
  76. if($this->hasComponent($name))
  77. return $this->getComponent($name);
  78. else
  79. return parent::__get($name);
  80. }
  81. /**
  82. * Checks if a property value is null.
  83. * This method overrides the parent implementation by checking
  84. * if the named application component is loaded.
  85. * @param string the property name or the event name
  86. * @return boolean whether the property value is null
  87. */
  88. public function __isset($name)
  89. {
  90. if($this->hasComponent($name))
  91. return $this->getComponent($name)!==null;
  92. else
  93. return parent::__isset($name);
  94. }
  95. /**
  96. * @return string the module ID.
  97. */
  98. public function getId()
  99. {
  100. return $this->_id;
  101. }
  102. /**
  103. * @param string the module ID
  104. */
  105. public function setId($id)
  106. {
  107. $this->_id=$id;
  108. }
  109. /**
  110. * @return string the root directory of the module. Defaults to the directory containing the module class.
  111. */
  112. public function getBasePath()
  113. {
  114. if($this->_basePath===null)
  115. {
  116. $class=new ReflectionClass(get_class($this));
  117. $this->_basePath=dirname($class->getFileName());
  118. }
  119. return $this->_basePath;
  120. }
  121. /**
  122. * Sets the root directory of the module.
  123. * This method can only be invoked at the beginning of the constructor.
  124. * @param string the root directory of the module.
  125. * @throws CException if the directory does not exist.
  126. */
  127. public function setBasePath($path)
  128. {
  129. if(($this->_basePath=realpath($path))===false || !is_dir($this->_basePath))
  130. throw new CException(Yii::t('yii','Base path "{path}" is not a valid directory.',
  131. array('{path}'=>$path)));
  132. }
  133. /**
  134. * @return CAttributeCollection the list of user-defined parameters
  135. */
  136. public function getParams()
  137. {
  138. if($this->_params!==null)
  139. return $this->_params;
  140. else
  141. {
  142. $this->_params=new CAttributeCollection;
  143. $this->_params->caseSensitive=true;
  144. return $this->_params;
  145. }
  146. }
  147. /**
  148. * @param array user-defined parameters. This should be in name-value pairs.
  149. */
  150. public function setParams($value)
  151. {
  152. $params=$this->getParams();
  153. foreach($value as $k=>$v)
  154. $params->add($k,$v);
  155. }
  156. /**
  157. * @return string the directory that contains the application modules. Defaults to the 'modules' subdirectory of {@link basePath}.
  158. */
  159. public function getModulePath()
  160. {
  161. if($this->_modulePath!==null)
  162. return $this->_modulePath;
  163. else
  164. return $this->_modulePath=$this->getBasePath().DIRECTORY_SEPARATOR.'modules';
  165. }
  166. /**
  167. * @param string the directory that contains the application modules.
  168. * @throws CException if the directory is invalid
  169. */
  170. public function setModulePath($value)
  171. {
  172. if(($this->_modulePath=realpath($value))===false || !is_dir($this->_modulePath))
  173. throw new CException(Yii::t('yii','The module path "{path}" is not a valid directory.',
  174. array('{path}'=>$value)));
  175. }
  176. /**
  177. * Sets the aliases that are used in the module.
  178. * @param array list of aliases to be imported
  179. */
  180. public function setImport($aliases)
  181. {
  182. foreach($aliases as $alias)
  183. Yii::import($alias);
  184. }
  185. /**
  186. * Defines the root aliases.
  187. * @param array list of aliases to be defined. The array keys are root aliases,
  188. * while the array values are paths or aliases corresponding to the root aliases.
  189. * For example,
  190. * <pre>
  191. * array(
  192. * 'models'=>'application.models', // an existing alias
  193. * 'extensions'=>'application.extensions', // an existing alias
  194. * 'backend'=>dirname(__FILE__).'/../backend', // a directory
  195. * )
  196. * </pre>
  197. * @since 1.0.5
  198. */
  199. public function setAliases($mappings)
  200. {
  201. foreach($mappings as $name=>$alias)
  202. {
  203. if(($path=Yii::getPathOfAlias($alias))!==false)
  204. Yii::setPathOfAlias($name,$path);
  205. else
  206. Yii::setPathOfAlias($name,$alias);
  207. }
  208. }
  209. /**
  210. * @return CModule the parent module. Null if this module does not have a parent.
  211. */
  212. public function getParentModule()
  213. {
  214. return $this->_parentModule;
  215. }
  216. /**
  217. * Retrieves the named application module.
  218. * The module has to be declared in {@link modules}. A new instance will be created
  219. * when calling this method with the given ID for the first time.
  220. * @param string application module ID (case-sensitive)
  221. * @return CModule the module instance, null if the module is disabled or does not exist.
  222. */
  223. public function getModule($id)
  224. {
  225. if(isset($this->_modules[$id]) || array_key_exists($id,$this->_modules))
  226. return $this->_modules[$id];
  227. else if(isset($this->_moduleConfig[$id]))
  228. {
  229. $config=$this->_moduleConfig[$id];
  230. if(!isset($config['enabled']) || $config['enabled'])
  231. {
  232. Yii::trace("Loading \"$id\" module",'system.base.CModule');
  233. $class=$config['class'];
  234. unset($config['class'], $config['enabled']);
  235. if($this===Yii::app())
  236. $module=Yii::createComponent($class,$id,null,$config);
  237. else
  238. $module=Yii::createComponent($class,$this->getId().'/'.$id,$this,$config);
  239. return $this->_modules[$id]=$module;
  240. }
  241. }
  242. }
  243. /**
  244. * Returns a value indicating whether the specified module is installed.
  245. * @param string the module ID
  246. * @return boolean whether the specified module is installed.
  247. * @since 1.1.2
  248. */
  249. public function hasModule($id)
  250. {
  251. return isset($this->_moduleConfig[$id]) || isset($this->_modules[$id]);
  252. }
  253. /**
  254. * @return array the configuration of the currently installed modules (module ID => configuration)
  255. */
  256. public function getModules()
  257. {
  258. return $this->_moduleConfig;
  259. }
  260. /**
  261. * Configures the sub-modules of this module.
  262. *
  263. * Call this method to declare sub-modules and configure them with their initial property values.
  264. * The parameter should be an array of module configurations. Each array element represents a single module,
  265. * which can be either a string representing the module ID or an ID-configuration pair representing
  266. * a module with the specified ID and the initial property values.
  267. *
  268. * For example, the following array declares two modules:
  269. * <pre>
  270. * array(
  271. * 'admin', // a single module ID
  272. * 'payment'=>array( // ID-configuration pair
  273. * 'server'=>'paymentserver.com',
  274. * ),
  275. * )
  276. * </pre>
  277. *
  278. * By default, the module class is determined using the expression <code>ucfirst($moduleID).'Module'</code>.
  279. * And the class file is located under <code>modules/$moduleID</code>.
  280. * You may override this default by explicitly specifying the 'class' option in the configuration.
  281. *
  282. * You may also enable or disable a module by specifying the 'enabled' option in the configuration.
  283. *
  284. * @param array module configurations.
  285. */
  286. public function setModules($modules)
  287. {
  288. foreach($modules as $id=>$module)
  289. {
  290. if(is_int($id))
  291. {
  292. $id=$module;
  293. $module=array();
  294. }
  295. if(!isset($module['class']))
  296. {
  297. Yii::setPathOfAlias($id,$this->getModulePath().DIRECTORY_SEPARATOR.$id);
  298. $module['class']=$id.'.'.ucfirst($id).'Module';
  299. }
  300. if(isset($this->_moduleConfig[$id]))
  301. $this->_moduleConfig[$id]=CMap::mergeArray($this->_moduleConfig[$id],$module);
  302. else
  303. $this->_moduleConfig[$id]=$module;
  304. }
  305. }
  306. /**
  307. * @param string application component ID
  308. * @return boolean whether the named application component exists (including both loaded and disabled.)
  309. */
  310. public function hasComponent($id)
  311. {
  312. return isset($this->_components[$id]) || isset($this->_componentConfig[$id]);
  313. }
  314. /**
  315. * Retrieves the named application component.
  316. * @param string application component ID (case-sensitive)
  317. * @param boolean whether to create the component if it doesn't exist yet. This parameter
  318. * has been available since version 1.0.6.
  319. * @return IApplicationComponent the application component instance, null if the application component is disabled or does not exist.
  320. * @see hasComponent
  321. */
  322. public function getComponent($id,$createIfNull=true)
  323. {
  324. if(isset($this->_components[$id]))
  325. return $this->_components[$id];
  326. else if(isset($this->_componentConfig[$id]) && $createIfNull)
  327. {
  328. $config=$this->_componentConfig[$id];
  329. unset($this->_componentConfig[$id]);
  330. if(!isset($config['enabled']) || $config['enabled'])
  331. {
  332. Yii::trace("Loading \"$id\" application component",'system.CModule');
  333. unset($config['enabled']);
  334. $component=Yii::createComponent($config);
  335. $component->init();
  336. return $this->_components[$id]=$component;
  337. }
  338. }
  339. }
  340. /**
  341. * Puts a component under the management of the module.
  342. * The component will be initialized (by calling its {@link CApplicationComponent::init() init()}
  343. * method if it has not done so.
  344. * @param string component ID
  345. * @param IApplicationComponent the component
  346. */
  347. public function setComponent($id,$component)
  348. {
  349. $this->_components[$id]=$component;
  350. if(!$component->getIsInitialized())
  351. $component->init();
  352. }
  353. /**
  354. * Returns the application components.
  355. * @param boolean whether to return the loaded components only. If this is set false,
  356. * then all components specified in the configuration will be returned, whether they are loaded or not.
  357. * Loaded components will be returned as objects, while unloaded components as configuration arrays.
  358. * This parameter has been available since version 1.1.3.
  359. * @return array the application components (indexed by their IDs)
  360. */
  361. public function getComponents($loadedOnly=true)
  362. {
  363. if($loadedOnly)
  364. return $this->_components;
  365. else
  366. return array_merge($this->_componentConfig, $this->_components);
  367. }
  368. /**
  369. * Sets the application components.
  370. *
  371. * When a configuration is used to specify a component, it should consist of
  372. * the component's initial property values (name-value pairs). Additionally,
  373. * a component can be enabled (default) or disabled by specifying the 'enabled' value
  374. * in the configuration.
  375. *
  376. * If a configuration is specified with an ID that is the same as an existing
  377. * component or configuration, the existing one will be replaced silently.
  378. *
  379. * The following is the configuration for two components:
  380. * <pre>
  381. * array(
  382. * 'db'=>array(
  383. * 'class'=>'CDbConnection',
  384. * 'connectionString'=>'sqlite:path/to/file.db',
  385. * ),
  386. * 'cache'=>array(
  387. * 'class'=>'CDbCache',
  388. * 'connectionID'=>'db',
  389. * 'enabled'=>!YII_DEBUG, // enable caching in non-debug mode
  390. * ),
  391. * )
  392. * </pre>
  393. *
  394. * @param array application components(id=>component configuration or instances)
  395. */
  396. public function setComponents($components)
  397. {
  398. foreach($components as $id=>$component)
  399. {
  400. if($component instanceof IApplicationComponent)
  401. $this->setComponent($id,$component);
  402. else if(isset($this->_componentConfig[$id]))
  403. $this->_componentConfig[$id]=CMap::mergeArray($this->_componentConfig[$id],$component);
  404. else
  405. $this->_componentConfig[$id]=$component;
  406. }
  407. }
  408. /**
  409. * Configures the module with the specified configuration.
  410. * @param array the configuration array
  411. */
  412. public function configure($config)
  413. {
  414. if(is_array($config))
  415. {
  416. foreach($config as $key=>$value)
  417. $this->$key=$value;
  418. }
  419. }
  420. /**
  421. * Loads static application components.
  422. */
  423. protected function preloadComponents()
  424. {
  425. foreach($this->preload as $id)
  426. $this->getComponent($id);
  427. }
  428. /**
  429. * Preinitializes the module.
  430. * This method is called at the beginning of the module constructor.
  431. * You may override this method to do some customized preinitialization work.
  432. * Note that at this moment, the module is not configured yet.
  433. * @see init
  434. */
  435. protected function preinit()
  436. {
  437. }
  438. /**
  439. * Initializes the module.
  440. * This method is called at the end of the module constructor.
  441. * Note that at this moment, the module has been configured, the behaviors
  442. * have been attached and the application components have been registered.
  443. * @see preinit
  444. */
  445. protected function init()
  446. {
  447. }
  448. }