Merge pull request #15982 from civicrm/5.20
[civicrm-core.git] / Civi / Api4 / Utils / FormattingUtil.php
1 <?php
2
3 /*
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
6 | |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
11 */
12
13 /**
14 *
15 * @package CRM
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 * $Id$
18 *
19 */
20
21
22 namespace Civi\Api4\Utils;
23
24 use CRM_Utils_Array as UtilsArray;
25
26 require_once 'api/v3/utils.php';
27
28 class FormattingUtil {
29
30 /**
31 * Massage values into the format the BAO expects for a write operation
32 *
33 * @param $params
34 * @param $entity
35 * @param $fields
36 * @throws \API_Exception
37 */
38 public static function formatWriteParams(&$params, $entity, $fields) {
39 foreach ($fields as $name => $field) {
40 if (!empty($params[$name])) {
41 $value =& $params[$name];
42 // Hack for null values -- see comment below
43 if ($value === 'null') {
44 $value = 'Null';
45 }
46 FormattingUtil::formatValue($value, $field, $entity);
47 // Ensure we have an array for serialized fields
48 if (!empty($field['serialize'] && !is_array($value))) {
49 $value = (array) $value;
50 }
51 }
52 /*
53 * Because of the wacky way that database values are saved we need to format
54 * some of the values here. In this strange world the string 'null' is used to
55 * unset values. Hence if we encounter true null we change it to string 'null'.
56 *
57 * If we encounter the string 'null' then we assume the user actually wants to
58 * set the value to string null. However since the string null is reserved for
59 * unsetting values we must change it. Another quirk of the DB_DataObject is
60 * that it allows 'Null' to be set, but any other variation of string 'null'
61 * will be converted to true null, e.g. 'nuLL', 'NUlL' etc. so we change it to
62 * 'Null'.
63 */
64 elseif (array_key_exists($name, $params) && $params[$name] === NULL) {
65 $params[$name] = 'null';
66 }
67 }
68
69 \CRM_Utils_API_HTMLInputCoder::singleton()->encodeRow($params);
70 }
71
72 /**
73 * Transform raw api input to appropriate format for use in a SQL query.
74 *
75 * This is used by read AND write actions (Get, Create, Update, Replace)
76 *
77 * @param $value
78 * @param $fieldSpec
79 * @param string $entity
80 * Ex: 'Contact', 'Domain'
81 * @throws \API_Exception
82 */
83 public static function formatValue(&$value, $fieldSpec, $entity) {
84 if (is_array($value)) {
85 foreach ($value as &$val) {
86 self::formatValue($val, $fieldSpec, $entity);
87 }
88 return;
89 }
90 $fk = UtilsArray::value('fk_entity', $fieldSpec);
91 if ($fieldSpec['name'] == 'id') {
92 $fk = $entity;
93 }
94 $dataType = UtilsArray::value('data_type', $fieldSpec);
95
96 if ($fk === 'Domain' && $value === 'current_domain') {
97 $value = \CRM_Core_Config::domainID();
98 }
99
100 if ($fk === 'Contact' && !is_numeric($value)) {
101 $value = \_civicrm_api3_resolve_contactID($value);
102 if ('unknown-user' === $value) {
103 throw new \API_Exception("\"{$fieldSpec['name']}\" \"{$value}\" cannot be resolved to a contact ID", 2002, ['error_field' => $fieldSpec['name'], "type" => "integer"]);
104 }
105 }
106
107 switch ($dataType) {
108 case 'Timestamp':
109 $value = date('Y-m-d H:i:s', strtotime($value));
110 break;
111
112 case 'Date':
113 $value = date('Ymd', strtotime($value));
114 break;
115 }
116
117 $hic = \CRM_Utils_API_HTMLInputCoder::singleton();
118 if (!$hic->isSkippedField($fieldSpec['name'])) {
119 $value = $hic->encodeValue($value);
120 }
121 }
122
123 }