[NFC] array formatting:
[civicrm-core.git] / CRM / Contact / BAO / Individual.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2019 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2019
32 */
33
34 /**
35 * Class contains functions for individual contact type.
36 */
37 class CRM_Contact_BAO_Individual extends CRM_Contact_DAO_Contact {
38
39 /**
40 * Class constructor.
41 */
42 public function __construct() {
43 }
44
45 /**
46 * Function is used to format the individual contact values.
47 *
48 * @param array $params
49 * (reference ) an assoc array of name/value pairs.
50 * @param CRM_Contact_BAO_Contact $contact
51 * Contact object.
52 *
53 * @return CRM_Contact_BAO_Contact
54 */
55 public static function format(&$params, &$contact) {
56 if (!self::dataExists($params)) {
57 return NULL;
58 }
59
60 // "null" value for example is passed by dedupe merge in order to empty.
61 // Display name computation shouldn't consider such values.
62 foreach (['first_name', 'middle_name', 'last_name', 'nick_name', 'formal_title', 'birth_date', 'deceased_date'] as $displayField) {
63 if (CRM_Utils_Array::value($displayField, $params) == "null") {
64 $params[$displayField] = '';
65 }
66 }
67
68 $sortName = $displayName = '';
69 $firstName = CRM_Utils_Array::value('first_name', $params, '');
70 $middleName = CRM_Utils_Array::value('middle_name', $params, '');
71 $lastName = CRM_Utils_Array::value('last_name', $params, '');
72 $nickName = CRM_Utils_Array::value('nick_name', $params, '');
73 $prefix_id = CRM_Utils_Array::value('prefix_id', $params, '');
74 $suffix_id = CRM_Utils_Array::value('suffix_id', $params, '');
75 $formalTitle = CRM_Utils_Array::value('formal_title', $params, '');
76
77 // get prefix and suffix names
78 $prefix = $suffix = NULL;
79 if ($prefix_id) {
80 $params['individual_prefix'] = $prefix = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'prefix_id', $prefix_id);
81 }
82 if ($suffix_id) {
83 $params['individual_suffix'] = $suffix = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'suffix_id', $suffix_id);
84 }
85
86 $params['is_deceased'] = CRM_Utils_Array::value('is_deceased', $params, FALSE);
87
88 $individual = NULL;
89 if ($contact->id) {
90 $individual = new CRM_Contact_BAO_Contact();
91 $individual->id = $contact->id;
92 if ($individual->find(TRUE)) {
93
94 //lets allow to update single name field though preserveDBName
95 //but if db having null value and params contain value, CRM-4330.
96 $useDBNames = [];
97
98 foreach (['last', 'middle', 'first', 'nick'] as $name) {
99 $dbName = "{$name}_name";
100 $value = $individual->$dbName;
101
102 // the db has name values
103 if ($value && !empty($params['preserveDBName'])) {
104 $useDBNames[] = $name;
105 }
106 }
107
108 foreach (['prefix', 'suffix'] as $name) {
109 $dbName = "{$name}_id";
110 $value = $individual->$dbName;
111 if ($value && !empty($params['preserveDBName'])) {
112 $useDBNames[] = $name;
113 }
114 }
115
116 if ($individual->formal_title && !empty($params['preserveDBName'])) {
117 $useDBNames[] = 'formal_title';
118 }
119
120 // CRM-4430
121 //1. preserve db name if want
122 //2. lets get value from param if exists.
123 //3. if not in params, lets get from db.
124
125 foreach (['last', 'middle', 'first', 'nick'] as $name) {
126 $phpName = "{$name}Name";
127 $dbName = "{$name}_name";
128 $value = $individual->$dbName;
129 if (in_array($name, $useDBNames)) {
130 $params[$dbName] = $value;
131 $contact->$dbName = $value;
132 $$phpName = $value;
133 }
134 elseif (array_key_exists($dbName, $params)) {
135 $$phpName = $params[$dbName];
136 }
137 elseif ($value) {
138 $$phpName = $value;
139 }
140 }
141
142 foreach (['prefix', 'suffix'] as $name) {
143 $dbName = "{$name}_id";
144
145 $value = $individual->$dbName;
146 if (in_array($name, $useDBNames)) {
147 $params[$dbName] = $value;
148 $contact->$dbName = $value;
149 if ($value) {
150 $$name = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', $dbName, $value);
151 }
152 else {
153 $$name = NULL;
154 }
155 }
156 elseif (array_key_exists($dbName, $params)) {
157 // CRM-5278
158 if (!empty($params[$dbName])) {
159 $$name = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', $dbName, $params[$dbName]);
160 }
161 }
162 elseif ($value) {
163 $$name = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', $dbName, $value);
164 }
165 }
166
167 if (in_array('formal_title', $useDBNames)) {
168 $params['formal_title'] = $individual->formal_title;
169 $contact->formal_title = $individual->formal_title;
170 $formalTitle = $individual->formal_title;
171 }
172 elseif (array_key_exists('formal_title', $params)) {
173 $formalTitle = $params['formal_title'];
174 }
175 elseif ($individual->formal_title) {
176 $formalTitle = $individual->formal_title;
177 }
178 }
179 }
180
181 //first trim before further processing.
182 foreach (['lastName', 'firstName', 'middleName'] as $fld) {
183 $$fld = trim($$fld);
184 }
185
186 if ($lastName || $firstName || $middleName) {
187 // make sure we have values for all the name fields.
188 $formatted = $params;
189 $nameParams = [
190 'first_name' => $firstName,
191 'middle_name' => $middleName,
192 'last_name' => $lastName,
193 'nick_name' => $nickName,
194 'individual_suffix' => $suffix,
195 'individual_prefix' => $prefix,
196 'prefix_id' => $prefix_id,
197 'suffix_id' => $suffix_id,
198 'formal_title' => $formalTitle,
199 ];
200 // make sure we have all the name fields.
201 foreach ($nameParams as $name => $value) {
202 if (empty($formatted[$name]) && $value) {
203 $formatted[$name] = $value;
204 }
205 }
206
207 $tokens = [];
208 CRM_Utils_Hook::tokens($tokens);
209 $tokenFields = [];
210 foreach ($tokens as $catTokens) {
211 foreach ($catTokens as $token => $label) {
212 $tokenFields[] = $token;
213 }
214 }
215
216 //build the sort name.
217 $format = Civi::settings()->get('sort_name_format');
218 $sortName = CRM_Utils_Address::format($formatted, $format,
219 FALSE, FALSE, $tokenFields
220 );
221 $sortName = trim($sortName);
222
223 //build the display name.
224 $format = Civi::settings()->get('display_name_format');
225 $displayName = CRM_Utils_Address::format($formatted, $format,
226 FALSE, FALSE, $tokenFields
227 );
228 $displayName = trim($displayName);
229 }
230
231 //start further check for email.
232 if (empty($sortName) || empty($displayName)) {
233 $email = NULL;
234 if (!empty($params['email']) &&
235 is_array($params['email'])
236 ) {
237 foreach ($params['email'] as $emailBlock) {
238 if (isset($emailBlock['is_primary'])) {
239 $email = $emailBlock['email'];
240 break;
241 }
242 }
243 }
244 $uniqId = CRM_Utils_Array::value('user_unique_id', $params);
245 if (!$email && $contact->id) {
246 $email = CRM_Contact_BAO_Contact::getPrimaryEmail($contact->id);
247 }
248 }
249
250 //now set the names.
251 $names = ['displayName' => 'display_name', 'sortName' => 'sort_name'];
252 foreach ($names as $value => $name) {
253 if (empty($$value)) {
254 if ($email) {
255 $$value = $email;
256 }
257 elseif ($uniqId) {
258 $$value = $uniqId;
259 }
260 elseif (!empty($params[$name])) {
261 $$value = $params[$name];
262 }
263 // If we have nothing else going on set sort_name to display_name.
264 elseif ($displayName) {
265 $$value = $displayName;
266 }
267 }
268 //finally if we could not pass anything lets keep db.
269 if (!empty($$value)) {
270 $contact->$name = $$value;
271 }
272 }
273
274 $format = CRM_Utils_Date::getDateFormat('birth');
275 if ($date = CRM_Utils_Array::value('birth_date', $params)) {
276 if (in_array($format, [
277 'dd-mm',
278 'mm/dd',
279 ])) {
280 $separator = '/';
281 if ($format == 'dd-mm') {
282 $separator = '-';
283 }
284 $date = $date . $separator . '1902';
285 }
286 elseif (in_array($format, [
287 'yy-mm',
288 ])) {
289 $date = $date . '-01';
290 }
291 elseif (in_array($format, [
292 'M yy',
293 ])) {
294 $date = $date . '-01';
295 }
296 elseif (in_array($format, [
297 'yy',
298 ])) {
299 $date = $date . '-01-01';
300 }
301 $contact->birth_date = CRM_Utils_Date::processDate($date);
302 }
303 elseif ($contact->birth_date) {
304 $contact->birth_date = CRM_Utils_Date::isoToMysql($contact->birth_date);
305 }
306
307 if ($date = CRM_Utils_Array::value('deceased_date', $params)) {
308 if (in_array($format, [
309 'dd-mm',
310 'mm/dd',
311 ])) {
312 $separator = '/';
313 if ($format == 'dd-mm') {
314 $separator = '-';
315 }
316 $date = $date . $separator . '1902';
317 }
318 elseif (in_array($format, [
319 'yy-mm',
320 ])) {
321 $date = $date . '-01';
322 }
323 elseif (in_array($format, [
324 'M yy',
325 ])) {
326 $date = $date . '-01';
327 }
328 elseif (in_array($format, [
329 'yy',
330 ])) {
331 $date = $date . '-01-01';
332 }
333
334 $contact->deceased_date = CRM_Utils_Date::processDate($date);
335 }
336 elseif ($contact->deceased_date) {
337 $contact->deceased_date = CRM_Utils_Date::isoToMysql($contact->deceased_date);
338 }
339
340 if ($middle_name = CRM_Utils_Array::value('middle_name', $params)) {
341 $contact->middle_name = $middle_name;
342 }
343
344 return $contact;
345 }
346
347 /**
348 * Regenerates display_name for contacts with given prefixes/suffixes.
349 *
350 * @param array $ids
351 * The array with the prefix/suffix id governing which contacts to regenerate.
352 * @param int $action
353 * The action describing whether prefix/suffix was UPDATED or DELETED.
354 */
355 public static function updateDisplayNames(&$ids, $action) {
356 // get the proper field name (prefix_id or suffix_id) and its value
357 $fieldName = '';
358 foreach ($ids as $key => $value) {
359 switch ($key) {
360 case 'individualPrefix':
361 $fieldName = 'prefix_id';
362 $fieldValue = $value;
363 break 2;
364
365 case 'individualSuffix':
366 $fieldName = 'suffix_id';
367 $fieldValue = $value;
368 break 2;
369 }
370 }
371 if ($fieldName == '') {
372 return;
373 }
374
375 // query for the affected individuals
376 $fieldValue = CRM_Utils_Type::escape($fieldValue, 'Integer');
377 $contact = new CRM_Contact_BAO_Contact();
378 $contact->$fieldName = $fieldValue;
379 $contact->find();
380
381 // iterate through the affected individuals and rebuild their display_names
382 while ($contact->fetch()) {
383 $contact = new CRM_Contact_BAO_Contact();
384 $contact->id = $contact->contact_id;
385 if ($action == CRM_Core_Action::DELETE) {
386 $contact->$fieldName = 'NULL';
387 $contact->save();
388 }
389 $contact->display_name = $contact->displayName();
390 $contact->save();
391 }
392 }
393
394 /**
395 * Creates display name.
396 *
397 * @return string
398 * the constructed display name
399 */
400 public function displayName() {
401 $prefix = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'prefix_id');
402 $suffix = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'suffix_id');
403 return str_replace(' ', ' ', trim($prefix[$this->prefix_id] . ' ' . $this->first_name . ' ' . $this->middle_name . ' ' . $this->last_name . ' ' . $suffix[$this->suffix_id]));
404 }
405
406 /**
407 * Check if there is data to create the object.
408 *
409 * @param array $params
410 *
411 * @return bool
412 */
413 public static function dataExists($params) {
414 if ($params['contact_type'] == 'Individual') {
415 return TRUE;
416 }
417
418 return FALSE;
419 }
420
421 }