mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-03 13:58:55 +08:00
Fixes #1452: Added Module::getInstance() to allow accessing the module instance from anywhere within the module
This commit is contained in:
@ -3,8 +3,9 @@ Modules
|
||||
|
||||
Modules are self-contained software units that consist of [models](structure-models.md), [views](structure-views.md),
|
||||
[controllers](structure-controllers.md), and other supporting components. End users can access the controllers
|
||||
of a module when it is installed in [application](structure-applications.md). Modules differ from
|
||||
[applications](structure-applications.md) in that the former cannot be deployed alone and must reside within the latter.
|
||||
of a module when it is installed in [application](structure-applications.md). For these reasons, modules are
|
||||
often viewed as mini-applications. Modules differ from [applications](structure-applications.md) in that
|
||||
modules cannot be deployed alone and must reside within applications.
|
||||
|
||||
|
||||
## Creating Modules <a name="creating-modules"></a>
|
||||
@ -135,7 +136,7 @@ the [[yii\base\Application::modules|modules]] property of the application. The f
|
||||
```
|
||||
|
||||
The [[yii\base\Application::modules|modules]] property takes an array of module configurations. Each array key
|
||||
represents a module ID which uniquely identifies the module among all modules in the application, and the corresponding
|
||||
represents a *module ID* which uniquely identifies the module among all modules in the application, and the corresponding
|
||||
array value is a [configuration](concept-configurations.md) for creating the module.
|
||||
|
||||
|
||||
@ -152,8 +153,24 @@ controller in the `forum` module.
|
||||
|
||||
### Accessing Modules <a name="accessing-modules"></a>
|
||||
|
||||
A module is instantiated when one of its controllers is accessed by end users. You may access the instance of a module
|
||||
using the approaches shown in the following example:
|
||||
Within a module, you may often need to get the instance of the [module class](#module-classes) so that you can
|
||||
access the module ID, module parameters, module components, etc. You can do so by using the following statement:
|
||||
|
||||
```php
|
||||
$module = MyModuleClass::getInstance();
|
||||
```
|
||||
|
||||
where `MyModuleClass` refers to the name of the module class that you are interested in. The `getInstance()` method
|
||||
will return the currently requested instance of the module class. If the module is not requested, the method will
|
||||
return null. Note that You do not want to manually create a new instance of the module class because it will be
|
||||
different from the one created by Yii in response to a request.
|
||||
|
||||
> Info: When developing a module, you should not assume the module will use a fixed ID. This is because a module
|
||||
can be associated with an arbitrary ID when used in an application or within another module. In order to get
|
||||
the module ID, you should use the above approach to get the module instance first, and then get the ID via
|
||||
`$module->id`.
|
||||
|
||||
You may also access the instance of a module using the following approaches:
|
||||
|
||||
```php
|
||||
// get the module whose ID is "forum"
|
||||
@ -163,8 +180,8 @@ $module = \Yii::$app->getModule('forum');
|
||||
$module = \Yii::$app->controller->module;
|
||||
```
|
||||
|
||||
The first approach is only useful in application code which has knowledge about the module ID, while the second approach
|
||||
is best used by the code within the module.
|
||||
The first approach is only useful when you know the module ID, while the second approach is best used when you
|
||||
know about the controllers being requested.
|
||||
|
||||
Once getting hold of a module instance, you can access parameters or components registered with the module. For example,
|
||||
|
||||
@ -230,5 +247,5 @@ a set of closely related features. Each such feature group can be developed as a
|
||||
maintained by a specific developer or team.
|
||||
|
||||
Modules are also a good way of reusing code at the feature group level. Some commonly used features, such as
|
||||
user management, comment management, can all be developed in terms of modules so that they can be resued easily
|
||||
user management, comment management, can all be developed in terms of modules so that they can be reused easily
|
||||
in future projects.
|
||||
|
||||
@ -66,6 +66,7 @@ Yii Framework 2 Change Log
|
||||
- Bug: Fixed the bug that requesting protected or private action methods would cause 500 error instead of 404 (qiangxue)
|
||||
- Bug: Fixed Object of class Imagick could not be converted to string in CaptchaAction (eXprojects, cebe)
|
||||
- Enh #422: Added Support for BIT(M) data type default values in Schema (cebe)
|
||||
- Enh #1452: Added `Module::getInstance()` to allow accessing the module instance from anywhere within the module (qiangxue)
|
||||
- Enh #2264: `CookieCollection::has()` will return false for expired or removed cookies (qiangxue)
|
||||
- Enh #2435: `yii\db\IntegrityException` is now thrown on database integrity errors instead of general `yii\db\Exception` (samdark)
|
||||
- Enh #2558: Enhanced support for memcached by adding `yii\caching\MemCache::persistentId` and `yii\caching\MemCache::options` (qiangxue)
|
||||
@ -110,12 +111,14 @@ Yii Framework 2 Change Log
|
||||
- Enh #3774: Added `FileValidator::checkExtensionByMimeType` to support validating file types against file mime-types (Ragazzo)
|
||||
- Enh #3801: Base migration controller `yii\console\controllers\BaseMigrateController` extracted (klimov-paul)
|
||||
- Enh #3811: Now Gii model generator makes autocomplete for model class field (mitalcoi)
|
||||
- Enh #3926: `yii\widgets\Breadcrumbs::$links`. Allows individual link to have its own `template` (creocoder, umneeq)
|
||||
- Enh #3939: `\yii\Inflector::slug()` improvements (samdark)
|
||||
- Added protected `\yii\Inflector::transliterate()` that could be replaced with custom translit implementation.
|
||||
- Added proper tests for both intl-based slug and PHP fallback.
|
||||
- Removed character maps for non-latin languages.
|
||||
- Improved overall slug results.
|
||||
- Added note about the fact that intl is required for non-latin languages to requirements checker.
|
||||
- Enh #4028: Added ability to `yii\widgets\Menu` to encode each item's label separately (creocoder, umneeq)
|
||||
- Enh: Added support for using sub-queries when building a DB query with `IN` condition (qiangxue)
|
||||
- Enh: Supported adding a new response formatter without the need to reconfigure existing formatters (qiangxue)
|
||||
- Enh: Added `yii\web\UrlManager::addRules()` to simplify adding new URL rules (qiangxue)
|
||||
@ -129,8 +132,6 @@ Yii Framework 2 Change Log
|
||||
- Enh: Added param `hideOnSinglePage` to `yii\widgets\LinkPager` (arturf)
|
||||
- Enh: Added support for array attributes in `in` validator (creocoder)
|
||||
- Enh: Improved `yii\helpers\Inflector::slug` to support more cases for Russian, Hebrew and special characters (samdark)
|
||||
- Enh #3926: `yii\widgets\Breadcrumbs::$links`. Allows individual link to have its own `template` (creocoder, umneeq)
|
||||
- Enh #4028: Added ability to `yii\widgets\Menu` to encode each item's label separately (creocoder, umneeq)
|
||||
- Chg #2287: Split `yii\db\ColumnSchema::typecast()` into two methods `phpTypecast()` and `dbTypecast()` to allow specifying PDO type explicitly (cebe)
|
||||
- Chg #2898: `yii\console\controllers\AssetController` is now using hashes instead of timestamps (samdark)
|
||||
- Chg #2913: RBAC `DbManager` is now initialized via migration (samdark)
|
||||
|
||||
@ -189,6 +189,7 @@ abstract class Application extends Module
|
||||
public function __construct($config = [])
|
||||
{
|
||||
Yii::$app = $this;
|
||||
$this->setInstance($this);
|
||||
|
||||
$this->state = self::STATE_BEGIN;
|
||||
|
||||
|
||||
@ -122,7 +122,10 @@ class Module extends ServiceLocator
|
||||
* @var array child modules of this module
|
||||
*/
|
||||
private $_modules = [];
|
||||
|
||||
/**
|
||||
* @var array list of currently requested modules indexed by their class names
|
||||
*/
|
||||
private static $_instances = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -137,6 +140,32 @@ class Module extends ServiceLocator
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently requested instance of this module class.
|
||||
* If the module class is not currently requested, null will be returned.
|
||||
* This method is provided so that you access the module instance from anywhere within the module.
|
||||
* @return static|null the currently requested instance of this module class, or null if the module class is not requested.
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
$class = get_called_class();
|
||||
return isset(self::$_instances[$class]) ? self::$_instances[$class] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently requested instance of this module class.
|
||||
* @param Module|null $instance the currently requested instance of this module class.
|
||||
* If it is null, the instance of the calling class will be removed, if any.
|
||||
*/
|
||||
public static function setInstance($instance)
|
||||
{
|
||||
if ($instance === null) {
|
||||
unset(self::$_instances[get_class()]);
|
||||
} else {
|
||||
self::$_instances[get_class($instance)] = $instance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the module.
|
||||
*
|
||||
@ -326,8 +355,10 @@ class Module extends ServiceLocator
|
||||
if (is_array($this->_modules[$id]) && !isset($this->_modules[$id]['class'])) {
|
||||
$this->_modules[$id]['class'] = 'yii\base\Module';
|
||||
}
|
||||
|
||||
return $this->_modules[$id] = Yii::createObject($this->_modules[$id], [$id, $this]);
|
||||
/** @var $module Module */
|
||||
$module = Yii::createObject($this->_modules[$id], [$id, $this]);
|
||||
$module->setInstance($module);
|
||||
return $this->_modules[$id] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user