(REF) APIv4 FieldSpec - Extract ArrayFormatTrait. Add loadArray().
authorTim Otten <totten@civicrm.org>
Fri, 16 Jul 2021 06:34:32 +0000 (23:34 -0700)
committerTim Otten <totten@civicrm.org>
Fri, 16 Jul 2021 06:38:24 +0000 (23:38 -0700)
Civi/Api4/Service/Spec/FieldSpec.php
Civi/Schema/Traits/ArrayFormatTrait.php [new file with mode: 0644]

index 98390294169fbb4eb079275e88e8bd7b43b7af29..f971b16de81221b397337ffbaa1256678079ad0b 100644 (file)
@@ -12,6 +12,7 @@
 
 namespace Civi\Api4\Service\Spec;
 
+use Civi\Schema\Traits\ArrayFormatTrait;
 use Civi\Schema\Traits\BasicSpecTrait;
 use Civi\Schema\Traits\DataTypeSpecTrait;
 use Civi\Schema\Traits\GuiSpecTrait;
@@ -35,6 +36,9 @@ class FieldSpec {
   // SqlSpecTrait tableName, columnName, operators, sqlFilters
   use SqlSpecTrait;
 
+  // ArrayFormatTrait: toArray():array, loadArray($array)
+  use ArrayFormatTrait;
+
   /**
    * @var mixed
    */
@@ -217,32 +221,4 @@ class FieldSpec {
     return $this;
   }
 
-  /**
-   * Gets all public variables, converted to snake_case
-   *
-   * @return array
-   */
-  public function toArray() {
-    // Anonymous class will only have access to public vars
-    $getter = new class {
-
-      function getPublicVars($object) {
-        return get_object_vars($object);
-      }
-
-    };
-
-    // If getOptions was never called, make options a boolean
-    if (!isset($this->options)) {
-      $this->options = isset($this->optionsCallback);
-    }
-
-    $ret = [];
-    foreach ($getter->getPublicVars($this) as $key => $val) {
-      $key = strtolower(preg_replace('/(?=[A-Z])/', '_$0', $key));
-      $ret[$key] = $val;
-    }
-    return $ret;
-  }
-
 }
diff --git a/Civi/Schema/Traits/ArrayFormatTrait.php b/Civi/Schema/Traits/ArrayFormatTrait.php
new file mode 100644 (file)
index 0000000..520568d
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC. All rights reserved.                        |
+ |                                                                    |
+ | This work is published under the GNU AGPLv3 license with some      |
+ | permitted exceptions and without any warranty. For full license    |
+ | and copyright information, see https://civicrm.org/licensing       |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Schema\Traits;
+
+/**
+ *
+ *
+ * @package Civi\Schema\Traits
+ */
+trait ArrayFormatTrait {
+
+  /**
+   * Gets all public variables, converted to snake_case
+   *
+   * @return array
+   */
+  public function toArray() {
+    // Anonymous class will only have access to public vars
+    $getter = new class {
+
+      function getPublicVars($object) {
+        return get_object_vars($object);
+      }
+
+    };
+
+    // If getOptions was never called, make options a boolean
+    if (property_exists($this, 'options') && !isset($this->options)) {
+      $this->options = isset($this->optionsCallback);
+    }
+
+    $ret = [];
+    foreach ($getter->getPublicVars($this) as $key => $val) {
+      $key = strtolower(preg_replace('/(?=[A-Z])/', '_$0', $key));
+      $ret[$key] = $val;
+    }
+    return $ret;
+  }
+
+  /**
+   * Populate this field-spec using values from an array.
+   *
+   * @param iterable $values
+   *   List of public variables, expressed in snake_case.
+   *   Ex: ['title' => 'Color', 'default_value' => '#f00']
+   * @param  bool $strict
+   *   In strict mode, properties are only accepted if they are formally defined on the current class.
+   * @return $this
+   */
+  public function loadArray(iterable $values, bool $strict = FALSE) {
+    foreach ($values as $key => $value) {
+      $field = \CRM_Utils_String::convertStringToCamel($key, FALSE);
+      $setter = 'set' . ucfirst($field);
+      if ($strict && !property_exists($this, $field) && !method_exists($this, $setter) && $value !== NULL) {
+        throw new \CRM_Core_Exception(sprintf('Cannot assign field (%s::%s aka %s)', get_class($this), $field, $key));
+      }
+      if (is_callable([$this, $setter])) {
+        $this->{$setter}($value);
+      }
+      else {
+        $this->{$field} = $value;
+      }
+    }
+    return $this;
+  }
+
+}