3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
12 namespace Civi\Schema\Traits
;
14 use Civi\Api4\Utils\ReflectionUtils
;
17 * Automatically define getter/setter methods for public and protected fields.
22 * - Add the trait (`use MagicGetterSetterTrait;`).
23 * - Add a public or protected property (`protected $fooBar;`).
24 * - When using the class, you may now call `setFooBar($value)` and `getFooBar()`.
28 * - To provide better hints/DX in IDEs, you may add the `@method` notations
29 * to the class docblock. There are several examples of this in APIv4
30 * (see e.g. `AbstractAction.php` or `AbstractQueryAction.php`).
31 * - When/if you need to customize the behavior of a getter/setter, then simply
32 * add your own method. This takes precedence over magic mehods.
33 * - If a field name begins with `_`, then it will be excluded.
35 * @package Civi\Schema\Traits
37 trait MagicGetterSetterTrait
{
40 * Magic function to provide getters/setters.
42 * @param string $method
43 * @param array $arguments
44 * @return static|mixed
45 * @throws \CRM_Core_Exception
47 public function __call($method, $arguments) {
48 $mode = substr($method, 0, 3);
49 $prop = lcfirst(substr($method, 3));
50 $props = static::getMagicProperties();
51 if (isset($props[$prop])) {
57 if (count($arguments) < 1) {
58 throw new \
CRM_Core_Exception(sprintf('Missing required parameter for method %s::%s()', static::CLASS, $method));
60 $this->$prop = $arguments[0];
65 throw new \
CRM_Core_Exception(sprintf('Unknown method: %s::%s()', static::CLASS, $method));
69 * Get a list of class properties for which magic methods are supported.
72 * List of supported properties, keyed by property name.
73 * Array(string $propertyName => bool $true).
75 protected static function getMagicProperties(): array {
76 // Thread-local cache of class metadata. Class metadata is immutable at runtime, so this is strictly write-once. It should ideally be reused across varied test-functions.
78 $CLASS = static::CLASS;
79 $cache =& $caches[$CLASS];
80 if ($cache === NULL) {
82 foreach (ReflectionUtils
::findStandardProperties(static::CLASS) as $property) {
83 /** @var \ReflectionProperty $property */
84 $cache[$property->getName()] = TRUE;