Files
yii2/framework/base/Event.php
Robert Korulczyk ba0ab403b5 Added php-cs-fixer coding standards validation to Travis CI (#14100)
* php-cs-fixer: PSR2 rule.

* php-cs-fixer: PSR2 rule - fix views.

* Travis setup refactoring.

* Add php-cs-fixer to travis cs tests.

* Fix tests on hhvm-3.12

* improve travis config

* composer update

* revert composer update

* improve travis config

* Fix CS.

* Extract config to separate classes.

* Extract config to separate classes.

* Add file header.

* Force short array syntax.

* binary_operator_spaces fixer

* Fix broken tests

* cast_spaces fixer

* concat_space fixer

* dir_constant fixer

* ereg_to_preg fixer

* function_typehint_space fixer

* hash_to_slash_comment fixer

* is_null fixer

* linebreak_after_opening_tag fixer

* lowercase_cast fixer

* magic_constant_casing fixer

* modernize_types_casting fixer

* native_function_casing fixer

* new_with_braces fixer

* no_alias_functions fixer

* no_blank_lines_after_class_opening fixer

* no_blank_lines_after_phpdoc fixer

* no_empty_comment fixer

* no_empty_phpdoc fixer

* no_empty_statement fixer

* no_extra_consecutive_blank_lines fixer

* no_leading_import_slash fixer

* no_leading_namespace_whitespace fixer

* no_mixed_echo_print fixer

* no_multiline_whitespace_around_double_arrow fixer

* no_multiline_whitespace_before_semicolons fixer

* no_php4_constructor fixer

* no_short_bool_cast fixer

* no_singleline_whitespace_before_semicolons fixer

* no_spaces_around_offset fixer

* no_trailing_comma_in_list_call fixer

* no_trailing_comma_in_singleline_array fixer

* no_unneeded_control_parentheses fixer

* no_unused_imports fixer

* no_useless_return fixer

* no_whitespace_before_comma_in_array fixer

* no_whitespace_in_blank_line fixer

* not_operator_with_successor_space fixer

* object_operator_without_whitespace fixer

* ordered_imports fixer

* php_unit_construct fixer

* php_unit_dedicate_assert fixer

* php_unit_fqcn_annotation fixer

* phpdoc_indent fixer

* phpdoc_no_access fixer

* phpdoc_no_empty_return fixer

* phpdoc_no_package fixer

* phpdoc_no_useless_inheritdoc fixer

* Fix broken tests

* phpdoc_return_self_reference fixer

* phpdoc_single_line_var_spacing fixer

* phpdoc_single_line_var_spacing fixer

* phpdoc_to_comment fixer

* phpdoc_trim fixer

* phpdoc_var_without_name fixer

* psr4 fixer

* self_accessor fixer

* short_scalar_cast fixer

* single_blank_line_before_namespace fixer

* single_quote fixer

* standardize_not_equals fixer

* ternary_operator_spaces fixer

* trailing_comma_in_multiline_array fixer

* trim_array_spaces fixer

* protected_to_private fixer

* unary_operator_spaces fixer

* whitespace_after_comma_in_array fixer

* `parent::setRules()` -> `$this->setRules()`

* blank_line_after_opening_tag fixer

* Update finder config.

* Revert changes for YiiRequirementChecker.

* Fix array formatting.

* Add missing import.

* Fix CS for new code merged from master.

* Fix some indentation issues.
2017-06-12 12:25:45 +03:00

228 lines
7.7 KiB
PHP

<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\base;
/**
* 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 Object
{
/**
* @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 = [];
/**
* 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.
*
* 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 ($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()]].
*
* @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])) {
return false;
}
if ($handler === null) {
unset(self::$_events[$name][$class]);
return true;
}
$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;
}
/**
* Detaches all registered class-level event handlers.
* @see on()
* @see off()
* @since 2.0.10
*/
public static function offAll()
{
self::$_events = [];
}
/**
* 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::$_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)
);
foreach ($classes as $class) {
if (!empty(self::$_events[$name][$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)
{
if (empty(self::$_events[$name])) {
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) {
if (empty(self::$_events[$name][$class])) {
continue;
}
foreach (self::$_events[$name][$class] as $handler) {
$event->data = $handler[1];
call_user_func($handler[0], $event);
if ($event->handled) {
return;
}
}
}
}
}