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