/libraries/src/Event/AbstractEvent.php
https://github.com/Hackwar/joomla-cms · PHP · 172 lines · 63 code · 20 blank · 89 comment · 10 complexity · 07a8b7b64a5c1c16ef9953b0c1ec4dc1 MD5 · raw file
- <?php
- /**
- * Joomla! Content Management System
- *
- * @copyright (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
- * @license GNU General Public License version 2 or later; see LICENSE
- */
- namespace Joomla\CMS\Event;
- \defined('JPATH_PLATFORM') or die;
- use BadMethodCallException;
- use Joomla\Event\Event as BaseEvent;
- use Joomla\String\Normalise;
- /**
- * This class implements the base Event object used system-wide to offer orthogonality. Core objects such as Models,
- * Controllers, etc create such events on-the-fly and dispatch them through the application's Dispatcher (colloquially
- * known as the "Joomla! plugin system"). This way a suitable plugin, typically a "system" plugin, can modify the
- * behaviour of any internal class, providing system-wide services such as tags, content versioning, comments or even
- * low-level services such as the implementation of created/modified/locked behaviours, record hit counter etc.
- *
- * You can create a new Event with something like this:
- *
- * $event = AbstractEvent::create('onModelBeforeSomething', $myModel, $arguments);
- *
- * You can access the subject object from your event Listener using $event['subject']. It is up to your listener to
- * determine whether it should apply its functionality against the subject.
- *
- * This AbstractEvent class implements a mutable event which is allowed to change its arguments at runtime. This is
- * generally unadvisable. It's best to use AbstractImmutableEvent instead and constrict all your interaction to the
- * subject class.
- *
- * @since 4.0.0
- */
- abstract class AbstractEvent extends BaseEvent
- {
- /**
- * Creates a new CMS event object for a given event name and subject. The following arguments must be given:
- * subject object The subject of the event. This is the core object you are going to manipulate.
- * eventClass string The Event class name. If you do not provide it Joomla\CMS\Events\<eventNameWithoutOnPrefix>
- * will be used.
- *
- * @param string $eventName The name of the event, e.g. onTableBeforeLoad
- * @param array $arguments Additional arguments to pass to the event
- *
- * @return static
- *
- * @since 4.0.0
- * @throws BadMethodCallException If you do not provide a subject argument
- */
- public static function create(string $eventName, array $arguments = [])
- {
- // Get the class name from the arguments, if specified
- $eventClassName = '';
- if (isset($arguments['eventClass']))
- {
- $eventClassName = $arguments['eventClass'];
- unset($arguments['eventClass']);
- }
- /**
- * If the class name isn't set/found determine it from the event name, e.g. TableBeforeLoadEvent from
- * the onTableBeforeLoad event name.
- */
- if (empty($eventClassName) || !class_exists($eventClassName, true))
- {
- $bareName = strpos($eventName, 'on') === 0 ? substr($eventName, 2) : $eventName;
- $parts = Normalise::fromCamelCase($bareName, true);
- $eventClassName = __NAMESPACE__ . '\\' . ucfirst(array_shift($parts)) . '\\';
- $eventClassName .= implode('', $parts);
- $eventClassName .= 'Event';
- }
- // Make sure a non-empty subject argument exists and that it is an object
- if (!isset($arguments['subject']) || empty($arguments['subject']) || !\is_object($arguments['subject']))
- {
- throw new BadMethodCallException("No subject given for the $eventName event");
- }
- // Create and return the event object
- if (class_exists($eventClassName, true))
- {
- return new $eventClassName($eventName, $arguments);
- }
- return new GenericEvent($eventName, $arguments);
- }
- /**
- * Constructor. Overridden to go through the argument setters.
- *
- * @param string $name The event name.
- * @param array $arguments The event arguments.
- *
- * @since 4.0.0
- */
- public function __construct(string $name, array $arguments = [])
- {
- parent::__construct($name, $arguments);
- $this->arguments = [];
- foreach ($arguments as $argumentName => $value)
- {
- $this->setArgument($argumentName, $value);
- }
- }
- /**
- * Get an event argument value. It will use a getter method if one exists. The getters have the signature:
- *
- * get<ArgumentName>($value): mixed
- *
- * where:
- *
- * $value is the value currently stored in the $arguments array of the event
- * It returns the value to return to the caller.
- *
- * @param string $name The argument name.
- * @param mixed $default The default value if not found.
- *
- * @return mixed The argument value or the default value.
- *
- * @since 4.0.0
- */
- public function getArgument($name, $default = null)
- {
- $methodName = 'get' . ucfirst($name);
- $value = parent::getArgument($name, $default);
- if (method_exists($this, $methodName))
- {
- return $this->{$methodName}($value);
- }
- return $value;
- }
- /**
- * Add argument to event. It will use a setter method if one exists. The setters have the signature:
- *
- * set<ArgumentName>($value): mixed
- *
- * where:
- *
- * $value is the value being set by the user
- * It returns the value to return to set in the $arguments array of the event.
- *
- * @param string $name Argument name.
- * @param mixed $value Value.
- *
- * @return $this
- *
- * @since 4.0.0
- */
- public function setArgument($name, $value)
- {
- $methodName = 'set' . ucfirst($name);
- if (method_exists($this, $methodName))
- {
- $value = $this->{$methodName}($value);
- }
- return parent::setArgument($name, $value);
- }
- }