summaryrefslogtreecommitdiff
path: root/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils
diff options
context:
space:
mode:
Diffstat (limited to 'www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils')
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ActionUtil.php27
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ArrayInsertionUtil.php73
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/CoreUtil.php42
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/FormattingUtil.php106
-rw-r--r--www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ReflectionUtils.php119
5 files changed, 367 insertions, 0 deletions
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ActionUtil.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ActionUtil.php
new file mode 100644
index 00000000..628bc6fa
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ActionUtil.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Civi\Api4\Utils;
+
+class ActionUtil {
+
+ /**
+ * @param $entityName
+ * @param $actionName
+ * @return \Civi\Api4\Generic\AbstractAction
+ * @throws \Civi\API\Exception\NotImplementedException
+ */
+ public static function getAction($entityName, $actionName) {
+ // For custom pseudo-entities
+ if (strpos($entityName, 'Custom_') === 0) {
+ return \Civi\Api4\CustomValue::$actionName(substr($entityName, 7));
+ }
+ else {
+ $callable = ["\\Civi\\Api4\\$entityName", $actionName];
+ if (!is_callable($callable)) {
+ throw new \Civi\API\Exception\NotImplementedException("API ($entityName, $actionName) does not exist (join the API team and implement it!)");
+ }
+ return call_user_func($callable);
+ }
+ }
+
+}
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ArrayInsertionUtil.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ArrayInsertionUtil.php
new file mode 100644
index 00000000..54e3944b
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ArrayInsertionUtil.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Civi\Api4\Utils;
+
+use CRM_Utils_Array as UtilsArray;
+
+class ArrayInsertionUtil {
+ /**
+ * If the values to be inserted contain a key _parent_id they will only be
+ * inserted if the parent node ID matches their ID
+ *
+ * @param $array
+ * The array to insert the value in
+ * @param array $parts
+ * Path to insertion point with structure:
+ * [[ name => is_multiple ], ..]
+ * @param mixed $values
+ * The value to be inserted
+ */
+ public static function insert(&$array, $parts, $values) {
+ $key = key($parts);
+ $isMulti = array_shift($parts);
+ if (!isset($array[$key])) {
+ $array[$key] = $isMulti ? [] : NULL;
+ }
+ if (empty($parts)) {
+ $values = self::filterValues($array, $isMulti, $values);
+ $array[$key] = $values;
+ }
+ else {
+ if ($isMulti) {
+ foreach ($array[$key] as &$subArray) {
+ self::insert($subArray, $parts, $values);
+ }
+ }
+ else {
+ self::insert($array[$key], $parts, $values);
+ }
+ }
+ }
+
+ /**
+ * @param $parentArray
+ * @param $isMulti
+ * @param $values
+ *
+ * @return array|mixed
+ */
+ private static function filterValues($parentArray, $isMulti, $values) {
+ $parentID = UtilsArray::value('id', $parentArray);
+
+ if ($parentID) {
+ $values = array_filter($values, function ($value) use ($parentID) {
+ return UtilsArray::value('_parent_id', $value) == $parentID;
+ });
+ }
+
+ $unsets = ['_parent_id', '_base_id'];
+ array_walk($values, function (&$value) use ($unsets) {
+ foreach ($unsets as $unset) {
+ if (isset($value[$unset])) {
+ unset($value[$unset]);
+ }
+ }
+ });
+
+ if (!$isMulti) {
+ $values = array_shift($values);
+ }
+ return $values;
+ }
+
+}
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/CoreUtil.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/CoreUtil.php
new file mode 100644
index 00000000..b43e62ca
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/CoreUtil.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Civi\Api4\Utils;
+
+use Civi\Api4\CustomGroup;
+
+require_once 'api/v3/utils.php';
+
+class CoreUtil {
+
+ /**
+ * todo this class should not rely on api3 code
+ *
+ * @param $entityName
+ *
+ * @return \CRM_Core_DAO|string
+ * The DAO name for use in static calls. Return doc block is hacked to allow
+ * auto-completion of static methods
+ */
+ public static function getDAOFromApiName($entityName) {
+ if ($entityName === 'CustomValue' || strpos($entityName, 'Custom_') === 0) {
+ return 'CRM_Contact_BAO_Contact';
+ }
+ return \_civicrm_api3_get_DAO($entityName);
+ }
+
+ /**
+ * Get table name of given Custom group
+ *
+ * @param string $customGroupName
+ *
+ * @return string
+ */
+ public static function getCustomTableByName($customGroupName) {
+ return CustomGroup::get()
+ ->addSelect('table_name')
+ ->addWhere('name', '=', $customGroupName)
+ ->execute()
+ ->first()['table_name'];
+ }
+
+}
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/FormattingUtil.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/FormattingUtil.php
new file mode 100644
index 00000000..3a7cdae5
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/FormattingUtil.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace Civi\Api4\Utils;
+
+use CRM_Utils_Array as UtilsArray;
+
+require_once 'api/v3/utils.php';
+
+class FormattingUtil {
+
+ /**
+ * Massage values into the format the BAO expects for a write operation
+ *
+ * @param $params
+ * @param $entity
+ * @param $fields
+ * @throws \API_Exception
+ */
+ public static function formatWriteParams(&$params, $entity, $fields) {
+ foreach ($fields as $name => $field) {
+ if (!empty($params[$name])) {
+ $value =& $params[$name];
+ // Hack for null values -- see comment below
+ if ($value === 'null') {
+ $value = 'Null';
+ }
+ FormattingUtil::formatValue($value, $field, $entity);
+ // Ensure we have an array for serialized fields
+ if (!empty($field['serialize'] && !is_array($value))) {
+ $value = (array) $value;
+ }
+ }
+ /*
+ * Because of the wacky way that database values are saved we need to format
+ * some of the values here. In this strange world the string 'null' is used to
+ * unset values. Hence if we encounter true null we change it to string 'null'.
+ *
+ * If we encounter the string 'null' then we assume the user actually wants to
+ * set the value to string null. However since the string null is reserved for
+ * unsetting values we must change it. Another quirk of the DB_DataObject is
+ * that it allows 'Null' to be set, but any other variation of string 'null'
+ * will be converted to true null, e.g. 'nuLL', 'NUlL' etc. so we change it to
+ * 'Null'.
+ */
+ elseif (array_key_exists($name, $params) && $params[$name] === NULL) {
+ $params[$name] = 'null';
+ }
+
+ if (strstr($entity, 'Custom_')) {
+ if ($name == 'entity_id') {
+ $params['entityID'] = $params['entity_id'];
+ unset($params['entity_id']);
+ }
+ elseif (!empty($field['custom_field_id'])) {
+ $params['custom_' . $field['custom_field_id']] = $params[$name];
+ unset($params[$name]);
+ }
+ }
+ }
+ }
+
+ /**
+ * Transform raw api input to appropriate format for use in a SQL query.
+ *
+ * This is used by read AND write actions (Get, Create, Update, Replace)
+ *
+ * @param $value
+ * @param $fieldSpec
+ * @throws \API_Exception
+ */
+ public static function formatValue(&$value, $fieldSpec, $entity) {
+ if (is_array($value)) {
+ foreach ($value as &$val) {
+ self::formatValue($val, $fieldSpec, $entity);
+ }
+ return;
+ }
+ $fk = UtilsArray::value('fk_entity', $fieldSpec);
+ if ($fieldSpec['name'] == 'id') {
+ $fk = $entity;
+ }
+ $dataType = UtilsArray::value('data_type', $fieldSpec);
+
+ if ($fk === 'Domain' && $value === 'current_domain') {
+ $value = \CRM_Core_Config::domainID();
+ }
+
+ if ($fk === 'Contact' && !is_numeric($value)) {
+ $value = \_civicrm_api3_resolve_contactID($value);
+ if ('unknown-user' === $value) {
+ throw new \API_Exception("\"{$fieldSpec['name']}\" \"{$value}\" cannot be resolved to a contact ID", 2002, ['error_field' => $fieldSpec['name'], "type" => "integer"]);
+ }
+ }
+
+ switch ($dataType) {
+ case 'Timestamp':
+ $value = date('Y-m-d H:i:s', strtotime($value));
+ break;
+
+ case 'Date':
+ $value = date('Ymd', strtotime($value));
+ break;
+ }
+ }
+
+}
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ReflectionUtils.php b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ReflectionUtils.php
new file mode 100644
index 00000000..76662647
--- /dev/null
+++ b/www/crm/wp-content/plugins/civicrm/civicrm/ext/api4/Civi/Api4/Utils/ReflectionUtils.php
@@ -0,0 +1,119 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.7 |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2015 |
+ +--------------------------------------------------------------------+
+ | This file is a part of CiviCRM. |
+ | |
+ | CiviCRM is free software; you can copy, modify, and distribute it |
+ | under the terms of the GNU Affero General Public License |
+ | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
+ | |
+ | CiviCRM is distributed in the hope that it will be useful, but |
+ | WITHOUT ANY WARRANTY; without even the implied warranty of |
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
+ | See the GNU Affero General Public License for more details. |
+ | |
+ | You should have received a copy of the GNU Affero General Public |
+ | License and the CiviCRM Licensing Exception along |
+ | with this program; if not, contact CiviCRM LLC |
+ | at info[AT]civicrm[DOT]org. If you have questions about the |
+ | GNU Affero General Public License or the licensing of CiviCRM, |
+ | see the CiviCRM license FAQ at http://civicrm.org/licensing |
+ +--------------------------------------------------------------------+
+ */
+
+namespace Civi\Api4\Utils;
+
+/**
+ * Just another place to put static functions...
+ */
+class ReflectionUtils {
+ /**
+ * @param \Reflector|\ReflectionClass $reflection
+ * @param string $type
+ * If we are not reflecting the class itself, specify "Method", "Property", etc.
+ *
+ * @return array
+ */
+ public static function getCodeDocs($reflection, $type = NULL) {
+ $docs = self::parseDocBlock($reflection->getDocComment());
+
+ // Recurse into parent functions
+ if (isset($docs['inheritDoc']) || isset($docs['inheritdoc'])) {
+ unset($docs['inheritDoc'], $docs['inheritdoc']);
+ $newReflection = NULL;
+ try {
+ if ($type) {
+ $name = $reflection->getName();
+ $reflectionClass = $reflection->getDeclaringClass()->getParentClass();
+ if ($reflectionClass) {
+ $getItem = "get$type";
+ $newReflection = $reflectionClass->$getItem($name);
+ }
+ }
+ else {
+ $newReflection = $reflection->getParentClass();
+ }
+ }
+ catch (\ReflectionException $e) {}
+ if ($newReflection) {
+ // Mix in
+ $additionalDocs = self::getCodeDocs($newReflection, $type);
+ if (!empty($docs['comment']) && !empty($additionalDocs['comment'])) {
+ $docs['comment'] .= "\n\n" . $additionalDocs['comment'];
+ }
+ $docs += $additionalDocs;
+ }
+ }
+ return $docs;
+ }
+
+ /**
+ * @param string $comment
+ * @return array
+ */
+ public static function parseDocBlock($comment) {
+ $info = [];
+ foreach (preg_split("/((\r?\n)|(\r\n?))/", $comment) as $num => $line) {
+ if (!$num || strpos($line, '*/') !== FALSE) {
+ continue;
+ }
+ $line = ltrim(trim($line), '* ');
+ if (strpos($line, '@') === 0) {
+ $words = explode(' ', $line);
+ $key = substr($words[0], 1);
+ if ($key == 'var') {
+ $info['type'] = explode('|', $words[1]);
+ }
+ elseif ($key == 'options') {
+ $val = str_replace(', ', ',', implode(' ', array_slice($words, 1)));
+ $info['options'] = explode(',', $val);
+ }
+ else {
+ // Unrecognized annotation, but we'll duly add it to the info array
+ $val = implode(' ', array_slice($words, 1));
+ $info[$key] = strlen($val) ? $val : TRUE;
+ }
+ }
+ elseif ($num == 1) {
+ $info['description'] = $line;
+ }
+ elseif (!$line) {
+ if (isset($info['comment'])) {
+ $info['comment'] .= "\n";
+ }
+ }
+ else {
+ $info['comment'] = isset($info['comment']) ? "{$info['comment']}\n$line" : $line;
+ }
+ }
+ if (isset($info['comment'])) {
+ $info['comment'] = trim($info['comment']);
+ }
+ return $info;
+ }
+
+}