init
This commit is contained in:
122
vendor/yiisoft/yii2/base/Action.php
vendored
Normal file
122
vendor/yiisoft/yii2/base/Action.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Action is the base class for all controller action classes.
|
||||
*
|
||||
* Action provides a way to reuse action method code. An action method in an Action
|
||||
* class can be used in multiple controllers or in different projects.
|
||||
*
|
||||
* Derived classes must implement a method named `run()`. This method
|
||||
* will be invoked by the controller when the action is requested.
|
||||
* The `run()` method can have parameters which will be filled up
|
||||
* with user input values automatically according to their names.
|
||||
* For example, if the `run()` method is declared as follows:
|
||||
*
|
||||
* ```php
|
||||
* public function run($id, $type = 'book') { ... }
|
||||
* ```
|
||||
*
|
||||
* And the parameters provided for the action are: `['id' => 1]`.
|
||||
* Then the `run()` method will be invoked as `run(1)` automatically.
|
||||
*
|
||||
* For more details and usage information on Action, see the [guide article on actions](guide:structure-controllers).
|
||||
*
|
||||
* @property string $uniqueId The unique ID of this action among the whole application. This property is
|
||||
* read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Action extends Component
|
||||
{
|
||||
/**
|
||||
* @var string ID of the action
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @var Controller|\yii\web\Controller|\yii\console\Controller the controller that owns this action
|
||||
*/
|
||||
public $controller;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $id the ID of this action
|
||||
* @param Controller $controller the controller that owns this action
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties
|
||||
*/
|
||||
public function __construct($id, $controller, $config = [])
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->controller = $controller;
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique ID of this action among the whole application.
|
||||
*
|
||||
* @return string the unique ID of this action among the whole application.
|
||||
*/
|
||||
public function getUniqueId()
|
||||
{
|
||||
return $this->controller->getUniqueId() . '/' . $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs this action with the specified parameters.
|
||||
* This method is mainly invoked by the controller.
|
||||
*
|
||||
* @param array $params the parameters to be bound to the action's run() method.
|
||||
* @return mixed the result of the action
|
||||
* @throws InvalidConfigException if the action class does not have a run() method
|
||||
*/
|
||||
public function runWithParams($params)
|
||||
{
|
||||
if (!method_exists($this, 'run')) {
|
||||
throw new InvalidConfigException(get_class($this) . ' must define a "run()" method.');
|
||||
}
|
||||
$args = $this->controller->bindActionParams($this, $params);
|
||||
Yii::debug('Running action: ' . get_class($this) . '::run()', __METHOD__);
|
||||
if (Yii::$app->requestedParams === null) {
|
||||
Yii::$app->requestedParams = $args;
|
||||
}
|
||||
if ($this->beforeRun()) {
|
||||
$result = call_user_func_array([$this, 'run'], $args);
|
||||
$this->afterRun();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called right before `run()` is executed.
|
||||
* You may override this method to do preparation work for the action run.
|
||||
* If the method returns false, it will cancel the action.
|
||||
*
|
||||
* @return bool whether to run the action.
|
||||
*/
|
||||
protected function beforeRun()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called right after `run()` is executed.
|
||||
* You may override this method to do post-processing work for the action run.
|
||||
*/
|
||||
protected function afterRun()
|
||||
{
|
||||
}
|
||||
}
|
||||
46
vendor/yiisoft/yii2/base/ActionEvent.php
vendored
Normal file
46
vendor/yiisoft/yii2/base/ActionEvent.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ActionEvent represents the event parameter used for an action event.
|
||||
*
|
||||
* By setting the [[isValid]] property, one may control whether to continue running the action.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ActionEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var Action the action currently being executed
|
||||
*/
|
||||
public $action;
|
||||
/**
|
||||
* @var mixed the action result. Event handlers may modify this property to change the action result.
|
||||
*/
|
||||
public $result;
|
||||
/**
|
||||
* @var bool whether to continue running the action. Event handlers of
|
||||
* [[Controller::EVENT_BEFORE_ACTION]] may set this property to decide whether
|
||||
* to continue running the current action.
|
||||
*/
|
||||
public $isValid = true;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param Action $action the action associated with this action event.
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties
|
||||
*/
|
||||
public function __construct($action, $config = [])
|
||||
{
|
||||
$this->action = $action;
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
171
vendor/yiisoft/yii2/base/ActionFilter.php
vendored
Normal file
171
vendor/yiisoft/yii2/base/ActionFilter.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/**
|
||||
* ActionFilter is the base class for action filters.
|
||||
*
|
||||
* An action filter will participate in the action execution workflow by responding to
|
||||
* the `beforeAction` and `afterAction` events triggered by modules and controllers.
|
||||
*
|
||||
* Check implementation of [[\yii\filters\AccessControl]], [[\yii\filters\PageCache]] and [[\yii\filters\HttpCache]] as examples on how to use it.
|
||||
*
|
||||
* For more details and usage information on ActionFilter, see the [guide article on filters](guide:structure-filters).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ActionFilter extends Behavior
|
||||
{
|
||||
/**
|
||||
* @var array list of action IDs that this filter should apply to. If this property is not set,
|
||||
* then the filter applies to all actions, unless they are listed in [[except]].
|
||||
* If an action ID appears in both [[only]] and [[except]], this filter will NOT apply to it.
|
||||
*
|
||||
* Note that if the filter is attached to a module, the action IDs should also include child module IDs (if any)
|
||||
* and controller IDs.
|
||||
*
|
||||
* Since version 2.0.9 action IDs can be specified as wildcards, e.g. `site/*`.
|
||||
*
|
||||
* @see except
|
||||
*/
|
||||
public $only;
|
||||
/**
|
||||
* @var array list of action IDs that this filter should not apply to.
|
||||
* @see only
|
||||
*/
|
||||
public $except = [];
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attach($owner)
|
||||
{
|
||||
$this->owner = $owner;
|
||||
$owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function detach()
|
||||
{
|
||||
if ($this->owner) {
|
||||
$this->owner->off(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
|
||||
$this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
|
||||
$this->owner = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ActionEvent $event
|
||||
*/
|
||||
public function beforeFilter($event)
|
||||
{
|
||||
if (!$this->isActive($event->action)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event->isValid = $this->beforeAction($event->action);
|
||||
if ($event->isValid) {
|
||||
// call afterFilter only if beforeFilter succeeds
|
||||
// beforeFilter and afterFilter should be properly nested
|
||||
$this->owner->on(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter'], null, false);
|
||||
} else {
|
||||
$event->handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ActionEvent $event
|
||||
*/
|
||||
public function afterFilter($event)
|
||||
{
|
||||
$event->result = $this->afterAction($event->action, $event->result);
|
||||
$this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right before an action is to be executed (after all possible filters.)
|
||||
* You may override this method to do last-minute preparation for the action.
|
||||
* @param Action $action the action to be executed.
|
||||
* @return bool whether the action should continue to be executed.
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right after an action is executed.
|
||||
* You may override this method to do some postprocessing for the action.
|
||||
* @param Action $action the action just executed.
|
||||
* @param mixed $result the action execution result
|
||||
* @return mixed the processed action result.
|
||||
*/
|
||||
public function afterAction($action, $result)
|
||||
{
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an action ID by converting [[Action::$uniqueId]] into an ID relative to the module.
|
||||
* @param Action $action
|
||||
* @return string
|
||||
* @since 2.0.7
|
||||
*/
|
||||
protected function getActionId($action)
|
||||
{
|
||||
if ($this->owner instanceof Module) {
|
||||
$mid = $this->owner->getUniqueId();
|
||||
$id = $action->getUniqueId();
|
||||
if ($mid !== '' && strpos($id, $mid) === 0) {
|
||||
$id = substr($id, strlen($mid) + 1);
|
||||
}
|
||||
} else {
|
||||
$id = $action->id;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether the filter is active for the given action.
|
||||
* @param Action $action the action being filtered
|
||||
* @return bool whether the filter is active for the given action.
|
||||
*/
|
||||
protected function isActive($action)
|
||||
{
|
||||
$id = $this->getActionId($action);
|
||||
|
||||
if (empty($this->only)) {
|
||||
$onlyMatch = true;
|
||||
} else {
|
||||
$onlyMatch = false;
|
||||
foreach ($this->only as $pattern) {
|
||||
if (StringHelper::matchWildcard($pattern, $id)) {
|
||||
$onlyMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$exceptMatch = false;
|
||||
foreach ($this->except as $pattern) {
|
||||
if (StringHelper::matchWildcard($pattern, $id)) {
|
||||
$exceptMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !$exceptMatch && $onlyMatch;
|
||||
}
|
||||
}
|
||||
676
vendor/yiisoft/yii2/base/Application.php
vendored
Normal file
676
vendor/yiisoft/yii2/base/Application.php
vendored
Normal file
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Application is the base class for all application classes.
|
||||
*
|
||||
* For more details and usage information on Application, see the [guide article on applications](guide:structure-applications).
|
||||
*
|
||||
* @property \yii\web\AssetManager $assetManager The asset manager application component. This property is
|
||||
* read-only.
|
||||
* @property \yii\rbac\ManagerInterface $authManager The auth manager application component. Null is returned
|
||||
* if auth manager is not configured. This property is read-only.
|
||||
* @property string $basePath The root directory of the application.
|
||||
* @property \yii\caching\CacheInterface $cache The cache application component. Null if the component is not
|
||||
* enabled. This property is read-only.
|
||||
* @property array $container Values given in terms of name-value pairs. This property is write-only.
|
||||
* @property \yii\db\Connection $db The database connection. This property is read-only.
|
||||
* @property \yii\web\ErrorHandler|\yii\console\ErrorHandler $errorHandler The error handler application
|
||||
* component. This property is read-only.
|
||||
* @property \yii\i18n\Formatter $formatter The formatter application component. This property is read-only.
|
||||
* @property \yii\i18n\I18N $i18n The internationalization application component. This property is read-only.
|
||||
* @property \yii\log\Dispatcher $log The log dispatcher application component. This property is read-only.
|
||||
* @property \yii\mail\MailerInterface $mailer The mailer application component. This property is read-only.
|
||||
* @property \yii\web\Request|\yii\console\Request $request The request component. This property is read-only.
|
||||
* @property \yii\web\Response|\yii\console\Response $response The response component. This property is
|
||||
* read-only.
|
||||
* @property string $runtimePath The directory that stores runtime files. Defaults to the "runtime"
|
||||
* subdirectory under [[basePath]].
|
||||
* @property \yii\base\Security $security The security application component. This property is read-only.
|
||||
* @property string $timeZone The time zone used by this application.
|
||||
* @property string $uniqueId The unique ID of the module. This property is read-only.
|
||||
* @property \yii\web\UrlManager $urlManager The URL manager for this application. This property is read-only.
|
||||
* @property string $vendorPath The directory that stores vendor files. Defaults to "vendor" directory under
|
||||
* [[basePath]].
|
||||
* @property View|\yii\web\View $view The view application component that is used to render various view
|
||||
* files. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class Application extends Module
|
||||
{
|
||||
/**
|
||||
* @event Event an event raised before the application starts to handle a request.
|
||||
*/
|
||||
const EVENT_BEFORE_REQUEST = 'beforeRequest';
|
||||
/**
|
||||
* @event Event an event raised after the application successfully handles a request (before the response is sent out).
|
||||
*/
|
||||
const EVENT_AFTER_REQUEST = 'afterRequest';
|
||||
/**
|
||||
* Application state used by [[state]]: application just started.
|
||||
*/
|
||||
const STATE_BEGIN = 0;
|
||||
/**
|
||||
* Application state used by [[state]]: application is initializing.
|
||||
*/
|
||||
const STATE_INIT = 1;
|
||||
/**
|
||||
* Application state used by [[state]]: application is triggering [[EVENT_BEFORE_REQUEST]].
|
||||
*/
|
||||
const STATE_BEFORE_REQUEST = 2;
|
||||
/**
|
||||
* Application state used by [[state]]: application is handling the request.
|
||||
*/
|
||||
const STATE_HANDLING_REQUEST = 3;
|
||||
/**
|
||||
* Application state used by [[state]]: application is triggering [[EVENT_AFTER_REQUEST]]..
|
||||
*/
|
||||
const STATE_AFTER_REQUEST = 4;
|
||||
/**
|
||||
* Application state used by [[state]]: application is about to send response.
|
||||
*/
|
||||
const STATE_SENDING_RESPONSE = 5;
|
||||
/**
|
||||
* Application state used by [[state]]: application has ended.
|
||||
*/
|
||||
const STATE_END = 6;
|
||||
|
||||
/**
|
||||
* @var string the namespace that controller classes are located in.
|
||||
* This namespace will be used to load controller classes by prepending it to the controller class name.
|
||||
* The default namespace is `app\controllers`.
|
||||
*
|
||||
* Please refer to the [guide about class autoloading](guide:concept-autoloading.md) for more details.
|
||||
*/
|
||||
public $controllerNamespace = 'app\\controllers';
|
||||
/**
|
||||
* @var string the application name.
|
||||
*/
|
||||
public $name = 'My Application';
|
||||
/**
|
||||
* @var string the charset currently used for the application.
|
||||
*/
|
||||
public $charset = 'UTF-8';
|
||||
/**
|
||||
* @var string the language that is meant to be used for end users. It is recommended that you
|
||||
* use [IETF language tags](http://en.wikipedia.org/wiki/IETF_language_tag). For example, `en` stands
|
||||
* for English, while `en-US` stands for English (United States).
|
||||
* @see sourceLanguage
|
||||
*/
|
||||
public $language = 'en-US';
|
||||
/**
|
||||
* @var string the language that the application is written in. This mainly refers to
|
||||
* the language that the messages and view files are written in.
|
||||
* @see language
|
||||
*/
|
||||
public $sourceLanguage = 'en-US';
|
||||
/**
|
||||
* @var Controller the currently active controller instance
|
||||
*/
|
||||
public $controller;
|
||||
/**
|
||||
* @var string|bool the layout that should be applied for views in this application. Defaults to 'main'.
|
||||
* If this is false, layout will be disabled.
|
||||
*/
|
||||
public $layout = 'main';
|
||||
/**
|
||||
* @var string the requested route
|
||||
*/
|
||||
public $requestedRoute;
|
||||
/**
|
||||
* @var Action the requested Action. If null, it means the request cannot be resolved into an action.
|
||||
*/
|
||||
public $requestedAction;
|
||||
/**
|
||||
* @var array the parameters supplied to the requested action.
|
||||
*/
|
||||
public $requestedParams;
|
||||
/**
|
||||
* @var array list of installed Yii extensions. Each array element represents a single extension
|
||||
* with the following structure:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* 'name' => 'extension name',
|
||||
* 'version' => 'version number',
|
||||
* 'bootstrap' => 'BootstrapClassName', // optional, may also be a configuration array
|
||||
* 'alias' => [
|
||||
* '@alias1' => 'to/path1',
|
||||
* '@alias2' => 'to/path2',
|
||||
* ],
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* The "bootstrap" class listed above will be instantiated during the application
|
||||
* [[bootstrap()|bootstrapping process]]. If the class implements [[BootstrapInterface]],
|
||||
* its [[BootstrapInterface::bootstrap()|bootstrap()]] method will be also be called.
|
||||
*
|
||||
* If not set explicitly in the application config, this property will be populated with the contents of
|
||||
* `@vendor/yiisoft/extensions.php`.
|
||||
*/
|
||||
public $extensions;
|
||||
/**
|
||||
* @var array list of components that should be run during the application [[bootstrap()|bootstrapping process]].
|
||||
*
|
||||
* Each component may be specified in one of the following formats:
|
||||
*
|
||||
* - an application component ID as specified via [[components]].
|
||||
* - a module ID as specified via [[modules]].
|
||||
* - a class name.
|
||||
* - a configuration array.
|
||||
* - a Closure
|
||||
*
|
||||
* During the bootstrapping process, each component will be instantiated. If the component class
|
||||
* implements [[BootstrapInterface]], its [[BootstrapInterface::bootstrap()|bootstrap()]] method
|
||||
* will be also be called.
|
||||
*/
|
||||
public $bootstrap = [];
|
||||
/**
|
||||
* @var int the current application state during a request handling life cycle.
|
||||
* This property is managed by the application. Do not modify this property.
|
||||
*/
|
||||
public $state;
|
||||
/**
|
||||
* @var array list of loaded modules indexed by their class names.
|
||||
*/
|
||||
public $loadedModules = [];
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties.
|
||||
* Note that the configuration must contain both [[id]] and [[basePath]].
|
||||
* @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
Yii::$app = $this;
|
||||
static::setInstance($this);
|
||||
|
||||
$this->state = self::STATE_BEGIN;
|
||||
|
||||
$this->preInit($config);
|
||||
|
||||
$this->registerErrorHandler($config);
|
||||
|
||||
Component::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-initializes the application.
|
||||
* This method is called at the beginning of the application constructor.
|
||||
* It initializes several important application properties.
|
||||
* If you override this method, please make sure you call the parent implementation.
|
||||
* @param array $config the application configuration
|
||||
* @throws InvalidConfigException if either [[id]] or [[basePath]] configuration is missing.
|
||||
*/
|
||||
public function preInit(&$config)
|
||||
{
|
||||
if (!isset($config['id'])) {
|
||||
throw new InvalidConfigException('The "id" configuration for the Application is required.');
|
||||
}
|
||||
if (isset($config['basePath'])) {
|
||||
$this->setBasePath($config['basePath']);
|
||||
unset($config['basePath']);
|
||||
} else {
|
||||
throw new InvalidConfigException('The "basePath" configuration for the Application is required.');
|
||||
}
|
||||
|
||||
if (isset($config['vendorPath'])) {
|
||||
$this->setVendorPath($config['vendorPath']);
|
||||
unset($config['vendorPath']);
|
||||
} else {
|
||||
// set "@vendor"
|
||||
$this->getVendorPath();
|
||||
}
|
||||
if (isset($config['runtimePath'])) {
|
||||
$this->setRuntimePath($config['runtimePath']);
|
||||
unset($config['runtimePath']);
|
||||
} else {
|
||||
// set "@runtime"
|
||||
$this->getRuntimePath();
|
||||
}
|
||||
|
||||
if (isset($config['timeZone'])) {
|
||||
$this->setTimeZone($config['timeZone']);
|
||||
unset($config['timeZone']);
|
||||
} elseif (!ini_get('date.timezone')) {
|
||||
$this->setTimeZone('UTC');
|
||||
}
|
||||
|
||||
if (isset($config['container'])) {
|
||||
$this->setContainer($config['container']);
|
||||
|
||||
unset($config['container']);
|
||||
}
|
||||
|
||||
// merge core components with custom components
|
||||
foreach ($this->coreComponents() as $id => $component) {
|
||||
if (!isset($config['components'][$id])) {
|
||||
$config['components'][$id] = $component;
|
||||
} elseif (is_array($config['components'][$id]) && !isset($config['components'][$id]['class'])) {
|
||||
$config['components'][$id]['class'] = $component['class'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->state = self::STATE_INIT;
|
||||
$this->bootstrap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes extensions and executes bootstrap components.
|
||||
* This method is called by [[init()]] after the application has been fully configured.
|
||||
* If you override this method, make sure you also call the parent implementation.
|
||||
*/
|
||||
protected function bootstrap()
|
||||
{
|
||||
if ($this->extensions === null) {
|
||||
$file = Yii::getAlias('@vendor/yiisoft/extensions.php');
|
||||
$this->extensions = is_file($file) ? include $file : [];
|
||||
}
|
||||
foreach ($this->extensions as $extension) {
|
||||
if (!empty($extension['alias'])) {
|
||||
foreach ($extension['alias'] as $name => $path) {
|
||||
Yii::setAlias($name, $path);
|
||||
}
|
||||
}
|
||||
if (isset($extension['bootstrap'])) {
|
||||
$component = Yii::createObject($extension['bootstrap']);
|
||||
if ($component instanceof BootstrapInterface) {
|
||||
Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
|
||||
$component->bootstrap($this);
|
||||
} else {
|
||||
Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->bootstrap as $mixed) {
|
||||
$component = null;
|
||||
if ($mixed instanceof \Closure) {
|
||||
Yii::debug('Bootstrap with Closure', __METHOD__);
|
||||
if (!$component = call_user_func($mixed, $this)) {
|
||||
continue;
|
||||
}
|
||||
} elseif (is_string($mixed)) {
|
||||
if ($this->has($mixed)) {
|
||||
$component = $this->get($mixed);
|
||||
} elseif ($this->hasModule($mixed)) {
|
||||
$component = $this->getModule($mixed);
|
||||
} elseif (strpos($mixed, '\\') === false) {
|
||||
throw new InvalidConfigException("Unknown bootstrapping component ID: $mixed");
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($component)) {
|
||||
$component = Yii::createObject($mixed);
|
||||
}
|
||||
|
||||
if ($component instanceof BootstrapInterface) {
|
||||
Yii::debug('Bootstrap with ' . get_class($component) . '::bootstrap()', __METHOD__);
|
||||
$component->bootstrap($this);
|
||||
} else {
|
||||
Yii::debug('Bootstrap with ' . get_class($component), __METHOD__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the errorHandler component as a PHP error handler.
|
||||
* @param array $config application config
|
||||
*/
|
||||
protected function registerErrorHandler(&$config)
|
||||
{
|
||||
if (YII_ENABLE_ERROR_HANDLER) {
|
||||
if (!isset($config['components']['errorHandler']['class'])) {
|
||||
echo "Error: no errorHandler component is configured.\n";
|
||||
exit(1);
|
||||
}
|
||||
$this->set('errorHandler', $config['components']['errorHandler']);
|
||||
unset($config['components']['errorHandler']);
|
||||
$this->getErrorHandler()->register();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ID that uniquely identifies this module among all modules within the current application.
|
||||
* Since this is an application instance, it will always return an empty string.
|
||||
* @return string the unique ID of the module.
|
||||
*/
|
||||
public function getUniqueId()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the root directory of the application and the @app alias.
|
||||
* This method can only be invoked at the beginning of the constructor.
|
||||
* @param string $path the root directory of the application.
|
||||
* @property string the root directory of the application.
|
||||
* @throws InvalidArgumentException if the directory does not exist.
|
||||
*/
|
||||
public function setBasePath($path)
|
||||
{
|
||||
parent::setBasePath($path);
|
||||
Yii::setAlias('@app', $this->getBasePath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the application.
|
||||
* This is the main entrance of an application.
|
||||
* @return int the exit status (0 means normal, non-zero values mean abnormal)
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
try {
|
||||
$this->state = self::STATE_BEFORE_REQUEST;
|
||||
$this->trigger(self::EVENT_BEFORE_REQUEST);
|
||||
|
||||
$this->state = self::STATE_HANDLING_REQUEST;
|
||||
$response = $this->handleRequest($this->getRequest());
|
||||
|
||||
$this->state = self::STATE_AFTER_REQUEST;
|
||||
$this->trigger(self::EVENT_AFTER_REQUEST);
|
||||
|
||||
$this->state = self::STATE_SENDING_RESPONSE;
|
||||
$response->send();
|
||||
|
||||
$this->state = self::STATE_END;
|
||||
|
||||
return $response->exitStatus;
|
||||
} catch (ExitException $e) {
|
||||
$this->end($e->statusCode, isset($response) ? $response : null);
|
||||
return $e->statusCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the specified request.
|
||||
*
|
||||
* This method should return an instance of [[Response]] or its child class
|
||||
* which represents the handling result of the request.
|
||||
*
|
||||
* @param Request $request the request to be handled
|
||||
* @return Response the resulting response
|
||||
*/
|
||||
abstract public function handleRequest($request);
|
||||
|
||||
private $_runtimePath;
|
||||
|
||||
/**
|
||||
* Returns the directory that stores runtime files.
|
||||
* @return string the directory that stores runtime files.
|
||||
* Defaults to the "runtime" subdirectory under [[basePath]].
|
||||
*/
|
||||
public function getRuntimePath()
|
||||
{
|
||||
if ($this->_runtimePath === null) {
|
||||
$this->setRuntimePath($this->getBasePath() . DIRECTORY_SEPARATOR . 'runtime');
|
||||
}
|
||||
|
||||
return $this->_runtimePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory that stores runtime files.
|
||||
* @param string $path the directory that stores runtime files.
|
||||
*/
|
||||
public function setRuntimePath($path)
|
||||
{
|
||||
$this->_runtimePath = Yii::getAlias($path);
|
||||
Yii::setAlias('@runtime', $this->_runtimePath);
|
||||
}
|
||||
|
||||
private $_vendorPath;
|
||||
|
||||
/**
|
||||
* Returns the directory that stores vendor files.
|
||||
* @return string the directory that stores vendor files.
|
||||
* Defaults to "vendor" directory under [[basePath]].
|
||||
*/
|
||||
public function getVendorPath()
|
||||
{
|
||||
if ($this->_vendorPath === null) {
|
||||
$this->setVendorPath($this->getBasePath() . DIRECTORY_SEPARATOR . 'vendor');
|
||||
}
|
||||
|
||||
return $this->_vendorPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory that stores vendor files.
|
||||
* @param string $path the directory that stores vendor files.
|
||||
*/
|
||||
public function setVendorPath($path)
|
||||
{
|
||||
$this->_vendorPath = Yii::getAlias($path);
|
||||
Yii::setAlias('@vendor', $this->_vendorPath);
|
||||
Yii::setAlias('@bower', $this->_vendorPath . DIRECTORY_SEPARATOR . 'bower');
|
||||
Yii::setAlias('@npm', $this->_vendorPath . DIRECTORY_SEPARATOR . 'npm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time zone used by this application.
|
||||
* This is a simple wrapper of PHP function date_default_timezone_get().
|
||||
* If time zone is not configured in php.ini or application config,
|
||||
* it will be set to UTC by default.
|
||||
* @return string the time zone used by this application.
|
||||
* @see http://php.net/manual/en/function.date-default-timezone-get.php
|
||||
*/
|
||||
public function getTimeZone()
|
||||
{
|
||||
return date_default_timezone_get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time zone used by this application.
|
||||
* This is a simple wrapper of PHP function date_default_timezone_set().
|
||||
* Refer to the [php manual](http://www.php.net/manual/en/timezones.php) for available timezones.
|
||||
* @param string $value the time zone used by this application.
|
||||
* @see http://php.net/manual/en/function.date-default-timezone-set.php
|
||||
*/
|
||||
public function setTimeZone($value)
|
||||
{
|
||||
date_default_timezone_set($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the database connection component.
|
||||
* @return \yii\db\Connection the database connection.
|
||||
*/
|
||||
public function getDb()
|
||||
{
|
||||
return $this->get('db');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the log dispatcher component.
|
||||
* @return \yii\log\Dispatcher the log dispatcher application component.
|
||||
*/
|
||||
public function getLog()
|
||||
{
|
||||
return $this->get('log');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error handler component.
|
||||
* @return \yii\web\ErrorHandler|\yii\console\ErrorHandler the error handler application component.
|
||||
*/
|
||||
public function getErrorHandler()
|
||||
{
|
||||
return $this->get('errorHandler');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cache component.
|
||||
* @return \yii\caching\CacheInterface the cache application component. Null if the component is not enabled.
|
||||
*/
|
||||
public function getCache()
|
||||
{
|
||||
return $this->get('cache', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the formatter component.
|
||||
* @return \yii\i18n\Formatter the formatter application component.
|
||||
*/
|
||||
public function getFormatter()
|
||||
{
|
||||
return $this->get('formatter');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request component.
|
||||
* @return \yii\web\Request|\yii\console\Request the request component.
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->get('request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the response component.
|
||||
* @return \yii\web\Response|\yii\console\Response the response component.
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->get('response');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view object.
|
||||
* @return View|\yii\web\View the view application component that is used to render various view files.
|
||||
*/
|
||||
public function getView()
|
||||
{
|
||||
return $this->get('view');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL manager for this application.
|
||||
* @return \yii\web\UrlManager the URL manager for this application.
|
||||
*/
|
||||
public function getUrlManager()
|
||||
{
|
||||
return $this->get('urlManager');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the internationalization (i18n) component.
|
||||
* @return \yii\i18n\I18N the internationalization application component.
|
||||
*/
|
||||
public function getI18n()
|
||||
{
|
||||
return $this->get('i18n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mailer component.
|
||||
* @return \yii\mail\MailerInterface the mailer application component.
|
||||
*/
|
||||
public function getMailer()
|
||||
{
|
||||
return $this->get('mailer');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the auth manager for this application.
|
||||
* @return \yii\rbac\ManagerInterface the auth manager application component.
|
||||
* Null is returned if auth manager is not configured.
|
||||
*/
|
||||
public function getAuthManager()
|
||||
{
|
||||
return $this->get('authManager', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the asset manager.
|
||||
* @return \yii\web\AssetManager the asset manager application component.
|
||||
*/
|
||||
public function getAssetManager()
|
||||
{
|
||||
return $this->get('assetManager');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the security component.
|
||||
* @return \yii\base\Security the security application component.
|
||||
*/
|
||||
public function getSecurity()
|
||||
{
|
||||
return $this->get('security');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration of core application components.
|
||||
* @see set()
|
||||
*/
|
||||
public function coreComponents()
|
||||
{
|
||||
return [
|
||||
'log' => ['class' => 'yii\log\Dispatcher'],
|
||||
'view' => ['class' => 'yii\web\View'],
|
||||
'formatter' => ['class' => 'yii\i18n\Formatter'],
|
||||
'i18n' => ['class' => 'yii\i18n\I18N'],
|
||||
'mailer' => ['class' => 'yii\swiftmailer\Mailer'],
|
||||
'urlManager' => ['class' => 'yii\web\UrlManager'],
|
||||
'assetManager' => ['class' => 'yii\web\AssetManager'],
|
||||
'security' => ['class' => 'yii\base\Security'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates the application.
|
||||
* This method replaces the `exit()` function by ensuring the application life cycle is completed
|
||||
* before terminating the application.
|
||||
* @param int $status the exit status (value 0 means normal exit while other values mean abnormal exit).
|
||||
* @param Response $response the response to be sent. If not set, the default application [[response]] component will be used.
|
||||
* @throws ExitException if the application is in testing mode
|
||||
*/
|
||||
public function end($status = 0, $response = null)
|
||||
{
|
||||
if ($this->state === self::STATE_BEFORE_REQUEST || $this->state === self::STATE_HANDLING_REQUEST) {
|
||||
$this->state = self::STATE_AFTER_REQUEST;
|
||||
$this->trigger(self::EVENT_AFTER_REQUEST);
|
||||
}
|
||||
|
||||
if ($this->state !== self::STATE_SENDING_RESPONSE && $this->state !== self::STATE_END) {
|
||||
$this->state = self::STATE_END;
|
||||
$response = $response ?: $this->getResponse();
|
||||
$response->send();
|
||||
}
|
||||
|
||||
if (YII_ENV_TEST) {
|
||||
throw new ExitException($status);
|
||||
}
|
||||
|
||||
exit($status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures [[Yii::$container]] with the $config.
|
||||
*
|
||||
* @param array $config values given in terms of name-value pairs
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function setContainer($config)
|
||||
{
|
||||
Yii::configure(Yii::$container, $config);
|
||||
}
|
||||
}
|
||||
82
vendor/yiisoft/yii2/base/ArrayAccessTrait.php
vendored
Normal file
82
vendor/yiisoft/yii2/base/ArrayAccessTrait.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ArrayAccessTrait provides the implementation for [[\IteratorAggregate]], [[\ArrayAccess]] and [[\Countable]].
|
||||
*
|
||||
* Note that ArrayAccessTrait requires the class using it contain a property named `data` which should be an array.
|
||||
* The data will be exposed by ArrayAccessTrait to support accessing the class object like an array.
|
||||
*
|
||||
* @property array $data
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
trait ArrayAccessTrait
|
||||
{
|
||||
/**
|
||||
* Returns an iterator for traversing the data.
|
||||
* This method is required by the SPL interface [[\IteratorAggregate]].
|
||||
* It will be implicitly called when you use `foreach` to traverse the collection.
|
||||
* @return \ArrayIterator an iterator for traversing the cookies in the collection.
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of data items.
|
||||
* This method is required by Countable interface.
|
||||
* @return int number of data elements.
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by the interface [[\ArrayAccess]].
|
||||
* @param mixed $offset the offset to check on
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->data[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by the interface [[\ArrayAccess]].
|
||||
* @param int $offset the offset to retrieve element.
|
||||
* @return mixed the element at the offset, null if no element is found at the offset
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
return isset($this->data[$offset]) ? $this->data[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by the interface [[\ArrayAccess]].
|
||||
* @param int $offset the offset to set element
|
||||
* @param mixed $item the element value
|
||||
*/
|
||||
public function offsetSet($offset, $item)
|
||||
{
|
||||
$this->data[$offset] = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by the interface [[\ArrayAccess]].
|
||||
* @param mixed $offset the offset to unset element
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->data[$offset]);
|
||||
}
|
||||
}
|
||||
92
vendor/yiisoft/yii2/base/Arrayable.php
vendored
Normal file
92
vendor/yiisoft/yii2/base/Arrayable.php
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* Arrayable is the interface that should be implemented by classes who want to support customizable representation of their instances.
|
||||
*
|
||||
* For example, if a class implements Arrayable, by calling [[toArray()]], an instance of this class
|
||||
* can be turned into an array (including all its embedded objects) which can then be further transformed easily
|
||||
* into other formats, such as JSON, XML.
|
||||
*
|
||||
* The methods [[fields()]] and [[extraFields()]] allow the implementing classes to customize how and which of their data
|
||||
* should be formatted and put into the result of [[toArray()]].
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
interface Arrayable
|
||||
{
|
||||
/**
|
||||
* Returns the list of fields that should be returned by default by [[toArray()]] when no specific fields are specified.
|
||||
*
|
||||
* A field is a named element in the returned array by [[toArray()]].
|
||||
*
|
||||
* This method should return an array of field names or field definitions.
|
||||
* If the former, the field name will be treated as an object property name whose value will be used
|
||||
* as the field value. If the latter, the array key should be the field name while the array value should be
|
||||
* the corresponding field definition which can be either an object property name or a PHP callable
|
||||
* returning the corresponding field value. The signature of the callable should be:
|
||||
*
|
||||
* ```php
|
||||
* function ($model, $field) {
|
||||
* // return field value
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* For example, the following code declares four fields:
|
||||
*
|
||||
* - `email`: the field name is the same as the property name `email`;
|
||||
* - `firstName` and `lastName`: the field names are `firstName` and `lastName`, and their
|
||||
* values are obtained from the `first_name` and `last_name` properties;
|
||||
* - `fullName`: the field name is `fullName`. Its value is obtained by concatenating `first_name`
|
||||
* and `last_name`.
|
||||
*
|
||||
* ```php
|
||||
* return [
|
||||
* 'email',
|
||||
* 'firstName' => 'first_name',
|
||||
* 'lastName' => 'last_name',
|
||||
* 'fullName' => function ($model) {
|
||||
* return $model->first_name . ' ' . $model->last_name;
|
||||
* },
|
||||
* ];
|
||||
* ```
|
||||
*
|
||||
* @return array the list of field names or field definitions.
|
||||
* @see toArray()
|
||||
*/
|
||||
public function fields();
|
||||
|
||||
/**
|
||||
* Returns the list of additional fields that can be returned by [[toArray()]] in addition to those listed in [[fields()]].
|
||||
*
|
||||
* This method is similar to [[fields()]] except that the list of fields declared
|
||||
* by this method are not returned by default by [[toArray()]]. Only when a field in the list
|
||||
* is explicitly requested, will it be included in the result of [[toArray()]].
|
||||
*
|
||||
* @return array the list of expandable field names or field definitions. Please refer
|
||||
* to [[fields()]] on the format of the return value.
|
||||
* @see toArray()
|
||||
* @see fields()
|
||||
*/
|
||||
public function extraFields();
|
||||
|
||||
/**
|
||||
* Converts the object into an array.
|
||||
*
|
||||
* @param array $fields the fields that the output array should contain. Fields not specified
|
||||
* in [[fields()]] will be ignored. If this parameter is empty, all fields as specified in [[fields()]] will be returned.
|
||||
* @param array $expand the additional fields that the output array should contain.
|
||||
* Fields not specified in [[extraFields()]] will be ignored. If this parameter is empty, no extra fields
|
||||
* will be returned.
|
||||
* @param bool $recursive whether to recursively return array representation of embedded objects.
|
||||
* @return array the array representation of the object
|
||||
*/
|
||||
public function toArray(array $fields = [], array $expand = [], $recursive = true);
|
||||
}
|
||||
242
vendor/yiisoft/yii2/base/ArrayableTrait.php
vendored
Normal file
242
vendor/yiisoft/yii2/base/ArrayableTrait.php
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\ArrayHelper;
|
||||
use yii\web\Link;
|
||||
use yii\web\Linkable;
|
||||
|
||||
/**
|
||||
* ArrayableTrait provides a common implementation of the [[Arrayable]] interface.
|
||||
*
|
||||
* ArrayableTrait implements [[toArray()]] by respecting the field definitions as declared
|
||||
* in [[fields()]] and [[extraFields()]].
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
trait ArrayableTrait
|
||||
{
|
||||
/**
|
||||
* Returns the list of fields that should be returned by default by [[toArray()]] when no specific fields are specified.
|
||||
*
|
||||
* A field is a named element in the returned array by [[toArray()]].
|
||||
*
|
||||
* This method should return an array of field names or field definitions.
|
||||
* If the former, the field name will be treated as an object property name whose value will be used
|
||||
* as the field value. If the latter, the array key should be the field name while the array value should be
|
||||
* the corresponding field definition which can be either an object property name or a PHP callable
|
||||
* returning the corresponding field value. The signature of the callable should be:
|
||||
*
|
||||
* ```php
|
||||
* function ($model, $field) {
|
||||
* // return field value
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* For example, the following code declares four fields:
|
||||
*
|
||||
* - `email`: the field name is the same as the property name `email`;
|
||||
* - `firstName` and `lastName`: the field names are `firstName` and `lastName`, and their
|
||||
* values are obtained from the `first_name` and `last_name` properties;
|
||||
* - `fullName`: the field name is `fullName`. Its value is obtained by concatenating `first_name`
|
||||
* and `last_name`.
|
||||
*
|
||||
* ```php
|
||||
* return [
|
||||
* 'email',
|
||||
* 'firstName' => 'first_name',
|
||||
* 'lastName' => 'last_name',
|
||||
* 'fullName' => function () {
|
||||
* return $this->first_name . ' ' . $this->last_name;
|
||||
* },
|
||||
* ];
|
||||
* ```
|
||||
*
|
||||
* In this method, you may also want to return different lists of fields based on some context
|
||||
* information. For example, depending on the privilege of the current application user,
|
||||
* you may return different sets of visible fields or filter out some fields.
|
||||
*
|
||||
* The default implementation of this method returns the public object member variables indexed by themselves.
|
||||
*
|
||||
* @return array the list of field names or field definitions.
|
||||
* @see toArray()
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
$fields = array_keys(Yii::getObjectVars($this));
|
||||
return array_combine($fields, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of fields that can be expanded further and returned by [[toArray()]].
|
||||
*
|
||||
* This method is similar to [[fields()]] except that the list of fields returned
|
||||
* by this method are not returned by default by [[toArray()]]. Only when field names
|
||||
* to be expanded are explicitly specified when calling [[toArray()]], will their values
|
||||
* be exported.
|
||||
*
|
||||
* The default implementation returns an empty array.
|
||||
*
|
||||
* You may override this method to return a list of expandable fields based on some context information
|
||||
* (e.g. the current application user).
|
||||
*
|
||||
* @return array the list of expandable field names or field definitions. Please refer
|
||||
* to [[fields()]] on the format of the return value.
|
||||
* @see toArray()
|
||||
* @see fields()
|
||||
*/
|
||||
public function extraFields()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the model into an array.
|
||||
*
|
||||
* This method will first identify which fields to be included in the resulting array by calling [[resolveFields()]].
|
||||
* It will then turn the model into an array with these fields. If `$recursive` is true,
|
||||
* any embedded objects will also be converted into arrays.
|
||||
* When embeded objects are [[Arrayable]], their respective nested fields will be extracted and passed to [[toArray()]].
|
||||
*
|
||||
* If the model implements the [[Linkable]] interface, the resulting array will also have a `_link` element
|
||||
* which refers to a list of links as specified by the interface.
|
||||
*
|
||||
* @param array $fields the fields being requested.
|
||||
* If empty or if it contains '*', all fields as specified by [[fields()]] will be returned.
|
||||
* Fields can be nested, separated with dots (.). e.g.: item.field.sub-field
|
||||
* `$recursive` must be true for nested fields to be extracted. If `$recursive` is false, only the root fields will be extracted.
|
||||
* @param array $expand the additional fields being requested for exporting. Only fields declared in [[extraFields()]]
|
||||
* will be considered.
|
||||
* Expand can also be nested, separated with dots (.). e.g.: item.expand1.expand2
|
||||
* `$recursive` must be true for nested expands to be extracted. If `$recursive` is false, only the root expands will be extracted.
|
||||
* @param bool $recursive whether to recursively return array representation of embedded objects.
|
||||
* @return array the array representation of the object
|
||||
*/
|
||||
public function toArray(array $fields = [], array $expand = [], $recursive = true)
|
||||
{
|
||||
$data = [];
|
||||
foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
|
||||
$attribute = is_string($definition) ? $this->$definition : $definition($this, $field);
|
||||
|
||||
if ($recursive) {
|
||||
$nestedFields = $this->extractFieldsFor($fields, $field);
|
||||
$nestedExpand = $this->extractFieldsFor($expand, $field);
|
||||
if ($attribute instanceof Arrayable) {
|
||||
$attribute = $attribute->toArray($nestedFields, $nestedExpand);
|
||||
} elseif (is_array($attribute)) {
|
||||
$attribute = array_map(
|
||||
function ($item) use ($nestedFields, $nestedExpand) {
|
||||
if ($item instanceof Arrayable) {
|
||||
return $item->toArray($nestedFields, $nestedExpand);
|
||||
}
|
||||
return $item;
|
||||
},
|
||||
$attribute
|
||||
);
|
||||
}
|
||||
}
|
||||
$data[$field] = $attribute;
|
||||
}
|
||||
|
||||
if ($this instanceof Linkable) {
|
||||
$data['_links'] = Link::serialize($this->getLinks());
|
||||
}
|
||||
|
||||
return $recursive ? ArrayHelper::toArray($data) : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the root field names from nested fields.
|
||||
* Nested fields are separated with dots (.). e.g: "item.id"
|
||||
* The previous example would extract "item".
|
||||
*
|
||||
* @param array $fields The fields requested for extraction
|
||||
* @return array root fields extracted from the given nested fields
|
||||
* @since 2.0.14
|
||||
*/
|
||||
protected function extractRootFields(array $fields)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$result[] = current(explode('.', $field, 2));
|
||||
}
|
||||
|
||||
if (in_array('*', $result, true)) {
|
||||
$result = [];
|
||||
}
|
||||
|
||||
return array_unique($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract nested fields from a fields collection for a given root field
|
||||
* Nested fields are separated with dots (.). e.g: "item.id"
|
||||
* The previous example would extract "id".
|
||||
*
|
||||
* @param array $fields The fields requested for extraction
|
||||
* @param string $rootField The root field for which we want to extract the nested fields
|
||||
* @return array nested fields extracted for the given field
|
||||
* @since 2.0.14
|
||||
*/
|
||||
protected function extractFieldsFor(array $fields, $rootField)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (0 === strpos($field, "{$rootField}.")) {
|
||||
$result[] = preg_replace('/^' . preg_quote($rootField, '/') . '\./i', '', $field);
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines which fields can be returned by [[toArray()]].
|
||||
* This method will first extract the root fields from the given fields.
|
||||
* Then it will check the requested root fields against those declared in [[fields()]] and [[extraFields()]]
|
||||
* to determine which fields can be returned.
|
||||
* @param array $fields the fields being requested for exporting
|
||||
* @param array $expand the additional fields being requested for exporting
|
||||
* @return array the list of fields to be exported. The array keys are the field names, and the array values
|
||||
* are the corresponding object property names or PHP callables returning the field values.
|
||||
*/
|
||||
protected function resolveFields(array $fields, array $expand)
|
||||
{
|
||||
$fields = $this->extractRootFields($fields);
|
||||
$expand = $this->extractRootFields($expand);
|
||||
$result = [];
|
||||
|
||||
foreach ($this->fields() as $field => $definition) {
|
||||
if (is_int($field)) {
|
||||
$field = $definition;
|
||||
}
|
||||
if (empty($fields) || in_array($field, $fields, true)) {
|
||||
$result[$field] = $definition;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($expand)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($this->extraFields() as $field => $definition) {
|
||||
if (is_int($field)) {
|
||||
$field = $definition;
|
||||
}
|
||||
if (in_array($field, $expand, true)) {
|
||||
$result[$field] = $definition;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
295
vendor/yiisoft/yii2/base/BaseObject.php
vendored
Normal file
295
vendor/yiisoft/yii2/base/BaseObject.php
vendored
Normal file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* BaseObject is the base class that implements the *property* feature.
|
||||
*
|
||||
* A property is defined by a getter method (e.g. `getLabel`), and/or a setter method (e.g. `setLabel`). For example,
|
||||
* the following getter and setter methods define a property named `label`:
|
||||
*
|
||||
* ```php
|
||||
* private $_label;
|
||||
*
|
||||
* public function getLabel()
|
||||
* {
|
||||
* return $this->_label;
|
||||
* }
|
||||
*
|
||||
* public function setLabel($value)
|
||||
* {
|
||||
* $this->_label = $value;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Property names are *case-insensitive*.
|
||||
*
|
||||
* A property can be accessed like a member variable of an object. Reading or writing a property will cause the invocation
|
||||
* of the corresponding getter or setter method. For example,
|
||||
*
|
||||
* ```php
|
||||
* // equivalent to $label = $object->getLabel();
|
||||
* $label = $object->label;
|
||||
* // equivalent to $object->setLabel('abc');
|
||||
* $object->label = 'abc';
|
||||
* ```
|
||||
*
|
||||
* If a property has only a getter method and has no setter method, it is considered as *read-only*. In this case, trying
|
||||
* to modify the property value will cause an exception.
|
||||
*
|
||||
* One can call [[hasProperty()]], [[canGetProperty()]] and/or [[canSetProperty()]] to check the existence of a property.
|
||||
*
|
||||
* Besides the property feature, BaseObject also introduces an important object initialization life cycle. In particular,
|
||||
* creating an new instance of BaseObject or its derived class will involve the following life cycles sequentially:
|
||||
*
|
||||
* 1. the class constructor is invoked;
|
||||
* 2. object properties are initialized according to the given configuration;
|
||||
* 3. the `init()` method is invoked.
|
||||
*
|
||||
* In the above, both Step 2 and 3 occur at the end of the class constructor. It is recommended that
|
||||
* you perform object initialization in the `init()` method because at that stage, the object configuration
|
||||
* is already applied.
|
||||
*
|
||||
* In order to ensure the above life cycles, if a child class of BaseObject needs to override the constructor,
|
||||
* it should be done like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function __construct($param1, $param2, ..., $config = [])
|
||||
* {
|
||||
* ...
|
||||
* parent::__construct($config);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* That is, a `$config` parameter (defaults to `[]`) should be declared as the last parameter
|
||||
* of the constructor, and the parent implementation should be called at the end of the constructor.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0.13
|
||||
*/
|
||||
class BaseObject implements Configurable
|
||||
{
|
||||
/**
|
||||
* Returns the fully qualified name of this class.
|
||||
* @return string the fully qualified name of this class.
|
||||
* @deprecated since 2.0.14. On PHP >=5.5, use `::class` instead.
|
||||
*/
|
||||
public static function className()
|
||||
{
|
||||
return get_called_class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The default implementation does two things:
|
||||
*
|
||||
* - Initializes the object with the given configuration `$config`.
|
||||
* - Call [[init()]].
|
||||
*
|
||||
* If this method is overridden in a child class, it is recommended that
|
||||
*
|
||||
* - the last parameter of the constructor is a configuration array, like `$config` here.
|
||||
* - call the parent implementation at the end of the constructor.
|
||||
*
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
{
|
||||
if (!empty($config)) {
|
||||
Yii::configure($this, $config);
|
||||
}
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the object.
|
||||
* This method is invoked at the end of the constructor after the object is initialized with the
|
||||
* given configuration.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of an object property.
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `$value = $object->property;`.
|
||||
* @param string $name the property name
|
||||
* @return mixed the property value
|
||||
* @throws UnknownPropertyException if the property is not defined
|
||||
* @throws InvalidCallException if the property is write-only
|
||||
* @see __set()
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$getter = 'get' . $name;
|
||||
if (method_exists($this, $getter)) {
|
||||
return $this->$getter();
|
||||
} elseif (method_exists($this, 'set' . $name)) {
|
||||
throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
|
||||
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets value of an object property.
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `$object->property = $value;`.
|
||||
* @param string $name the property name or the event name
|
||||
* @param mixed $value the property value
|
||||
* @throws UnknownPropertyException if the property is not defined
|
||||
* @throws InvalidCallException if the property is read-only
|
||||
* @see __get()
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$setter = 'set' . $name;
|
||||
if (method_exists($this, $setter)) {
|
||||
$this->$setter($value);
|
||||
} elseif (method_exists($this, 'get' . $name)) {
|
||||
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
|
||||
} else {
|
||||
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a property is set, i.e. defined and not null.
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `isset($object->property)`.
|
||||
*
|
||||
* Note that if the property is not defined, false will be returned.
|
||||
* @param string $name the property name or the event name
|
||||
* @return bool whether the named property is set (not null).
|
||||
* @see http://php.net/manual/en/function.isset.php
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
$getter = 'get' . $name;
|
||||
if (method_exists($this, $getter)) {
|
||||
return $this->$getter() !== null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an object property to null.
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `unset($object->property)`.
|
||||
*
|
||||
* Note that if the property is not defined, this method will do nothing.
|
||||
* If the property is read-only, it will throw an exception.
|
||||
* @param string $name the property name
|
||||
* @throws InvalidCallException if the property is read only.
|
||||
* @see http://php.net/manual/en/function.unset.php
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
$setter = 'set' . $name;
|
||||
if (method_exists($this, $setter)) {
|
||||
$this->$setter(null);
|
||||
} elseif (method_exists($this, 'get' . $name)) {
|
||||
throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the named method which is not a class method.
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when an unknown method is being invoked.
|
||||
* @param string $name the method name
|
||||
* @param array $params method parameters
|
||||
* @throws UnknownMethodException when calling unknown method
|
||||
* @return mixed the method return value
|
||||
*/
|
||||
public function __call($name, $params)
|
||||
{
|
||||
throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a property is defined.
|
||||
*
|
||||
* A property is defined if:
|
||||
*
|
||||
* - the class has a getter or setter method associated with the specified name
|
||||
* (in this case, property name is case-insensitive);
|
||||
* - the class has a member variable with the specified name (when `$checkVars` is true);
|
||||
*
|
||||
* @param string $name the property name
|
||||
* @param bool $checkVars whether to treat member variables as properties
|
||||
* @return bool whether the property is defined
|
||||
* @see canGetProperty()
|
||||
* @see canSetProperty()
|
||||
*/
|
||||
public function hasProperty($name, $checkVars = true)
|
||||
{
|
||||
return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a property can be read.
|
||||
*
|
||||
* A property is readable if:
|
||||
*
|
||||
* - the class has a getter method associated with the specified name
|
||||
* (in this case, property name is case-insensitive);
|
||||
* - the class has a member variable with the specified name (when `$checkVars` is true);
|
||||
*
|
||||
* @param string $name the property name
|
||||
* @param bool $checkVars whether to treat member variables as properties
|
||||
* @return bool whether the property can be read
|
||||
* @see canSetProperty()
|
||||
*/
|
||||
public function canGetProperty($name, $checkVars = true)
|
||||
{
|
||||
return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a property can be set.
|
||||
*
|
||||
* A property is writable if:
|
||||
*
|
||||
* - the class has a setter method associated with the specified name
|
||||
* (in this case, property name is case-insensitive);
|
||||
* - the class has a member variable with the specified name (when `$checkVars` is true);
|
||||
*
|
||||
* @param string $name the property name
|
||||
* @param bool $checkVars whether to treat member variables as properties
|
||||
* @return bool whether the property can be written
|
||||
* @see canGetProperty()
|
||||
*/
|
||||
public function canSetProperty($name, $checkVars = true)
|
||||
{
|
||||
return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a method is defined.
|
||||
*
|
||||
* The default implementation is a call to php function `method_exists()`.
|
||||
* You may override this method when you implemented the php magic method `__call()`.
|
||||
* @param string $name the method name
|
||||
* @return bool whether the method is defined
|
||||
*/
|
||||
public function hasMethod($name)
|
||||
{
|
||||
return method_exists($this, $name);
|
||||
}
|
||||
}
|
||||
94
vendor/yiisoft/yii2/base/Behavior.php
vendored
Normal file
94
vendor/yiisoft/yii2/base/Behavior.php
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* Behavior is the base class for all behavior classes.
|
||||
*
|
||||
* A behavior can be used to enhance the functionality of an existing component without modifying its code.
|
||||
* In particular, it can "inject" its own methods and properties into the component
|
||||
* and make them directly accessible via the component. It can also respond to the events triggered in the component
|
||||
* and thus intercept the normal code execution.
|
||||
*
|
||||
* For more details and usage information on Behavior, see the [guide article on behaviors](guide:concept-behaviors).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Behavior extends BaseObject
|
||||
{
|
||||
/**
|
||||
* @var Component|null the owner of this behavior
|
||||
*/
|
||||
public $owner;
|
||||
|
||||
|
||||
/**
|
||||
* Declares event handlers for the [[owner]]'s events.
|
||||
*
|
||||
* Child classes may override this method to declare what PHP callbacks should
|
||||
* be attached to the events of the [[owner]] component.
|
||||
*
|
||||
* The callbacks will be attached to the [[owner]]'s events when the behavior is
|
||||
* attached to the owner; and they will be detached from the events when
|
||||
* the behavior is detached from the component.
|
||||
*
|
||||
* The callbacks can be any of the following:
|
||||
*
|
||||
* - method in this behavior: `'handleClick'`, equivalent to `[$this, 'handleClick']`
|
||||
* - object method: `[$object, 'handleClick']`
|
||||
* - static method: `['Page', 'handleClick']`
|
||||
* - anonymous function: `function ($event) { ... }`
|
||||
*
|
||||
* The following is an example:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
|
||||
* Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* @return array events (array keys) and the corresponding event handler methods (array values).
|
||||
*/
|
||||
public function events()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the behavior object to the component.
|
||||
* The default implementation will set the [[owner]] property
|
||||
* and attach event handlers as declared in [[events]].
|
||||
* Make sure you call the parent implementation if you override this method.
|
||||
* @param Component $owner the component that this behavior is to be attached to.
|
||||
*/
|
||||
public function attach($owner)
|
||||
{
|
||||
$this->owner = $owner;
|
||||
foreach ($this->events() as $event => $handler) {
|
||||
$owner->on($event, is_string($handler) ? [$this, $handler] : $handler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches the behavior object from the component.
|
||||
* The default implementation will unset the [[owner]] property
|
||||
* and detach event handlers declared in [[events]].
|
||||
* Make sure you call the parent implementation if you override this method.
|
||||
*/
|
||||
public function detach()
|
||||
{
|
||||
if ($this->owner) {
|
||||
foreach ($this->events() as $event => $handler) {
|
||||
$this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler);
|
||||
}
|
||||
$this->owner = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
62
vendor/yiisoft/yii2/base/BootstrapInterface.php
vendored
Normal file
62
vendor/yiisoft/yii2/base/BootstrapInterface.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* BootstrapInterface is the interface that should be implemented by classes who want to participate in the application bootstrap process.
|
||||
*
|
||||
* The main method [[bootstrap()]] will be invoked by an application at the beginning of its `init()` method.
|
||||
*
|
||||
* Bootstrapping classes can be registered in two approaches.
|
||||
*
|
||||
* The first approach is mainly used by extensions and is managed by the Composer installation process.
|
||||
* You mainly need to list the bootstrapping class of your extension in the `composer.json` file like following,
|
||||
*
|
||||
* ```json
|
||||
* {
|
||||
* // ...
|
||||
* "extra": {
|
||||
* "bootstrap": "path\\to\\MyBootstrapClass"
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If the extension is installed, the bootstrap information will be saved in [[Application::extensions]].
|
||||
*
|
||||
* The second approach is used by application code which needs to register some code to be run during
|
||||
* the bootstrap process. This is done by configuring the [[Application::bootstrap]] property:
|
||||
*
|
||||
* ```php
|
||||
* return [
|
||||
* // ...
|
||||
* 'bootstrap' => [
|
||||
* "path\\to\\MyBootstrapClass1",
|
||||
* [
|
||||
* 'class' => "path\\to\\MyBootstrapClass2",
|
||||
* 'prop1' => 'value1',
|
||||
* 'prop2' => 'value2',
|
||||
* ],
|
||||
* ],
|
||||
* ];
|
||||
* ```
|
||||
*
|
||||
* As you can see, you can register a bootstrapping class in terms of either a class name or a configuration class.
|
||||
*
|
||||
* For more details and usage information on BootstrapInterface, see the [guide article on bootstrapping applications](guide:structure-applications).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
interface BootstrapInterface
|
||||
{
|
||||
/**
|
||||
* Bootstrap method to be called during application bootstrap stage.
|
||||
* @param Application $app the application currently running
|
||||
*/
|
||||
public function bootstrap($app);
|
||||
}
|
||||
765
vendor/yiisoft/yii2/base/Component.php
vendored
Normal file
765
vendor/yiisoft/yii2/base/Component.php
vendored
Normal file
@@ -0,0 +1,765 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/**
|
||||
* Component is the base class that implements the *property*, *event* and *behavior* features.
|
||||
*
|
||||
* Component provides the *event* and *behavior* features, in addition to the *property* feature which is implemented in
|
||||
* its parent class [[\yii\base\BaseObject|BaseObject]].
|
||||
*
|
||||
* Event is a way to "inject" custom code into existing code at certain places. For example, a comment object can trigger
|
||||
* an "add" event when the user adds a comment. We can write custom code and attach it to this event so that when the event
|
||||
* is triggered (i.e. comment will be added), our custom code will be executed.
|
||||
*
|
||||
* An event is identified by a name that should be unique within the class it is defined at. Event names are *case-sensitive*.
|
||||
*
|
||||
* One or multiple PHP callbacks, called *event handlers*, can be attached to an event. You can call [[trigger()]] to
|
||||
* raise an event. When an event is raised, the event handlers will be invoked automatically in the order they were
|
||||
* attached.
|
||||
*
|
||||
* To attach an event handler to an event, call [[on()]]:
|
||||
*
|
||||
* ```php
|
||||
* $post->on('update', function ($event) {
|
||||
* // send email notification
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* In the above, an anonymous function is attached to the "update" event of the post. You may attach
|
||||
* the following types of event handlers:
|
||||
*
|
||||
* - anonymous function: `function ($event) { ... }`
|
||||
* - object method: `[$object, 'handleAdd']`
|
||||
* - static class method: `['Page', 'handleAdd']`
|
||||
* - global function: `'handleAdd'`
|
||||
*
|
||||
* The signature of an event handler should be like the following:
|
||||
*
|
||||
* ```php
|
||||
* function foo($event)
|
||||
* ```
|
||||
*
|
||||
* where `$event` is an [[Event]] object which includes parameters associated with the event.
|
||||
*
|
||||
* You can also attach a handler to an event when configuring a component with a configuration array.
|
||||
* The syntax is like the following:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* 'on add' => function ($event) { ... }
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* where `on add` stands for attaching an event to the `add` event.
|
||||
*
|
||||
* Sometimes, you may want to associate extra data with an event handler when you attach it to an event
|
||||
* and then access it when the handler is invoked. You may do so by
|
||||
*
|
||||
* ```php
|
||||
* $post->on('update', function ($event) {
|
||||
* // the data can be accessed via $event->data
|
||||
* }, $data);
|
||||
* ```
|
||||
*
|
||||
* A behavior is an instance of [[Behavior]] or its child class. A component can be attached with one or multiple
|
||||
* behaviors. When a behavior is attached to a component, its public properties and methods can be accessed via the
|
||||
* component directly, as if the component owns those properties and methods.
|
||||
*
|
||||
* To attach a behavior to a component, declare it in [[behaviors()]], or explicitly call [[attachBehavior]]. Behaviors
|
||||
* declared in [[behaviors()]] are automatically attached to the corresponding component.
|
||||
*
|
||||
* One can also attach a behavior to a component when configuring it with a configuration array. The syntax is like the
|
||||
* following:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* 'as tree' => [
|
||||
* 'class' => 'Tree',
|
||||
* ],
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* where `as tree` stands for attaching a behavior named `tree`, and the array will be passed to [[\Yii::createObject()]]
|
||||
* to create the behavior object.
|
||||
*
|
||||
* For more details and usage information on Component, see the [guide article on components](guide:concept-components).
|
||||
*
|
||||
* @property Behavior[] $behaviors List of behaviors attached to this component. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Component extends BaseObject
|
||||
{
|
||||
/**
|
||||
* @var array the attached event handlers (event name => handlers)
|
||||
*/
|
||||
private $_events = [];
|
||||
/**
|
||||
* @var array the event handlers attached for wildcard patterns (event name wildcard => handlers)
|
||||
* @since 2.0.14
|
||||
*/
|
||||
private $_eventWildcards = [];
|
||||
/**
|
||||
* @var Behavior[]|null the attached behaviors (behavior name => behavior). This is `null` when not initialized.
|
||||
*/
|
||||
private $_behaviors;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of a component property.
|
||||
*
|
||||
* This method will check in the following order and act accordingly:
|
||||
*
|
||||
* - a property defined by a getter: return the getter result
|
||||
* - a property of a behavior: return the behavior property value
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `$value = $component->property;`.
|
||||
* @param string $name the property name
|
||||
* @return mixed the property value or the value of a behavior's property
|
||||
* @throws UnknownPropertyException if the property is not defined
|
||||
* @throws InvalidCallException if the property is write-only.
|
||||
* @see __set()
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
$getter = 'get' . $name;
|
||||
if (method_exists($this, $getter)) {
|
||||
// read property, e.g. getName()
|
||||
return $this->$getter();
|
||||
}
|
||||
|
||||
// behavior property
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $behavior) {
|
||||
if ($behavior->canGetProperty($name)) {
|
||||
return $behavior->$name;
|
||||
}
|
||||
}
|
||||
|
||||
if (method_exists($this, 'set' . $name)) {
|
||||
throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
|
||||
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a component property.
|
||||
*
|
||||
* This method will check in the following order and act accordingly:
|
||||
*
|
||||
* - a property defined by a setter: set the property value
|
||||
* - an event in the format of "on xyz": attach the handler to the event "xyz"
|
||||
* - a behavior in the format of "as xyz": attach the behavior named as "xyz"
|
||||
* - a property of a behavior: set the behavior property value
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `$component->property = $value;`.
|
||||
* @param string $name the property name or the event name
|
||||
* @param mixed $value the property value
|
||||
* @throws UnknownPropertyException if the property is not defined
|
||||
* @throws InvalidCallException if the property is read-only.
|
||||
* @see __get()
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
$setter = 'set' . $name;
|
||||
if (method_exists($this, $setter)) {
|
||||
// set property
|
||||
$this->$setter($value);
|
||||
|
||||
return;
|
||||
} elseif (strncmp($name, 'on ', 3) === 0) {
|
||||
// on event: attach event handler
|
||||
$this->on(trim(substr($name, 3)), $value);
|
||||
|
||||
return;
|
||||
} elseif (strncmp($name, 'as ', 3) === 0) {
|
||||
// as behavior: attach behavior
|
||||
$name = trim(substr($name, 3));
|
||||
$this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// behavior property
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $behavior) {
|
||||
if ($behavior->canSetProperty($name)) {
|
||||
$behavior->$name = $value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (method_exists($this, 'get' . $name)) {
|
||||
throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
|
||||
throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a property is set, i.e. defined and not null.
|
||||
*
|
||||
* This method will check in the following order and act accordingly:
|
||||
*
|
||||
* - a property defined by a setter: return whether the property is set
|
||||
* - a property of a behavior: return whether the property is set
|
||||
* - return `false` for non existing properties
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `isset($component->property)`.
|
||||
* @param string $name the property name or the event name
|
||||
* @return bool whether the named property is set
|
||||
* @see http://php.net/manual/en/function.isset.php
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
$getter = 'get' . $name;
|
||||
if (method_exists($this, $getter)) {
|
||||
return $this->$getter() !== null;
|
||||
}
|
||||
|
||||
// behavior property
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $behavior) {
|
||||
if ($behavior->canGetProperty($name)) {
|
||||
return $behavior->$name !== null;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a component property to be null.
|
||||
*
|
||||
* This method will check in the following order and act accordingly:
|
||||
*
|
||||
* - a property defined by a setter: set the property value to be null
|
||||
* - a property of a behavior: set the property value to be null
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when executing `unset($component->property)`.
|
||||
* @param string $name the property name
|
||||
* @throws InvalidCallException if the property is read only.
|
||||
* @see http://php.net/manual/en/function.unset.php
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
$setter = 'set' . $name;
|
||||
if (method_exists($this, $setter)) {
|
||||
$this->$setter(null);
|
||||
return;
|
||||
}
|
||||
|
||||
// behavior property
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $behavior) {
|
||||
if ($behavior->canSetProperty($name)) {
|
||||
$behavior->$name = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidCallException('Unsetting an unknown or read-only property: ' . get_class($this) . '::' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the named method which is not a class method.
|
||||
*
|
||||
* This method will check if any attached behavior has
|
||||
* the named method and will execute it if available.
|
||||
*
|
||||
* Do not call this method directly as it is a PHP magic method that
|
||||
* will be implicitly called when an unknown method is being invoked.
|
||||
* @param string $name the method name
|
||||
* @param array $params method parameters
|
||||
* @return mixed the method return value
|
||||
* @throws UnknownMethodException when calling unknown method
|
||||
*/
|
||||
public function __call($name, $params)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $object) {
|
||||
if ($object->hasMethod($name)) {
|
||||
return call_user_func_array([$object, $name], $params);
|
||||
}
|
||||
}
|
||||
throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after the object is created by cloning an existing one.
|
||||
* It removes all behaviors because they are attached to the old object.
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->_events = [];
|
||||
$this->_eventWildcards = [];
|
||||
$this->_behaviors = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a property is defined for this component.
|
||||
*
|
||||
* A property is defined if:
|
||||
*
|
||||
* - the class has a getter or setter method associated with the specified name
|
||||
* (in this case, property name is case-insensitive);
|
||||
* - the class has a member variable with the specified name (when `$checkVars` is true);
|
||||
* - an attached behavior has a property of the given name (when `$checkBehaviors` is true).
|
||||
*
|
||||
* @param string $name the property name
|
||||
* @param bool $checkVars whether to treat member variables as properties
|
||||
* @param bool $checkBehaviors whether to treat behaviors' properties as properties of this component
|
||||
* @return bool whether the property is defined
|
||||
* @see canGetProperty()
|
||||
* @see canSetProperty()
|
||||
*/
|
||||
public function hasProperty($name, $checkVars = true, $checkBehaviors = true)
|
||||
{
|
||||
return $this->canGetProperty($name, $checkVars, $checkBehaviors) || $this->canSetProperty($name, false, $checkBehaviors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a property can be read.
|
||||
*
|
||||
* A property can be read if:
|
||||
*
|
||||
* - the class has a getter method associated with the specified name
|
||||
* (in this case, property name is case-insensitive);
|
||||
* - the class has a member variable with the specified name (when `$checkVars` is true);
|
||||
* - an attached behavior has a readable property of the given name (when `$checkBehaviors` is true).
|
||||
*
|
||||
* @param string $name the property name
|
||||
* @param bool $checkVars whether to treat member variables as properties
|
||||
* @param bool $checkBehaviors whether to treat behaviors' properties as properties of this component
|
||||
* @return bool whether the property can be read
|
||||
* @see canSetProperty()
|
||||
*/
|
||||
public function canGetProperty($name, $checkVars = true, $checkBehaviors = true)
|
||||
{
|
||||
if (method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name)) {
|
||||
return true;
|
||||
} elseif ($checkBehaviors) {
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $behavior) {
|
||||
if ($behavior->canGetProperty($name, $checkVars)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a property can be set.
|
||||
*
|
||||
* A property can be written if:
|
||||
*
|
||||
* - the class has a setter method associated with the specified name
|
||||
* (in this case, property name is case-insensitive);
|
||||
* - the class has a member variable with the specified name (when `$checkVars` is true);
|
||||
* - an attached behavior has a writable property of the given name (when `$checkBehaviors` is true).
|
||||
*
|
||||
* @param string $name the property name
|
||||
* @param bool $checkVars whether to treat member variables as properties
|
||||
* @param bool $checkBehaviors whether to treat behaviors' properties as properties of this component
|
||||
* @return bool whether the property can be written
|
||||
* @see canGetProperty()
|
||||
*/
|
||||
public function canSetProperty($name, $checkVars = true, $checkBehaviors = true)
|
||||
{
|
||||
if (method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name)) {
|
||||
return true;
|
||||
} elseif ($checkBehaviors) {
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $behavior) {
|
||||
if ($behavior->canSetProperty($name, $checkVars)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether a method is defined.
|
||||
*
|
||||
* A method is defined if:
|
||||
*
|
||||
* - the class has a method with the specified name
|
||||
* - an attached behavior has a method with the given name (when `$checkBehaviors` is true).
|
||||
*
|
||||
* @param string $name the property name
|
||||
* @param bool $checkBehaviors whether to treat behaviors' methods as methods of this component
|
||||
* @return bool whether the method is defined
|
||||
*/
|
||||
public function hasMethod($name, $checkBehaviors = true)
|
||||
{
|
||||
if (method_exists($this, $name)) {
|
||||
return true;
|
||||
} elseif ($checkBehaviors) {
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $behavior) {
|
||||
if ($behavior->hasMethod($name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of behaviors that this component should behave as.
|
||||
*
|
||||
* Child classes may override this method to specify the behaviors they want to behave as.
|
||||
*
|
||||
* The return value of this method should be an array of behavior objects or configurations
|
||||
* indexed by behavior names. A behavior configuration can be either a string specifying
|
||||
* the behavior class or an array of the following structure:
|
||||
*
|
||||
* ```php
|
||||
* 'behaviorName' => [
|
||||
* 'class' => 'BehaviorClass',
|
||||
* 'property1' => 'value1',
|
||||
* 'property2' => 'value2',
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* Note that a behavior class must extend from [[Behavior]]. Behaviors can be attached using a name or anonymously.
|
||||
* When a name is used as the array key, using this name, the behavior can later be retrieved using [[getBehavior()]]
|
||||
* or be detached using [[detachBehavior()]]. Anonymous behaviors can not be retrieved or detached.
|
||||
*
|
||||
* Behaviors declared in this method will be attached to the component automatically (on demand).
|
||||
*
|
||||
* @return array the behavior configurations.
|
||||
*/
|
||||
public function behaviors()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether there is any handler attached to the named event.
|
||||
* @param string $name the event name
|
||||
* @return bool whether there is any handler attached to the event.
|
||||
*/
|
||||
public function hasEventHandlers($name)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
|
||||
foreach ($this->_eventWildcards as $wildcard => $handlers) {
|
||||
if (!empty($handlers) && StringHelper::matchWildcard($wildcard, $name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return !empty($this->_events[$name]) || Event::hasHandlers($this, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches an event handler to an event.
|
||||
*
|
||||
* The event handler must be a valid PHP callback. The following are
|
||||
* some examples:
|
||||
*
|
||||
* ```
|
||||
* function ($event) { ... } // anonymous function
|
||||
* [$object, 'handleClick'] // $object->handleClick()
|
||||
* ['Page', 'handleClick'] // Page::handleClick()
|
||||
* 'handleClick' // global function handleClick()
|
||||
* ```
|
||||
*
|
||||
* The event handler must be defined with the following signature,
|
||||
*
|
||||
* ```
|
||||
* function ($event)
|
||||
* ```
|
||||
*
|
||||
* where `$event` is an [[Event]] object which includes parameters associated with the event.
|
||||
*
|
||||
* Since 2.0.14 you can specify event name as a wildcard pattern:
|
||||
*
|
||||
* ```php
|
||||
* $component->on('event.group.*', function ($event) {
|
||||
* Yii::trace($event->name . ' is triggered.');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @param string $name the event name
|
||||
* @param callable $handler the event handler
|
||||
* @param mixed $data the data to be passed to the event handler when the event is triggered.
|
||||
* When the event handler is invoked, this data can be accessed via [[Event::data]].
|
||||
* @param bool $append whether to append new event handler to the end of the existing
|
||||
* handler list. If false, the new handler will be inserted at the beginning of the existing
|
||||
* handler list.
|
||||
* @see off()
|
||||
*/
|
||||
public function on($name, $handler, $data = null, $append = true)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
|
||||
if (strpos($name, '*') !== false) {
|
||||
if ($append || empty($this->_eventWildcards[$name])) {
|
||||
$this->_eventWildcards[$name][] = [$handler, $data];
|
||||
} else {
|
||||
array_unshift($this->_eventWildcards[$name], [$handler, $data]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($append || empty($this->_events[$name])) {
|
||||
$this->_events[$name][] = [$handler, $data];
|
||||
} else {
|
||||
array_unshift($this->_events[$name], [$handler, $data]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches an existing event handler from this component.
|
||||
*
|
||||
* This method is the opposite of [[on()]].
|
||||
*
|
||||
* Note: in case wildcard pattern is passed for event name, only the handlers registered with this
|
||||
* wildcard will be removed, while handlers registered with plain names matching this wildcard will remain.
|
||||
*
|
||||
* @param string $name event name
|
||||
* @param callable $handler the event handler to be removed.
|
||||
* If it is null, all handlers attached to the named event will be removed.
|
||||
* @return bool if a handler is found and detached
|
||||
* @see on()
|
||||
*/
|
||||
public function off($name, $handler = null)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
if (empty($this->_events[$name]) && empty($this->_eventWildcards[$name])) {
|
||||
return false;
|
||||
}
|
||||
if ($handler === null) {
|
||||
unset($this->_events[$name], $this->_eventWildcards[$name]);
|
||||
return true;
|
||||
}
|
||||
|
||||
$removed = false;
|
||||
// plain event names
|
||||
if (isset($this->_events[$name])) {
|
||||
foreach ($this->_events[$name] as $i => $event) {
|
||||
if ($event[0] === $handler) {
|
||||
unset($this->_events[$name][$i]);
|
||||
$removed = true;
|
||||
}
|
||||
}
|
||||
if ($removed) {
|
||||
$this->_events[$name] = array_values($this->_events[$name]);
|
||||
return $removed;
|
||||
}
|
||||
}
|
||||
|
||||
// wildcard event names
|
||||
if (isset($this->_eventWildcards[$name])) {
|
||||
foreach ($this->_eventWildcards[$name] as $i => $event) {
|
||||
if ($event[0] === $handler) {
|
||||
unset($this->_eventWildcards[$name][$i]);
|
||||
$removed = true;
|
||||
}
|
||||
}
|
||||
if ($removed) {
|
||||
$this->_eventWildcards[$name] = array_values($this->_eventWildcards[$name]);
|
||||
// remove empty wildcards to save future redundant regex checks:
|
||||
if (empty($this->_eventWildcards[$name])) {
|
||||
unset($this->_eventWildcards[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers an event.
|
||||
* This method represents the happening of an event. It invokes
|
||||
* all attached handlers for the event including class-level handlers.
|
||||
* @param string $name the event name
|
||||
* @param Event $event the event parameter. If not set, a default [[Event]] object will be created.
|
||||
*/
|
||||
public function trigger($name, Event $event = null)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
|
||||
$eventHandlers = [];
|
||||
foreach ($this->_eventWildcards as $wildcard => $handlers) {
|
||||
if (StringHelper::matchWildcard($wildcard, $name)) {
|
||||
$eventHandlers = array_merge($eventHandlers, $handlers);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->_events[$name])) {
|
||||
$eventHandlers = array_merge($eventHandlers, $this->_events[$name]);
|
||||
}
|
||||
|
||||
if (!empty($eventHandlers)) {
|
||||
if ($event === null) {
|
||||
$event = new Event();
|
||||
}
|
||||
if ($event->sender === null) {
|
||||
$event->sender = $this;
|
||||
}
|
||||
$event->handled = false;
|
||||
$event->name = $name;
|
||||
foreach ($eventHandlers as $handler) {
|
||||
$event->data = $handler[1];
|
||||
call_user_func($handler[0], $event);
|
||||
// stop further handling if the event is handled
|
||||
if ($event->handled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// invoke class-level attached handlers
|
||||
Event::trigger($this, $name, $event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the named behavior object.
|
||||
* @param string $name the behavior name
|
||||
* @return null|Behavior the behavior object, or null if the behavior does not exist
|
||||
*/
|
||||
public function getBehavior($name)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
return isset($this->_behaviors[$name]) ? $this->_behaviors[$name] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all behaviors attached to this component.
|
||||
* @return Behavior[] list of behaviors attached to this component
|
||||
*/
|
||||
public function getBehaviors()
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
return $this->_behaviors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a behavior to this component.
|
||||
* This method will create the behavior object based on the given
|
||||
* configuration. After that, the behavior object will be attached to
|
||||
* this component by calling the [[Behavior::attach()]] method.
|
||||
* @param string $name the name of the behavior.
|
||||
* @param string|array|Behavior $behavior the behavior configuration. This can be one of the following:
|
||||
*
|
||||
* - a [[Behavior]] object
|
||||
* - a string specifying the behavior class
|
||||
* - an object configuration array that will be passed to [[Yii::createObject()]] to create the behavior object.
|
||||
*
|
||||
* @return Behavior the behavior object
|
||||
* @see detachBehavior()
|
||||
*/
|
||||
public function attachBehavior($name, $behavior)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
return $this->attachBehaviorInternal($name, $behavior);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a list of behaviors to the component.
|
||||
* Each behavior is indexed by its name and should be a [[Behavior]] object,
|
||||
* a string specifying the behavior class, or an configuration array for creating the behavior.
|
||||
* @param array $behaviors list of behaviors to be attached to the component
|
||||
* @see attachBehavior()
|
||||
*/
|
||||
public function attachBehaviors($behaviors)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
foreach ($behaviors as $name => $behavior) {
|
||||
$this->attachBehaviorInternal($name, $behavior);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches a behavior from the component.
|
||||
* The behavior's [[Behavior::detach()]] method will be invoked.
|
||||
* @param string $name the behavior's name.
|
||||
* @return null|Behavior the detached behavior. Null if the behavior does not exist.
|
||||
*/
|
||||
public function detachBehavior($name)
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
if (isset($this->_behaviors[$name])) {
|
||||
$behavior = $this->_behaviors[$name];
|
||||
unset($this->_behaviors[$name]);
|
||||
$behavior->detach();
|
||||
return $behavior;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches all behaviors from the component.
|
||||
*/
|
||||
public function detachBehaviors()
|
||||
{
|
||||
$this->ensureBehaviors();
|
||||
foreach ($this->_behaviors as $name => $behavior) {
|
||||
$this->detachBehavior($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure that the behaviors declared in [[behaviors()]] are attached to this component.
|
||||
*/
|
||||
public function ensureBehaviors()
|
||||
{
|
||||
if ($this->_behaviors === null) {
|
||||
$this->_behaviors = [];
|
||||
foreach ($this->behaviors() as $name => $behavior) {
|
||||
$this->attachBehaviorInternal($name, $behavior);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a behavior to this component.
|
||||
* @param string|int $name the name of the behavior. If this is an integer, it means the behavior
|
||||
* is an anonymous one. Otherwise, the behavior is a named one and any existing behavior with the same name
|
||||
* will be detached first.
|
||||
* @param string|array|Behavior $behavior the behavior to be attached
|
||||
* @return Behavior the attached behavior.
|
||||
*/
|
||||
private function attachBehaviorInternal($name, $behavior)
|
||||
{
|
||||
if (!($behavior instanceof Behavior)) {
|
||||
$behavior = Yii::createObject($behavior);
|
||||
}
|
||||
if (is_int($name)) {
|
||||
$behavior->attach($this);
|
||||
$this->_behaviors[] = $behavior;
|
||||
} else {
|
||||
if (isset($this->_behaviors[$name])) {
|
||||
$this->_behaviors[$name]->detach();
|
||||
}
|
||||
$behavior->attach($this);
|
||||
$this->_behaviors[$name] = $behavior;
|
||||
}
|
||||
|
||||
return $behavior;
|
||||
}
|
||||
}
|
||||
33
vendor/yiisoft/yii2/base/Configurable.php
vendored
Normal file
33
vendor/yiisoft/yii2/base/Configurable.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* Configurable is the interface that should be implemented by classes who support configuring
|
||||
* its properties through the last parameter to its constructor.
|
||||
*
|
||||
* The interface does not declare any method. Classes implementing this interface must declare their constructors
|
||||
* like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function __constructor($param1, $param2, ..., $config = [])
|
||||
* ```
|
||||
*
|
||||
* That is, the last parameter of the constructor must accept a configuration array.
|
||||
*
|
||||
* This interface is mainly used by [[\yii\di\Container]] so that it can pass object configuration as the
|
||||
* last parameter to the implementing class' constructor.
|
||||
*
|
||||
* For more details and usage information on Configurable, see the [guide article on configurations](guide:concept-configurations).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0.3
|
||||
*/
|
||||
interface Configurable
|
||||
{
|
||||
}
|
||||
524
vendor/yiisoft/yii2/base/Controller.php
vendored
Normal file
524
vendor/yiisoft/yii2/base/Controller.php
vendored
Normal file
@@ -0,0 +1,524 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Controller is the base class for classes containing controller logic.
|
||||
*
|
||||
* For more details and usage information on Controller, see the [guide article on controllers](guide:structure-controllers).
|
||||
*
|
||||
* @property Module[] $modules All ancestor modules that this controller is located within. This property is
|
||||
* read-only.
|
||||
* @property string $route The route (module ID, controller ID and action ID) of the current request. This
|
||||
* property is read-only.
|
||||
* @property string $uniqueId The controller ID that is prefixed with the module ID (if any). This property is
|
||||
* read-only.
|
||||
* @property View|\yii\web\View $view The view object that can be used to render views or view files.
|
||||
* @property string $viewPath The directory containing the view files for this controller.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Controller extends Component implements ViewContextInterface
|
||||
{
|
||||
/**
|
||||
* @event ActionEvent an event raised right before executing a controller action.
|
||||
* You may set [[ActionEvent::isValid]] to be false to cancel the action execution.
|
||||
*/
|
||||
const EVENT_BEFORE_ACTION = 'beforeAction';
|
||||
/**
|
||||
* @event ActionEvent an event raised right after executing a controller action.
|
||||
*/
|
||||
const EVENT_AFTER_ACTION = 'afterAction';
|
||||
|
||||
/**
|
||||
* @var string the ID of this controller.
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @var Module the module that this controller belongs to.
|
||||
*/
|
||||
public $module;
|
||||
/**
|
||||
* @var string the ID of the action that is used when the action ID is not specified
|
||||
* in the request. Defaults to 'index'.
|
||||
*/
|
||||
public $defaultAction = 'index';
|
||||
/**
|
||||
* @var null|string|false the name of the layout to be applied to this controller's views.
|
||||
* This property mainly affects the behavior of [[render()]].
|
||||
* Defaults to null, meaning the actual layout value should inherit that from [[module]]'s layout value.
|
||||
* If false, no layout will be applied.
|
||||
*/
|
||||
public $layout;
|
||||
/**
|
||||
* @var Action the action that is currently being executed. This property will be set
|
||||
* by [[run()]] when it is called by [[Application]] to run an action.
|
||||
*/
|
||||
public $action;
|
||||
|
||||
/**
|
||||
* @var View the view object that can be used to render views or view files.
|
||||
*/
|
||||
private $_view;
|
||||
/**
|
||||
* @var string the root directory that contains view files for this controller.
|
||||
*/
|
||||
private $_viewPath;
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id the ID of this controller.
|
||||
* @param Module $module the module that this controller belongs to.
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties.
|
||||
*/
|
||||
public function __construct($id, $module, $config = [])
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->module = $module;
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declares external actions for the controller.
|
||||
*
|
||||
* This method is meant to be overwritten to declare external actions for the controller.
|
||||
* It should return an array, with array keys being action IDs, and array values the corresponding
|
||||
* action class names or action configuration arrays. For example,
|
||||
*
|
||||
* ```php
|
||||
* return [
|
||||
* 'action1' => 'app\components\Action1',
|
||||
* 'action2' => [
|
||||
* 'class' => 'app\components\Action2',
|
||||
* 'property1' => 'value1',
|
||||
* 'property2' => 'value2',
|
||||
* ],
|
||||
* ];
|
||||
* ```
|
||||
*
|
||||
* [[\Yii::createObject()]] will be used later to create the requested action
|
||||
* using the configuration provided here.
|
||||
*/
|
||||
public function actions()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs an action within this controller with the specified action ID and parameters.
|
||||
* If the action ID is empty, the method will use [[defaultAction]].
|
||||
* @param string $id the ID of the action to be executed.
|
||||
* @param array $params the parameters (name-value pairs) to be passed to the action.
|
||||
* @return mixed the result of the action.
|
||||
* @throws InvalidRouteException if the requested action ID cannot be resolved into an action successfully.
|
||||
* @see createAction()
|
||||
*/
|
||||
public function runAction($id, $params = [])
|
||||
{
|
||||
$action = $this->createAction($id);
|
||||
if ($action === null) {
|
||||
throw new InvalidRouteException('Unable to resolve the request: ' . $this->getUniqueId() . '/' . $id);
|
||||
}
|
||||
|
||||
Yii::debug('Route to run: ' . $action->getUniqueId(), __METHOD__);
|
||||
|
||||
if (Yii::$app->requestedAction === null) {
|
||||
Yii::$app->requestedAction = $action;
|
||||
}
|
||||
|
||||
$oldAction = $this->action;
|
||||
$this->action = $action;
|
||||
|
||||
$modules = [];
|
||||
$runAction = true;
|
||||
|
||||
// call beforeAction on modules
|
||||
foreach ($this->getModules() as $module) {
|
||||
if ($module->beforeAction($action)) {
|
||||
array_unshift($modules, $module);
|
||||
} else {
|
||||
$runAction = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$result = null;
|
||||
|
||||
if ($runAction && $this->beforeAction($action)) {
|
||||
// run the action
|
||||
$result = $action->runWithParams($params);
|
||||
|
||||
$result = $this->afterAction($action, $result);
|
||||
|
||||
// call afterAction on modules
|
||||
foreach ($modules as $module) {
|
||||
/* @var $module Module */
|
||||
$result = $module->afterAction($action, $result);
|
||||
}
|
||||
}
|
||||
|
||||
if ($oldAction !== null) {
|
||||
$this->action = $oldAction;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a request specified in terms of a route.
|
||||
* The route can be either an ID of an action within this controller or a complete route consisting
|
||||
* of module IDs, controller ID and action ID. If the route starts with a slash '/', the parsing of
|
||||
* the route will start from the application; otherwise, it will start from the parent module of this controller.
|
||||
* @param string $route the route to be handled, e.g., 'view', 'comment/view', '/admin/comment/view'.
|
||||
* @param array $params the parameters to be passed to the action.
|
||||
* @return mixed the result of the action.
|
||||
* @see runAction()
|
||||
*/
|
||||
public function run($route, $params = [])
|
||||
{
|
||||
$pos = strpos($route, '/');
|
||||
if ($pos === false) {
|
||||
return $this->runAction($route, $params);
|
||||
} elseif ($pos > 0) {
|
||||
return $this->module->runAction($route, $params);
|
||||
}
|
||||
|
||||
return Yii::$app->runAction(ltrim($route, '/'), $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the parameters to the action.
|
||||
* This method is invoked by [[Action]] when it begins to run with the given parameters.
|
||||
* @param Action $action the action to be bound with parameters.
|
||||
* @param array $params the parameters to be bound to the action.
|
||||
* @return array the valid parameters that the action can run with.
|
||||
*/
|
||||
public function bindActionParams($action, $params)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an action based on the given action ID.
|
||||
* The method first checks if the action ID has been declared in [[actions()]]. If so,
|
||||
* it will use the configuration declared there to create the action object.
|
||||
* If not, it will look for a controller method whose name is in the format of `actionXyz`
|
||||
* where `Xyz` stands for the action ID. If found, an [[InlineAction]] representing that
|
||||
* method will be created and returned.
|
||||
* @param string $id the action ID.
|
||||
* @return Action|null the newly created action instance. Null if the ID doesn't resolve into any action.
|
||||
*/
|
||||
public function createAction($id)
|
||||
{
|
||||
if ($id === '') {
|
||||
$id = $this->defaultAction;
|
||||
}
|
||||
|
||||
$actionMap = $this->actions();
|
||||
if (isset($actionMap[$id])) {
|
||||
return Yii::createObject($actionMap[$id], [$id, $this]);
|
||||
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
|
||||
$methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id))));
|
||||
if (method_exists($this, $methodName)) {
|
||||
$method = new \ReflectionMethod($this, $methodName);
|
||||
if ($method->isPublic() && $method->getName() === $methodName) {
|
||||
return new InlineAction($id, $this, $methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right before an action is executed.
|
||||
*
|
||||
* The method will trigger the [[EVENT_BEFORE_ACTION]] event. The return value of the method
|
||||
* will determine whether the action should continue to run.
|
||||
*
|
||||
* In case the action should not run, the request should be handled inside of the `beforeAction` code
|
||||
* by either providing the necessary output or redirecting the request. Otherwise the response will be empty.
|
||||
*
|
||||
* If you override this method, your code should look like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function beforeAction($action)
|
||||
* {
|
||||
* // your custom code here, if you want the code to run before action filters,
|
||||
* // which are triggered on the [[EVENT_BEFORE_ACTION]] event, e.g. PageCache or AccessControl
|
||||
*
|
||||
* if (!parent::beforeAction($action)) {
|
||||
* return false;
|
||||
* }
|
||||
*
|
||||
* // other custom code here
|
||||
*
|
||||
* return true; // or false to not run the action
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param Action $action the action to be executed.
|
||||
* @return bool whether the action should continue to run.
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
$event = new ActionEvent($action);
|
||||
$this->trigger(self::EVENT_BEFORE_ACTION, $event);
|
||||
return $event->isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right after an action is executed.
|
||||
*
|
||||
* The method will trigger the [[EVENT_AFTER_ACTION]] event. The return value of the method
|
||||
* will be used as the action return value.
|
||||
*
|
||||
* If you override this method, your code should look like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function afterAction($action, $result)
|
||||
* {
|
||||
* $result = parent::afterAction($action, $result);
|
||||
* // your custom code here
|
||||
* return $result;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param Action $action the action just executed.
|
||||
* @param mixed $result the action return result.
|
||||
* @return mixed the processed action result.
|
||||
*/
|
||||
public function afterAction($action, $result)
|
||||
{
|
||||
$event = new ActionEvent($action);
|
||||
$event->result = $result;
|
||||
$this->trigger(self::EVENT_AFTER_ACTION, $event);
|
||||
return $event->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all ancestor modules of this controller.
|
||||
* The first module in the array is the outermost one (i.e., the application instance),
|
||||
* while the last is the innermost one.
|
||||
* @return Module[] all ancestor modules that this controller is located within.
|
||||
*/
|
||||
public function getModules()
|
||||
{
|
||||
$modules = [$this->module];
|
||||
$module = $this->module;
|
||||
while ($module->module !== null) {
|
||||
array_unshift($modules, $module->module);
|
||||
$module = $module->module;
|
||||
}
|
||||
|
||||
return $modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the controller.
|
||||
* @return string the controller ID that is prefixed with the module ID (if any).
|
||||
*/
|
||||
public function getUniqueId()
|
||||
{
|
||||
return $this->module instanceof Application ? $this->id : $this->module->getUniqueId() . '/' . $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the route of the current request.
|
||||
* @return string the route (module ID, controller ID and action ID) of the current request.
|
||||
*/
|
||||
public function getRoute()
|
||||
{
|
||||
return $this->action !== null ? $this->action->getUniqueId() : $this->getUniqueId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view and applies layout if available.
|
||||
*
|
||||
* The view to be rendered can be specified in one of the following formats:
|
||||
*
|
||||
* - [path alias](guide:concept-aliases) (e.g. "@app/views/site/index");
|
||||
* - absolute path within application (e.g. "//site/index"): the view name starts with double slashes.
|
||||
* The actual view file will be looked for under the [[Application::viewPath|view path]] of the application.
|
||||
* - absolute path within module (e.g. "/site/index"): the view name starts with a single slash.
|
||||
* The actual view file will be looked for under the [[Module::viewPath|view path]] of [[module]].
|
||||
* - relative path (e.g. "index"): the actual view file will be looked for under [[viewPath]].
|
||||
*
|
||||
* To determine which layout should be applied, the following two steps are conducted:
|
||||
*
|
||||
* 1. In the first step, it determines the layout name and the context module:
|
||||
*
|
||||
* - If [[layout]] is specified as a string, use it as the layout name and [[module]] as the context module;
|
||||
* - If [[layout]] is null, search through all ancestor modules of this controller and find the first
|
||||
* module whose [[Module::layout|layout]] is not null. The layout and the corresponding module
|
||||
* are used as the layout name and the context module, respectively. If such a module is not found
|
||||
* or the corresponding layout is not a string, it will return false, meaning no applicable layout.
|
||||
*
|
||||
* 2. In the second step, it determines the actual layout file according to the previously found layout name
|
||||
* and context module. The layout name can be:
|
||||
*
|
||||
* - a [path alias](guide:concept-aliases) (e.g. "@app/views/layouts/main");
|
||||
* - an absolute path (e.g. "/main"): the layout name starts with a slash. The actual layout file will be
|
||||
* looked for under the [[Application::layoutPath|layout path]] of the application;
|
||||
* - a relative path (e.g. "main"): the actual layout file will be looked for under the
|
||||
* [[Module::layoutPath|layout path]] of the context module.
|
||||
*
|
||||
* If the layout name does not contain a file extension, it will use the default one `.php`.
|
||||
*
|
||||
* @param string $view the view name.
|
||||
* @param array $params the parameters (name-value pairs) that should be made available in the view.
|
||||
* These parameters will not be available in the layout.
|
||||
* @return string the rendering result.
|
||||
* @throws InvalidArgumentException if the view file or the layout file does not exist.
|
||||
*/
|
||||
public function render($view, $params = [])
|
||||
{
|
||||
$content = $this->getView()->render($view, $params, $this);
|
||||
return $this->renderContent($content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a static string by applying a layout.
|
||||
* @param string $content the static string being rendered
|
||||
* @return string the rendering result of the layout with the given static string as the `$content` variable.
|
||||
* If the layout is disabled, the string will be returned back.
|
||||
* @since 2.0.1
|
||||
*/
|
||||
public function renderContent($content)
|
||||
{
|
||||
$layoutFile = $this->findLayoutFile($this->getView());
|
||||
if ($layoutFile !== false) {
|
||||
return $this->getView()->renderFile($layoutFile, ['content' => $content], $this);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view without applying layout.
|
||||
* This method differs from [[render()]] in that it does not apply any layout.
|
||||
* @param string $view the view name. Please refer to [[render()]] on how to specify a view name.
|
||||
* @param array $params the parameters (name-value pairs) that should be made available in the view.
|
||||
* @return string the rendering result.
|
||||
* @throws InvalidArgumentException if the view file does not exist.
|
||||
*/
|
||||
public function renderPartial($view, $params = [])
|
||||
{
|
||||
return $this->getView()->render($view, $params, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view file.
|
||||
* @param string $file the view file to be rendered. This can be either a file path or a [path alias](guide:concept-aliases).
|
||||
* @param array $params the parameters (name-value pairs) that should be made available in the view.
|
||||
* @return string the rendering result.
|
||||
* @throws InvalidArgumentException if the view file does not exist.
|
||||
*/
|
||||
public function renderFile($file, $params = [])
|
||||
{
|
||||
return $this->getView()->renderFile($file, $params, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view object that can be used to render views or view files.
|
||||
* The [[render()]], [[renderPartial()]] and [[renderFile()]] methods will use
|
||||
* this view object to implement the actual view rendering.
|
||||
* If not set, it will default to the "view" application component.
|
||||
* @return View|\yii\web\View the view object that can be used to render views or view files.
|
||||
*/
|
||||
public function getView()
|
||||
{
|
||||
if ($this->_view === null) {
|
||||
$this->_view = Yii::$app->getView();
|
||||
}
|
||||
|
||||
return $this->_view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the view object to be used by this controller.
|
||||
* @param View|\yii\web\View $view the view object that can be used to render views or view files.
|
||||
*/
|
||||
public function setView($view)
|
||||
{
|
||||
$this->_view = $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory containing view files for this controller.
|
||||
* The default implementation returns the directory named as controller [[id]] under the [[module]]'s
|
||||
* [[viewPath]] directory.
|
||||
* @return string the directory containing the view files for this controller.
|
||||
*/
|
||||
public function getViewPath()
|
||||
{
|
||||
if ($this->_viewPath === null) {
|
||||
$this->_viewPath = $this->module->getViewPath() . DIRECTORY_SEPARATOR . $this->id;
|
||||
}
|
||||
|
||||
return $this->_viewPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory that contains the view files.
|
||||
* @param string $path the root directory of view files.
|
||||
* @throws InvalidArgumentException if the directory is invalid
|
||||
* @since 2.0.7
|
||||
*/
|
||||
public function setViewPath($path)
|
||||
{
|
||||
$this->_viewPath = Yii::getAlias($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the applicable layout file.
|
||||
* @param View $view the view object to render the layout file.
|
||||
* @return string|bool the layout file path, or false if layout is not needed.
|
||||
* Please refer to [[render()]] on how to specify this parameter.
|
||||
* @throws InvalidArgumentException if an invalid path alias is used to specify the layout.
|
||||
*/
|
||||
public function findLayoutFile($view)
|
||||
{
|
||||
$module = $this->module;
|
||||
if (is_string($this->layout)) {
|
||||
$layout = $this->layout;
|
||||
} elseif ($this->layout === null) {
|
||||
while ($module !== null && $module->layout === null) {
|
||||
$module = $module->module;
|
||||
}
|
||||
if ($module !== null && is_string($module->layout)) {
|
||||
$layout = $module->layout;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($layout)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strncmp($layout, '@', 1) === 0) {
|
||||
$file = Yii::getAlias($layout);
|
||||
} elseif (strncmp($layout, '/', 1) === 0) {
|
||||
$file = Yii::$app->getLayoutPath() . DIRECTORY_SEPARATOR . substr($layout, 1);
|
||||
} else {
|
||||
$file = $module->getLayoutPath() . DIRECTORY_SEPARATOR . $layout;
|
||||
}
|
||||
|
||||
if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
|
||||
return $file;
|
||||
}
|
||||
$path = $file . '.' . $view->defaultExtension;
|
||||
if ($view->defaultExtension !== 'php' && !is_file($path)) {
|
||||
$path = $file . '.php';
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
}
|
||||
40
vendor/yiisoft/yii2/base/DynamicContentAwareInterface.php
vendored
Normal file
40
vendor/yiisoft/yii2/base/DynamicContentAwareInterface.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* DynamicContentAwareInterface is the interface that should be implemented by classes
|
||||
* which support a [[View]] dynamic content feature.
|
||||
*
|
||||
* @author Sergey Makinen <sergey@makinen.ru>
|
||||
* @since 2.0.14
|
||||
*/
|
||||
interface DynamicContentAwareInterface
|
||||
{
|
||||
/**
|
||||
* Returns a list of placeholders for dynamic content. This method
|
||||
* is used internally to implement the content caching feature.
|
||||
* @return array a list of placeholders.
|
||||
*/
|
||||
public function getDynamicPlaceholders();
|
||||
|
||||
/**
|
||||
* Sets a list of placeholders for dynamic content. This method
|
||||
* is used internally to implement the content caching feature.
|
||||
* @param array $placeholders a list of placeholders.
|
||||
*/
|
||||
public function setDynamicPlaceholders($placeholders);
|
||||
|
||||
/**
|
||||
* Adds a placeholder for dynamic content.
|
||||
* This method is used internally to implement the content caching feature.
|
||||
* @param string $name the placeholder name.
|
||||
* @param string $statements the PHP statements for generating the dynamic content.
|
||||
*/
|
||||
public function addDynamicPlaceholder($name, $statements);
|
||||
}
|
||||
83
vendor/yiisoft/yii2/base/DynamicContentAwareTrait.php
vendored
Normal file
83
vendor/yiisoft/yii2/base/DynamicContentAwareTrait.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* DynamicContentAwareTrait implements common methods for classes
|
||||
* which support a [[View]] dynamic content feature.
|
||||
*
|
||||
* @author Sergey Makinen <sergey@makinen.ru>
|
||||
* @since 2.0.14
|
||||
*/
|
||||
trait DynamicContentAwareTrait
|
||||
{
|
||||
/**
|
||||
* @var string[] a list of placeholders for dynamic content
|
||||
*/
|
||||
private $_dynamicPlaceholders;
|
||||
|
||||
/**
|
||||
* Returns the view object that can be used to render views or view files using dynamic contents.
|
||||
* @return View the view object that can be used to render views or view files.
|
||||
*/
|
||||
abstract protected function getView();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDynamicPlaceholders()
|
||||
{
|
||||
return $this->_dynamicPlaceholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDynamicPlaceholders($placeholders)
|
||||
{
|
||||
$this->_dynamicPlaceholders = $placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addDynamicPlaceholder($name, $statements)
|
||||
{
|
||||
$this->_dynamicPlaceholders[$name] = $statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces placeholders in $content with results of evaluated dynamic statements.
|
||||
* @param string $content content to be parsed.
|
||||
* @param string[] $placeholders placeholders and their values.
|
||||
* @param bool $isRestoredFromCache whether content is going to be restored from cache.
|
||||
* @return string final content.
|
||||
*/
|
||||
protected function updateDynamicContent($content, $placeholders, $isRestoredFromCache = false)
|
||||
{
|
||||
if (empty($placeholders) || !is_array($placeholders)) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
if (count($this->getView()->getDynamicContents()) === 0) {
|
||||
// outermost cache: replace placeholder with dynamic content
|
||||
foreach ($placeholders as $name => $statements) {
|
||||
$placeholders[$name] = $this->getView()->evaluateDynamicContent($statements);
|
||||
}
|
||||
$content = strtr($content, $placeholders);
|
||||
}
|
||||
if ($isRestoredFromCache) {
|
||||
$view = $this->getView();
|
||||
foreach ($placeholders as $name => $statements) {
|
||||
$view->addDynamicPlaceholder($name, $statements);
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
202
vendor/yiisoft/yii2/base/DynamicModel.php
vendored
Normal file
202
vendor/yiisoft/yii2/base/DynamicModel.php
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use yii\validators\Validator;
|
||||
|
||||
/**
|
||||
* DynamicModel is a model class primarily used to support ad hoc data validation.
|
||||
*
|
||||
* The typical usage of DynamicModel is as follows,
|
||||
*
|
||||
* ```php
|
||||
* public function actionSearch($name, $email)
|
||||
* {
|
||||
* $model = DynamicModel::validateData(compact('name', 'email'), [
|
||||
* [['name', 'email'], 'string', 'max' => 128],
|
||||
* ['email', 'email'],
|
||||
* ]);
|
||||
* if ($model->hasErrors()) {
|
||||
* // validation fails
|
||||
* } else {
|
||||
* // validation succeeds
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The above example shows how to validate `$name` and `$email` with the help of DynamicModel.
|
||||
* The [[validateData()]] method creates an instance of DynamicModel, defines the attributes
|
||||
* using the given data (`name` and `email` in this example), and then calls [[Model::validate()]].
|
||||
*
|
||||
* You can check the validation result by [[hasErrors()]], like you do with a normal model.
|
||||
* You may also access the dynamic attributes defined through the model instance, e.g.,
|
||||
* `$model->name` and `$model->email`.
|
||||
*
|
||||
* Alternatively, you may use the following more "classic" syntax to perform ad-hoc data validation:
|
||||
*
|
||||
* ```php
|
||||
* $model = new DynamicModel(compact('name', 'email'));
|
||||
* $model->addRule(['name', 'email'], 'string', ['max' => 128])
|
||||
* ->addRule('email', 'email')
|
||||
* ->validate();
|
||||
* ```
|
||||
*
|
||||
* DynamicModel implements the above ad-hoc data validation feature by supporting the so-called
|
||||
* "dynamic attributes". It basically allows an attribute to be defined dynamically through its constructor
|
||||
* or [[defineAttribute()]].
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class DynamicModel extends Model
|
||||
{
|
||||
private $_attributes = [];
|
||||
|
||||
|
||||
/**
|
||||
* Constructors.
|
||||
* @param array $attributes the dynamic attributes (name-value pairs, or names) being defined
|
||||
* @param array $config the configuration array to be applied to this object.
|
||||
*/
|
||||
public function __construct(array $attributes = [], $config = [])
|
||||
{
|
||||
foreach ($attributes as $name => $value) {
|
||||
if (is_int($name)) {
|
||||
$this->_attributes[$value] = null;
|
||||
} else {
|
||||
$this->_attributes[$name] = $value;
|
||||
}
|
||||
}
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
if (array_key_exists($name, $this->_attributes)) {
|
||||
return $this->_attributes[$name];
|
||||
}
|
||||
|
||||
return parent::__get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __set($name, $value)
|
||||
{
|
||||
if (array_key_exists($name, $this->_attributes)) {
|
||||
$this->_attributes[$name] = $value;
|
||||
} else {
|
||||
parent::__set($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __isset($name)
|
||||
{
|
||||
if (array_key_exists($name, $this->_attributes)) {
|
||||
return isset($this->_attributes[$name]);
|
||||
}
|
||||
|
||||
return parent::__isset($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __unset($name)
|
||||
{
|
||||
if (array_key_exists($name, $this->_attributes)) {
|
||||
unset($this->_attributes[$name]);
|
||||
} else {
|
||||
parent::__unset($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an attribute.
|
||||
* @param string $name the attribute name
|
||||
* @param mixed $value the attribute value
|
||||
*/
|
||||
public function defineAttribute($name, $value = null)
|
||||
{
|
||||
$this->_attributes[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undefines an attribute.
|
||||
* @param string $name the attribute name
|
||||
*/
|
||||
public function undefineAttribute($name)
|
||||
{
|
||||
unset($this->_attributes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a validation rule to this model.
|
||||
* You can also directly manipulate [[validators]] to add or remove validation rules.
|
||||
* This method provides a shortcut.
|
||||
* @param string|array $attributes the attribute(s) to be validated by the rule
|
||||
* @param mixed $validator the validator for the rule.This can be a built-in validator name,
|
||||
* a method name of the model class, an anonymous function, or a validator class name.
|
||||
* @param array $options the options (name-value pairs) to be applied to the validator
|
||||
* @return $this the model itself
|
||||
*/
|
||||
public function addRule($attributes, $validator, $options = [])
|
||||
{
|
||||
$validators = $this->getValidators();
|
||||
$validators->append(Validator::createValidator($validator, $this, (array) $attributes, $options));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given data with the specified validation rules.
|
||||
* This method will create a DynamicModel instance, populate it with the data to be validated,
|
||||
* create the specified validation rules, and then validate the data using these rules.
|
||||
* @param array $data the data (name-value pairs) to be validated
|
||||
* @param array $rules the validation rules. Please refer to [[Model::rules()]] on the format of this parameter.
|
||||
* @return static the model instance that contains the data being validated
|
||||
* @throws InvalidConfigException if a validation rule is not specified correctly.
|
||||
*/
|
||||
public static function validateData(array $data, $rules = [])
|
||||
{
|
||||
/* @var $model DynamicModel */
|
||||
$model = new static($data);
|
||||
if (!empty($rules)) {
|
||||
$validators = $model->getValidators();
|
||||
foreach ($rules as $rule) {
|
||||
if ($rule instanceof Validator) {
|
||||
$validators->append($rule);
|
||||
} elseif (is_array($rule) && isset($rule[0], $rule[1])) { // attributes, validator type
|
||||
$validator = Validator::createValidator($rule[1], $model, (array) $rule[0], array_slice($rule, 2));
|
||||
$validators->append($validator);
|
||||
} else {
|
||||
throw new InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$model->validate();
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
return array_keys($this->_attributes);
|
||||
}
|
||||
}
|
||||
114
vendor/yiisoft/yii2/base/ErrorException.php
vendored
Normal file
114
vendor/yiisoft/yii2/base/ErrorException.php
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* ErrorException represents a PHP error.
|
||||
*
|
||||
* For more details and usage information on ErrorException, see the [guide article on handling errors](guide:runtime-handling-errors).
|
||||
*
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ErrorException extends \ErrorException
|
||||
{
|
||||
/**
|
||||
* This constant represents a fatal error in the HHVM engine.
|
||||
*
|
||||
* PHP Zend runtime won't call the error handler on fatals, HHVM will, with an error code of 16777217
|
||||
* We will handle fatal error a bit different on HHVM.
|
||||
* @see https://github.com/facebook/hhvm/blob/master/hphp/runtime/base/runtime-error.h#L62
|
||||
* @since 2.0.6
|
||||
*/
|
||||
const E_HHVM_FATAL_ERROR = 16777217; // E_ERROR | (1 << 24)
|
||||
|
||||
|
||||
/**
|
||||
* Constructs the exception.
|
||||
* @link http://php.net/manual/en/errorexception.construct.php
|
||||
* @param $message [optional]
|
||||
* @param $code [optional]
|
||||
* @param $severity [optional]
|
||||
* @param $filename [optional]
|
||||
* @param $lineno [optional]
|
||||
* @param $previous [optional]
|
||||
*/
|
||||
public function __construct($message = '', $code = 0, $severity = 1, $filename = __FILE__, $lineno = __LINE__, \Exception $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
|
||||
|
||||
if (function_exists('xdebug_get_function_stack')) {
|
||||
// XDebug trace can't be modified and used directly with PHP 7
|
||||
// @see https://github.com/yiisoft/yii2/pull/11723
|
||||
$xDebugTrace = array_slice(array_reverse(xdebug_get_function_stack()), 3, -1);
|
||||
$trace = [];
|
||||
foreach ($xDebugTrace as $frame) {
|
||||
if (!isset($frame['function'])) {
|
||||
$frame['function'] = 'unknown';
|
||||
}
|
||||
|
||||
// XDebug < 2.1.1: http://bugs.xdebug.org/view.php?id=695
|
||||
if (!isset($frame['type']) || $frame['type'] === 'static') {
|
||||
$frame['type'] = '::';
|
||||
} elseif ($frame['type'] === 'dynamic') {
|
||||
$frame['type'] = '->';
|
||||
}
|
||||
|
||||
// XDebug has a different key name
|
||||
if (isset($frame['params']) && !isset($frame['args'])) {
|
||||
$frame['args'] = $frame['params'];
|
||||
}
|
||||
$trace[] = $frame;
|
||||
}
|
||||
|
||||
$ref = new \ReflectionProperty('Exception', 'trace');
|
||||
$ref->setAccessible(true);
|
||||
$ref->setValue($this, $trace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if error is one of fatal type.
|
||||
*
|
||||
* @param array $error error got from error_get_last()
|
||||
* @return bool if error is one of fatal type
|
||||
*/
|
||||
public static function isFatalError($error)
|
||||
{
|
||||
return isset($error['type']) && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, self::E_HHVM_FATAL_ERROR]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
static $names = [
|
||||
E_COMPILE_ERROR => 'PHP Compile Error',
|
||||
E_COMPILE_WARNING => 'PHP Compile Warning',
|
||||
E_CORE_ERROR => 'PHP Core Error',
|
||||
E_CORE_WARNING => 'PHP Core Warning',
|
||||
E_DEPRECATED => 'PHP Deprecated Warning',
|
||||
E_ERROR => 'PHP Fatal Error',
|
||||
E_NOTICE => 'PHP Notice',
|
||||
E_PARSE => 'PHP Parse Error',
|
||||
E_RECOVERABLE_ERROR => 'PHP Recoverable Error',
|
||||
E_STRICT => 'PHP Strict Warning',
|
||||
E_USER_DEPRECATED => 'PHP User Deprecated Warning',
|
||||
E_USER_ERROR => 'PHP User Error',
|
||||
E_USER_NOTICE => 'PHP User Notice',
|
||||
E_USER_WARNING => 'PHP User Warning',
|
||||
E_WARNING => 'PHP Warning',
|
||||
self::E_HHVM_FATAL_ERROR => 'HHVM Fatal Error',
|
||||
];
|
||||
|
||||
return isset($names[$this->getCode()]) ? $names[$this->getCode()] : 'Error';
|
||||
}
|
||||
}
|
||||
360
vendor/yiisoft/yii2/base/ErrorHandler.php
vendored
Normal file
360
vendor/yiisoft/yii2/base/ErrorHandler.php
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\VarDumper;
|
||||
use yii\web\HttpException;
|
||||
|
||||
/**
|
||||
* ErrorHandler handles uncaught PHP errors and exceptions.
|
||||
*
|
||||
* ErrorHandler is configured as an application component in [[\yii\base\Application]] by default.
|
||||
* You can access that instance via `Yii::$app->errorHandler`.
|
||||
*
|
||||
* For more details and usage information on ErrorHandler, see the [guide article on handling errors](guide:runtime-handling-errors).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @author Alexander Makarov <sam@rmcreative.ru>
|
||||
* @author Carsten Brandt <mail@cebe.cc>
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class ErrorHandler extends Component
|
||||
{
|
||||
/**
|
||||
* @var bool whether to discard any existing page output before error display. Defaults to true.
|
||||
*/
|
||||
public $discardExistingOutput = true;
|
||||
/**
|
||||
* @var int the size of the reserved memory. A portion of memory is pre-allocated so that
|
||||
* when an out-of-memory issue occurs, the error handler is able to handle the error with
|
||||
* the help of this reserved memory. If you set this value to be 0, no memory will be reserved.
|
||||
* Defaults to 256KB.
|
||||
*/
|
||||
public $memoryReserveSize = 262144;
|
||||
/**
|
||||
* @var \Exception|null the exception that is being handled currently.
|
||||
*/
|
||||
public $exception;
|
||||
|
||||
/**
|
||||
* @var string Used to reserve memory for fatal error handler.
|
||||
*/
|
||||
private $_memoryReserve;
|
||||
/**
|
||||
* @var \Exception from HHVM error that stores backtrace
|
||||
*/
|
||||
private $_hhvmException;
|
||||
|
||||
|
||||
/**
|
||||
* Register this error handler.
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
ini_set('display_errors', false);
|
||||
set_exception_handler([$this, 'handleException']);
|
||||
if (defined('HHVM_VERSION')) {
|
||||
set_error_handler([$this, 'handleHhvmError']);
|
||||
} else {
|
||||
set_error_handler([$this, 'handleError']);
|
||||
}
|
||||
if ($this->memoryReserveSize > 0) {
|
||||
$this->_memoryReserve = str_repeat('x', $this->memoryReserveSize);
|
||||
}
|
||||
register_shutdown_function([$this, 'handleFatalError']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this error handler by restoring the PHP error and exception handlers.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
restore_error_handler();
|
||||
restore_exception_handler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles uncaught PHP exceptions.
|
||||
*
|
||||
* This method is implemented as a PHP exception handler.
|
||||
*
|
||||
* @param \Exception $exception the exception that is not caught
|
||||
*/
|
||||
public function handleException($exception)
|
||||
{
|
||||
if ($exception instanceof ExitException) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->exception = $exception;
|
||||
|
||||
// disable error capturing to avoid recursive errors while handling exceptions
|
||||
$this->unregister();
|
||||
|
||||
// set preventive HTTP status code to 500 in case error handling somehow fails and headers are sent
|
||||
// HTTP exceptions will override this value in renderException()
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
http_response_code(500);
|
||||
}
|
||||
|
||||
try {
|
||||
$this->logException($exception);
|
||||
if ($this->discardExistingOutput) {
|
||||
$this->clearOutput();
|
||||
}
|
||||
$this->renderException($exception);
|
||||
if (!YII_ENV_TEST) {
|
||||
\Yii::getLogger()->flush(true);
|
||||
if (defined('HHVM_VERSION')) {
|
||||
flush();
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// an other exception could be thrown while displaying the exception
|
||||
$this->handleFallbackExceptionMessage($e, $exception);
|
||||
} catch (\Throwable $e) {
|
||||
// additional check for \Throwable introduced in PHP 7
|
||||
$this->handleFallbackExceptionMessage($e, $exception);
|
||||
}
|
||||
|
||||
$this->exception = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles exception thrown during exception processing in [[handleException()]].
|
||||
* @param \Exception|\Throwable $exception Exception that was thrown during main exception processing.
|
||||
* @param \Exception $previousException Main exception processed in [[handleException()]].
|
||||
* @since 2.0.11
|
||||
*/
|
||||
protected function handleFallbackExceptionMessage($exception, $previousException)
|
||||
{
|
||||
$msg = "An Error occurred while handling another error:\n";
|
||||
$msg .= (string) $exception;
|
||||
$msg .= "\nPrevious exception:\n";
|
||||
$msg .= (string) $previousException;
|
||||
if (YII_DEBUG) {
|
||||
if (PHP_SAPI === 'cli') {
|
||||
echo $msg . "\n";
|
||||
} else {
|
||||
echo '<pre>' . htmlspecialchars($msg, ENT_QUOTES, Yii::$app->charset) . '</pre>';
|
||||
}
|
||||
} else {
|
||||
echo 'An internal server error occurred.';
|
||||
}
|
||||
$msg .= "\n\$_SERVER = " . VarDumper::export($_SERVER);
|
||||
error_log($msg);
|
||||
if (defined('HHVM_VERSION')) {
|
||||
flush();
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles HHVM execution errors such as warnings and notices.
|
||||
*
|
||||
* This method is used as a HHVM error handler. It will store exception that will
|
||||
* be used in fatal error handler
|
||||
*
|
||||
* @param int $code the level of the error raised.
|
||||
* @param string $message the error message.
|
||||
* @param string $file the filename that the error was raised in.
|
||||
* @param int $line the line number the error was raised at.
|
||||
* @param mixed $context
|
||||
* @param mixed $backtrace trace of error
|
||||
* @return bool whether the normal error handler continues.
|
||||
*
|
||||
* @throws ErrorException
|
||||
* @since 2.0.6
|
||||
*/
|
||||
public function handleHhvmError($code, $message, $file, $line, $context, $backtrace)
|
||||
{
|
||||
if ($this->handleError($code, $message, $file, $line)) {
|
||||
return true;
|
||||
}
|
||||
if (E_ERROR & $code) {
|
||||
$exception = new ErrorException($message, $code, $code, $file, $line);
|
||||
$ref = new \ReflectionProperty('\Exception', 'trace');
|
||||
$ref->setAccessible(true);
|
||||
$ref->setValue($exception, $backtrace);
|
||||
$this->_hhvmException = $exception;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles PHP execution errors such as warnings and notices.
|
||||
*
|
||||
* This method is used as a PHP error handler. It will simply raise an [[ErrorException]].
|
||||
*
|
||||
* @param int $code the level of the error raised.
|
||||
* @param string $message the error message.
|
||||
* @param string $file the filename that the error was raised in.
|
||||
* @param int $line the line number the error was raised at.
|
||||
* @return bool whether the normal error handler continues.
|
||||
*
|
||||
* @throws ErrorException
|
||||
*/
|
||||
public function handleError($code, $message, $file, $line)
|
||||
{
|
||||
if (error_reporting() & $code) {
|
||||
// load ErrorException manually here because autoloading them will not work
|
||||
// when error occurs while autoloading a class
|
||||
if (!class_exists('yii\\base\\ErrorException', false)) {
|
||||
require_once __DIR__ . '/ErrorException.php';
|
||||
}
|
||||
$exception = new ErrorException($message, $code, $code, $file, $line);
|
||||
|
||||
// in case error appeared in __toString method we can't throw any exception
|
||||
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
array_shift($trace);
|
||||
foreach ($trace as $frame) {
|
||||
if ($frame['function'] === '__toString') {
|
||||
$this->handleException($exception);
|
||||
if (defined('HHVM_VERSION')) {
|
||||
flush();
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles fatal PHP errors.
|
||||
*/
|
||||
public function handleFatalError()
|
||||
{
|
||||
unset($this->_memoryReserve);
|
||||
|
||||
// load ErrorException manually here because autoloading them will not work
|
||||
// when error occurs while autoloading a class
|
||||
if (!class_exists('yii\\base\\ErrorException', false)) {
|
||||
require_once __DIR__ . '/ErrorException.php';
|
||||
}
|
||||
|
||||
$error = error_get_last();
|
||||
|
||||
if (ErrorException::isFatalError($error)) {
|
||||
if (!empty($this->_hhvmException)) {
|
||||
$exception = $this->_hhvmException;
|
||||
} else {
|
||||
$exception = new ErrorException($error['message'], $error['type'], $error['type'], $error['file'], $error['line']);
|
||||
}
|
||||
$this->exception = $exception;
|
||||
|
||||
$this->logException($exception);
|
||||
|
||||
if ($this->discardExistingOutput) {
|
||||
$this->clearOutput();
|
||||
}
|
||||
$this->renderException($exception);
|
||||
|
||||
// need to explicitly flush logs because exit() next will terminate the app immediately
|
||||
Yii::getLogger()->flush(true);
|
||||
if (defined('HHVM_VERSION')) {
|
||||
flush();
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the exception.
|
||||
* @param \Exception $exception the exception to be rendered.
|
||||
*/
|
||||
abstract protected function renderException($exception);
|
||||
|
||||
/**
|
||||
* Logs the given exception.
|
||||
* @param \Exception $exception the exception to be logged
|
||||
* @since 2.0.3 this method is now public.
|
||||
*/
|
||||
public function logException($exception)
|
||||
{
|
||||
$category = get_class($exception);
|
||||
if ($exception instanceof HttpException) {
|
||||
$category = 'yii\\web\\HttpException:' . $exception->statusCode;
|
||||
} elseif ($exception instanceof \ErrorException) {
|
||||
$category .= ':' . $exception->getSeverity();
|
||||
}
|
||||
Yii::error($exception, $category);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all output echoed before calling this method.
|
||||
*/
|
||||
public function clearOutput()
|
||||
{
|
||||
// the following manual level counting is to deal with zlib.output_compression set to On
|
||||
for ($level = ob_get_level(); $level > 0; --$level) {
|
||||
if (!@ob_end_clean()) {
|
||||
ob_clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an exception into a PHP error.
|
||||
*
|
||||
* This method can be used to convert exceptions inside of methods like `__toString()`
|
||||
* to PHP errors because exceptions cannot be thrown inside of them.
|
||||
* @param \Exception $exception the exception to convert to a PHP error.
|
||||
*/
|
||||
public static function convertExceptionToError($exception)
|
||||
{
|
||||
trigger_error(static::convertExceptionToString($exception), E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an exception into a simple string.
|
||||
* @param \Exception|\Error $exception the exception being converted
|
||||
* @return string the string representation of the exception.
|
||||
*/
|
||||
public static function convertExceptionToString($exception)
|
||||
{
|
||||
if ($exception instanceof UserException) {
|
||||
return "{$exception->getName()}: {$exception->getMessage()}";
|
||||
}
|
||||
|
||||
if (YII_DEBUG) {
|
||||
return static::convertExceptionToVerboseString($exception);
|
||||
}
|
||||
|
||||
return 'An internal server error occurred.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an exception into a string that has verbose information about the exception and its trace.
|
||||
* @param \Exception|\Error $exception the exception being converted
|
||||
* @return string the string representation of the exception.
|
||||
*
|
||||
* @since 2.0.14
|
||||
*/
|
||||
public static function convertExceptionToVerboseString($exception)
|
||||
{
|
||||
if ($exception instanceof Exception) {
|
||||
$message = "Exception ({$exception->getName()})";
|
||||
} elseif ($exception instanceof ErrorException) {
|
||||
$message = (string)$exception->getName();
|
||||
} else {
|
||||
$message = 'Exception';
|
||||
}
|
||||
$message .= " '" . get_class($exception) . "' with message '{$exception->getMessage()}' \n\nin "
|
||||
. $exception->getFile() . ':' . $exception->getLine() . "\n\n"
|
||||
. "Stack trace:\n" . $exception->getTraceAsString();
|
||||
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
317
vendor/yiisoft/yii2/base/Event.php
vendored
Normal file
317
vendor/yiisoft/yii2/base/Event.php
vendored
Normal file
@@ -0,0 +1,317 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/**
|
||||
* Event is the base class for all event classes.
|
||||
*
|
||||
* It encapsulates the parameters associated with an event.
|
||||
* The [[sender]] property describes who raises the event.
|
||||
* And the [[handled]] property indicates if the event is handled.
|
||||
* If an event handler sets [[handled]] to be `true`, the rest of the
|
||||
* uninvoked handlers will no longer be called to handle the event.
|
||||
*
|
||||
* Additionally, when attaching an event handler, extra data may be passed
|
||||
* and be available via the [[data]] property when the event handler is invoked.
|
||||
*
|
||||
* For more details and usage information on Event, see the [guide article on events](guide:concept-events).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Event extends BaseObject
|
||||
{
|
||||
/**
|
||||
* @var string the event name. This property is set by [[Component::trigger()]] and [[trigger()]].
|
||||
* Event handlers may use this property to check what event it is handling.
|
||||
*/
|
||||
public $name;
|
||||
/**
|
||||
* @var object the sender of this event. If not set, this property will be
|
||||
* set as the object whose `trigger()` method is called.
|
||||
* This property may also be a `null` when this event is a
|
||||
* class-level event which is triggered in a static context.
|
||||
*/
|
||||
public $sender;
|
||||
/**
|
||||
* @var bool whether the event is handled. Defaults to `false`.
|
||||
* When a handler sets this to be `true`, the event processing will stop and
|
||||
* ignore the rest of the uninvoked event handlers.
|
||||
*/
|
||||
public $handled = false;
|
||||
/**
|
||||
* @var mixed the data that is passed to [[Component::on()]] when attaching an event handler.
|
||||
* Note that this varies according to which event handler is currently executing.
|
||||
*/
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* @var array contains all globally registered event handlers.
|
||||
*/
|
||||
private static $_events = [];
|
||||
/**
|
||||
* @var array the globally registered event handlers attached for wildcard patterns (event name wildcard => handlers)
|
||||
* @since 2.0.14
|
||||
*/
|
||||
private static $_eventWildcards = [];
|
||||
|
||||
|
||||
/**
|
||||
* Attaches an event handler to a class-level event.
|
||||
*
|
||||
* When a class-level event is triggered, event handlers attached
|
||||
* to that class and all parent classes will be invoked.
|
||||
*
|
||||
* For example, the following code attaches an event handler to `ActiveRecord`'s
|
||||
* `afterInsert` event:
|
||||
*
|
||||
* ```php
|
||||
* Event::on(ActiveRecord::className(), ActiveRecord::EVENT_AFTER_INSERT, function ($event) {
|
||||
* Yii::trace(get_class($event->sender) . ' is inserted.');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* The handler will be invoked for EVERY successful ActiveRecord insertion.
|
||||
*
|
||||
* Since 2.0.14 you can specify either class name or event name as a wildcard pattern:
|
||||
*
|
||||
* ```php
|
||||
* Event::on('app\models\db\*', '*Insert', function ($event) {
|
||||
* Yii::trace(get_class($event->sender) . ' is inserted.');
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* For more details about how to declare an event handler, please refer to [[Component::on()]].
|
||||
*
|
||||
* @param string $class the fully qualified class name to which the event handler needs to attach.
|
||||
* @param string $name the event name.
|
||||
* @param callable $handler the event handler.
|
||||
* @param mixed $data the data to be passed to the event handler when the event is triggered.
|
||||
* When the event handler is invoked, this data can be accessed via [[Event::data]].
|
||||
* @param bool $append whether to append new event handler to the end of the existing
|
||||
* handler list. If `false`, the new handler will be inserted at the beginning of the existing
|
||||
* handler list.
|
||||
* @see off()
|
||||
*/
|
||||
public static function on($class, $name, $handler, $data = null, $append = true)
|
||||
{
|
||||
$class = ltrim($class, '\\');
|
||||
|
||||
if (strpos($class, '*') !== false || strpos($name, '*') !== false) {
|
||||
if ($append || empty(self::$_eventWildcards[$name][$class])) {
|
||||
self::$_eventWildcards[$name][$class][] = [$handler, $data];
|
||||
} else {
|
||||
array_unshift(self::$_eventWildcards[$name][$class], [$handler, $data]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ($append || empty(self::$_events[$name][$class])) {
|
||||
self::$_events[$name][$class][] = [$handler, $data];
|
||||
} else {
|
||||
array_unshift(self::$_events[$name][$class], [$handler, $data]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches an event handler from a class-level event.
|
||||
*
|
||||
* This method is the opposite of [[on()]].
|
||||
*
|
||||
* Note: in case wildcard pattern is passed for class name or event name, only the handlers registered with this
|
||||
* wildcard will be removed, while handlers registered with plain names matching this wildcard will remain.
|
||||
*
|
||||
* @param string $class the fully qualified class name from which the event handler needs to be detached.
|
||||
* @param string $name the event name.
|
||||
* @param callable $handler the event handler to be removed.
|
||||
* If it is `null`, all handlers attached to the named event will be removed.
|
||||
* @return bool whether a handler is found and detached.
|
||||
* @see on()
|
||||
*/
|
||||
public static function off($class, $name, $handler = null)
|
||||
{
|
||||
$class = ltrim($class, '\\');
|
||||
if (empty(self::$_events[$name][$class]) && empty(self::$_eventWildcards[$name][$class])) {
|
||||
return false;
|
||||
}
|
||||
if ($handler === null) {
|
||||
unset(self::$_events[$name][$class]);
|
||||
unset(self::$_eventWildcards[$name][$class]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// plain event names
|
||||
if (isset(self::$_events[$name][$class])) {
|
||||
$removed = false;
|
||||
foreach (self::$_events[$name][$class] as $i => $event) {
|
||||
if ($event[0] === $handler) {
|
||||
unset(self::$_events[$name][$class][$i]);
|
||||
$removed = true;
|
||||
}
|
||||
}
|
||||
if ($removed) {
|
||||
self::$_events[$name][$class] = array_values(self::$_events[$name][$class]);
|
||||
return $removed;
|
||||
}
|
||||
}
|
||||
|
||||
// wildcard event names
|
||||
$removed = false;
|
||||
foreach (self::$_eventWildcards[$name][$class] as $i => $event) {
|
||||
if ($event[0] === $handler) {
|
||||
unset(self::$_eventWildcards[$name][$class][$i]);
|
||||
$removed = true;
|
||||
}
|
||||
}
|
||||
if ($removed) {
|
||||
self::$_eventWildcards[$name][$class] = array_values(self::$_eventWildcards[$name][$class]);
|
||||
// remove empty wildcards to save future redundant regex checks :
|
||||
if (empty(self::$_eventWildcards[$name][$class])) {
|
||||
unset(self::$_eventWildcards[$name][$class]);
|
||||
if (empty(self::$_eventWildcards[$name])) {
|
||||
unset(self::$_eventWildcards[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detaches all registered class-level event handlers.
|
||||
* @see on()
|
||||
* @see off()
|
||||
* @since 2.0.10
|
||||
*/
|
||||
public static function offAll()
|
||||
{
|
||||
self::$_events = [];
|
||||
self::$_eventWildcards = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether there is any handler attached to the specified class-level event.
|
||||
* Note that this method will also check all parent classes to see if there is any handler attached
|
||||
* to the named event.
|
||||
* @param string|object $class the object or the fully qualified class name specifying the class-level event.
|
||||
* @param string $name the event name.
|
||||
* @return bool whether there is any handler attached to the event.
|
||||
*/
|
||||
public static function hasHandlers($class, $name)
|
||||
{
|
||||
if (empty(self::$_eventWildcards) && empty(self::$_events[$name])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_object($class)) {
|
||||
$class = get_class($class);
|
||||
} else {
|
||||
$class = ltrim($class, '\\');
|
||||
}
|
||||
|
||||
$classes = array_merge(
|
||||
[$class],
|
||||
class_parents($class, true),
|
||||
class_implements($class, true)
|
||||
);
|
||||
|
||||
// regular events
|
||||
foreach ($classes as $class) {
|
||||
if (!empty(self::$_events[$name][$class])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// wildcard events
|
||||
foreach (self::$_eventWildcards as $nameWildcard => $classHandlers) {
|
||||
if (!StringHelper::matchWildcard($nameWildcard, $name)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($classHandlers as $classWildcard => $handlers) {
|
||||
if (empty($handlers)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($classes as $class) {
|
||||
if (!StringHelper::matchWildcard($classWildcard, $class)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a class-level event.
|
||||
* This method will cause invocation of event handlers that are attached to the named event
|
||||
* for the specified class and all its parent classes.
|
||||
* @param string|object $class the object or the fully qualified class name specifying the class-level event.
|
||||
* @param string $name the event name.
|
||||
* @param Event $event the event parameter. If not set, a default [[Event]] object will be created.
|
||||
*/
|
||||
public static function trigger($class, $name, $event = null)
|
||||
{
|
||||
$wildcardEventHandlers = [];
|
||||
foreach (self::$_eventWildcards as $nameWildcard => $classHandlers) {
|
||||
if (!StringHelper::matchWildcard($nameWildcard, $name)) {
|
||||
continue;
|
||||
}
|
||||
$wildcardEventHandlers = array_merge($wildcardEventHandlers, $classHandlers);
|
||||
}
|
||||
|
||||
if (empty(self::$_events[$name]) && empty($wildcardEventHandlers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event === null) {
|
||||
$event = new static();
|
||||
}
|
||||
$event->handled = false;
|
||||
$event->name = $name;
|
||||
|
||||
if (is_object($class)) {
|
||||
if ($event->sender === null) {
|
||||
$event->sender = $class;
|
||||
}
|
||||
$class = get_class($class);
|
||||
} else {
|
||||
$class = ltrim($class, '\\');
|
||||
}
|
||||
|
||||
$classes = array_merge(
|
||||
[$class],
|
||||
class_parents($class, true),
|
||||
class_implements($class, true)
|
||||
);
|
||||
|
||||
foreach ($classes as $class) {
|
||||
$eventHandlers = [];
|
||||
foreach ($wildcardEventHandlers as $classWildcard => $handlers) {
|
||||
if (StringHelper::matchWildcard($classWildcard, $class)) {
|
||||
$eventHandlers = array_merge($eventHandlers, $handlers);
|
||||
unset($wildcardEventHandlers[$classWildcard]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty(self::$_events[$name][$class])) {
|
||||
$eventHandlers = array_merge($eventHandlers, self::$_events[$name][$class]);
|
||||
}
|
||||
|
||||
foreach ($eventHandlers as $handler) {
|
||||
$event->data = $handler[1];
|
||||
call_user_func($handler[0], $event);
|
||||
if ($event->handled) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
vendor/yiisoft/yii2/base/Exception.php
vendored
Normal file
27
vendor/yiisoft/yii2/base/Exception.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* Exception represents a generic exception for all purposes.
|
||||
*
|
||||
* For more details and usage information on Exception, see the [guide article on handling errors](guide:runtime-handling-errors).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Exception extends \Exception
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Exception';
|
||||
}
|
||||
}
|
||||
38
vendor/yiisoft/yii2/base/ExitException.php
vendored
Normal file
38
vendor/yiisoft/yii2/base/ExitException.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ExitException represents a normal termination of an application.
|
||||
*
|
||||
* Do not catch ExitException. Yii will handle this exception to terminate the application gracefully.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ExitException extends \Exception
|
||||
{
|
||||
/**
|
||||
* @var int the exit status code
|
||||
*/
|
||||
public $statusCode;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param int $status the exit status code
|
||||
* @param string $message error message
|
||||
* @param int $code error code
|
||||
* @param \Exception $previous The previous exception used for the exception chaining.
|
||||
*/
|
||||
public function __construct($status = 0, $message = null, $code = 0, \Exception $previous = null)
|
||||
{
|
||||
$this->statusCode = $status;
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
59
vendor/yiisoft/yii2/base/InlineAction.php
vendored
Normal file
59
vendor/yiisoft/yii2/base/InlineAction.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* InlineAction represents an action that is defined as a controller method.
|
||||
*
|
||||
* The name of the controller method is available via [[actionMethod]] which
|
||||
* is set by the [[controller]] who creates this action.
|
||||
*
|
||||
* For more details and usage information on InlineAction, see the [guide article on actions](guide:structure-controllers).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class InlineAction extends Action
|
||||
{
|
||||
/**
|
||||
* @var string the controller method that this inline action is associated with
|
||||
*/
|
||||
public $actionMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param string $id the ID of this action
|
||||
* @param Controller $controller the controller that owns this action
|
||||
* @param string $actionMethod the controller method that this inline action is associated with
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties
|
||||
*/
|
||||
public function __construct($id, $controller, $actionMethod, $config = [])
|
||||
{
|
||||
$this->actionMethod = $actionMethod;
|
||||
parent::__construct($id, $controller, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs this action with the specified parameters.
|
||||
* This method is mainly invoked by the controller.
|
||||
* @param array $params action parameters
|
||||
* @return mixed the result of the action
|
||||
*/
|
||||
public function runWithParams($params)
|
||||
{
|
||||
$args = $this->controller->bindActionParams($this, $params);
|
||||
Yii::debug('Running action: ' . get_class($this->controller) . '::' . $this->actionMethod . '()', __METHOD__);
|
||||
if (Yii::$app->requestedParams === null) {
|
||||
Yii::$app->requestedParams = $args;
|
||||
}
|
||||
|
||||
return call_user_func_array([$this->controller, $this->actionMethod], $args);
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/InvalidArgumentException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/InvalidArgumentException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* InvalidArgumentException represents an exception caused by invalid arguments passed to a method.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0.14
|
||||
*/
|
||||
class InvalidArgumentException extends InvalidParamException
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Invalid Argument';
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/InvalidCallException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/InvalidCallException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* InvalidCallException represents an exception caused by calling a method in a wrong way.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class InvalidCallException extends \BadMethodCallException
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Invalid Call';
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/InvalidConfigException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/InvalidConfigException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* InvalidConfigException represents an exception caused by incorrect object configuration.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class InvalidConfigException extends Exception
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Invalid Configuration';
|
||||
}
|
||||
}
|
||||
26
vendor/yiisoft/yii2/base/InvalidParamException.php
vendored
Normal file
26
vendor/yiisoft/yii2/base/InvalidParamException.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* InvalidParamException represents an exception caused by invalid parameters passed to a method.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
* @deprecated since 2.0.14. Use [[InvalidArgumentException]] instead.
|
||||
*/
|
||||
class InvalidParamException extends \BadMethodCallException
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Invalid Parameter';
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/InvalidRouteException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/InvalidRouteException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* InvalidRouteException represents an exception caused by an invalid route.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class InvalidRouteException extends UserException
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Invalid Route';
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/InvalidValueException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/InvalidValueException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* InvalidValueException represents an exception caused by a function returning a value of unexpected type.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class InvalidValueException extends \UnexpectedValueException
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Invalid Return Value';
|
||||
}
|
||||
}
|
||||
1002
vendor/yiisoft/yii2/base/Model.php
vendored
Normal file
1002
vendor/yiisoft/yii2/base/Model.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
23
vendor/yiisoft/yii2/base/ModelEvent.php
vendored
Normal file
23
vendor/yiisoft/yii2/base/ModelEvent.php
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ModelEvent represents the parameter needed by [[Model]] events.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ModelEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var bool whether the model is in valid status. Defaults to true.
|
||||
* A model is in valid status if it passes validations or certain checks.
|
||||
*/
|
||||
public $isValid = true;
|
||||
}
|
||||
762
vendor/yiisoft/yii2/base/Module.php
vendored
Normal file
762
vendor/yiisoft/yii2/base/Module.php
vendored
Normal file
@@ -0,0 +1,762 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
use yii\di\ServiceLocator;
|
||||
|
||||
/**
|
||||
* Module is the base class for module and application classes.
|
||||
*
|
||||
* A module represents a sub-application which contains MVC elements by itself, such as
|
||||
* models, views, controllers, etc.
|
||||
*
|
||||
* A module may consist of [[modules|sub-modules]].
|
||||
*
|
||||
* [[components|Components]] may be registered with the module so that they are globally
|
||||
* accessible within the module.
|
||||
*
|
||||
* For more details and usage information on Module, see the [guide article on modules](guide:structure-modules).
|
||||
*
|
||||
* @property array $aliases List of path aliases to be defined. The array keys are alias names (must start
|
||||
* with `@`) and the array values are the corresponding paths or aliases. See [[setAliases()]] for an example.
|
||||
* This property is write-only.
|
||||
* @property string $basePath The root directory of the module.
|
||||
* @property string $controllerPath The directory that contains the controller classes. This property is
|
||||
* read-only.
|
||||
* @property string $layoutPath The root directory of layout files. Defaults to "[[viewPath]]/layouts".
|
||||
* @property array $modules The modules (indexed by their IDs).
|
||||
* @property string $uniqueId The unique ID of the module. This property is read-only.
|
||||
* @property string $version The version of this module. Note that the type of this property differs in getter
|
||||
* and setter. See [[getVersion()]] and [[setVersion()]] for details.
|
||||
* @property string $viewPath The root directory of view files. Defaults to "[[basePath]]/views".
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Module extends ServiceLocator
|
||||
{
|
||||
/**
|
||||
* @event ActionEvent an event raised before executing a controller action.
|
||||
* You may set [[ActionEvent::isValid]] to be `false` to cancel the action execution.
|
||||
*/
|
||||
const EVENT_BEFORE_ACTION = 'beforeAction';
|
||||
/**
|
||||
* @event ActionEvent an event raised after executing a controller action.
|
||||
*/
|
||||
const EVENT_AFTER_ACTION = 'afterAction';
|
||||
|
||||
/**
|
||||
* @var array custom module parameters (name => value).
|
||||
*/
|
||||
public $params = [];
|
||||
/**
|
||||
* @var string an ID that uniquely identifies this module among other modules which have the same [[module|parent]].
|
||||
*/
|
||||
public $id;
|
||||
/**
|
||||
* @var Module the parent module of this module. `null` if this module does not have a parent.
|
||||
*/
|
||||
public $module;
|
||||
/**
|
||||
* @var string|bool the layout that should be applied for views within this module. This refers to a view name
|
||||
* relative to [[layoutPath]]. If this is not set, it means the layout value of the [[module|parent module]]
|
||||
* will be taken. If this is `false`, layout will be disabled within this module.
|
||||
*/
|
||||
public $layout;
|
||||
/**
|
||||
* @var array mapping from controller ID to controller configurations.
|
||||
* Each name-value pair specifies the configuration of a single controller.
|
||||
* A controller configuration can be either a string or an array.
|
||||
* If the former, the string should be the fully qualified class name of the controller.
|
||||
* If the latter, the array must contain a `class` element which specifies
|
||||
* the controller's fully qualified class name, and the rest of the name-value pairs
|
||||
* in the array are used to initialize the corresponding controller properties. For example,
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* 'account' => 'app\controllers\UserController',
|
||||
* 'article' => [
|
||||
* 'class' => 'app\controllers\PostController',
|
||||
* 'pageTitle' => 'something new',
|
||||
* ],
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
public $controllerMap = [];
|
||||
/**
|
||||
* @var string the namespace that controller classes are in.
|
||||
* This namespace will be used to load controller classes by prepending it to the controller
|
||||
* class name.
|
||||
*
|
||||
* If not set, it will use the `controllers` sub-namespace under the namespace of this module.
|
||||
* For example, if the namespace of this module is `foo\bar`, then the default
|
||||
* controller namespace would be `foo\bar\controllers`.
|
||||
*
|
||||
* See also the [guide section on autoloading](guide:concept-autoloading) to learn more about
|
||||
* defining namespaces and how classes are loaded.
|
||||
*/
|
||||
public $controllerNamespace;
|
||||
/**
|
||||
* @var string the default route of this module. Defaults to `default`.
|
||||
* The route may consist of child module ID, controller ID, and/or action ID.
|
||||
* For example, `help`, `post/create`, `admin/post/create`.
|
||||
* If action ID is not given, it will take the default value as specified in
|
||||
* [[Controller::defaultAction]].
|
||||
*/
|
||||
public $defaultRoute = 'default';
|
||||
|
||||
/**
|
||||
* @var string the root directory of the module.
|
||||
*/
|
||||
private $_basePath;
|
||||
/**
|
||||
* @var string the root directory that contains view files for this module
|
||||
*/
|
||||
private $_viewPath;
|
||||
/**
|
||||
* @var string the root directory that contains layout view files for this module.
|
||||
*/
|
||||
private $_layoutPath;
|
||||
/**
|
||||
* @var array child modules of this module
|
||||
*/
|
||||
private $_modules = [];
|
||||
/**
|
||||
* @var string|callable the version of this module.
|
||||
* Version can be specified as a PHP callback, which can accept module instance as an argument and should
|
||||
* return the actual version. For example:
|
||||
*
|
||||
* ```php
|
||||
* function (Module $module) {
|
||||
* //return string|int
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* If not set, [[defaultVersion()]] will be used to determine actual value.
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
private $_version;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param string $id the ID of this module.
|
||||
* @param Module $parent the parent module (if any).
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties.
|
||||
*/
|
||||
public function __construct($id, $parent = null, $config = [])
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->module = $parent;
|
||||
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(Yii::$app->loadedModules[$class]) ? Yii::$app->loadedModules[$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(Yii::$app->loadedModules[get_called_class()]);
|
||||
} else {
|
||||
Yii::$app->loadedModules[get_class($instance)] = $instance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the module.
|
||||
*
|
||||
* This method is called after the module is created and initialized with property values
|
||||
* given in configuration. The default implementation will initialize [[controllerNamespace]]
|
||||
* if it is not set.
|
||||
*
|
||||
* If you override this method, please make sure you call the parent implementation.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($this->controllerNamespace === null) {
|
||||
$class = get_class($this);
|
||||
if (($pos = strrpos($class, '\\')) !== false) {
|
||||
$this->controllerNamespace = substr($class, 0, $pos) . '\\controllers';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ID that uniquely identifies this module among all modules within the current application.
|
||||
* Note that if the module is an application, an empty string will be returned.
|
||||
* @return string the unique ID of the module.
|
||||
*/
|
||||
public function getUniqueId()
|
||||
{
|
||||
return $this->module ? ltrim($this->module->getUniqueId() . '/' . $this->id, '/') : $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root directory of the module.
|
||||
* It defaults to the directory containing the module class file.
|
||||
* @return string the root directory of the module.
|
||||
*/
|
||||
public function getBasePath()
|
||||
{
|
||||
if ($this->_basePath === null) {
|
||||
$class = new \ReflectionClass($this);
|
||||
$this->_basePath = dirname($class->getFileName());
|
||||
}
|
||||
|
||||
return $this->_basePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the root directory of the module.
|
||||
* This method can only be invoked at the beginning of the constructor.
|
||||
* @param string $path the root directory of the module. This can be either a directory name or a [path alias](guide:concept-aliases).
|
||||
* @throws InvalidArgumentException if the directory does not exist.
|
||||
*/
|
||||
public function setBasePath($path)
|
||||
{
|
||||
$path = Yii::getAlias($path);
|
||||
$p = strncmp($path, 'phar://', 7) === 0 ? $path : realpath($path);
|
||||
if ($p !== false && is_dir($p)) {
|
||||
$this->_basePath = $p;
|
||||
} else {
|
||||
throw new InvalidArgumentException("The directory does not exist: $path");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory that contains the controller classes according to [[controllerNamespace]].
|
||||
* Note that in order for this method to return a value, you must define
|
||||
* an alias for the root namespace of [[controllerNamespace]].
|
||||
* @return string the directory that contains the controller classes.
|
||||
* @throws InvalidArgumentException if there is no alias defined for the root namespace of [[controllerNamespace]].
|
||||
*/
|
||||
public function getControllerPath()
|
||||
{
|
||||
return Yii::getAlias('@' . str_replace('\\', '/', $this->controllerNamespace));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory that contains the view files for this module.
|
||||
* @return string the root directory of view files. Defaults to "[[basePath]]/views".
|
||||
*/
|
||||
public function getViewPath()
|
||||
{
|
||||
if ($this->_viewPath === null) {
|
||||
$this->_viewPath = $this->getBasePath() . DIRECTORY_SEPARATOR . 'views';
|
||||
}
|
||||
|
||||
return $this->_viewPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory that contains the view files.
|
||||
* @param string $path the root directory of view files.
|
||||
* @throws InvalidArgumentException if the directory is invalid.
|
||||
*/
|
||||
public function setViewPath($path)
|
||||
{
|
||||
$this->_viewPath = Yii::getAlias($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory that contains layout view files for this module.
|
||||
* @return string the root directory of layout files. Defaults to "[[viewPath]]/layouts".
|
||||
*/
|
||||
public function getLayoutPath()
|
||||
{
|
||||
if ($this->_layoutPath === null) {
|
||||
$this->_layoutPath = $this->getViewPath() . DIRECTORY_SEPARATOR . 'layouts';
|
||||
}
|
||||
|
||||
return $this->_layoutPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory that contains the layout files.
|
||||
* @param string $path the root directory or [path alias](guide:concept-aliases) of layout files.
|
||||
* @throws InvalidArgumentException if the directory is invalid
|
||||
*/
|
||||
public function setLayoutPath($path)
|
||||
{
|
||||
$this->_layoutPath = Yii::getAlias($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns current module version.
|
||||
* If version is not explicitly set, [[defaultVersion()]] method will be used to determine its value.
|
||||
* @return string the version of this module.
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
if ($this->_version === null) {
|
||||
$this->_version = $this->defaultVersion();
|
||||
} else {
|
||||
if (!is_scalar($this->_version)) {
|
||||
$this->_version = call_user_func($this->_version, $this);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets current module version.
|
||||
* @param string|callable $version the version of this module.
|
||||
* Version can be specified as a PHP callback, which can accept module instance as an argument and should
|
||||
* return the actual version. For example:
|
||||
*
|
||||
* ```php
|
||||
* function (Module $module) {
|
||||
* //return string
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function setVersion($version)
|
||||
{
|
||||
$this->_version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default module version.
|
||||
* Child class may override this method to provide more specific version detection.
|
||||
* @return string the version of this module.
|
||||
* @since 2.0.11
|
||||
*/
|
||||
protected function defaultVersion()
|
||||
{
|
||||
if ($this->module === null) {
|
||||
return '1.0';
|
||||
}
|
||||
|
||||
return $this->module->getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines path aliases.
|
||||
* This method calls [[Yii::setAlias()]] to register the path aliases.
|
||||
* This method is provided so that you can define path aliases when configuring a module.
|
||||
* @property array list of path aliases to be defined. The array keys are alias names
|
||||
* (must start with `@`) and the array values are the corresponding paths or aliases.
|
||||
* See [[setAliases()]] for an example.
|
||||
* @param array $aliases list of path aliases to be defined. The array keys are alias names
|
||||
* (must start with `@`) and the array values are the corresponding paths or aliases.
|
||||
* For example,
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* '@models' => '@app/models', // an existing alias
|
||||
* '@backend' => __DIR__ . '/../backend', // a directory
|
||||
* ]
|
||||
* ```
|
||||
*/
|
||||
public function setAliases($aliases)
|
||||
{
|
||||
foreach ($aliases as $name => $alias) {
|
||||
Yii::setAlias($name, $alias);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the child module of the specified ID exists.
|
||||
* This method supports checking the existence of both child and grand child modules.
|
||||
* @param string $id module ID. For grand child modules, use ID path relative to this module (e.g. `admin/content`).
|
||||
* @return bool whether the named module exists. Both loaded and unloaded modules
|
||||
* are considered.
|
||||
*/
|
||||
public function hasModule($id)
|
||||
{
|
||||
if (($pos = strpos($id, '/')) !== false) {
|
||||
// sub-module
|
||||
$module = $this->getModule(substr($id, 0, $pos));
|
||||
|
||||
return $module === null ? false : $module->hasModule(substr($id, $pos + 1));
|
||||
}
|
||||
|
||||
return isset($this->_modules[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the child module of the specified ID.
|
||||
* This method supports retrieving both child modules and grand child modules.
|
||||
* @param string $id module ID (case-sensitive). To retrieve grand child modules,
|
||||
* use ID path relative to this module (e.g. `admin/content`).
|
||||
* @param bool $load whether to load the module if it is not yet loaded.
|
||||
* @return Module|null the module instance, `null` if the module does not exist.
|
||||
* @see hasModule()
|
||||
*/
|
||||
public function getModule($id, $load = true)
|
||||
{
|
||||
if (($pos = strpos($id, '/')) !== false) {
|
||||
// sub-module
|
||||
$module = $this->getModule(substr($id, 0, $pos));
|
||||
|
||||
return $module === null ? null : $module->getModule(substr($id, $pos + 1), $load);
|
||||
}
|
||||
|
||||
if (isset($this->_modules[$id])) {
|
||||
if ($this->_modules[$id] instanceof self) {
|
||||
return $this->_modules[$id];
|
||||
} elseif ($load) {
|
||||
Yii::debug("Loading module: $id", __METHOD__);
|
||||
/* @var $module Module */
|
||||
$module = Yii::createObject($this->_modules[$id], [$id, $this]);
|
||||
$module->setInstance($module);
|
||||
return $this->_modules[$id] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sub-module to this module.
|
||||
* @param string $id module ID.
|
||||
* @param Module|array|null $module the sub-module to be added to this module. This can
|
||||
* be one of the following:
|
||||
*
|
||||
* - a [[Module]] object
|
||||
* - a configuration array: when [[getModule()]] is called initially, the array
|
||||
* will be used to instantiate the sub-module
|
||||
* - `null`: the named sub-module will be removed from this module
|
||||
*/
|
||||
public function setModule($id, $module)
|
||||
{
|
||||
if ($module === null) {
|
||||
unset($this->_modules[$id]);
|
||||
} else {
|
||||
$this->_modules[$id] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sub-modules in this module.
|
||||
* @param bool $loadedOnly whether to return the loaded sub-modules only. If this is set `false`,
|
||||
* then all sub-modules registered in this module will be returned, whether they are loaded or not.
|
||||
* Loaded modules will be returned as objects, while unloaded modules as configuration arrays.
|
||||
* @return array the modules (indexed by their IDs).
|
||||
*/
|
||||
public function getModules($loadedOnly = false)
|
||||
{
|
||||
if ($loadedOnly) {
|
||||
$modules = [];
|
||||
foreach ($this->_modules as $module) {
|
||||
if ($module instanceof self) {
|
||||
$modules[] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
return $modules;
|
||||
}
|
||||
|
||||
return $this->_modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers sub-modules in the current module.
|
||||
*
|
||||
* Each sub-module should be specified as a name-value pair, where
|
||||
* name refers to the ID of the module and value the module or a configuration
|
||||
* array that can be used to create the module. In the latter case, [[Yii::createObject()]]
|
||||
* will be used to create the module.
|
||||
*
|
||||
* If a new sub-module has the same ID as an existing one, the existing one will be overwritten silently.
|
||||
*
|
||||
* The following is an example for registering two sub-modules:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* 'comment' => [
|
||||
* 'class' => 'app\modules\comment\CommentModule',
|
||||
* 'db' => 'db',
|
||||
* ],
|
||||
* 'booking' => ['class' => 'app\modules\booking\BookingModule'],
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* @param array $modules modules (id => module configuration or instances).
|
||||
*/
|
||||
public function setModules($modules)
|
||||
{
|
||||
foreach ($modules as $id => $module) {
|
||||
$this->_modules[$id] = $module;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a controller action specified by a route.
|
||||
* This method parses the specified route and creates the corresponding child module(s), controller and action
|
||||
* instances. It then calls [[Controller::runAction()]] to run the action with the given parameters.
|
||||
* If the route is empty, the method will use [[defaultRoute]].
|
||||
* @param string $route the route that specifies the action.
|
||||
* @param array $params the parameters to be passed to the action
|
||||
* @return mixed the result of the action.
|
||||
* @throws InvalidRouteException if the requested route cannot be resolved into an action successfully.
|
||||
*/
|
||||
public function runAction($route, $params = [])
|
||||
{
|
||||
$parts = $this->createController($route);
|
||||
if (is_array($parts)) {
|
||||
/* @var $controller Controller */
|
||||
list($controller, $actionID) = $parts;
|
||||
$oldController = Yii::$app->controller;
|
||||
Yii::$app->controller = $controller;
|
||||
$result = $controller->runAction($actionID, $params);
|
||||
if ($oldController !== null) {
|
||||
Yii::$app->controller = $oldController;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$id = $this->getUniqueId();
|
||||
throw new InvalidRouteException('Unable to resolve the request "' . ($id === '' ? $route : $id . '/' . $route) . '".');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a controller instance based on the given route.
|
||||
*
|
||||
* The route should be relative to this module. The method implements the following algorithm
|
||||
* to resolve the given route:
|
||||
*
|
||||
* 1. If the route is empty, use [[defaultRoute]];
|
||||
* 2. If the first segment of the route is a valid module ID as declared in [[modules]],
|
||||
* call the module's `createController()` with the rest part of the route;
|
||||
* 3. If the first segment of the route is found in [[controllerMap]], create a controller
|
||||
* based on the corresponding configuration found in [[controllerMap]];
|
||||
* 4. The given route is in the format of `abc/def/xyz`. Try either `abc\DefController`
|
||||
* or `abc\def\XyzController` class within the [[controllerNamespace|controller namespace]].
|
||||
*
|
||||
* If any of the above steps resolves into a controller, it is returned together with the rest
|
||||
* part of the route which will be treated as the action ID. Otherwise, `false` will be returned.
|
||||
*
|
||||
* @param string $route the route consisting of module, controller and action IDs.
|
||||
* @return array|bool If the controller is created successfully, it will be returned together
|
||||
* with the requested action ID. Otherwise `false` will be returned.
|
||||
* @throws InvalidConfigException if the controller class and its file do not match.
|
||||
*/
|
||||
public function createController($route)
|
||||
{
|
||||
if ($route === '') {
|
||||
$route = $this->defaultRoute;
|
||||
}
|
||||
|
||||
// double slashes or leading/ending slashes may cause substr problem
|
||||
$route = trim($route, '/');
|
||||
if (strpos($route, '//') !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($route, '/') !== false) {
|
||||
list($id, $route) = explode('/', $route, 2);
|
||||
} else {
|
||||
$id = $route;
|
||||
$route = '';
|
||||
}
|
||||
|
||||
// module and controller map take precedence
|
||||
if (isset($this->controllerMap[$id])) {
|
||||
$controller = Yii::createObject($this->controllerMap[$id], [$id, $this]);
|
||||
return [$controller, $route];
|
||||
}
|
||||
$module = $this->getModule($id);
|
||||
if ($module !== null) {
|
||||
return $module->createController($route);
|
||||
}
|
||||
|
||||
if (($pos = strrpos($route, '/')) !== false) {
|
||||
$id .= '/' . substr($route, 0, $pos);
|
||||
$route = substr($route, $pos + 1);
|
||||
}
|
||||
|
||||
$controller = $this->createControllerByID($id);
|
||||
if ($controller === null && $route !== '') {
|
||||
$controller = $this->createControllerByID($id . '/' . $route);
|
||||
$route = '';
|
||||
}
|
||||
|
||||
return $controller === null ? false : [$controller, $route];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a controller based on the given controller ID.
|
||||
*
|
||||
* The controller ID is relative to this module. The controller class
|
||||
* should be namespaced under [[controllerNamespace]].
|
||||
*
|
||||
* Note that this method does not check [[modules]] or [[controllerMap]].
|
||||
*
|
||||
* @param string $id the controller ID.
|
||||
* @return Controller|null the newly created controller instance, or `null` if the controller ID is invalid.
|
||||
* @throws InvalidConfigException if the controller class and its file name do not match.
|
||||
* This exception is only thrown when in debug mode.
|
||||
*/
|
||||
public function createControllerByID($id)
|
||||
{
|
||||
$pos = strrpos($id, '/');
|
||||
if ($pos === false) {
|
||||
$prefix = '';
|
||||
$className = $id;
|
||||
} else {
|
||||
$prefix = substr($id, 0, $pos + 1);
|
||||
$className = substr($id, $pos + 1);
|
||||
}
|
||||
|
||||
if ($this->isIncorrectClassNameOrPrefix($className, $prefix)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$className = preg_replace_callback('%-([a-z0-9_])%i', function ($matches) {
|
||||
return ucfirst($matches[1]);
|
||||
}, ucfirst($className)) . 'Controller';
|
||||
$className = ltrim($this->controllerNamespace . '\\' . str_replace('/', '\\', $prefix) . $className, '\\');
|
||||
if (strpos($className, '-') !== false || !class_exists($className)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_subclass_of($className, 'yii\base\Controller')) {
|
||||
$controller = Yii::createObject($className, [$id, $this]);
|
||||
return get_class($controller) === $className ? $controller : null;
|
||||
} elseif (YII_DEBUG) {
|
||||
throw new InvalidConfigException('Controller class must extend from \\yii\\base\\Controller.');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if class name or prefix is incorrect
|
||||
*
|
||||
* @param string $className
|
||||
* @param string $prefix
|
||||
* @return bool
|
||||
*/
|
||||
private function isIncorrectClassNameOrPrefix($className, $prefix)
|
||||
{
|
||||
if (!preg_match('%^[a-z][a-z0-9\\-_]*$%', $className)) {
|
||||
return true;
|
||||
}
|
||||
if ($prefix !== '' && !preg_match('%^[a-z0-9_/]+$%i', $prefix)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right before an action within this module is executed.
|
||||
*
|
||||
* The method will trigger the [[EVENT_BEFORE_ACTION]] event. The return value of the method
|
||||
* will determine whether the action should continue to run.
|
||||
*
|
||||
* In case the action should not run, the request should be handled inside of the `beforeAction` code
|
||||
* by either providing the necessary output or redirecting the request. Otherwise the response will be empty.
|
||||
*
|
||||
* If you override this method, your code should look like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function beforeAction($action)
|
||||
* {
|
||||
* if (!parent::beforeAction($action)) {
|
||||
* return false;
|
||||
* }
|
||||
*
|
||||
* // your custom code here
|
||||
*
|
||||
* return true; // or false to not run the action
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param Action $action the action to be executed.
|
||||
* @return bool whether the action should continue to be executed.
|
||||
*/
|
||||
public function beforeAction($action)
|
||||
{
|
||||
$event = new ActionEvent($action);
|
||||
$this->trigger(self::EVENT_BEFORE_ACTION, $event);
|
||||
return $event->isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right after an action within this module is executed.
|
||||
*
|
||||
* The method will trigger the [[EVENT_AFTER_ACTION]] event. The return value of the method
|
||||
* will be used as the action return value.
|
||||
*
|
||||
* If you override this method, your code should look like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function afterAction($action, $result)
|
||||
* {
|
||||
* $result = parent::afterAction($action, $result);
|
||||
* // your custom code here
|
||||
* return $result;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param Action $action the action just executed.
|
||||
* @param mixed $result the action return result.
|
||||
* @return mixed the processed action result.
|
||||
*/
|
||||
public function afterAction($action, $result)
|
||||
{
|
||||
$event = new ActionEvent($action);
|
||||
$event->result = $result;
|
||||
$this->trigger(self::EVENT_AFTER_ACTION, $event);
|
||||
return $event->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Since version 2.0.13, if a component isn't defined in the module, it will be looked up in the parent module.
|
||||
* The parent module may be the application.
|
||||
*/
|
||||
public function get($id, $throwException = true)
|
||||
{
|
||||
if (!isset($this->module)) {
|
||||
return parent::get($id, $throwException);
|
||||
}
|
||||
|
||||
$component = parent::get($id, false);
|
||||
if ($component === null) {
|
||||
$component = $this->module->get($id, $throwException);
|
||||
}
|
||||
return $component;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Since version 2.0.13, if a component isn't defined in the module, it will be looked up in the parent module.
|
||||
* The parent module may be the application.
|
||||
*/
|
||||
public function has($id, $checkInstance = false)
|
||||
{
|
||||
return parent::has($id, $checkInstance) || (isset($this->module) && $this->module->has($id, $checkInstance));
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/NotSupportedException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/NotSupportedException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* NotSupportedException represents an exception caused by accessing features that are not supported.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class NotSupportedException extends Exception
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Not Supported';
|
||||
}
|
||||
}
|
||||
30
vendor/yiisoft/yii2/base/Object.php
vendored
Normal file
30
vendor/yiisoft/yii2/base/Object.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Object is the base class that implements the *property* feature.
|
||||
*
|
||||
* It has been replaced by [[BaseObject]] in version 2.0.13 because `object` has become a reserved word which can not be
|
||||
* used as class name in PHP 7.2.
|
||||
*
|
||||
* Please refer to [[BaseObject]] for detailed documentation and to the
|
||||
* [UPGRADE notes](https://github.com/yiisoft/yii2/blob/2.0.13/framework/UPGRADE.md#upgrade-from-yii-2012)
|
||||
* on how to migrate your application to use [[BaseObject]] class to make your application compatible with PHP 7.2.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
* @deprecated since 2.0.13, the class name `Object` is invalid since PHP 7.2, use [[BaseObject]] instead.
|
||||
* @see https://wiki.php.net/rfc/object-typehint
|
||||
* @see https://github.com/yiisoft/yii2/issues/7936#issuecomment-315384669
|
||||
*/
|
||||
class Object extends BaseObject
|
||||
{
|
||||
}
|
||||
88
vendor/yiisoft/yii2/base/Request.php
vendored
Normal file
88
vendor/yiisoft/yii2/base/Request.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Request represents a request that is handled by an [[Application]].
|
||||
*
|
||||
* For more details and usage information on Request, see the [guide article on requests](guide:runtime-requests).
|
||||
*
|
||||
* @property bool $isConsoleRequest The value indicating whether the current request is made via console.
|
||||
* @property string $scriptFile Entry script file path (processed w/ realpath()).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class Request extends Component
|
||||
{
|
||||
private $_scriptFile;
|
||||
private $_isConsoleRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Resolves the current request into a route and the associated parameters.
|
||||
* @return array the first element is the route, and the second is the associated parameters.
|
||||
*/
|
||||
abstract public function resolve();
|
||||
|
||||
/**
|
||||
* Returns a value indicating whether the current request is made via command line.
|
||||
* @return bool the value indicating whether the current request is made via console
|
||||
*/
|
||||
public function getIsConsoleRequest()
|
||||
{
|
||||
return $this->_isConsoleRequest !== null ? $this->_isConsoleRequest : PHP_SAPI === 'cli';
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value indicating whether the current request is made via command line.
|
||||
* @param bool $value the value indicating whether the current request is made via command line
|
||||
*/
|
||||
public function setIsConsoleRequest($value)
|
||||
{
|
||||
$this->_isConsoleRequest = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns entry script file path.
|
||||
* @return string entry script file path (processed w/ realpath())
|
||||
* @throws InvalidConfigException if the entry script file path cannot be determined automatically.
|
||||
*/
|
||||
public function getScriptFile()
|
||||
{
|
||||
if ($this->_scriptFile === null) {
|
||||
if (isset($_SERVER['SCRIPT_FILENAME'])) {
|
||||
$this->setScriptFile($_SERVER['SCRIPT_FILENAME']);
|
||||
} else {
|
||||
throw new InvalidConfigException('Unable to determine the entry script file path.');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_scriptFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry script file path.
|
||||
* The entry script file path can normally be determined based on the `SCRIPT_FILENAME` SERVER variable.
|
||||
* However, for some server configurations, this may not be correct or feasible.
|
||||
* This setter is provided so that the entry script file path can be manually specified.
|
||||
* @param string $value the entry script file path. This can be either a file path or a [path alias](guide:concept-aliases).
|
||||
* @throws InvalidConfigException if the provided entry script file path is invalid.
|
||||
*/
|
||||
public function setScriptFile($value)
|
||||
{
|
||||
$scriptFile = realpath(Yii::getAlias($value));
|
||||
if ($scriptFile !== false && is_file($scriptFile)) {
|
||||
$this->_scriptFile = $scriptFile;
|
||||
} else {
|
||||
throw new InvalidConfigException('Unable to determine the entry script file path.');
|
||||
}
|
||||
}
|
||||
}
|
||||
46
vendor/yiisoft/yii2/base/Response.php
vendored
Normal file
46
vendor/yiisoft/yii2/base/Response.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* Response represents the response of an [[Application]] to a [[Request]].
|
||||
*
|
||||
* For more details and usage information on Response, see the [guide article on responses](guide:runtime-responses).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Response extends Component
|
||||
{
|
||||
/**
|
||||
* @var int the exit status. Exit statuses should be in the range 0 to 254.
|
||||
* The status 0 means the program terminates successfully.
|
||||
*/
|
||||
public $exitStatus = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Sends the response to client.
|
||||
*/
|
||||
public function send()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all existing output buffers.
|
||||
*/
|
||||
public function clearOutputBuffers()
|
||||
{
|
||||
// the following manual level counting is to deal with zlib.output_compression set to On
|
||||
for ($level = ob_get_level(); $level > 0; --$level) {
|
||||
if (!@ob_end_clean()) {
|
||||
ob_clean();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
761
vendor/yiisoft/yii2/base/Security.php
vendored
Normal file
761
vendor/yiisoft/yii2/base/Security.php
vendored
Normal file
@@ -0,0 +1,761 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\StringHelper;
|
||||
|
||||
/**
|
||||
* Security provides a set of methods to handle common security-related tasks.
|
||||
*
|
||||
* In particular, Security supports the following features:
|
||||
*
|
||||
* - Encryption/decryption: [[encryptByKey()]], [[decryptByKey()]], [[encryptByPassword()]] and [[decryptByPassword()]]
|
||||
* - Key derivation using standard algorithms: [[pbkdf2()]] and [[hkdf()]]
|
||||
* - Data tampering prevention: [[hashData()]] and [[validateData()]]
|
||||
* - Password validation: [[generatePasswordHash()]] and [[validatePassword()]]
|
||||
*
|
||||
* > Note: this class requires 'OpenSSL' PHP extension for random key/string generation on Windows and
|
||||
* for encryption/decryption on all platforms. For the highest security level PHP version >= 5.5.0 is recommended.
|
||||
*
|
||||
* For more details and usage information on Security, see the [guide article on security](guide:security-overview).
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @author Tom Worster <fsb@thefsb.org>
|
||||
* @author Klimov Paul <klimov.paul@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Security extends Component
|
||||
{
|
||||
/**
|
||||
* @var string The cipher to use for encryption and decryption.
|
||||
*/
|
||||
public $cipher = 'AES-128-CBC';
|
||||
/**
|
||||
* @var array[] Look-up table of block sizes and key sizes for each supported OpenSSL cipher.
|
||||
*
|
||||
* In each element, the key is one of the ciphers supported by OpenSSL (@see openssl_get_cipher_methods()).
|
||||
* The value is an array of two integers, the first is the cipher's block size in bytes and the second is
|
||||
* the key size in bytes.
|
||||
*
|
||||
* > Warning: All OpenSSL ciphers that we recommend are in the default value, i.e. AES in CBC mode.
|
||||
*
|
||||
* > Note: Yii's encryption protocol uses the same size for cipher key, HMAC signature key and key
|
||||
* derivation salt.
|
||||
*/
|
||||
public $allowedCiphers = [
|
||||
'AES-128-CBC' => [16, 16],
|
||||
'AES-192-CBC' => [16, 24],
|
||||
'AES-256-CBC' => [16, 32],
|
||||
];
|
||||
/**
|
||||
* @var string Hash algorithm for key derivation. Recommend sha256, sha384 or sha512.
|
||||
* @see [hash_algos()](http://php.net/manual/en/function.hash-algos.php)
|
||||
*/
|
||||
public $kdfHash = 'sha256';
|
||||
/**
|
||||
* @var string Hash algorithm for message authentication. Recommend sha256, sha384 or sha512.
|
||||
* @see [hash_algos()](http://php.net/manual/en/function.hash-algos.php)
|
||||
*/
|
||||
public $macHash = 'sha256';
|
||||
/**
|
||||
* @var string HKDF info value for derivation of message authentication key.
|
||||
* @see hkdf()
|
||||
*/
|
||||
public $authKeyInfo = 'AuthorizationKey';
|
||||
/**
|
||||
* @var int derivation iterations count.
|
||||
* Set as high as possible to hinder dictionary password attacks.
|
||||
*/
|
||||
public $derivationIterations = 100000;
|
||||
/**
|
||||
* @var string strategy, which should be used to generate password hash.
|
||||
* Available strategies:
|
||||
* - 'password_hash' - use of PHP `password_hash()` function with PASSWORD_DEFAULT algorithm.
|
||||
* This option is recommended, but it requires PHP version >= 5.5.0
|
||||
* - 'crypt' - use PHP `crypt()` function.
|
||||
* @deprecated since version 2.0.7, [[generatePasswordHash()]] ignores [[passwordHashStrategy]] and
|
||||
* uses `password_hash()` when available or `crypt()` when not.
|
||||
*/
|
||||
public $passwordHashStrategy;
|
||||
/**
|
||||
* @var int Default cost used for password hashing.
|
||||
* Allowed value is between 4 and 31.
|
||||
* @see generatePasswordHash()
|
||||
* @since 2.0.6
|
||||
*/
|
||||
public $passwordHashCost = 13;
|
||||
|
||||
|
||||
/**
|
||||
* Encrypts data using a password.
|
||||
* Derives keys for encryption and authentication from the password using PBKDF2 and a random salt,
|
||||
* which is deliberately slow to protect against dictionary attacks. Use [[encryptByKey()]] to
|
||||
* encrypt fast using a cryptographic key rather than a password. Key derivation time is
|
||||
* determined by [[$derivationIterations]], which should be set as high as possible.
|
||||
* The encrypted data includes a keyed message authentication code (MAC) so there is no need
|
||||
* to hash input or output data.
|
||||
* > Note: Avoid encrypting with passwords wherever possible. Nothing can protect against
|
||||
* poor-quality or compromised passwords.
|
||||
* @param string $data the data to encrypt
|
||||
* @param string $password the password to use for encryption
|
||||
* @return string the encrypted data
|
||||
* @see decryptByPassword()
|
||||
* @see encryptByKey()
|
||||
*/
|
||||
public function encryptByPassword($data, $password)
|
||||
{
|
||||
return $this->encrypt($data, true, $password, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts data using a cryptographic key.
|
||||
* Derives keys for encryption and authentication from the input key using HKDF and a random salt,
|
||||
* which is very fast relative to [[encryptByPassword()]]. The input key must be properly
|
||||
* random -- use [[generateRandomKey()]] to generate keys.
|
||||
* The encrypted data includes a keyed message authentication code (MAC) so there is no need
|
||||
* to hash input or output data.
|
||||
* @param string $data the data to encrypt
|
||||
* @param string $inputKey the input to use for encryption and authentication
|
||||
* @param string $info optional context and application specific information, see [[hkdf()]]
|
||||
* @return string the encrypted data
|
||||
* @see decryptByKey()
|
||||
* @see encryptByPassword()
|
||||
*/
|
||||
public function encryptByKey($data, $inputKey, $info = null)
|
||||
{
|
||||
return $this->encrypt($data, false, $inputKey, $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies and decrypts data encrypted with [[encryptByPassword()]].
|
||||
* @param string $data the encrypted data to decrypt
|
||||
* @param string $password the password to use for decryption
|
||||
* @return bool|string the decrypted data or false on authentication failure
|
||||
* @see encryptByPassword()
|
||||
*/
|
||||
public function decryptByPassword($data, $password)
|
||||
{
|
||||
return $this->decrypt($data, true, $password, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies and decrypts data encrypted with [[encryptByKey()]].
|
||||
* @param string $data the encrypted data to decrypt
|
||||
* @param string $inputKey the input to use for encryption and authentication
|
||||
* @param string $info optional context and application specific information, see [[hkdf()]]
|
||||
* @return bool|string the decrypted data or false on authentication failure
|
||||
* @see encryptByKey()
|
||||
*/
|
||||
public function decryptByKey($data, $inputKey, $info = null)
|
||||
{
|
||||
return $this->decrypt($data, false, $inputKey, $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts data.
|
||||
*
|
||||
* @param string $data data to be encrypted
|
||||
* @param bool $passwordBased set true to use password-based key derivation
|
||||
* @param string $secret the encryption password or key
|
||||
* @param string|null $info context/application specific information, e.g. a user ID
|
||||
* See [RFC 5869 Section 3.2](https://tools.ietf.org/html/rfc5869#section-3.2) for more details.
|
||||
*
|
||||
* @return string the encrypted data
|
||||
* @throws InvalidConfigException on OpenSSL not loaded
|
||||
* @throws Exception on OpenSSL error
|
||||
* @see decrypt()
|
||||
*/
|
||||
protected function encrypt($data, $passwordBased, $secret, $info)
|
||||
{
|
||||
if (!extension_loaded('openssl')) {
|
||||
throw new InvalidConfigException('Encryption requires the OpenSSL PHP extension');
|
||||
}
|
||||
if (!isset($this->allowedCiphers[$this->cipher][0], $this->allowedCiphers[$this->cipher][1])) {
|
||||
throw new InvalidConfigException($this->cipher . ' is not an allowed cipher');
|
||||
}
|
||||
|
||||
list($blockSize, $keySize) = $this->allowedCiphers[$this->cipher];
|
||||
|
||||
$keySalt = $this->generateRandomKey($keySize);
|
||||
if ($passwordBased) {
|
||||
$key = $this->pbkdf2($this->kdfHash, $secret, $keySalt, $this->derivationIterations, $keySize);
|
||||
} else {
|
||||
$key = $this->hkdf($this->kdfHash, $secret, $keySalt, $info, $keySize);
|
||||
}
|
||||
|
||||
$iv = $this->generateRandomKey($blockSize);
|
||||
|
||||
$encrypted = openssl_encrypt($data, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
|
||||
if ($encrypted === false) {
|
||||
throw new \yii\base\Exception('OpenSSL failure on encryption: ' . openssl_error_string());
|
||||
}
|
||||
|
||||
$authKey = $this->hkdf($this->kdfHash, $key, null, $this->authKeyInfo, $keySize);
|
||||
$hashed = $this->hashData($iv . $encrypted, $authKey);
|
||||
|
||||
/*
|
||||
* Output: [keySalt][MAC][IV][ciphertext]
|
||||
* - keySalt is KEY_SIZE bytes long
|
||||
* - MAC: message authentication code, length same as the output of MAC_HASH
|
||||
* - IV: initialization vector, length $blockSize
|
||||
*/
|
||||
return $keySalt . $hashed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts data.
|
||||
*
|
||||
* @param string $data encrypted data to be decrypted.
|
||||
* @param bool $passwordBased set true to use password-based key derivation
|
||||
* @param string $secret the decryption password or key
|
||||
* @param string|null $info context/application specific information, @see encrypt()
|
||||
*
|
||||
* @return bool|string the decrypted data or false on authentication failure
|
||||
* @throws InvalidConfigException on OpenSSL not loaded
|
||||
* @throws Exception on OpenSSL error
|
||||
* @see encrypt()
|
||||
*/
|
||||
protected function decrypt($data, $passwordBased, $secret, $info)
|
||||
{
|
||||
if (!extension_loaded('openssl')) {
|
||||
throw new InvalidConfigException('Encryption requires the OpenSSL PHP extension');
|
||||
}
|
||||
if (!isset($this->allowedCiphers[$this->cipher][0], $this->allowedCiphers[$this->cipher][1])) {
|
||||
throw new InvalidConfigException($this->cipher . ' is not an allowed cipher');
|
||||
}
|
||||
|
||||
list($blockSize, $keySize) = $this->allowedCiphers[$this->cipher];
|
||||
|
||||
$keySalt = StringHelper::byteSubstr($data, 0, $keySize);
|
||||
if ($passwordBased) {
|
||||
$key = $this->pbkdf2($this->kdfHash, $secret, $keySalt, $this->derivationIterations, $keySize);
|
||||
} else {
|
||||
$key = $this->hkdf($this->kdfHash, $secret, $keySalt, $info, $keySize);
|
||||
}
|
||||
|
||||
$authKey = $this->hkdf($this->kdfHash, $key, null, $this->authKeyInfo, $keySize);
|
||||
$data = $this->validateData(StringHelper::byteSubstr($data, $keySize, null), $authKey);
|
||||
if ($data === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$iv = StringHelper::byteSubstr($data, 0, $blockSize);
|
||||
$encrypted = StringHelper::byteSubstr($data, $blockSize, null);
|
||||
|
||||
$decrypted = openssl_decrypt($encrypted, $this->cipher, $key, OPENSSL_RAW_DATA, $iv);
|
||||
if ($decrypted === false) {
|
||||
throw new \yii\base\Exception('OpenSSL failure on decryption: ' . openssl_error_string());
|
||||
}
|
||||
|
||||
return $decrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a key from the given input key using the standard HKDF algorithm.
|
||||
* Implements HKDF specified in [RFC 5869](https://tools.ietf.org/html/rfc5869).
|
||||
* Recommend use one of the SHA-2 hash algorithms: sha224, sha256, sha384 or sha512.
|
||||
* @param string $algo a hash algorithm supported by `hash_hmac()`, e.g. 'SHA-256'
|
||||
* @param string $inputKey the source key
|
||||
* @param string $salt the random salt
|
||||
* @param string $info optional info to bind the derived key material to application-
|
||||
* and context-specific information, e.g. a user ID or API version, see
|
||||
* [RFC 5869](https://tools.ietf.org/html/rfc5869)
|
||||
* @param int $length length of the output key in bytes. If 0, the output key is
|
||||
* the length of the hash algorithm output.
|
||||
* @throws InvalidArgumentException when HMAC generation fails.
|
||||
* @return string the derived key
|
||||
*/
|
||||
public function hkdf($algo, $inputKey, $salt = null, $info = null, $length = 0)
|
||||
{
|
||||
if (function_exists('hash_hkdf')) {
|
||||
$outputKey = hash_hkdf($algo, $inputKey, $length, $info, $salt);
|
||||
if ($outputKey === false) {
|
||||
throw new InvalidArgumentException('Invalid parameters to hash_hkdf()');
|
||||
}
|
||||
|
||||
return $outputKey;
|
||||
}
|
||||
|
||||
$test = @hash_hmac($algo, '', '', true);
|
||||
if (!$test) {
|
||||
throw new InvalidArgumentException('Failed to generate HMAC with hash algorithm: ' . $algo);
|
||||
}
|
||||
$hashLength = StringHelper::byteLength($test);
|
||||
if (is_string($length) && preg_match('{^\d{1,16}$}', $length)) {
|
||||
$length = (int) $length;
|
||||
}
|
||||
if (!is_int($length) || $length < 0 || $length > 255 * $hashLength) {
|
||||
throw new InvalidArgumentException('Invalid length');
|
||||
}
|
||||
$blocks = $length !== 0 ? ceil($length / $hashLength) : 1;
|
||||
|
||||
if ($salt === null) {
|
||||
$salt = str_repeat("\0", $hashLength);
|
||||
}
|
||||
$prKey = hash_hmac($algo, $inputKey, $salt, true);
|
||||
|
||||
$hmac = '';
|
||||
$outputKey = '';
|
||||
for ($i = 1; $i <= $blocks; $i++) {
|
||||
$hmac = hash_hmac($algo, $hmac . $info . chr($i), $prKey, true);
|
||||
$outputKey .= $hmac;
|
||||
}
|
||||
|
||||
if ($length !== 0) {
|
||||
$outputKey = StringHelper::byteSubstr($outputKey, 0, $length);
|
||||
}
|
||||
|
||||
return $outputKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives a key from the given password using the standard PBKDF2 algorithm.
|
||||
* Implements HKDF2 specified in [RFC 2898](http://tools.ietf.org/html/rfc2898#section-5.2)
|
||||
* Recommend use one of the SHA-2 hash algorithms: sha224, sha256, sha384 or sha512.
|
||||
* @param string $algo a hash algorithm supported by `hash_hmac()`, e.g. 'SHA-256'
|
||||
* @param string $password the source password
|
||||
* @param string $salt the random salt
|
||||
* @param int $iterations the number of iterations of the hash algorithm. Set as high as
|
||||
* possible to hinder dictionary password attacks.
|
||||
* @param int $length length of the output key in bytes. If 0, the output key is
|
||||
* the length of the hash algorithm output.
|
||||
* @return string the derived key
|
||||
* @throws InvalidArgumentException when hash generation fails due to invalid params given.
|
||||
*/
|
||||
public function pbkdf2($algo, $password, $salt, $iterations, $length = 0)
|
||||
{
|
||||
if (function_exists('hash_pbkdf2')) {
|
||||
$outputKey = hash_pbkdf2($algo, $password, $salt, $iterations, $length, true);
|
||||
if ($outputKey === false) {
|
||||
throw new InvalidArgumentException('Invalid parameters to hash_pbkdf2()');
|
||||
}
|
||||
|
||||
return $outputKey;
|
||||
}
|
||||
|
||||
// todo: is there a nice way to reduce the code repetition in hkdf() and pbkdf2()?
|
||||
$test = @hash_hmac($algo, '', '', true);
|
||||
if (!$test) {
|
||||
throw new InvalidArgumentException('Failed to generate HMAC with hash algorithm: ' . $algo);
|
||||
}
|
||||
if (is_string($iterations) && preg_match('{^\d{1,16}$}', $iterations)) {
|
||||
$iterations = (int) $iterations;
|
||||
}
|
||||
if (!is_int($iterations) || $iterations < 1) {
|
||||
throw new InvalidArgumentException('Invalid iterations');
|
||||
}
|
||||
if (is_string($length) && preg_match('{^\d{1,16}$}', $length)) {
|
||||
$length = (int) $length;
|
||||
}
|
||||
if (!is_int($length) || $length < 0) {
|
||||
throw new InvalidArgumentException('Invalid length');
|
||||
}
|
||||
$hashLength = StringHelper::byteLength($test);
|
||||
$blocks = $length !== 0 ? ceil($length / $hashLength) : 1;
|
||||
|
||||
$outputKey = '';
|
||||
for ($j = 1; $j <= $blocks; $j++) {
|
||||
$hmac = hash_hmac($algo, $salt . pack('N', $j), $password, true);
|
||||
$xorsum = $hmac;
|
||||
for ($i = 1; $i < $iterations; $i++) {
|
||||
$hmac = hash_hmac($algo, $hmac, $password, true);
|
||||
$xorsum ^= $hmac;
|
||||
}
|
||||
$outputKey .= $xorsum;
|
||||
}
|
||||
|
||||
if ($length !== 0) {
|
||||
$outputKey = StringHelper::byteSubstr($outputKey, 0, $length);
|
||||
}
|
||||
|
||||
return $outputKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prefixes data with a keyed hash value so that it can later be detected if it is tampered.
|
||||
* There is no need to hash inputs or outputs of [[encryptByKey()]] or [[encryptByPassword()]]
|
||||
* as those methods perform the task.
|
||||
* @param string $data the data to be protected
|
||||
* @param string $key the secret key to be used for generating hash. Should be a secure
|
||||
* cryptographic key.
|
||||
* @param bool $rawHash whether the generated hash value is in raw binary format. If false, lowercase
|
||||
* hex digits will be generated.
|
||||
* @return string the data prefixed with the keyed hash
|
||||
* @throws InvalidConfigException when HMAC generation fails.
|
||||
* @see validateData()
|
||||
* @see generateRandomKey()
|
||||
* @see hkdf()
|
||||
* @see pbkdf2()
|
||||
*/
|
||||
public function hashData($data, $key, $rawHash = false)
|
||||
{
|
||||
$hash = hash_hmac($this->macHash, $data, $key, $rawHash);
|
||||
if (!$hash) {
|
||||
throw new InvalidConfigException('Failed to generate HMAC with hash algorithm: ' . $this->macHash);
|
||||
}
|
||||
|
||||
return $hash . $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates if the given data is tampered.
|
||||
* @param string $data the data to be validated. The data must be previously
|
||||
* generated by [[hashData()]].
|
||||
* @param string $key the secret key that was previously used to generate the hash for the data in [[hashData()]].
|
||||
* function to see the supported hashing algorithms on your system. This must be the same
|
||||
* as the value passed to [[hashData()]] when generating the hash for the data.
|
||||
* @param bool $rawHash this should take the same value as when you generate the data using [[hashData()]].
|
||||
* It indicates whether the hash value in the data is in binary format. If false, it means the hash value consists
|
||||
* of lowercase hex digits only.
|
||||
* hex digits will be generated.
|
||||
* @return string|false the real data with the hash stripped off. False if the data is tampered.
|
||||
* @throws InvalidConfigException when HMAC generation fails.
|
||||
* @see hashData()
|
||||
*/
|
||||
public function validateData($data, $key, $rawHash = false)
|
||||
{
|
||||
$test = @hash_hmac($this->macHash, '', '', $rawHash);
|
||||
if (!$test) {
|
||||
throw new InvalidConfigException('Failed to generate HMAC with hash algorithm: ' . $this->macHash);
|
||||
}
|
||||
$hashLength = StringHelper::byteLength($test);
|
||||
if (StringHelper::byteLength($data) >= $hashLength) {
|
||||
$hash = StringHelper::byteSubstr($data, 0, $hashLength);
|
||||
$pureData = StringHelper::byteSubstr($data, $hashLength, null);
|
||||
|
||||
$calculatedHash = hash_hmac($this->macHash, $pureData, $key, $rawHash);
|
||||
|
||||
if ($this->compareString($hash, $calculatedHash)) {
|
||||
return $pureData;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private $_useLibreSSL;
|
||||
private $_randomFile;
|
||||
|
||||
/**
|
||||
* Generates specified number of random bytes.
|
||||
* Note that output may not be ASCII.
|
||||
* @see generateRandomString() if you need a string.
|
||||
*
|
||||
* @param int $length the number of bytes to generate
|
||||
* @return string the generated random bytes
|
||||
* @throws InvalidArgumentException if wrong length is specified
|
||||
* @throws Exception on failure.
|
||||
*/
|
||||
public function generateRandomKey($length = 32)
|
||||
{
|
||||
if (!is_int($length)) {
|
||||
throw new InvalidArgumentException('First parameter ($length) must be an integer');
|
||||
}
|
||||
|
||||
if ($length < 1) {
|
||||
throw new InvalidArgumentException('First parameter ($length) must be greater than 0');
|
||||
}
|
||||
|
||||
// always use random_bytes() if it is available
|
||||
if (function_exists('random_bytes')) {
|
||||
return random_bytes($length);
|
||||
}
|
||||
|
||||
// The recent LibreSSL RNGs are faster and likely better than /dev/urandom.
|
||||
// Parse OPENSSL_VERSION_TEXT because OPENSSL_VERSION_NUMBER is no use for LibreSSL.
|
||||
// https://bugs.php.net/bug.php?id=71143
|
||||
if ($this->_useLibreSSL === null) {
|
||||
$this->_useLibreSSL = defined('OPENSSL_VERSION_TEXT')
|
||||
&& preg_match('{^LibreSSL (\d\d?)\.(\d\d?)\.(\d\d?)$}', OPENSSL_VERSION_TEXT, $matches)
|
||||
&& (10000 * $matches[1]) + (100 * $matches[2]) + $matches[3] >= 20105;
|
||||
}
|
||||
|
||||
// Since 5.4.0, openssl_random_pseudo_bytes() reads from CryptGenRandom on Windows instead
|
||||
// of using OpenSSL library. LibreSSL is OK everywhere but don't use OpenSSL on non-Windows.
|
||||
if (function_exists('openssl_random_pseudo_bytes')
|
||||
&& ($this->_useLibreSSL
|
||||
|| (
|
||||
DIRECTORY_SEPARATOR !== '/'
|
||||
&& substr_compare(PHP_OS, 'win', 0, 3, true) === 0
|
||||
))
|
||||
) {
|
||||
$key = openssl_random_pseudo_bytes($length, $cryptoStrong);
|
||||
if ($cryptoStrong === false) {
|
||||
throw new Exception(
|
||||
'openssl_random_pseudo_bytes() set $crypto_strong false. Your PHP setup is insecure.'
|
||||
);
|
||||
}
|
||||
if ($key !== false && StringHelper::byteLength($key) === $length) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
// mcrypt_create_iv() does not use libmcrypt. Since PHP 5.3.7 it directly reads
|
||||
// CryptGenRandom on Windows. Elsewhere it directly reads /dev/urandom.
|
||||
if (function_exists('mcrypt_create_iv')) {
|
||||
$key = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
|
||||
if (StringHelper::byteLength($key) === $length) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
// If not on Windows, try to open a random device.
|
||||
if ($this->_randomFile === null && DIRECTORY_SEPARATOR === '/') {
|
||||
// urandom is a symlink to random on FreeBSD.
|
||||
$device = PHP_OS === 'FreeBSD' ? '/dev/random' : '/dev/urandom';
|
||||
// Check random device for special character device protection mode. Use lstat()
|
||||
// instead of stat() in case an attacker arranges a symlink to a fake device.
|
||||
$lstat = @lstat($device);
|
||||
if ($lstat !== false && ($lstat['mode'] & 0170000) === 020000) {
|
||||
$this->_randomFile = fopen($device, 'rb') ?: null;
|
||||
|
||||
if (is_resource($this->_randomFile)) {
|
||||
// Reduce PHP stream buffer from default 8192 bytes to optimize data
|
||||
// transfer from the random device for smaller values of $length.
|
||||
// This also helps to keep future randoms out of user memory space.
|
||||
$bufferSize = 8;
|
||||
|
||||
if (function_exists('stream_set_read_buffer')) {
|
||||
stream_set_read_buffer($this->_randomFile, $bufferSize);
|
||||
}
|
||||
// stream_set_read_buffer() isn't implemented on HHVM
|
||||
if (function_exists('stream_set_chunk_size')) {
|
||||
stream_set_chunk_size($this->_randomFile, $bufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_resource($this->_randomFile)) {
|
||||
$buffer = '';
|
||||
$stillNeed = $length;
|
||||
while ($stillNeed > 0) {
|
||||
$someBytes = fread($this->_randomFile, $stillNeed);
|
||||
if ($someBytes === false) {
|
||||
break;
|
||||
}
|
||||
$buffer .= $someBytes;
|
||||
$stillNeed -= StringHelper::byteLength($someBytes);
|
||||
if ($stillNeed === 0) {
|
||||
// Leaving file pointer open in order to make next generation faster by reusing it.
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
fclose($this->_randomFile);
|
||||
$this->_randomFile = null;
|
||||
}
|
||||
|
||||
throw new Exception('Unable to generate a random key');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random string of specified length.
|
||||
* The string generated matches [A-Za-z0-9_-]+ and is transparent to URL-encoding.
|
||||
*
|
||||
* @param int $length the length of the key in characters
|
||||
* @return string the generated random key
|
||||
* @throws Exception on failure.
|
||||
*/
|
||||
public function generateRandomString($length = 32)
|
||||
{
|
||||
if (!is_int($length)) {
|
||||
throw new InvalidArgumentException('First parameter ($length) must be an integer');
|
||||
}
|
||||
|
||||
if ($length < 1) {
|
||||
throw new InvalidArgumentException('First parameter ($length) must be greater than 0');
|
||||
}
|
||||
|
||||
$bytes = $this->generateRandomKey($length);
|
||||
return substr(StringHelper::base64UrlEncode($bytes), 0, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a secure hash from a password and a random salt.
|
||||
*
|
||||
* The generated hash can be stored in database.
|
||||
* Later when a password needs to be validated, the hash can be fetched and passed
|
||||
* to [[validatePassword()]]. For example,
|
||||
*
|
||||
* ```php
|
||||
* // generates the hash (usually done during user registration or when the password is changed)
|
||||
* $hash = Yii::$app->getSecurity()->generatePasswordHash($password);
|
||||
* // ...save $hash in database...
|
||||
*
|
||||
* // during login, validate if the password entered is correct using $hash fetched from database
|
||||
* if (Yii::$app->getSecurity()->validatePassword($password, $hash)) {
|
||||
* // password is good
|
||||
* } else {
|
||||
* // password is bad
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param string $password The password to be hashed.
|
||||
* @param int $cost Cost parameter used by the Blowfish hash algorithm.
|
||||
* The higher the value of cost,
|
||||
* the longer it takes to generate the hash and to verify a password against it. Higher cost
|
||||
* therefore slows down a brute-force attack. For best protection against brute-force attacks,
|
||||
* set it to the highest value that is tolerable on production servers. The time taken to
|
||||
* compute the hash doubles for every increment by one of $cost.
|
||||
* @return string The password hash string. When [[passwordHashStrategy]] is set to 'crypt',
|
||||
* the output is always 60 ASCII characters, when set to 'password_hash' the output length
|
||||
* might increase in future versions of PHP (http://php.net/manual/en/function.password-hash.php)
|
||||
* @throws Exception on bad password parameter or cost parameter.
|
||||
* @see validatePassword()
|
||||
*/
|
||||
public function generatePasswordHash($password, $cost = null)
|
||||
{
|
||||
if ($cost === null) {
|
||||
$cost = $this->passwordHashCost;
|
||||
}
|
||||
|
||||
if (function_exists('password_hash')) {
|
||||
/* @noinspection PhpUndefinedConstantInspection */
|
||||
return password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
|
||||
}
|
||||
|
||||
$salt = $this->generateSalt($cost);
|
||||
$hash = crypt($password, $salt);
|
||||
// strlen() is safe since crypt() returns only ascii
|
||||
if (!is_string($hash) || strlen($hash) !== 60) {
|
||||
throw new Exception('Unknown error occurred while generating hash.');
|
||||
}
|
||||
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies a password against a hash.
|
||||
* @param string $password The password to verify.
|
||||
* @param string $hash The hash to verify the password against.
|
||||
* @return bool whether the password is correct.
|
||||
* @throws InvalidArgumentException on bad password/hash parameters or if crypt() with Blowfish hash is not available.
|
||||
* @see generatePasswordHash()
|
||||
*/
|
||||
public function validatePassword($password, $hash)
|
||||
{
|
||||
if (!is_string($password) || $password === '') {
|
||||
throw new InvalidArgumentException('Password must be a string and cannot be empty.');
|
||||
}
|
||||
|
||||
if (!preg_match('/^\$2[axy]\$(\d\d)\$[\.\/0-9A-Za-z]{22}/', $hash, $matches)
|
||||
|| $matches[1] < 4
|
||||
|| $matches[1] > 30
|
||||
) {
|
||||
throw new InvalidArgumentException('Hash is invalid.');
|
||||
}
|
||||
|
||||
if (function_exists('password_verify')) {
|
||||
return password_verify($password, $hash);
|
||||
}
|
||||
|
||||
$test = crypt($password, $hash);
|
||||
$n = strlen($test);
|
||||
if ($n !== 60) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->compareString($test, $hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a salt that can be used to generate a password hash.
|
||||
*
|
||||
* The PHP [crypt()](http://php.net/manual/en/function.crypt.php) built-in function
|
||||
* requires, for the Blowfish hash algorithm, a salt string in a specific format:
|
||||
* "$2a$", "$2x$" or "$2y$", a two digit cost parameter, "$", and 22 characters
|
||||
* from the alphabet "./0-9A-Za-z".
|
||||
*
|
||||
* @param int $cost the cost parameter
|
||||
* @return string the random salt value.
|
||||
* @throws InvalidArgumentException if the cost parameter is out of the range of 4 to 31.
|
||||
*/
|
||||
protected function generateSalt($cost = 13)
|
||||
{
|
||||
$cost = (int) $cost;
|
||||
if ($cost < 4 || $cost > 31) {
|
||||
throw new InvalidArgumentException('Cost must be between 4 and 31.');
|
||||
}
|
||||
|
||||
// Get a 20-byte random string
|
||||
$rand = $this->generateRandomKey(20);
|
||||
// Form the prefix that specifies Blowfish (bcrypt) algorithm and cost parameter.
|
||||
$salt = sprintf('$2y$%02d$', $cost);
|
||||
// Append the random salt data in the required base64 format.
|
||||
$salt .= str_replace('+', '.', substr(base64_encode($rand), 0, 22));
|
||||
|
||||
return $salt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs string comparison using timing attack resistant approach.
|
||||
* @see http://codereview.stackexchange.com/questions/13512
|
||||
* @param string $expected string to compare.
|
||||
* @param string $actual user-supplied string.
|
||||
* @return bool whether strings are equal.
|
||||
*/
|
||||
public function compareString($expected, $actual)
|
||||
{
|
||||
if (!is_string($expected)) {
|
||||
throw new InvalidArgumentException('Expected expected value to be a string, ' . gettype($expected) . ' given.');
|
||||
}
|
||||
|
||||
if (!is_string($actual)) {
|
||||
throw new InvalidArgumentException('Expected actual value to be a string, ' . gettype($actual) . ' given.');
|
||||
}
|
||||
|
||||
if (function_exists('hash_equals')) {
|
||||
return hash_equals($expected, $actual);
|
||||
}
|
||||
|
||||
$expected .= "\0";
|
||||
$actual .= "\0";
|
||||
$expectedLength = StringHelper::byteLength($expected);
|
||||
$actualLength = StringHelper::byteLength($actual);
|
||||
$diff = $expectedLength - $actualLength;
|
||||
for ($i = 0; $i < $actualLength; $i++) {
|
||||
$diff |= (ord($actual[$i]) ^ ord($expected[$i % $expectedLength]));
|
||||
}
|
||||
|
||||
return $diff === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Masks a token to make it uncompressible.
|
||||
* Applies a random mask to the token and prepends the mask used to the result making the string always unique.
|
||||
* Used to mitigate BREACH attack by randomizing how token is outputted on each request.
|
||||
* @param string $token An unmasked token.
|
||||
* @return string A masked token.
|
||||
* @since 2.0.12
|
||||
*/
|
||||
public function maskToken($token)
|
||||
{
|
||||
// The number of bytes in a mask is always equal to the number of bytes in a token.
|
||||
$mask = $this->generateRandomKey(StringHelper::byteLength($token));
|
||||
return StringHelper::base64UrlEncode($mask . ($mask ^ $token));
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmasks a token previously masked by `maskToken`.
|
||||
* @param string $maskedToken A masked token.
|
||||
* @return string An unmasked token, or an empty string in case of token format is invalid.
|
||||
* @since 2.0.12
|
||||
*/
|
||||
public function unmaskToken($maskedToken)
|
||||
{
|
||||
$decoded = StringHelper::base64UrlDecode($maskedToken);
|
||||
$length = StringHelper::byteLength($decoded) / 2;
|
||||
// Check if the masked token has an even length.
|
||||
if (!is_int($length)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return StringHelper::byteSubstr($decoded, $length, $length) ^ StringHelper::byteSubstr($decoded, 0, $length);
|
||||
}
|
||||
}
|
||||
30
vendor/yiisoft/yii2/base/StaticInstanceInterface.php
vendored
Normal file
30
vendor/yiisoft/yii2/base/StaticInstanceInterface.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* StaticInstanceInterface is the interface for providing static instances to classes,
|
||||
* which can be used to obtain class meta information that can not be expressed in static methods.
|
||||
* For example: adjustments made by DI or behaviors reveal only at object level, but might be needed
|
||||
* at class (static) level as well.
|
||||
*
|
||||
* To implement the [[instance()]] method you may use [[StaticInstanceTrait]].
|
||||
*
|
||||
* @author Paul Klimov <klimov.paul@gmail.com>
|
||||
* @since 2.0.13
|
||||
* @see StaticInstanceTrait
|
||||
*/
|
||||
interface StaticInstanceInterface
|
||||
{
|
||||
/**
|
||||
* Returns static class instance, which can be used to obtain meta information.
|
||||
* @param bool $refresh whether to re-create static instance even, if it is already cached.
|
||||
* @return static class instance.
|
||||
*/
|
||||
public static function instance($refresh = false);
|
||||
}
|
||||
41
vendor/yiisoft/yii2/base/StaticInstanceTrait.php
vendored
Normal file
41
vendor/yiisoft/yii2/base/StaticInstanceTrait.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* StaticInstanceTrait provides methods to satisfy [[StaticInstanceInterface]] interface.
|
||||
*
|
||||
* @see StaticInstanceInterface
|
||||
*
|
||||
* @author Paul Klimov <klimov.paul@gmail.com>
|
||||
* @since 2.0.13
|
||||
*/
|
||||
trait StaticInstanceTrait
|
||||
{
|
||||
/**
|
||||
* @var static[] static instances in format: `[className => object]`
|
||||
*/
|
||||
private static $_instances = [];
|
||||
|
||||
|
||||
/**
|
||||
* Returns static class instance, which can be used to obtain meta information.
|
||||
* @param bool $refresh whether to re-create static instance even, if it is already cached.
|
||||
* @return static class instance.
|
||||
*/
|
||||
public static function instance($refresh = false)
|
||||
{
|
||||
$className = get_called_class();
|
||||
if ($refresh || !isset(self::$_instances[$className])) {
|
||||
self::$_instances[$className] = Yii::createObject($className);
|
||||
}
|
||||
return self::$_instances[$className];
|
||||
}
|
||||
}
|
||||
189
vendor/yiisoft/yii2/base/Theme.php
vendored
Normal file
189
vendor/yiisoft/yii2/base/Theme.php
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\FileHelper;
|
||||
|
||||
/**
|
||||
* Theme represents an application theme.
|
||||
*
|
||||
* When [[View]] renders a view file, it will check the [[View::theme|active theme]]
|
||||
* to see if there is a themed version of the view file exists. If so, the themed version will be rendered instead.
|
||||
*
|
||||
* A theme is a directory consisting of view files which are meant to replace their non-themed counterparts.
|
||||
*
|
||||
* Theme uses [[pathMap]] to achieve the view file replacement:
|
||||
*
|
||||
* 1. It first looks for a key in [[pathMap]] that is a substring of the given view file path;
|
||||
* 2. If such a key exists, the corresponding value will be used to replace the corresponding part
|
||||
* in the view file path;
|
||||
* 3. It will then check if the updated view file exists or not. If so, that file will be used
|
||||
* to replace the original view file.
|
||||
* 4. If Step 2 or 3 fails, the original view file will be used.
|
||||
*
|
||||
* For example, if [[pathMap]] is `['@app/views' => '@app/themes/basic']`,
|
||||
* then the themed version for a view file `@app/views/site/index.php` will be
|
||||
* `@app/themes/basic/site/index.php`.
|
||||
*
|
||||
* It is possible to map a single path to multiple paths. For example,
|
||||
*
|
||||
* ```php
|
||||
* 'pathMap' => [
|
||||
* '@app/views' => [
|
||||
* '@app/themes/christmas',
|
||||
* '@app/themes/basic',
|
||||
* ],
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* In this case, the themed version could be either `@app/themes/christmas/site/index.php` or
|
||||
* `@app/themes/basic/site/index.php`. The former has precedence over the latter if both files exist.
|
||||
*
|
||||
* To use a theme, you should configure the [[View::theme|theme]] property of the "view" application
|
||||
* component like the following:
|
||||
*
|
||||
* ```php
|
||||
* 'view' => [
|
||||
* 'theme' => [
|
||||
* 'basePath' => '@app/themes/basic',
|
||||
* 'baseUrl' => '@web/themes/basic',
|
||||
* ],
|
||||
* ],
|
||||
* ```
|
||||
*
|
||||
* The above configuration specifies a theme located under the "themes/basic" directory of the Web folder
|
||||
* that contains the entry script of the application. If your theme is designed to handle modules,
|
||||
* you may configure the [[pathMap]] property like described above.
|
||||
*
|
||||
* For more details and usage information on Theme, see the [guide article on theming](guide:output-theming).
|
||||
*
|
||||
* @property string $basePath The root path of this theme. All resources of this theme are located under this
|
||||
* directory.
|
||||
* @property string $baseUrl The base URL (without ending slash) for this theme. All resources of this theme
|
||||
* are considered to be under this base URL.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Theme extends Component
|
||||
{
|
||||
/**
|
||||
* @var array the mapping between view directories and their corresponding themed versions.
|
||||
* This property is used by [[applyTo()]] when a view is trying to apply the theme.
|
||||
* [Path aliases](guide:concept-aliases) can be used when specifying directories.
|
||||
* If this property is empty or not set, a mapping [[Application::basePath]] to [[basePath]] will be used.
|
||||
*/
|
||||
public $pathMap;
|
||||
|
||||
private $_baseUrl;
|
||||
|
||||
|
||||
/**
|
||||
* @return string the base URL (without ending slash) for this theme. All resources of this theme are considered
|
||||
* to be under this base URL.
|
||||
*/
|
||||
public function getBaseUrl()
|
||||
{
|
||||
return $this->_baseUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url the base URL or [path alias](guide:concept-aliases) for this theme. All resources of this theme are considered
|
||||
* to be under this base URL.
|
||||
*/
|
||||
public function setBaseUrl($url)
|
||||
{
|
||||
$this->_baseUrl = $url === null ? null : rtrim(Yii::getAlias($url), '/');
|
||||
}
|
||||
|
||||
private $_basePath;
|
||||
|
||||
/**
|
||||
* @return string the root path of this theme. All resources of this theme are located under this directory.
|
||||
* @see pathMap
|
||||
*/
|
||||
public function getBasePath()
|
||||
{
|
||||
return $this->_basePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path the root path or [path alias](guide:concept-aliases) of this theme. All resources of this theme are located
|
||||
* under this directory.
|
||||
* @see pathMap
|
||||
*/
|
||||
public function setBasePath($path)
|
||||
{
|
||||
$this->_basePath = Yii::getAlias($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a file to a themed file if possible.
|
||||
* If there is no corresponding themed file, the original file will be returned.
|
||||
* @param string $path the file to be themed
|
||||
* @return string the themed file, or the original file if the themed version is not available.
|
||||
* @throws InvalidConfigException if [[basePath]] is not set
|
||||
*/
|
||||
public function applyTo($path)
|
||||
{
|
||||
$pathMap = $this->pathMap;
|
||||
if (empty($pathMap)) {
|
||||
if (($basePath = $this->getBasePath()) === null) {
|
||||
throw new InvalidConfigException('The "basePath" property must be set.');
|
||||
}
|
||||
$pathMap = [Yii::$app->getBasePath() => [$basePath]];
|
||||
}
|
||||
$path = FileHelper::normalizePath($path);
|
||||
foreach ($pathMap as $from => $tos) {
|
||||
$from = FileHelper::normalizePath(Yii::getAlias($from)) . DIRECTORY_SEPARATOR;
|
||||
if (strpos($path, $from) === 0) {
|
||||
$n = strlen($from);
|
||||
foreach ((array) $tos as $to) {
|
||||
$to = FileHelper::normalizePath(Yii::getAlias($to)) . DIRECTORY_SEPARATOR;
|
||||
$file = $to . substr($path, $n);
|
||||
if (is_file($file)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a relative URL into an absolute URL using [[baseUrl]].
|
||||
* @param string $url the relative URL to be converted.
|
||||
* @return string the absolute URL
|
||||
* @throws InvalidConfigException if [[baseUrl]] is not set
|
||||
*/
|
||||
public function getUrl($url)
|
||||
{
|
||||
if (($baseUrl = $this->getBaseUrl()) !== null) {
|
||||
return $baseUrl . '/' . ltrim($url, '/');
|
||||
}
|
||||
|
||||
throw new InvalidConfigException('The "baseUrl" property must be set.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a relative file path into an absolute one using [[basePath]].
|
||||
* @param string $path the relative file path to be converted.
|
||||
* @return string the absolute file path
|
||||
* @throws InvalidConfigException if [[basePath]] is not set
|
||||
*/
|
||||
public function getPath($path)
|
||||
{
|
||||
if (($basePath = $this->getBasePath()) !== null) {
|
||||
return $basePath . DIRECTORY_SEPARATOR . ltrim($path, '/\\');
|
||||
}
|
||||
|
||||
throw new InvalidConfigException('The "basePath" property must be set.');
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/UnknownClassException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/UnknownClassException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* UnknownClassException represents an exception caused by using an unknown class.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class UnknownClassException extends Exception
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Unknown Class';
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/UnknownMethodException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/UnknownMethodException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* UnknownMethodException represents an exception caused by accessing an unknown object method.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class UnknownMethodException extends \BadMethodCallException
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Unknown Method';
|
||||
}
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/UnknownPropertyException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/UnknownPropertyException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* UnknownPropertyException represents an exception caused by accessing unknown object properties.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class UnknownPropertyException extends Exception
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'Unknown Property';
|
||||
}
|
||||
}
|
||||
19
vendor/yiisoft/yii2/base/UserException.php
vendored
Normal file
19
vendor/yiisoft/yii2/base/UserException.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* UserException is the base class for exceptions that are meant to be shown to end users.
|
||||
* Such exceptions are often caused by mistakes of end users.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class UserException extends Exception
|
||||
{
|
||||
}
|
||||
574
vendor/yiisoft/yii2/base/View.php
vendored
Normal file
574
vendor/yiisoft/yii2/base/View.php
vendored
Normal file
@@ -0,0 +1,574 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use Yii;
|
||||
use yii\helpers\FileHelper;
|
||||
use yii\widgets\Block;
|
||||
use yii\widgets\ContentDecorator;
|
||||
use yii\widgets\FragmentCache;
|
||||
|
||||
/**
|
||||
* View represents a view object in the MVC pattern.
|
||||
*
|
||||
* View provides a set of methods (e.g. [[render()]]) for rendering purpose.
|
||||
*
|
||||
* For more details and usage information on View, see the [guide article on views](guide:structure-views).
|
||||
*
|
||||
* @property string|bool $viewFile The view file currently being rendered. False if no view file is being
|
||||
* rendered. This property is read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class View extends Component implements DynamicContentAwareInterface
|
||||
{
|
||||
/**
|
||||
* @event Event an event that is triggered by [[beginPage()]].
|
||||
*/
|
||||
const EVENT_BEGIN_PAGE = 'beginPage';
|
||||
/**
|
||||
* @event Event an event that is triggered by [[endPage()]].
|
||||
*/
|
||||
const EVENT_END_PAGE = 'endPage';
|
||||
/**
|
||||
* @event ViewEvent an event that is triggered by [[renderFile()]] right before it renders a view file.
|
||||
*/
|
||||
const EVENT_BEFORE_RENDER = 'beforeRender';
|
||||
/**
|
||||
* @event ViewEvent an event that is triggered by [[renderFile()]] right after it renders a view file.
|
||||
*/
|
||||
const EVENT_AFTER_RENDER = 'afterRender';
|
||||
|
||||
/**
|
||||
* @var ViewContextInterface the context under which the [[renderFile()]] method is being invoked.
|
||||
*/
|
||||
public $context;
|
||||
/**
|
||||
* @var mixed custom parameters that are shared among view templates.
|
||||
*/
|
||||
public $params = [];
|
||||
/**
|
||||
* @var array a list of available renderers indexed by their corresponding supported file extensions.
|
||||
* Each renderer may be a view renderer object or the configuration for creating the renderer object.
|
||||
* For example, the following configuration enables both Smarty and Twig view renderers:
|
||||
*
|
||||
* ```php
|
||||
* [
|
||||
* 'tpl' => ['class' => 'yii\smarty\ViewRenderer'],
|
||||
* 'twig' => ['class' => 'yii\twig\ViewRenderer'],
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
* If no renderer is available for the given view file, the view file will be treated as a normal PHP
|
||||
* and rendered via [[renderPhpFile()]].
|
||||
*/
|
||||
public $renderers;
|
||||
/**
|
||||
* @var string the default view file extension. This will be appended to view file names if they don't have file extensions.
|
||||
*/
|
||||
public $defaultExtension = 'php';
|
||||
/**
|
||||
* @var Theme|array|string the theme object or the configuration for creating the theme object.
|
||||
* If not set, it means theming is not enabled.
|
||||
*/
|
||||
public $theme;
|
||||
/**
|
||||
* @var array a list of named output blocks. The keys are the block names and the values
|
||||
* are the corresponding block content. You can call [[beginBlock()]] and [[endBlock()]]
|
||||
* to capture small fragments of a view. They can be later accessed somewhere else
|
||||
* through this property.
|
||||
*/
|
||||
public $blocks;
|
||||
/**
|
||||
* @var array|DynamicContentAwareInterface[] a list of currently active dynamic content class instances.
|
||||
* This property is used internally to implement the dynamic content caching feature. Do not modify it directly.
|
||||
* @internal
|
||||
* @deprecated Since 2.0.14. Do not use this property directly. Use methods [[getDynamicContents()]],
|
||||
* [[pushDynamicContent()]], [[popDynamicContent()]] instead.
|
||||
*/
|
||||
public $cacheStack = [];
|
||||
/**
|
||||
* @var array a list of placeholders for embedding dynamic contents. This property
|
||||
* is used internally to implement the content caching feature. Do not modify it directly.
|
||||
* @internal
|
||||
* @deprecated Since 2.0.14. Do not use this property directly. Use methods [[getDynamicPlaceholders()]],
|
||||
* [[setDynamicPlaceholders()]], [[addDynamicPlaceholder()]] instead.
|
||||
*/
|
||||
public $dynamicPlaceholders = [];
|
||||
|
||||
/**
|
||||
* @var array the view files currently being rendered. There may be multiple view files being
|
||||
* rendered at a moment because one view may be rendered within another.
|
||||
*/
|
||||
private $_viewFiles = [];
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the view component.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
if (is_array($this->theme)) {
|
||||
if (!isset($this->theme['class'])) {
|
||||
$this->theme['class'] = 'yii\base\Theme';
|
||||
}
|
||||
$this->theme = Yii::createObject($this->theme);
|
||||
} elseif (is_string($this->theme)) {
|
||||
$this->theme = Yii::createObject($this->theme);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view.
|
||||
*
|
||||
* The view to be rendered can be specified in one of the following formats:
|
||||
*
|
||||
* - [path alias](guide:concept-aliases) (e.g. "@app/views/site/index");
|
||||
* - absolute path within application (e.g. "//site/index"): the view name starts with double slashes.
|
||||
* The actual view file will be looked for under the [[Application::viewPath|view path]] of the application.
|
||||
* - absolute path within current module (e.g. "/site/index"): the view name starts with a single slash.
|
||||
* The actual view file will be looked for under the [[Module::viewPath|view path]] of the [[Controller::module|current module]].
|
||||
* - relative view (e.g. "index"): the view name does not start with `@` or `/`. The corresponding view file will be
|
||||
* looked for under the [[ViewContextInterface::getViewPath()|view path]] of the view `$context`.
|
||||
* If `$context` is not given, it will be looked for under the directory containing the view currently
|
||||
* being rendered (i.e., this happens when rendering a view within another view).
|
||||
*
|
||||
* @param string $view the view name.
|
||||
* @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
|
||||
* @param object $context the context to be assigned to the view and can later be accessed via [[context]]
|
||||
* in the view. If the context implements [[ViewContextInterface]], it may also be used to locate
|
||||
* the view file corresponding to a relative view name.
|
||||
* @return string the rendering result
|
||||
* @throws ViewNotFoundException if the view file does not exist.
|
||||
* @throws InvalidCallException if the view cannot be resolved.
|
||||
* @see renderFile()
|
||||
*/
|
||||
public function render($view, $params = [], $context = null)
|
||||
{
|
||||
$viewFile = $this->findViewFile($view, $context);
|
||||
return $this->renderFile($viewFile, $params, $context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the view file based on the given view name.
|
||||
* @param string $view the view name or the [path alias](guide:concept-aliases) of the view file. Please refer to [[render()]]
|
||||
* on how to specify this parameter.
|
||||
* @param object $context the context to be assigned to the view and can later be accessed via [[context]]
|
||||
* in the view. If the context implements [[ViewContextInterface]], it may also be used to locate
|
||||
* the view file corresponding to a relative view name.
|
||||
* @return string the view file path. Note that the file may not exist.
|
||||
* @throws InvalidCallException if a relative view name is given while there is no active context to
|
||||
* determine the corresponding view file.
|
||||
*/
|
||||
protected function findViewFile($view, $context = null)
|
||||
{
|
||||
if (strncmp($view, '@', 1) === 0) {
|
||||
// e.g. "@app/views/main"
|
||||
$file = Yii::getAlias($view);
|
||||
} elseif (strncmp($view, '//', 2) === 0) {
|
||||
// e.g. "//layouts/main"
|
||||
$file = Yii::$app->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
|
||||
} elseif (strncmp($view, '/', 1) === 0) {
|
||||
// e.g. "/site/index"
|
||||
if (Yii::$app->controller !== null) {
|
||||
$file = Yii::$app->controller->module->getViewPath() . DIRECTORY_SEPARATOR . ltrim($view, '/');
|
||||
} else {
|
||||
throw new InvalidCallException("Unable to locate view file for view '$view': no active controller.");
|
||||
}
|
||||
} elseif ($context instanceof ViewContextInterface) {
|
||||
$file = $context->getViewPath() . DIRECTORY_SEPARATOR . $view;
|
||||
} elseif (($currentViewFile = $this->getViewFile()) !== false) {
|
||||
$file = dirname($currentViewFile) . DIRECTORY_SEPARATOR . $view;
|
||||
} else {
|
||||
throw new InvalidCallException("Unable to resolve view file for view '$view': no active view context.");
|
||||
}
|
||||
|
||||
if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
|
||||
return $file;
|
||||
}
|
||||
$path = $file . '.' . $this->defaultExtension;
|
||||
if ($this->defaultExtension !== 'php' && !is_file($path)) {
|
||||
$path = $file . '.php';
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view file.
|
||||
*
|
||||
* If [[theme]] is enabled (not null), it will try to render the themed version of the view file as long
|
||||
* as it is available.
|
||||
*
|
||||
* The method will call [[FileHelper::localize()]] to localize the view file.
|
||||
*
|
||||
* If [[renderers|renderer]] is enabled (not null), the method will use it to render the view file.
|
||||
* Otherwise, it will simply include the view file as a normal PHP file, capture its output and
|
||||
* return it as a string.
|
||||
*
|
||||
* @param string $viewFile the view file. This can be either an absolute file path or an alias of it.
|
||||
* @param array $params the parameters (name-value pairs) that will be extracted and made available in the view file.
|
||||
* @param object $context the context that the view should use for rendering the view. If null,
|
||||
* existing [[context]] will be used.
|
||||
* @return string the rendering result
|
||||
* @throws ViewNotFoundException if the view file does not exist
|
||||
*/
|
||||
public function renderFile($viewFile, $params = [], $context = null)
|
||||
{
|
||||
$viewFile = Yii::getAlias($viewFile);
|
||||
|
||||
if ($this->theme !== null) {
|
||||
$viewFile = $this->theme->applyTo($viewFile);
|
||||
}
|
||||
if (is_file($viewFile)) {
|
||||
$viewFile = FileHelper::localize($viewFile);
|
||||
} else {
|
||||
throw new ViewNotFoundException("The view file does not exist: $viewFile");
|
||||
}
|
||||
|
||||
$oldContext = $this->context;
|
||||
if ($context !== null) {
|
||||
$this->context = $context;
|
||||
}
|
||||
$output = '';
|
||||
$this->_viewFiles[] = $viewFile;
|
||||
|
||||
if ($this->beforeRender($viewFile, $params)) {
|
||||
Yii::debug("Rendering view file: $viewFile", __METHOD__);
|
||||
$ext = pathinfo($viewFile, PATHINFO_EXTENSION);
|
||||
if (isset($this->renderers[$ext])) {
|
||||
if (is_array($this->renderers[$ext]) || is_string($this->renderers[$ext])) {
|
||||
$this->renderers[$ext] = Yii::createObject($this->renderers[$ext]);
|
||||
}
|
||||
/* @var $renderer ViewRenderer */
|
||||
$renderer = $this->renderers[$ext];
|
||||
$output = $renderer->render($this, $viewFile, $params);
|
||||
} else {
|
||||
$output = $this->renderPhpFile($viewFile, $params);
|
||||
}
|
||||
$this->afterRender($viewFile, $params, $output);
|
||||
}
|
||||
|
||||
array_pop($this->_viewFiles);
|
||||
$this->context = $oldContext;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|bool the view file currently being rendered. False if no view file is being rendered.
|
||||
*/
|
||||
public function getViewFile()
|
||||
{
|
||||
return end($this->_viewFiles);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right before [[renderFile()]] renders a view file.
|
||||
* The default implementation will trigger the [[EVENT_BEFORE_RENDER]] event.
|
||||
* If you override this method, make sure you call the parent implementation first.
|
||||
* @param string $viewFile the view file to be rendered.
|
||||
* @param array $params the parameter array passed to the [[render()]] method.
|
||||
* @return bool whether to continue rendering the view file.
|
||||
*/
|
||||
public function beforeRender($viewFile, $params)
|
||||
{
|
||||
$event = new ViewEvent([
|
||||
'viewFile' => $viewFile,
|
||||
'params' => $params,
|
||||
]);
|
||||
$this->trigger(self::EVENT_BEFORE_RENDER, $event);
|
||||
|
||||
return $event->isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right after [[renderFile()]] renders a view file.
|
||||
* The default implementation will trigger the [[EVENT_AFTER_RENDER]] event.
|
||||
* If you override this method, make sure you call the parent implementation first.
|
||||
* @param string $viewFile the view file being rendered.
|
||||
* @param array $params the parameter array passed to the [[render()]] method.
|
||||
* @param string $output the rendering result of the view file. Updates to this parameter
|
||||
* will be passed back and returned by [[renderFile()]].
|
||||
*/
|
||||
public function afterRender($viewFile, $params, &$output)
|
||||
{
|
||||
if ($this->hasEventHandlers(self::EVENT_AFTER_RENDER)) {
|
||||
$event = new ViewEvent([
|
||||
'viewFile' => $viewFile,
|
||||
'params' => $params,
|
||||
'output' => $output,
|
||||
]);
|
||||
$this->trigger(self::EVENT_AFTER_RENDER, $event);
|
||||
$output = $event->output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view file as a PHP script.
|
||||
*
|
||||
* This method treats the view file as a PHP script and includes the file.
|
||||
* It extracts the given parameters and makes them available in the view file.
|
||||
* The method captures the output of the included view file and returns it as a string.
|
||||
*
|
||||
* This method should mainly be called by view renderer or [[renderFile()]].
|
||||
*
|
||||
* @param string $_file_ the view file.
|
||||
* @param array $_params_ the parameters (name-value pairs) that will be extracted and made available in the view file.
|
||||
* @return string the rendering result
|
||||
* @throws \Exception
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function renderPhpFile($_file_, $_params_ = [])
|
||||
{
|
||||
$_obInitialLevel_ = ob_get_level();
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
extract($_params_, EXTR_OVERWRITE);
|
||||
try {
|
||||
require $_file_;
|
||||
return ob_get_clean();
|
||||
} catch (\Exception $e) {
|
||||
while (ob_get_level() > $_obInitialLevel_) {
|
||||
if (!@ob_end_clean()) {
|
||||
ob_clean();
|
||||
}
|
||||
}
|
||||
throw $e;
|
||||
} catch (\Throwable $e) {
|
||||
while (ob_get_level() > $_obInitialLevel_) {
|
||||
if (!@ob_end_clean()) {
|
||||
ob_clean();
|
||||
}
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders dynamic content returned by the given PHP statements.
|
||||
* This method is mainly used together with content caching (fragment caching and page caching)
|
||||
* when some portions of the content (called *dynamic content*) should not be cached.
|
||||
* The dynamic content must be returned by some PHP statements.
|
||||
* @param string $statements the PHP statements for generating the dynamic content.
|
||||
* @return string the placeholder of the dynamic content, or the dynamic content if there is no
|
||||
* active content cache currently.
|
||||
*/
|
||||
public function renderDynamic($statements)
|
||||
{
|
||||
if (!empty($this->cacheStack)) {
|
||||
$n = count($this->dynamicPlaceholders);
|
||||
$placeholder = "<![CDATA[YII-DYNAMIC-$n]]>";
|
||||
$this->addDynamicPlaceholder($placeholder, $statements);
|
||||
|
||||
return $placeholder;
|
||||
}
|
||||
|
||||
return $this->evaluateDynamicContent($statements);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDynamicPlaceholders()
|
||||
{
|
||||
return $this->dynamicPlaceholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDynamicPlaceholders($placeholders)
|
||||
{
|
||||
$this->dynamicPlaceholders = $placeholders;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addDynamicPlaceholder($placeholder, $statements)
|
||||
{
|
||||
foreach ($this->cacheStack as $cache) {
|
||||
if ($cache instanceof DynamicContentAwareInterface) {
|
||||
$cache->addDynamicPlaceholder($placeholder, $statements);
|
||||
} else {
|
||||
// TODO: Remove in 2.1
|
||||
$cache->dynamicPlaceholders[$placeholder] = $statements;
|
||||
}
|
||||
}
|
||||
$this->dynamicPlaceholders[$placeholder] = $statements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the given PHP statements.
|
||||
* This method is mainly used internally to implement dynamic content feature.
|
||||
* @param string $statements the PHP statements to be evaluated.
|
||||
* @return mixed the return value of the PHP statements.
|
||||
*/
|
||||
public function evaluateDynamicContent($statements)
|
||||
{
|
||||
return eval($statements);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of currently active dynamic content class instances.
|
||||
* @return DynamicContentAwareInterface[] class instances supporting dynamic contents.
|
||||
* @since 2.0.14
|
||||
*/
|
||||
public function getDynamicContents()
|
||||
{
|
||||
return $this->cacheStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a class instance supporting dynamic contents to the end of a list of currently active
|
||||
* dynamic content class instances.
|
||||
* @param DynamicContentAwareInterface $instance class instance supporting dynamic contents.
|
||||
* @since 2.0.14
|
||||
*/
|
||||
public function pushDynamicContent(DynamicContentAwareInterface $instance)
|
||||
{
|
||||
$this->cacheStack[] = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a last class instance supporting dynamic contents from a list of currently active
|
||||
* dynamic content class instances.
|
||||
* @since 2.0.14
|
||||
*/
|
||||
public function popDynamicContent()
|
||||
{
|
||||
array_pop($this->cacheStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins recording a block.
|
||||
*
|
||||
* This method is a shortcut to beginning [[Block]].
|
||||
* @param string $id the block ID.
|
||||
* @param bool $renderInPlace whether to render the block content in place.
|
||||
* Defaults to false, meaning the captured block will not be displayed.
|
||||
* @return Block the Block widget instance
|
||||
*/
|
||||
public function beginBlock($id, $renderInPlace = false)
|
||||
{
|
||||
return Block::begin([
|
||||
'id' => $id,
|
||||
'renderInPlace' => $renderInPlace,
|
||||
'view' => $this,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends recording a block.
|
||||
*/
|
||||
public function endBlock()
|
||||
{
|
||||
Block::end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins the rendering of content that is to be decorated by the specified view.
|
||||
*
|
||||
* This method can be used to implement nested layout. For example, a layout can be embedded
|
||||
* in another layout file specified as '@app/views/layouts/base.php' like the following:
|
||||
*
|
||||
* ```php
|
||||
* <?php $this->beginContent('@app/views/layouts/base.php'); ?>
|
||||
* //...layout content here...
|
||||
* <?php $this->endContent(); ?>
|
||||
* ```
|
||||
*
|
||||
* @param string $viewFile the view file that will be used to decorate the content enclosed by this widget.
|
||||
* This can be specified as either the view file path or [path alias](guide:concept-aliases).
|
||||
* @param array $params the variables (name => value) to be extracted and made available in the decorative view.
|
||||
* @return ContentDecorator the ContentDecorator widget instance
|
||||
* @see ContentDecorator
|
||||
*/
|
||||
public function beginContent($viewFile, $params = [])
|
||||
{
|
||||
return ContentDecorator::begin([
|
||||
'viewFile' => $viewFile,
|
||||
'params' => $params,
|
||||
'view' => $this,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the rendering of content.
|
||||
*/
|
||||
public function endContent()
|
||||
{
|
||||
ContentDecorator::end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins fragment caching.
|
||||
*
|
||||
* This method will display cached content if it is available.
|
||||
* If not, it will start caching and would expect an [[endCache()]]
|
||||
* call to end the cache and save the content into cache.
|
||||
* A typical usage of fragment caching is as follows,
|
||||
*
|
||||
* ```php
|
||||
* if ($this->beginCache($id)) {
|
||||
* // ...generate content here
|
||||
* $this->endCache();
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param string $id a unique ID identifying the fragment to be cached.
|
||||
* @param array $properties initial property values for [[FragmentCache]]
|
||||
* @return bool whether you should generate the content for caching.
|
||||
* False if the cached version is available.
|
||||
*/
|
||||
public function beginCache($id, $properties = [])
|
||||
{
|
||||
$properties['id'] = $id;
|
||||
$properties['view'] = $this;
|
||||
/* @var $cache FragmentCache */
|
||||
$cache = FragmentCache::begin($properties);
|
||||
if ($cache->getCachedContent() !== false) {
|
||||
$this->endCache();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends fragment caching.
|
||||
*/
|
||||
public function endCache()
|
||||
{
|
||||
FragmentCache::end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the beginning of a page.
|
||||
*/
|
||||
public function beginPage()
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
$this->trigger(self::EVENT_BEGIN_PAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the ending of a page.
|
||||
*/
|
||||
public function endPage()
|
||||
{
|
||||
$this->trigger(self::EVENT_END_PAGE);
|
||||
ob_end_flush();
|
||||
}
|
||||
}
|
||||
24
vendor/yiisoft/yii2/base/ViewContextInterface.php
vendored
Normal file
24
vendor/yiisoft/yii2/base/ViewContextInterface.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ViewContextInterface is the interface that should implemented by classes who want to support relative view names.
|
||||
*
|
||||
* The method [[getViewPath()]] should be implemented to return the view path that may be prefixed to a relative view name.
|
||||
*
|
||||
* @author Paul Klimov <klimov.paul@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
interface ViewContextInterface
|
||||
{
|
||||
/**
|
||||
* @return string the view path that may be prefixed to a relative view name.
|
||||
*/
|
||||
public function getViewPath();
|
||||
}
|
||||
39
vendor/yiisoft/yii2/base/ViewEvent.php
vendored
Normal file
39
vendor/yiisoft/yii2/base/ViewEvent.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ViewEvent represents events triggered by the [[View]] component.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class ViewEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var string the view file being rendered.
|
||||
*/
|
||||
public $viewFile;
|
||||
/**
|
||||
* @var array the parameter array passed to the [[View::render()]] method.
|
||||
*/
|
||||
public $params;
|
||||
/**
|
||||
* @var string the rendering result of [[View::renderFile()]].
|
||||
* Event handlers may modify this property and the modified output will be
|
||||
* returned by [[View::renderFile()]]. This property is only used
|
||||
* by [[View::EVENT_AFTER_RENDER]] event.
|
||||
*/
|
||||
public $output;
|
||||
/**
|
||||
* @var bool whether to continue rendering the view file. Event handlers of
|
||||
* [[View::EVENT_BEFORE_RENDER]] may set this property to decide whether
|
||||
* to continue rendering the current view file.
|
||||
*/
|
||||
public $isValid = true;
|
||||
}
|
||||
25
vendor/yiisoft/yii2/base/ViewNotFoundException.php
vendored
Normal file
25
vendor/yiisoft/yii2/base/ViewNotFoundException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ViewNotFoundException represents an exception caused by view file not found.
|
||||
*
|
||||
* @author Alexander Makarov
|
||||
* @since 2.0.10
|
||||
*/
|
||||
class ViewNotFoundException extends InvalidArgumentException
|
||||
{
|
||||
/**
|
||||
* @return string the user-friendly name of this exception
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'View not Found';
|
||||
}
|
||||
}
|
||||
30
vendor/yiisoft/yii2/base/ViewRenderer.php
vendored
Normal file
30
vendor/yiisoft/yii2/base/ViewRenderer.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* ViewRenderer is the base class for view renderer classes.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
abstract class ViewRenderer extends Component
|
||||
{
|
||||
/**
|
||||
* Renders a view file.
|
||||
*
|
||||
* This method is invoked by [[View]] whenever it tries to render a view.
|
||||
* Child classes must implement this method to render the given view file.
|
||||
*
|
||||
* @param View $view the view object used for rendering the file.
|
||||
* @param string $file the view file.
|
||||
* @param array $params the parameters to be passed to the view file.
|
||||
* @return string the rendering result
|
||||
*/
|
||||
abstract public function render($view, $file, $params);
|
||||
}
|
||||
322
vendor/yiisoft/yii2/base/Widget.php
vendored
Normal file
322
vendor/yiisoft/yii2/base/Widget.php
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
use ReflectionClass;
|
||||
use Yii;
|
||||
|
||||
/**
|
||||
* Widget is the base class for widgets.
|
||||
*
|
||||
* For more details and usage information on Widget, see the [guide article on widgets](guide:structure-widgets).
|
||||
*
|
||||
* @property string $id ID of the widget.
|
||||
* @property \yii\web\View $view The view object that can be used to render views or view files. Note that the
|
||||
* type of this property differs in getter and setter. See [[getView()]] and [[setView()]] for details.
|
||||
* @property string $viewPath The directory containing the view files for this widget. This property is
|
||||
* read-only.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @since 2.0
|
||||
*/
|
||||
class Widget extends Component implements ViewContextInterface
|
||||
{
|
||||
/**
|
||||
* @event Event an event that is triggered when the widget is initialized via [[init()]].
|
||||
* @since 2.0.11
|
||||
*/
|
||||
const EVENT_INIT = 'init';
|
||||
/**
|
||||
* @event WidgetEvent an event raised right before executing a widget.
|
||||
* You may set [[WidgetEvent::isValid]] to be false to cancel the widget execution.
|
||||
* @since 2.0.11
|
||||
*/
|
||||
const EVENT_BEFORE_RUN = 'beforeRun';
|
||||
/**
|
||||
* @event WidgetEvent an event raised right after executing a widget.
|
||||
* @since 2.0.11
|
||||
*/
|
||||
const EVENT_AFTER_RUN = 'afterRun';
|
||||
|
||||
/**
|
||||
* @var int a counter used to generate [[id]] for widgets.
|
||||
* @internal
|
||||
*/
|
||||
public static $counter = 0;
|
||||
/**
|
||||
* @var string the prefix to the automatically generated widget IDs.
|
||||
* @see getId()
|
||||
*/
|
||||
public static $autoIdPrefix = 'w';
|
||||
/**
|
||||
* @var Widget[] the widgets that are currently being rendered (not ended). This property
|
||||
* is maintained by [[begin()]] and [[end()]] methods.
|
||||
* @internal
|
||||
*/
|
||||
public static $stack = [];
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the object.
|
||||
* This method is called at the end of the constructor.
|
||||
* The default implementation will trigger an [[EVENT_INIT]] event.
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
parent::init();
|
||||
$this->trigger(self::EVENT_INIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins a widget.
|
||||
* This method creates an instance of the calling class. It will apply the configuration
|
||||
* to the created instance. A matching [[end()]] call should be called later.
|
||||
* As some widgets may use output buffering, the [[end()]] call should be made in the same view
|
||||
* to avoid breaking the nesting of output buffers.
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties
|
||||
* @return static the newly created widget instance
|
||||
* @see end()
|
||||
*/
|
||||
public static function begin($config = [])
|
||||
{
|
||||
$config['class'] = get_called_class();
|
||||
/* @var $widget Widget */
|
||||
$widget = Yii::createObject($config);
|
||||
static::$stack[] = $widget;
|
||||
|
||||
return $widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends a widget.
|
||||
* Note that the rendering result of the widget is directly echoed out.
|
||||
* @return static the widget instance that is ended.
|
||||
* @throws InvalidCallException if [[begin()]] and [[end()]] calls are not properly nested
|
||||
* @see begin()
|
||||
*/
|
||||
public static function end()
|
||||
{
|
||||
if (!empty(static::$stack)) {
|
||||
$widget = array_pop(static::$stack);
|
||||
if (get_class($widget) === get_called_class()) {
|
||||
/* @var $widget Widget */
|
||||
if ($widget->beforeRun()) {
|
||||
$result = $widget->run();
|
||||
$result = $widget->afterRun($result);
|
||||
echo $result;
|
||||
}
|
||||
|
||||
return $widget;
|
||||
}
|
||||
|
||||
throw new InvalidCallException('Expecting end() of ' . get_class($widget) . ', found ' . get_called_class());
|
||||
}
|
||||
|
||||
throw new InvalidCallException('Unexpected ' . get_called_class() . '::end() call. A matching begin() is not found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a widget instance and runs it.
|
||||
* The widget rendering result is returned by this method.
|
||||
* @param array $config name-value pairs that will be used to initialize the object properties
|
||||
* @return string the rendering result of the widget.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function widget($config = [])
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
try {
|
||||
/* @var $widget Widget */
|
||||
$config['class'] = get_called_class();
|
||||
$widget = Yii::createObject($config);
|
||||
$out = '';
|
||||
if ($widget->beforeRun()) {
|
||||
$result = $widget->run();
|
||||
$out = $widget->afterRun($result);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// close the output buffer opened above if it has not been closed already
|
||||
if (ob_get_level() > 0) {
|
||||
ob_end_clean();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return ob_get_clean() . $out;
|
||||
}
|
||||
|
||||
private $_id;
|
||||
|
||||
/**
|
||||
* Returns the ID of the widget.
|
||||
* @param bool $autoGenerate whether to generate an ID if it is not set previously
|
||||
* @return string ID of the widget.
|
||||
*/
|
||||
public function getId($autoGenerate = true)
|
||||
{
|
||||
if ($autoGenerate && $this->_id === null) {
|
||||
$this->_id = static::$autoIdPrefix . static::$counter++;
|
||||
}
|
||||
|
||||
return $this->_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ID of the widget.
|
||||
* @param string $value id of the widget.
|
||||
*/
|
||||
public function setId($value)
|
||||
{
|
||||
$this->_id = $value;
|
||||
}
|
||||
|
||||
private $_view;
|
||||
|
||||
/**
|
||||
* Returns the view object that can be used to render views or view files.
|
||||
* The [[render()]] and [[renderFile()]] methods will use
|
||||
* this view object to implement the actual view rendering.
|
||||
* If not set, it will default to the "view" application component.
|
||||
* @return \yii\web\View the view object that can be used to render views or view files.
|
||||
*/
|
||||
public function getView()
|
||||
{
|
||||
if ($this->_view === null) {
|
||||
$this->_view = Yii::$app->getView();
|
||||
}
|
||||
|
||||
return $this->_view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the view object to be used by this widget.
|
||||
* @param View $view the view object that can be used to render views or view files.
|
||||
*/
|
||||
public function setView($view)
|
||||
{
|
||||
$this->_view = $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the widget.
|
||||
* @return string the result of widget execution to be outputted.
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view.
|
||||
*
|
||||
* The view to be rendered can be specified in one of the following formats:
|
||||
*
|
||||
* - [path alias](guide:concept-aliases) (e.g. "@app/views/site/index");
|
||||
* - absolute path within application (e.g. "//site/index"): the view name starts with double slashes.
|
||||
* The actual view file will be looked for under the [[Application::viewPath|view path]] of the application.
|
||||
* - absolute path within module (e.g. "/site/index"): the view name starts with a single slash.
|
||||
* The actual view file will be looked for under the [[Module::viewPath|view path]] of the currently
|
||||
* active module.
|
||||
* - relative path (e.g. "index"): the actual view file will be looked for under [[viewPath]].
|
||||
*
|
||||
* If the view name does not contain a file extension, it will use the default one `.php`.
|
||||
*
|
||||
* @param string $view the view name.
|
||||
* @param array $params the parameters (name-value pairs) that should be made available in the view.
|
||||
* @return string the rendering result.
|
||||
* @throws InvalidArgumentException if the view file does not exist.
|
||||
*/
|
||||
public function render($view, $params = [])
|
||||
{
|
||||
return $this->getView()->render($view, $params, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a view file.
|
||||
* @param string $file the view file to be rendered. This can be either a file path or a [path alias](guide:concept-aliases).
|
||||
* @param array $params the parameters (name-value pairs) that should be made available in the view.
|
||||
* @return string the rendering result.
|
||||
* @throws InvalidArgumentException if the view file does not exist.
|
||||
*/
|
||||
public function renderFile($file, $params = [])
|
||||
{
|
||||
return $this->getView()->renderFile($file, $params, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory containing the view files for this widget.
|
||||
* The default implementation returns the 'views' subdirectory under the directory containing the widget class file.
|
||||
* @return string the directory containing the view files for this widget.
|
||||
*/
|
||||
public function getViewPath()
|
||||
{
|
||||
$class = new ReflectionClass($this);
|
||||
|
||||
return dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'views';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right before the widget is executed.
|
||||
*
|
||||
* The method will trigger the [[EVENT_BEFORE_RUN]] event. The return value of the method
|
||||
* will determine whether the widget should continue to run.
|
||||
*
|
||||
* When overriding this method, make sure you call the parent implementation like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function beforeRun()
|
||||
* {
|
||||
* if (!parent::beforeRun()) {
|
||||
* return false;
|
||||
* }
|
||||
*
|
||||
* // your custom code here
|
||||
*
|
||||
* return true; // or false to not run the widget
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @return bool whether the widget should continue to be executed.
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function beforeRun()
|
||||
{
|
||||
$event = new WidgetEvent();
|
||||
$this->trigger(self::EVENT_BEFORE_RUN, $event);
|
||||
return $event->isValid;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is invoked right after a widget is executed.
|
||||
*
|
||||
* The method will trigger the [[EVENT_AFTER_RUN]] event. The return value of the method
|
||||
* will be used as the widget return value.
|
||||
*
|
||||
* If you override this method, your code should look like the following:
|
||||
*
|
||||
* ```php
|
||||
* public function afterRun($result)
|
||||
* {
|
||||
* $result = parent::afterRun($result);
|
||||
* // your custom code here
|
||||
* return $result;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param mixed $result the widget return result.
|
||||
* @return mixed the processed widget result.
|
||||
* @since 2.0.11
|
||||
*/
|
||||
public function afterRun($result)
|
||||
{
|
||||
$event = new WidgetEvent();
|
||||
$event->result = $result;
|
||||
$this->trigger(self::EVENT_AFTER_RUN, $event);
|
||||
return $event->result;
|
||||
}
|
||||
}
|
||||
30
vendor/yiisoft/yii2/base/WidgetEvent.php
vendored
Normal file
30
vendor/yiisoft/yii2/base/WidgetEvent.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* @link http://www.yiiframework.com/
|
||||
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||
* @license http://www.yiiframework.com/license/
|
||||
*/
|
||||
|
||||
namespace yii\base;
|
||||
|
||||
/**
|
||||
* WidgetEvent represents the event parameter used for a widget event.
|
||||
*
|
||||
* By setting the [[isValid]] property, one may control whether to continue running the widget.
|
||||
*
|
||||
* @author Petra Barus <petra.barus@gmail.com>
|
||||
* @since 2.0.11
|
||||
*/
|
||||
class WidgetEvent extends Event
|
||||
{
|
||||
/**
|
||||
* @var mixed the widget result. Event handlers may modify this property to change the widget result.
|
||||
*/
|
||||
public $result;
|
||||
/**
|
||||
* @var bool whether to continue running the widget. Event handlers of
|
||||
* [[Widget::EVENT_BEFORE_RUN]] may set this property to decide whether
|
||||
* to continue running the current widget.
|
||||
*/
|
||||
public $isValid = true;
|
||||
}
|
||||
Reference in New Issue
Block a user