[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2022 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE 8 */ 9 10 namespace Joomla\CMS\Event; 11 12 use DomainException; 13 14 // phpcs:disable PSR1.Files.SideEffects 15 \defined('JPATH_PLATFORM') or die; 16 // phpcs:enable PSR1.Files.SideEffects 17 18 /** 19 * A Trait to reshape arguments maintaining b/c with legacy plugin events. 20 * 21 * Old plugin event handlers expect positional arguments, not named arguments, since they are simple 22 * PHP methods, e.g. 23 * public onExample($foo, $bar, $baz). 24 * Concrete Event classes, however, use named arguments which can be passed in any order. The 25 * following two examples are equivalent: 26 * $event1 = new ConcreteEventClass('onExample', ['foo' => 1, 'bar' => 2, 'baz' => 3]; 27 * $event2 = new ConcreteEventClass('onExample', ['bar' => 2, 'baz' => 3, 'foo' => 1,]; 28 * However, this means that the internal $arguments property of the event object holds the named 29 * arguments in a **different** order in each case. 30 * 31 * When the event handler is aware of the ConcreteEventClass it can retrieve named arguments and 32 * all is good in the world. However, when you have a legacy plugin listener registered through 33 * CMSPlugin::registerLegacyListener you have a major problem! The legacy listener is passing the 34 * arguments **positionally**, in the order they were added to the Event object. 35 * 36 * In the previous example, $event1 would work as expected because the foo, bar, and baz arguments 37 * were given in the same order legacy listeners expected them. On the other hand, $event2 would 38 * fail miserably because the call order would be $bar, $baz, $foo which is NOT what the legacy 39 * listener expected. 40 * 41 * The only way to fix that is to *reshape the argument* in the concrete event's constructor so that 42 * the order of arguments is guaranteed to be the same as expected by legacy listeners. Moreover, 43 * since Joomla is passing all arguments (except the 'result' argument) blindly to the legacy 44 * listener we must ensure that a. all necessary arguments are set and b. any other named arguments 45 * do NOT exist. Otherwise our legacy listeners would receive the wrong number of positional 46 * arguments and break. 47 * 48 * All this is achieved by the reshapeArguments() method in this trait which has to be called in the 49 * constructor of the concrete event class. 50 * 51 * This trait is marked as deprecated with a removal target of 5.0 because in Joomla 5 we will only 52 * be using concrete event classes with named arguments, removing legacy listeners and their 53 * positional arguments headaches. 54 * 55 * @since 4.2.0 56 * 57 * @deprecated 5.0 58 */ 59 trait ReshapeArgumentsAware 60 { 61 /** 62 * Reshape the arguments array to preserve b/c with legacy listeners 63 * 64 * @param array $arguments The named arguments array passed to the constructor. 65 * @param array $argumentNames The allowed argument names (mandatory AND optional). 66 * @param array $defaults Default values for optional arguments. 67 * 68 * @return array The reshaped arguments. 69 * 70 * @since 4.2.0 71 */ 72 protected function reshapeArguments(array $arguments, array $argumentNames, array $defaults = []) 73 { 74 $mandatoryKeys = array_diff($argumentNames, array_keys($defaults)); 75 $currentKeys = array_keys($arguments); 76 $missingKeys = array_diff($mandatoryKeys, $currentKeys); 77 $extraKeys = array_diff($currentKeys, $argumentNames); 78 79 // Am I missing any mandatory arguments? 80 if ($missingKeys) { 81 throw new DomainException(sprintf('Missing arguments for ā%sā event: %s', $this->getName(), implode(', ', $missingKeys))); 82 } 83 84 // Do I have unknown arguments? 85 if ($extraKeys) { 86 throw new DomainException(sprintf('Unknown arguments for ā%sā event: %s', $this->getName(), implode(', ', $missingKeys))); 87 } 88 89 // Reconstruct the arguments in the order specified in $argumentTypes 90 $reconstructed = []; 91 92 foreach ($argumentNames as $key) { 93 $reconstructed[$key] = $arguments[$key] ?? $defaults[$key]; 94 } 95 96 // Return the reconstructed arguments array 97 return $reconstructed; 98 } 99 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |