Merge pull request #13782 from eileenmcnaughton/tplwhite
[civicrm-core.git] / CRM / Core / BAO / UFGroup.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
6b83d5bd 31 * @copyright CiviCRM LLC (c) 2004-2019
6a488035
TO
32 */
33
34/**
8eedd10a 35 * UF group BAO class.
6a488035
TO
36 */
37class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup {
7da04cde 38 const PUBLIC_VISIBILITY = 1,
6a488035
TO
39 ADMIN_VISIBILITY = 2,
40 LISTINGS_VISIBILITY = 4;
41
42 /**
fe482240 43 * Cache the match clause used in this transaction.
6a488035
TO
44 *
45 * @var string
46 */
47 static $_matchFields = NULL;
48
49 /**
fe482240 50 * Fetch object based on array of properties.
6a488035 51 *
6a0b768e
TO
52 * @param array $params
53 * (reference) an assoc array of name/value pairs.
54 * @param array $defaults
55 * (reference) an assoc array to hold the flattened values.
6a488035 56 *
a6c01b45
CW
57 * @return object
58 * CRM_Core_DAO_UFGroup object
6a488035 59 */
00be9182 60 public static function retrieve(&$params, &$defaults) {
6a488035
TO
61 return CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
62 }
63
64 /**
65 * Retrieve the first non-generic contact type
66 *
6a0b768e
TO
67 * @param int $id
68 * Id of uf_group.
6a488035 69 *
a6c01b45
CW
70 * @return string
71 * contact type
6a488035 72 */
00be9182 73 public static function getContactType($id) {
6a488035
TO
74
75 $validTypes = array_filter(array_keys(CRM_Core_SelectValues::contactType()));
76 $validSubTypes = CRM_Contact_BAO_ContactType::subTypeInfo();
77
78 $typesParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
79 $types = explode(',', $typesParts[0]);
80
81 $cType = NULL;
82 foreach ($types as $type) {
83 if (in_array($type, $validTypes)) {
84 $cType = $type;
85 }
86 elseif (array_key_exists($type, $validSubTypes)) {
87 $cType = CRM_Utils_Array::value('parent', $validSubTypes[$type]);
88 }
2aa397bc 89 if ($cType) {
5d6ac993 90 break;
2aa397bc 91 }
6a488035
TO
92 }
93
94 return $cType;
95 }
96
97 /**
98 * Get the form title.
99 *
6a0b768e
TO
100 * @param int $id
101 * Id of uf_form.
6a488035 102 *
a6c01b45
CW
103 * @return string
104 * title
6a488035 105 *
6a488035
TO
106 */
107 public static function getTitle($id) {
108 return CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
109 }
110
111 /**
fe482240 112 * Update the is_active flag in the db.
6a488035 113 *
6a0b768e
TO
114 * @param int $id
115 * Id of the database record.
116 * @param bool $is_active
117 * Value we want to set the is_active field.
6a488035 118 *
8a4fede3 119 * @return bool
120 * true if we found and updated the object, else false
6a488035 121 */
00be9182 122 public static function setIsActive($id, $is_active) {
6a488035
TO
123 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
124 }
125
126 /**
fe482240 127 * Get all the registration fields.
6a488035 128 *
6a0b768e
TO
129 * @param int $action
130 * What action are we doing.
131 * @param int $mode
132 * Mode.
da6b46f4
EM
133 *
134 * @param null $ctype
6a488035 135 *
a6c01b45
CW
136 * @return array
137 * the fields that are needed for registration
6a488035 138 */
00be9182 139 public static function getRegistrationFields($action, $mode, $ctype = NULL) {
6a488035
TO
140 if ($mode & CRM_Profile_Form::MODE_REGISTER) {
141 $ufGroups = CRM_Core_BAO_UFGroup::getModuleUFGroup('User Registration');
142 }
143 else {
144 $ufGroups = CRM_Core_BAO_UFGroup::getModuleUFGroup('Profile');
145 }
146
147 if (!is_array($ufGroups)) {
148 return FALSE;
149 }
150
151 $fields = array();
152
153 foreach ($ufGroups as $id => $title) {
154 if ($ctype) {
155 $fieldType = CRM_Core_BAO_UFField::getProfileType($id);
156 if (($fieldType != 'Contact') &&
157 ($fieldType != $ctype) &&
158 !CRM_Contact_BAO_ContactType::isExtendsContactType($fieldType, $ctype)
159 ) {
160 continue;
161 }
162 if (CRM_Contact_BAO_ContactType::isaSubType($fieldType)) {
163 $profileSubType = $fieldType;
164 }
165 }
166
167 $subset = self::getFields($id, TRUE, $action,
168 NULL, NULL, FALSE, NULL, TRUE, $ctype
169 );
170
171 // we do not allow duplicates. the first field is the winner
172 foreach ($subset as $name => $field) {
a7488080 173 if (empty($fields[$name])) {
6a488035
TO
174 $fields[$name] = $field;
175 }
176 }
177 }
178
179 return $fields;
180 }
181
182 /**
fe482240 183 * Get all the listing fields.
6a488035 184 *
6a0b768e
TO
185 * @param int $action
186 * What action are we doing.
187 * @param int $visibility
188 * Visibility of fields we are interested in.
189 * @param bool $considerSelector
190 * Whether to consider the in_selector parameter.
da6b46f4 191 * @param array $ufGroupIds
6a0b768e 192 * @param bool $searchable
6a488035 193 *
da6b46f4
EM
194 * @param null $restrict
195 * @param bool $skipPermission
196 * @param int $permissionType
a6c01b45
CW
197 * @return array
198 * the fields that are listings related
6a488035 199 */
e7483cbe 200 public static function getListingFields(
6a488035
TO
201 $action,
202 $visibility,
203 $considerSelector = FALSE,
5d6ac993
TO
204 $ufGroupIds = NULL,
205 $searchable = NULL,
206 $restrict = NULL,
207 $skipPermission = FALSE,
208 $permissionType = CRM_Core_Permission::SEARCH
6a488035
TO
209 ) {
210 if ($ufGroupIds) {
211 $subset = self::getFields($ufGroupIds, FALSE, $action,
212 $visibility, $searchable,
213 FALSE, $restrict,
214 $skipPermission,
215 NULL,
216 $permissionType
217 );
218 if ($considerSelector) {
219 // drop the fields not meant for the selector
220 foreach ($subset as $name => $field) {
221 if (!$field['in_selector']) {
222 unset($subset[$name]);
223 }
224 }
225 }
226 $fields = $subset;
227 }
228 else {
ff4f7744 229 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
230
231 $fields = array();
232 foreach ($ufGroups as $id => $title) {
233 $subset = self::getFields($id, FALSE, $action,
234 $visibility, $searchable,
235 FALSE, $restrict,
236 $skipPermission,
237 NULL,
238 $permissionType
239 );
240 if ($considerSelector) {
241 // drop the fields not meant for the selector
242 foreach ($subset as $name => $field) {
4f99ca55
TO
243 if (!$field['in_selector']) {
244 unset($subset[$name]);
2aa397bc 245 }
6a488035
TO
246 }
247 }
248 $fields = array_merge($fields, $subset);
249 }
250 }
251 return $fields;
252 }
253
254 /**
255 * Get all the fields that belong to the group with the name title,
256 * and format for use with buildProfile. This is the SQL analog of
257 * formatUFFields().
258 *
6a0b768e
TO
259 * @param mix $id
260 * The id of the UF group or ids of ufgroup.
fd31fa4c 261 * @param bool|int $register are we interested in registration fields
6a0b768e
TO
262 * @param int $action
263 * What action are we doing.
264 * @param int $visibility
265 * Visibility of fields we are interested in.
266 * @param $searchable
fd31fa4c 267 * @param bool $showAll
6a0b768e
TO
268 * @param string $restrict
269 * Should we restrict based on a specified profile type.
fd31fa4c
EM
270 * @param bool $skipPermission
271 * @param null $ctype
272 * @param int $permissionType
273 * @param string $orderBy
274 * @param null $orderProfiles
275 *
54957108 276 * @param bool $eventProfile
277 *
a6c01b45 278 * @return array
54957108 279 * The fields that belong to this ufgroup(s)
280 * @throws \Exception
6a488035 281 */
e7483cbe 282 public static function getFields(
6a488035
TO
283 $id,
284 $register = FALSE,
285 $action = NULL,
5d6ac993 286 $visibility = NULL,
6a488035 287 $searchable = NULL,
5d6ac993 288 $showAll = FALSE,
6a488035
TO
289 $restrict = NULL,
290 $skipPermission = FALSE,
5d6ac993 291 $ctype = NULL,
6a488035 292 $permissionType = CRM_Core_Permission::CREATE,
5d6ac993 293 $orderBy = 'field_name',
44792363 294 $orderProfiles = NULL,
295 $eventProfile = FALSE
6a488035
TO
296 ) {
297 if (!is_array($id)) {
298 $id = CRM_Utils_Type::escape($id, 'Positive');
299 $profileIds = array($id);
300 }
301 else {
302 $profileIds = $id;
303 }
304
305 $gids = implode(',', $profileIds);
306 $params = array();
307 if ($restrict) {
f9d8a5d1 308 $query = "SELECT g.* from civicrm_uf_group g
309 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
6a488035 310 WHERE g.id IN ( {$gids} )
f9d8a5d1 311 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
6a488035
TO
312 ";
313 $params = array(1 => array($restrict, 'String'));
314 }
315 else {
316 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
317 }
318
319 if (!$showAll) {
320 $query .= " AND g.is_active = 1";
321 }
322
44792363 323 $checkPermission = array(
324 array(
325 'administer CiviCRM',
326 'manage event profiles',
327 ),
328 );
329 if ($eventProfile && CRM_Core_Permission::check($checkPermission)) {
330 $skipPermission = TRUE;
331 }
332
6a488035
TO
333 // add permissioning for profiles only if not registration
334 if (!$skipPermission) {
335 $permissionClause = CRM_Core_Permission::ufGroupClause($permissionType, 'g.');
336 $query .= " AND $permissionClause ";
337 }
338
339 if ($orderProfiles AND count($profileIds) > 1) {
340 $query .= " ORDER BY FIELD( g.id, {$gids} )";
341 }
5d6ac993
TO
342 $group = CRM_Core_DAO::executeQuery($query, $params);
343 $fields = array();
6a488035
TO
344 $validGroup = FALSE;
345
346 while ($group->fetch()) {
347 $validGroup = TRUE;
348 $query = self::createUFFieldQuery($group->id, $searchable, $showAll, $visibility, $orderBy);
349 $field = CRM_Core_DAO::executeQuery($query);
350
fc040dd2 351 $importableFields = self::getProfileFieldMetadata($showAll);
6a488035
TO
352 list($customFields, $addressCustomFields) = self::getCustomFields($ctype);
353
354 while ($field->fetch()) {
355 list($name, $formattedField) = self::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
356 if ($formattedField !== NULL) {
357 $fields[$name] = $formattedField;
358 }
359 }
360 $field->free();
361 }
362
363 if (empty($fields) && !$validGroup) {
364 CRM_Core_Error::fatal(ts('The requested Profile (gid=%1) is disabled OR it is not configured to be used for \'Profile\' listings in its Settings OR there is no Profile with that ID OR you do not have permission to access this profile. Please contact the site administrator if you need assistance.',
5d6ac993
TO
365 array(1 => implode(',', $profileIds))
366 ));
6a488035
TO
367 }
368 else {
369 self::reformatProfileFields($fields);
370 }
371
372 return $fields;
373 }
374
375 /**
376 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
377 * of getFields().
378 *
6a0b768e
TO
379 * @param array $groupArr
380 * (mimic CRM_UF_DAO_UFGroup).
381 * @param array $fieldArrs
382 * List of fields (each mimics CRM_UF_DAO_UFField).
383 * @param bool $visibility
384 * Visibility of fields we are interested in.
6a488035 385 * @param bool $searchable
77b97be7
EM
386 * @param bool $showAll
387 * @param null $ctype
388 * @param int $permissionType
389 *
6a488035 390 * @return array
c490a46a 391 * @see self::getFields
6a488035
TO
392 */
393 public static function formatUFFields(
394 $groupArr,
395 $fieldArrs,
396 $visibility = NULL,
397 $searchable = NULL,
398 $showAll = FALSE,
399 $ctype = NULL,
400 $permissionType = CRM_Core_Permission::CREATE
401 ) {
402 // $group = new CRM_Core_DAO_UFGroup();
403 // $group->copyValues($groupArr); // no... converts string('') to string('null')
404 $group = (object) $groupArr;
405
406 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
407 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
408 // they did -- the obvious fix would produce mutual recursion.
409 $ufGroupType = self::_calculateGroupType($fieldArrs);
5d6ac993
TO
410 $profileType = CRM_Core_BAO_UFField::calculateProfileType(implode(',', $ufGroupType));
411 $contactActivityProfile = CRM_Core_BAO_UFField::checkContactActivityProfileTypeByGroupType(implode(',', $ufGroupType));
6a488035
TO
412 $importableFields = self::getImportableFields($showAll, $profileType, $contactActivityProfile);
413 list($customFields, $addressCustomFields) = self::getCustomFields($ctype);
414
415 $formattedFields = array();
416 foreach ($fieldArrs as $fieldArr) {
6a488035
TO
417 $field = (object) $fieldArr;
418 if (!self::filterUFField($field, $searchable, $showAll, $visibility)) {
419 continue;
420 }
421
422 list($name, $formattedField) = self::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
423 if ($formattedField !== NULL) {
424 $formattedFields[$name] = $formattedField;
425 }
426 }
427 return $formattedFields;
428 }
429
430 /**
431 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
432 *
433 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
434 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
e7483cbe 435 * @param array $customFields
6a488035
TO
436 * @param array $addressCustomFields
437 * @param array $importableFields
6a0b768e
TO
438 * @param int $permissionType
439 * Eg CRM_Core_Permission::CREATE.
6a488035
TO
440 * @return array
441 */
442 protected static function formatUFField(
443 $group,
444 $field,
445 $customFields,
446 $addressCustomFields,
447 $importableFields,
448 $permissionType = CRM_Core_Permission::CREATE
449 ) {
450 $name = $field->field_name;
451 $title = $field->label;
452
453 $addressCustom = FALSE;
454 if (in_array($permissionType, array(
5d6ac993
TO
455 CRM_Core_Permission::CREATE,
456 CRM_Core_Permission::EDIT,
457 )) &&
6a488035
TO
458 in_array($field->field_name, array_keys($addressCustomFields))
459 ) {
460 $addressCustom = TRUE;
461 $name = "address_{$name}";
462 }
887e764d
PN
463 if ($field->field_name == 'url') {
464 $name .= "-{$field->website_type_id}";
465 }
466 elseif (!empty($field->location_type_id)) {
6a488035
TO
467 $name .= "-{$field->location_type_id}";
468 }
469 else {
470 $locationFields = self::getLocationFields();
471 if (in_array($field->field_name, $locationFields) || $addressCustom) {
472 $name .= '-Primary';
473 }
474 }
475
476 if (isset($field->phone_type_id)) {
477 $name .= "-{$field->phone_type_id}";
478 }
d86e674f 479 $fieldMetaData = CRM_Utils_Array::value($name, $importableFields, (isset($importableFields[$field->field_name]) ? $importableFields[$field->field_name] : array()));
6a488035
TO
480
481 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
482 // I guess to make field self sufficient with all the required data and avoid additional calls
483 $formattedField = array(
484 'name' => $name,
485 'groupTitle' => $group->title,
5d6ac993 486 'groupName' => $group->name,
ce1a9db4 487 'groupDisplayTitle' => (!empty($group->frontend_title)) ? $group->frontend_title : $group->title,
6a488035
TO
488 'groupHelpPre' => empty($group->help_pre) ? '' : $group->help_pre,
489 'groupHelpPost' => empty($group->help_post) ? '' : $group->help_post,
490 'title' => $title,
491 'where' => CRM_Utils_Array::value('where', CRM_Utils_Array::value($field->field_name, $importableFields)),
492 'attributes' => CRM_Core_DAO::makeAttribute(CRM_Utils_Array::value($field->field_name, $importableFields)),
493 'is_required' => $field->is_required,
494 'is_view' => $field->is_view,
495 'help_pre' => $field->help_pre,
496 'help_post' => $field->help_post,
497 'visibility' => $field->visibility,
498 'in_selector' => $field->in_selector,
499 'rule' => CRM_Utils_Array::value('rule', CRM_Utils_Array::value($field->field_name, $importableFields)),
500 'location_type_id' => isset($field->location_type_id) ? $field->location_type_id : NULL,
887e764d 501 'website_type_id' => isset($field->website_type_id) ? $field->website_type_id : NULL,
6a488035
TO
502 'phone_type_id' => isset($field->phone_type_id) ? $field->phone_type_id : NULL,
503 'group_id' => $group->id,
cd0dd278
DG
504 'add_to_group_id' => isset($group->add_to_group_id) ? $group->add_to_group_id : NULL,
505 'add_captcha' => isset($group->add_captcha) ? $group->add_captcha : NULL,
6a488035
TO
506 'field_type' => $field->field_type,
507 'field_id' => $field->id,
0c145cc0
DL
508 'pseudoconstant' => CRM_Utils_Array::value(
509 'pseudoconstant',
510 CRM_Utils_Array::value($field->field_name, $importableFields)
511 ),
512 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
513 'dbName' => CRM_Utils_Array::value(
514 'dbName',
515 CRM_Utils_Array::value($field->field_name, $importableFields)
516 ),
6a488035 517 'skipDisplay' => 0,
d86e674f 518 'data_type' => CRM_Utils_Type::getDataTypeFromFieldMetadata($fieldMetaData),
7799da7c 519 'bao' => CRM_Utils_Array::value('bao', $fieldMetaData),
6a488035
TO
520 );
521
d86e674f 522 $formattedField = CRM_Utils_Date::addDateMetadataToField($fieldMetaData, $formattedField);
523
6a488035
TO
524 //adding custom field property
525 if (substr($field->field_name, 0, 6) == 'custom' ||
526 substr($field->field_name, 0, 14) === 'address_custom'
527 ) {
528 // if field is not present in customFields, that means the user
529 // DOES NOT HAVE permission to access that field
530 if (array_key_exists($field->field_name, $customFields)) {
531 $formattedField['is_search_range'] = $customFields[$field->field_name]['is_search_range'];
532 // fix for CRM-1994
533 $formattedField['options_per_line'] = $customFields[$field->field_name]['options_per_line'];
6a488035
TO
534 $formattedField['html_type'] = $customFields[$field->field_name]['html_type'];
535
536 if (CRM_Utils_Array::value('html_type', $formattedField) == 'Select Date') {
537 $formattedField['date_format'] = $customFields[$field->field_name]['date_format'];
538 $formattedField['time_format'] = $customFields[$field->field_name]['time_format'];
d86e674f 539 $formattedField['is_datetime_field'] = TRUE;
2732685b 540 $formattedField['smarty_view_format'] = CRM_Utils_Date::getDateFieldViewFormat($formattedField['date_format']);
6a488035
TO
541 }
542
543 $formattedField['is_multi_summary'] = $field->is_multi_summary;
544 return array($name, $formattedField);
545 }
546 else {
547 $formattedField = NULL;
548 return array($name, $formattedField);
549 }
550 }
551 return array($name, $formattedField);
552 }
553
554 /**
fe482240 555 * Create a query to find all visible UFFields in a UFGroup.
6a488035
TO
556 *
557 * This is the SQL-variant of checkUFFieldDisplayable().
558 *
559 * @param int $groupId
560 * @param bool $searchable
561 * @param bool $showAll
562 * @param int $visibility
6a0b768e
TO
563 * @param string $orderBy
564 * Comma-delimited list of SQL columns.
6a488035
TO
565 * @return string
566 */
567 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
568 $where = " WHERE uf_group_id = {$groupId}";
569
570 if ($searchable) {
571 $where .= " AND is_searchable = 1";
572 }
573
574 if (!$showAll) {
575 $where .= " AND is_active = 1";
576 }
577
578 if ($visibility) {
579 $clause = array();
580 if ($visibility & self::PUBLIC_VISIBILITY) {
581 $clause[] = 'visibility = "Public Pages"';
582 }
583 if ($visibility & self::ADMIN_VISIBILITY) {
584 $clause[] = 'visibility = "User and User Admin Only"';
585 }
586 if ($visibility & self::LISTINGS_VISIBILITY) {
587 $clause[] = 'visibility = "Public Pages and Listings"';
588 }
589 if (!empty($clause)) {
590 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
591 }
592 }
593
594 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
595 if ($orderBy) {
596 $query .= ", " . $orderBy;
597 return $query;
598 }
599 return $query;
600 }
601
602 /**
fe482240 603 * Create a query to find all visible UFFields in a UFGroup.
6a488035
TO
604 *
605 * This is the PHP in-memory variant of createUFFieldQuery().
606 *
607 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
608 * @param bool $searchable
609 * @param bool $showAll
610 * @param int $visibility
a6c01b45
CW
611 * @return bool
612 * TRUE if field is displayable
6a488035
TO
613 */
614 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
615 if ($searchable && $field->is_searchable != 1) {
616 return FALSE;
617 }
618
619 if (!$showAll && $field->is_active != 1) {
620 return FALSE;
621 }
622
623 if ($visibility) {
624 $allowedVisibilities = array();
625 if ($visibility & self::PUBLIC_VISIBILITY) {
626 $allowedVisibilities[] = 'Public Pages';
627 }
628 if ($visibility & self::ADMIN_VISIBILITY) {
629 $allowedVisibilities[] = 'User and User Admin Only';
630 }
631 if ($visibility & self::LISTINGS_VISIBILITY) {
632 $allowedVisibilities[] = 'Public Pages and Listings';
633 }
634 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
635 if (!empty($allowedVisibilities) && !in_array($field->visibility, $allowedVisibilities)) {
636 return FALSE;
637 }
638 }
639
640 return TRUE;
641 }
642
b5c2afd0 643 /**
fc040dd2 644 * Get a list of filtered field metadata.
645 *
646 * @deprecated use getProfileFieldMetadata
647 *
b5c2afd0
EM
648 * @param $showAll
649 * @param $profileType
650 * @param $contactActivityProfile
fc040dd2 651 * @param bool $filterMode
652 * Filter mode means you are using importable fields for filtering rather than just getting metadata.
653 * With filter mode = FALSE BOTH activity fields and component fields are returned.
654 * I can't see why you would ever want to use this function in filter mode as the component fields are
655 * still unfiltered. However, I feel scared enough to leave it as it is. I have marked this function as
656 * deprecated and am recommending the wrapper 'getProfileFieldMetadata' in order to try to
657 * send this confusion to history.
b5c2afd0
EM
658 *
659 * @return array
660 */
fc040dd2 661 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile, $filterMode = TRUE) {
6a488035
TO
662 if (!$showAll) {
663 $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
664 }
665 else {
666 $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
667 }
668
fc040dd2 669 $activityFields = CRM_Activity_BAO_Activity::getProfileFields();
670 $componentFields = CRM_Core_Component::getQueryFields();
671 if ($filterMode == TRUE) {
672 if ($profileType == 'Activity' || $contactActivityProfile) {
673 $importableFields = array_merge($importableFields, $activityFields);
674 }
675 else {
676 $importableFields = array_merge($importableFields, $componentFields);
677 }
6a488035
TO
678 }
679 else {
fc040dd2 680 $importableFields = array_merge($importableFields, $activityFields, $componentFields);
6a488035
TO
681 }
682
6a488035
TO
683 $importableFields['group']['title'] = ts('Group(s)');
684 $importableFields['group']['where'] = NULL;
685 $importableFields['tag']['title'] = ts('Tag(s)');
686 $importableFields['tag']['where'] = NULL;
687 return $importableFields;
688 }
689
fc040dd2 690 /**
691 * Get the metadata for all potential profile fields.
692 *
693 * @param bool $isIncludeInactive
694 * Should disabled fields be included.
695 *
696 * @return array
697 * Field metadata for all fields that might potentially be in a profile.
698 */
699 protected static function getProfileFieldMetadata($isIncludeInactive) {
700 return self::getImportableFields($isIncludeInactive, NULL, NULL, NULL, TRUE);
701 }
702
bc854509 703 /**
704 * Get the fields relating to locations.
705 *
706 * @return array
707 */
6a488035
TO
708 public static function getLocationFields() {
709 static $locationFields = array(
710 'street_address',
711 'supplemental_address_1',
712 'supplemental_address_2',
207f62c6 713 'supplemental_address_3',
6a488035
TO
714 'city',
715 'postal_code',
716 'postal_code_suffix',
717 'geo_code_1',
718 'geo_code_2',
719 'state_province',
720 'country',
721 'county',
722 'phone',
723 'phone_and_ext',
724 'email',
725 'im',
726 'address_name',
727 'phone_ext',
728 );
729 return $locationFields;
730 }
731
b5c2afd0
EM
732 /**
733 * @param $ctype
734 *
735 * @return mixed
736 */
6a488035
TO
737 protected static function getCustomFields($ctype) {
738 static $customFieldCache = array();
739 if (!isset($customFieldCache[$ctype])) {
740 $customFields = CRM_Core_BAO_CustomField::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
741
742 // hack to add custom data for components
1cb28d5d 743 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
6a488035
TO
744 foreach ($components as $value) {
745 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField::getFieldsForImport($value));
746 }
747 $addressCustomFields = CRM_Core_BAO_CustomField::getFieldsForImport('Address');
748 $customFields = array_merge($customFields, $addressCustomFields);
749 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
750 }
751 return $customFieldCache[$ctype];
752 }
753
754 /**
fe482240 755 * Check the data validity.
6a488035 756 *
6a0b768e
TO
757 * @param int $userID
758 * The user id that we are actually editing.
b247a732 759 * @param string $name
760 * The machine-name of the group we are interested in.
2a6da8d7 761 * @param bool $register
6a0b768e
TO
762 * @param int $action
763 * The action of the form.
6a488035 764 *
2a6da8d7 765 * @pram boolean $register is this the registrtion form
e7483cbe 766 * @return bool
a6c01b45 767 * true if form is valid
6a488035 768 */
b247a732 769 public static function isValid($userID, $name, $register = FALSE, $action = NULL) {
6a488035
TO
770 if ($register) {
771 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
772 ts('Dynamic Form Creator'),
773 $action
774 );
775 $controller->set('id', $userID);
776 $controller->set('register', 1);
777 $controller->process();
778 return $controller->validate();
779 }
780 else {
781 // make sure we have a valid group
782 $group = new CRM_Core_DAO_UFGroup();
783
b247a732 784 $group->name = $name;
6a488035
TO
785
786 if ($group->find(TRUE) && $userID) {
787 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
788 $controller->set('gid', $group->id);
789 $controller->set('id', $userID);
790 $controller->set('register', 0);
791 $controller->process();
792 return $controller->validate();
793 }
794 return TRUE;
795 }
796 }
797
798 /**
fe482240 799 * Get the html for the form that represents this particular group.
6a488035 800 *
6a0b768e
TO
801 * @param int $userID
802 * The user id that we are actually editing.
803 * @param string $title
804 * The title of the group we are interested in.
805 * @param int $action
806 * The action of the form.
807 * @param bool $register
808 * Is this the registration form.
809 * @param bool $reset
810 * Should we reset the form?.
811 * @param int $profileID
812 * Do we have the profile ID?.
2a6da8d7
EM
813 *
814 * @param bool $doNotProcess
815 * @param null $ctype
6a488035 816 *
a6c01b45
CW
817 * @return string
818 * the html for the form on success, otherwise empty string
6a488035 819 */
e7483cbe 820 public static function getEditHTML(
5d6ac993 821 $userID,
6a488035 822 $title,
5d6ac993
TO
823 $action = NULL,
824 $register = FALSE,
825 $reset = FALSE,
826 $profileID = NULL,
6a488035 827 $doNotProcess = FALSE,
5d6ac993 828 $ctype = NULL
6a488035
TO
829 ) {
830
831 if ($register) {
832 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
833 ts('Dynamic Form Creator'),
834 $action
835 );
836 if ($reset || $doNotProcess) {
837 // hack to make sure we do not process this form
838 $oldQFDefault = CRM_Utils_Array::value('_qf_default',
839 $_POST
840 );
841 unset($_POST['_qf_default']);
842 unset($_REQUEST['_qf_default']);
843 if ($reset) {
844 $controller->reset();
845 }
846 }
847
848 $controller->set('id', $userID);
849 $controller->set('register', 1);
850 $controller->set('skipPermission', 1);
851 $controller->set('ctype', $ctype);
852 $controller->process();
853 if ($doNotProcess || !empty($_POST)) {
854 $controller->validate();
855 }
856 $controller->setEmbedded(TRUE);
857
858 //CRM-5839 - though we want to process form, get the control back.
859 $controller->setSkipRedirection(($doNotProcess) ? FALSE : TRUE);
860
861 $controller->run();
862
863 // we are done processing so restore the POST/REQUEST vars
864 if (($reset || $doNotProcess) && $oldQFDefault) {
865 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
866 }
867
868 $template = CRM_Core_Smarty::singleton();
869
870 // Hide CRM error messages if they are displayed using drupal form_set_error.
871 if (!empty($_POST)) {
872 $template->assign('suppressForm', TRUE);
873 }
874
875 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
876 }
877 else {
878 if (!$profileID) {
879 // make sure we have a valid group
880 $group = new CRM_Core_DAO_UFGroup();
881
882 $group->title = $title;
883
884 if ($group->find(TRUE)) {
885 $profileID = $group->id;
886 }
887 }
888
889 if ($profileID) {
890 // make sure profileID and ctype match if ctype exists
891 if ($ctype) {
892 $profileType = CRM_Core_BAO_UFField::getProfileType($profileID);
893 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
894 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
895 }
896
897 if (($profileType != 'Contact') && ($profileType != $ctype)) {
898 return NULL;
899 }
900 }
901
902 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
903 ts('Dynamic Form Creator'),
904 $action
905 );
906 if ($reset) {
907 $controller->reset();
908 }
909 $controller->set('gid', $profileID);
910 $controller->set('id', $userID);
911 $controller->set('register', 0);
912 $controller->set('skipPermission', 1);
913 if ($ctype) {
914 $controller->set('ctype', $ctype);
915 }
916 $controller->process();
917 $controller->setEmbedded(TRUE);
918
919 //CRM-5846 - give the control back to drupal.
920 $controller->setSkipRedirection(($doNotProcess) ? FALSE : TRUE);
921 $controller->run();
922
923 $template = CRM_Core_Smarty::singleton();
924
925 // Hide CRM error messages if they are displayed using drupal form_set_error.
926 if (!empty($_POST) && CRM_Core_Config::singleton()->userFramework == 'Drupal') {
927 if (arg(0) == 'user' || (arg(0) == 'admin' && arg(1) == 'people')) {
928 $template->assign('suppressForm', TRUE);
929 }
930 }
931
932 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
933 if (!$template->template_exists($templateFile)) {
934 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
935 }
936 return trim($template->fetch($templateFile));
937 }
938 else {
939 $userEmail = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID);
940
941 // if post not empty then only proceed
942 if (!empty($_POST)) {
943 // get the new email
944 $config = CRM_Core_Config::singleton();
945 $email = CRM_Utils_Array::value('mail', $_POST);
946
947 if (CRM_Utils_Rule::email($email) && ($email != $userEmail[1])) {
948 CRM_Core_BAO_UFMatch::updateContactEmail($userID, $email);
949 }
950 }
951 }
952 }
953 return '';
954 }
955
6a488035 956 /**
f3f00653 957 * Given a contact id and a field set, return the values from the db.
6a488035 958 *
100fef9d 959 * @param int $cid
6a0b768e
TO
960 * @param array $fields
961 * The profile fields of interest.
962 * @param array $values
963 * The values for the above fields.
964 * @param bool $searchable
965 * Searchable or not.
966 * @param array $componentWhere
967 * Component condition.
968 * @param bool $absolute
969 * Return urls in absolute form (useful when sending an email).
2a6da8d7 970 * @param null $additionalWhereClause
f3f00653 971 *
972 * @return null|array
6a488035 973 */
5d6ac993
TO
974 public static function getValues(
975 $cid, &$fields, &$values,
6a488035
TO
976 $searchable = TRUE, $componentWhere = NULL,
977 $absolute = FALSE, $additionalWhereClause = NULL
978 ) {
979 if (empty($cid) && empty($componentWhere)) {
980 return NULL;
981 }
982
983 // get the contact details (hier)
984 $returnProperties = CRM_Contact_BAO_Contact::makeHierReturnProperties($fields);
985 $params = $cid ? array(array('contact_id', '=', $cid, 0, 0)) : array();
986
987 // add conditions specified by components. eg partcipant_id etc
988 if (!empty($componentWhere)) {
989 $params = array_merge($params, $componentWhere);
990 }
991
992 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
6a488035 993
5d6ac993 994 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
6a488035 995 FALSE, FALSE, FALSE, $additionalWhereClause);
6511fc14 996 while ($details->fetch()) {
c4deda45
BS
997 if (!$details) {
998 return;
999 }
6a488035 1000 }
d9ab802d 1001 $query->convertToPseudoNames($details);
6a488035
TO
1002 $config = CRM_Core_Config::singleton();
1003
b2b0530a 1004 $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
5d6ac993
TO
1005 $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id');
1006 $websiteTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id');
6a488035
TO
1007
1008 $multipleFields = array('url');
6a488035
TO
1009
1010 //start of code to set the default values
1011 foreach ($fields as $name => $field) {
1012 // fix for CRM-3962
1013 if ($name == 'id') {
1014 $name = 'contact_id';
1015 }
1016
1017 // skip fields that should not be displayed separately
a7488080 1018 if (!empty($field['skipDisplay'])) {
6a488035
TO
1019 continue;
1020 }
1021
50bf705c 1022 // Create a unique, non-empty index for each field.
6a488035 1023 $index = $field['title'];
f9f40af3
TO
1024 if ($index === '') {
1025 $index = ' ';
2aa397bc 1026 }
5d6ac993 1027 while (array_key_exists($index, $values)) {
50bf705c 1028 $index .= ' ';
5d6ac993 1029 }
6a488035 1030
6a488035
TO
1031 $params[$index] = $values[$index] = '';
1032 $customFieldName = NULL;
1033 // hack for CRM-665
1034 if (isset($details->$name) || $name == 'group' || $name == 'tag') {
1035 // to handle gender / suffix / prefix
04ffef8d 1036 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
04ffef8d 1037 $params[$index] = $details->$name;
46796b19 1038 $values[$index] = $details->$name;
6a488035
TO
1039 }
1040 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)) {
5d6ac993 1041 $dname = $name . '_display';
6a488035 1042 $values[$index] = $details->$dname;
5d6ac993 1043 $name = $name . '_id';
6a488035
TO
1044 $params[$index] = $details->$name;
1045 }
1046 elseif (in_array($name, array(
5d6ac993
TO
1047 'state_province',
1048 'country',
21dfd5f5 1049 'county',
5d6ac993 1050 ))) {
6a488035 1051 $values[$index] = $details->$name;
5d6ac993 1052 $idx = $name . '_id';
6a488035
TO
1053 $params[$index] = $details->$idx;
1054 }
6a488035 1055 elseif ($name === 'preferred_language') {
6a488035 1056 $params[$index] = $details->$name;
a8c23526 1057 $values[$index] = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
6a488035
TO
1058 }
1059 elseif ($name == 'group') {
1060 $groups = CRM_Contact_BAO_GroupContact::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1061 $title = $ids = array();
1062
1063 foreach ($groups as $g) {
1064 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1065 // VIEW permission on that group
69953588 1066 $groupPerm = CRM_Contact_BAO_Group::checkPermission($g['group_id'], TRUE);
6a488035
TO
1067
1068 if ($g['visibility'] != 'User and User Admin Only' ||
1069 CRM_Utils_Array::key(CRM_Core_Permission::VIEW, $groupPerm)
1070 ) {
1071 $title[] = $g['title'];
1072 if ($g['visibility'] == 'Public Pages') {
1073 $ids[] = $g['group_id'];
1074 }
1075 }
1076 }
1077 $values[$index] = implode(', ', $title);
1078 $params[$index] = implode(',', $ids);
1079 }
1080 elseif ($name == 'tag') {
1081 $entityTags = CRM_Core_BAO_EntityTag::getTag($cid);
5d6ac993
TO
1082 $allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1083 $title = array();
6a488035
TO
1084 foreach ($entityTags as $tagId) {
1085 $title[] = $allTags[$tagId];
1086 }
1087 $values[$index] = implode(', ', $title);
1088 $params[$index] = implode(',', $entityTags);
1089 }
1090 elseif ($name == 'activity_status_id') {
1091 $activityStatus = CRM_Core_PseudoConstant::activityStatus();
1092 $values[$index] = $activityStatus[$details->$name];
1093 $params[$index] = $details->$name;
1094 }
1095 elseif ($name == 'activity_date_time') {
1096 $values[$index] = CRM_Utils_Date::customFormat($details->$name);
1097 $params[$index] = $details->$name;
1098 }
1099 elseif ($name == 'contact_sub_type') {
1100 $contactSubTypeNames = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details->$name);
1101 if (!empty($contactSubTypeNames)) {
1102 $contactSubTypeLabels = array();
1103 // get all contact subtypes
1104 $allContactSubTypes = CRM_Contact_BAO_ContactType::subTypeInfo();
1105 // build contact subtype labels array
5d6ac993 1106 foreach ($contactSubTypeNames as $cstName) {
6a488035
TO
1107 if ($cstName) {
1108 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1109 }
1110 }
1111 $values[$index] = implode(',', $contactSubTypeLabels);
1112 }
1113
1114 $params[$index] = $details->$name;
1115 }
1116 else {
1117 if (substr($name, 0, 7) === 'do_not_' || substr($name, 0, 3) === 'is_') {
1118 if ($details->$name) {
1119 $values[$index] = '[ x ]';
1120 }
1121 }
1122 else {
1123 if ($cfID = CRM_Core_BAO_CustomField::getKeyID($name)) {
1124 $htmlType = $field['html_type'];
1125
1126 // field_type is only set when we are retrieving profile values
1127 // when sending email, we call the same function to get custom field
1128 // values etc, i.e. emulating a profile
1129 $fieldType = CRM_Utils_Array::value('field_type', $field);
1130
1131 if ($htmlType == 'File') {
1132 $entityId = $cid;
1133 if (!$cid &&
5d6ac993
TO
1134 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1135 ) {
6a488035
TO
1136 $entityId = $componentWhere[0][2];
1137 }
1138
1139 $fileURL = CRM_Core_BAO_CustomField::getFileURL($entityId,
1140 $cfID,
1141 NULL,
b42d84aa 1142 $absolute,
1143 $additionalWhereClause
6a488035
TO
1144 );
1145 $params[$index] = $values[$index] = $fileURL['file_url'];
1146 }
1147 else {
1148 $customVal = NULL;
1149 if (isset($dao) && property_exists($dao, 'data_type') &&
1150 ($dao->data_type == 'Int' ||
1151 $dao->data_type == 'Boolean'
1152 )
1153 ) {
5d6ac993 1154 $customVal = (int ) ($details->{$name});
6a488035
TO
1155 }
1156 elseif (isset($dao) && property_exists($dao, 'data_type')
1157 && $dao->data_type == 'Float'
1158 ) {
5d6ac993 1159 $customVal = (float ) ($details->{$name});
6a488035
TO
1160 }
1161 elseif (!CRM_Utils_System::isNull(explode(CRM_Core_DAO::VALUE_SEPARATOR,
5d6ac993
TO
1162 $details->{$name}
1163 ))
1164 ) {
6a488035
TO
1165 $customVal = $details->{$name};
1166 }
1167
1168 //CRM-4582
1169 if (CRM_Utils_System::isNull($customVal)) {
1170 continue;
1171 }
1172
1173 $params[$index] = $customVal;
8cee0c70 1174 $values[$index] = CRM_Core_BAO_CustomField::displayValue($customVal, $cfID);
1b4d9e39 1175 if ($field['data_type'] == 'ContactReference') {
6a488035
TO
1176 $params[$index] = $values[$index];
1177 }
1178 if (CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField',
5d6ac993
TO
1179 $cfID, 'is_search_range'
1180 )
1181 ) {
6a488035
TO
1182 $customFieldName = "{$name}_from";
1183 }
1184 }
1185 }
1186 elseif ($name == 'image_URL') {
77d45291 1187 list($width, $height) = getimagesize(CRM_Utils_String::unstupifyUrl($details->$name));
6a488035
TO
1188 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact::getThumbSize($width, $height);
1189
1190 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1191 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1192 }
1193 elseif (in_array($name, array(
5d6ac993
TO
1194 'birth_date',
1195 'deceased_date',
5d6ac993 1196 ))) {
363544d7 1197 // @todo this set should be determined from metadata, not hard-coded.
6a488035
TO
1198 $values[$index] = CRM_Utils_Date::customFormat($details->$name);
1199 $params[$index] = CRM_Utils_Date::isoToMysql($details->$name);
1200 }
1201 else {
1202 $dao = '';
1203 if ($index == 'Campaign') {
1204 $dao = 'CRM_Campaign_DAO_Campaign';
1205 }
1206 elseif ($index == 'Contribution Page') {
1207 $dao = 'CRM_Contribute_DAO_ContributionPage';
1208 }
1209 if ($dao) {
1210 $value = CRM_Core_DAO::getFieldValue($dao, $details->$name, 'title');
1211 }
1212 else {
1213 $value = $details->$name;
1214 }
1215 $values[$index] = $value;
1216 }
1217 }
1218 }
1219 }
1220 elseif (strpos($name, '-') !== FALSE) {
1221 list($fieldName, $id, $type) = CRM_Utils_System::explode('-', $name, 3);
1222
1223 if (!in_array($fieldName, $multipleFields)) {
1224 if ($id == 'Primary') {
1225 // fix for CRM-1543
1226 // not sure why we'd every use Primary location type id
1227 // we need to fix the source if we are using it
1228 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1229 $locationTypeName = 1;
1230 }
1231 else {
1232 $locationTypeName = CRM_Utils_Array::value($id, $locationTypes);
1233 }
1234
1235 if (!$locationTypeName) {
1236 continue;
1237 }
1238
1239 $detailName = "{$locationTypeName}-{$fieldName}";
1240 $detailName = str_replace(' ', '_', $detailName);
1241
1242 if (in_array($fieldName, array(
5d6ac993
TO
1243 'phone',
1244 'im',
1245 'email',
21dfd5f5 1246 'openid',
5d6ac993 1247 ))) {
6a488035
TO
1248 if ($type) {
1249 $detailName .= "-{$type}";
1250 }
1251 }
1252
1253 if (in_array($fieldName, array(
5d6ac993
TO
1254 'state_province',
1255 'country',
21dfd5f5 1256 'county',
5d6ac993 1257 ))) {
6a488035 1258 $values[$index] = $details->$detailName;
5d6ac993 1259 $idx = $detailName . '_id';
6a488035
TO
1260 $params[$index] = $details->$idx;
1261 }
1262 elseif ($fieldName == 'im') {
1263 $providerId = $detailName . '-provider_id';
38913d36
TO
1264 if (isset($imProviders[$details->$providerId])) {
1265 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
6a488035
TO
1266 }
1267 else {
1268 $values[$index] = $details->$detailName;
1269 }
1270 $params[$index] = $details->$detailName;
1271 }
1272 elseif ($fieldName == 'phone') {
1273 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1274 if (isset($details->$phoneExtField)) {
1275 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1276 }
1277 else {
1278 $values[$index] = $details->$detailName;
1279 }
1280 $params[$index] = $details->$detailName;
1281 }
1282 else {
1283 $values[$index] = $params[$index] = $details->$detailName;
1284 }
1285 }
1286 else {
1287 $detailName = "website-{$id}-{$fieldName}";
1288 $url = CRM_Utils_System::fixURL($details->$detailName);
1289 if ($details->$detailName) {
5d6ac993
TO
1290 $websiteTypeId = "website-{$id}-website_type_id";
1291 $websiteType = $websiteTypes[$details->$websiteTypeId];
6a488035
TO
1292 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1293 }
1294 else {
1295 $values[$index] = '';
1296 }
1297 }
1298 }
1299
1300 if ((CRM_Utils_Array::value('visibility', $field) == 'Public Pages and Listings') &&
1301 CRM_Core_Permission::check('profile listings and forms')
1302 ) {
1303
1304 if (CRM_Utils_System::isNull($params[$index])) {
1305 $params[$index] = $values[$index];
1306 }
1307 if (!isset($params[$index])) {
1308 continue;
1309 }
1310 if (!$customFieldName) {
1311 $fieldName = $field['name'];
1312 }
1313 else {
1314 $fieldName = $customFieldName;
1315 }
1316
1317 $url = NULL;
1318 if (CRM_Core_BAO_CustomField::getKeyID($field['name'])) {
1319 $htmlType = $field['html_type'];
1320 if ($htmlType == 'Link') {
1321 $url = $params[$index];
1322 }
1323 elseif (in_array($htmlType, array(
5d6ac993
TO
1324 'CheckBox',
1325 'Multi-Select',
5d6ac993
TO
1326 'Multi-Select State/Province',
1327 'Multi-Select Country',
1328 ))) {
6a488035
TO
1329 $valSeperator = CRM_Core_DAO::VALUE_SEPARATOR;
1330 $selectedOptions = explode($valSeperator, $params[$index]);
1331
1332 foreach ($selectedOptions as $key => $multiOption) {
1333 if ($multiOption) {
1334 $url[] = CRM_Utils_System::url('civicrm/profile',
1335 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1336 urlencode($fieldName) .
1337 '=' .
1338 urlencode($multiOption)
1339 );
1340 }
1341 }
1342 }
1343 else {
1344 $url = CRM_Utils_System::url('civicrm/profile',
1345 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1346 urlencode($fieldName) .
1347 '=' .
1348 urlencode($params[$index])
1349 );
1350 }
1351 }
1352 else {
1353 $url = CRM_Utils_System::url('civicrm/profile',
1354 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1355 urlencode($fieldName) .
1356 '=' .
1357 urlencode($params[$index])
1358 );
1359 }
1360
1361 if ($url &&
1362 !empty($values[$index]) &&
1363 $searchable
1364 ) {
1365
1366 if (is_array($url) && !empty($url)) {
1367 $links = array();
1368 $eachMultiValue = explode(', ', $values[$index]);
1369 foreach ($eachMultiValue as $key => $valueLabel) {
1370 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1371 }
1372 $values[$index] = implode(', ', $links);
1373 }
1374 else {
1375 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1376 }
1377 }
1378 }
1379 }
1380 }
1381
1382 /**
1383 * Check if profile Group used by any module.
1384 *
6a0b768e
TO
1385 * @param int $id
1386 * Profile Id.
6a488035 1387 *
e7483cbe 1388 * @return bool
6a488035 1389 *
6a488035
TO
1390 */
1391 public static function usedByModule($id) {
1392 //check whether this group is used by any module(check uf join records)
1393 $sql = "SELECT id
1394 FROM civicrm_uf_join
1395 WHERE civicrm_uf_join.uf_group_id=$id";
1396
1397 $dao = new CRM_Core_DAO();
1398 $dao->query($sql);
1399 if ($dao->fetch()) {
1400 return TRUE;
1401 }
1402 else {
1403 return FALSE;
1404 }
1405 }
1406
1407 /**
1408 * Delete the profile Group.
1409 *
6a0b768e
TO
1410 * @param int $id
1411 * Profile Id.
6a488035 1412 *
e7483cbe 1413 * @return bool
6a488035 1414 *
6a488035
TO
1415 */
1416 public static function del($id) {
1417 //check whether this group contains any profile fields
1418 $profileField = new CRM_Core_DAO_UFField();
1419 $profileField->uf_group_id = $id;
1420 $profileField->find();
1421 while ($profileField->fetch()) {
1422 CRM_Core_BAO_UFField::del($profileField->id);
1423 }
1424
1425 //delete records from uf join table
1426 $ufJoin = new CRM_Core_DAO_UFJoin();
1427 $ufJoin->uf_group_id = $id;
1428 $ufJoin->delete();
1429
1430 //delete profile group
1431 $group = new CRM_Core_DAO_UFGroup();
1432 $group->id = $id;
1433 $group->delete();
1434 return 1;
1435 }
1436
1437 /**
fe482240 1438 * Add the UF Group.
6a488035 1439 *
6a0b768e
TO
1440 * @param array $params
1441 * Reference array contains the values submitted by the form.
1442 * @param array $ids
1443 * Reference array contains the id.
6a488035 1444 *
6a488035
TO
1445 *
1446 * @return object
1447 */
00be9182 1448 public static function add(&$params, $ids = array()) {
5d6ac993
TO
1449 $fields = array(
1450 'is_active',
1451 'add_captcha',
1452 'is_map',
1453 'is_update_dupe',
1454 'is_edit_link',
1455 'is_uf_link',
21dfd5f5 1456 'is_cms_user',
5d6ac993 1457 );
6a488035
TO
1458 foreach ($fields as $field) {
1459 $params[$field] = CRM_Utils_Array::value($field, $params, FALSE);
1460 }
1461
1462 $params['limit_listings_group_id'] = CRM_Utils_Array::value('group', $params);
1463 $params['add_to_group_id'] = CRM_Utils_Array::value('add_contact_to_group', $params);
1464
f80ef0e2 1465 //CRM-15427
1466 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1467 $params['group_type'] = implode(',', $params['group_type']);
1468 }
6a488035
TO
1469 $ufGroup = new CRM_Core_DAO_UFGroup();
1470 $ufGroup->copyValues($params);
1471
6a73ef3f 1472 $ufGroupID = CRM_Utils_Array::value('ufgroup', $ids, CRM_Utils_Array::value('id', $params));
25973039 1473 if (!$ufGroupID && empty($params['name'])) {
6a488035
TO
1474 $ufGroup->name = CRM_Utils_String::munge($ufGroup->title, '_', 56);
1475 }
1476 $ufGroup->id = $ufGroupID;
1477
1478 $ufGroup->save();
1479
25973039 1480 if (!$ufGroupID && empty($params['name'])) {
6a488035
TO
1481 $ufGroup->name = $ufGroup->name . "_{$ufGroup->id}";
1482 $ufGroup->save();
1483 }
1484
1485 return $ufGroup;
1486 }
1487
1488 /**
fe482240 1489 * Make uf join entries for an uf group.
6a488035 1490 *
6a0b768e
TO
1491 * @param array $params
1492 * (reference) an assoc array of name/value pairs.
1493 * @param int $ufGroupId
1494 * Ufgroup id.
6a488035 1495 */
00be9182 1496 public static function createUFJoin(&$params, $ufGroupId) {
6a488035
TO
1497 $groupTypes = CRM_Utils_Array::value('uf_group_type', $params);
1498
1499 // get ufjoin records for uf group
1500 $ufGroupRecord = CRM_Core_BAO_UFGroup::getUFJoinRecord($ufGroupId);
1501
1502 // get the list of all ufgroup types
1503 $allUFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1504
1505 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1506 if (!is_array($groupTypes)) {
1507 $groupTypes = array();
1508 }
1509
1510 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1511 if (!is_array($ufGroupRecord)) {
1512 $ufGroupRecord = array();
1513 }
1514
1515 // check which values has to be inserted/deleted for contact
1516 $menuRebuild = FALSE;
1517 foreach ($allUFGroupType as $key => $value) {
1518 $joinParams = array();
1519 $joinParams['uf_group_id'] = $ufGroupId;
1520 $joinParams['module'] = $key;
1521 if ($key == 'User Account') {
1522 $menuRebuild = TRUE;
1523 }
1524 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1525 // insert a new record
1526 CRM_Core_BAO_UFGroup::addUFJoin($joinParams);
1527 }
1528 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1529 // delete a record for existing ufgroup
1530 CRM_Core_BAO_UFGroup::delUFJoin($joinParams);
1531 }
1532 }
1533
1534 //update the weight
1535 $query = "
1536UPDATE civicrm_uf_join
1537SET weight = %1
1538WHERE uf_group_id = %2
1539AND ( entity_id IS NULL OR entity_id <= 0 )
1540";
5d6ac993
TO
1541 $p = array(
1542 1 => array($params['weight'], 'Integer'),
6a488035
TO
1543 2 => array($ufGroupId, 'Integer'),
1544 );
1545 CRM_Core_DAO::executeQuery($query, $p);
1546
4d16a7e1
DS
1547 // Do a menu rebuild, so it gets all the new menu entries for user account
1548 if ($menuRebuild) {
1549 $config = CRM_Core_Config::singleton();
1550 $config->userSystem->updateCategories();
6a488035
TO
1551 }
1552 }
1553
1554 /**
fe482240 1555 * Get the UF Join records for an ufgroup id.
6a488035 1556 *
6a0b768e
TO
1557 * @param int $ufGroupId
1558 * Uf group id.
1559 * @param int $displayName
1560 * If set return display name in array.
1561 * @param int $status
1562 * If set return module other than default modules (User Account/User registration/Profile).
77b97be7 1563 *
a6c01b45 1564 * @return array
6a488035 1565 *
6a488035
TO
1566 */
1567 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1568 if ($displayName) {
1569 $UFGroupType = array();
1570 $UFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1571 }
1572
1573 $ufJoin = array();
1574 $dao = new CRM_Core_DAO_UFJoin();
1575
1576 if ($ufGroupId) {
1577 $dao->uf_group_id = $ufGroupId;
1578 }
1579
1580 $dao->find();
1581 $ufJoin = array();
1582
1583 while ($dao->fetch()) {
1584 if (!$displayName) {
1585 $ufJoin[$dao->id] = $dao->module;
1586 }
1587 else {
1588 if (isset($UFGroupType[$dao->module])) {
1589 // skip the default modules
1590 if (!$status) {
1591 $ufJoin[$dao->id] = $UFGroupType[$dao->module];
1592 }
1593 // added for CRM-1475
1594 }
1595 elseif (!CRM_Utils_Array::key($dao->module, $ufJoin)) {
1596 $ufJoin[$dao->id] = $dao->module;
1597 }
1598 }
1599 }
1600 return $ufJoin;
1601 }
1602
1603 /**
fe482240 1604 * Function takes an associative array and creates a ufjoin record for ufgroup.
6a488035 1605 *
6a0b768e
TO
1606 * @param array $params
1607 * (reference) an assoc array of name/value pairs.
6a488035 1608 *
16b10e64 1609 * @return CRM_Core_BAO_UFJoin
6a488035 1610 */
00be9182 1611 public static function addUFJoin(&$params) {
6a488035
TO
1612 $ufJoin = new CRM_Core_DAO_UFJoin();
1613 $ufJoin->copyValues($params);
1614 $ufJoin->save();
1615 return $ufJoin;
1616 }
1617
1618 /**
fe482240 1619 * Delete the uf join record for an uf group.
6a488035 1620 *
6a0b768e
TO
1621 * @param array $params
1622 * (reference) an assoc array of name/value pairs.
6a488035 1623 */
00be9182 1624 public static function delUFJoin(&$params) {
6a488035
TO
1625 $ufJoin = new CRM_Core_DAO_UFJoin();
1626 $ufJoin->copyValues($params);
1627 $ufJoin->delete();
1628 }
1629
1630 /**
fe482240 1631 * Get the weight for ufjoin record.
6a488035 1632 *
6a0b768e
TO
1633 * @param int $ufGroupId
1634 * If $ufGroupId get update weight or add weight.
6a488035 1635 *
a6c01b45
CW
1636 * @return int
1637 * weight of the UFGroup
6a488035 1638 */
00be9182 1639 public static function getWeight($ufGroupId = NULL) {
6a488035
TO
1640 //calculate the weight
1641 $p = array();
1642 if (!$ufGroupId) {
1643 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1644 FROM civicrm_uf_join
1645 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1646 }
1647 else {
1648 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1649 FROM civicrm_uf_join
1650 WHERE civicrm_uf_join.uf_group_id = %1
1651 AND ( entity_id IS NULL OR entity_id <= 0 )";
1652 $p[1] = array($ufGroupId, 'Integer');
1653 }
1654
1655 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1656 $dao->fetch();
1657 return ($dao->new_weight) ? $dao->new_weight : 1;
1658 }
1659
1660 /**
fe482240 1661 * Get the uf group for a module.
6a488035 1662 *
6a0b768e
TO
1663 * @param string $moduleName
1664 * Module name.
1665 * @param int $count
1666 * No to increment the weight.
77b97be7 1667 * @param bool $skipPermission
6a0b768e
TO
1668 * @param int $op
1669 * Which operation (view, edit, create, etc) to check permission for.
2141efbf 1670 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
6a488035 1671 *
a6c01b45
CW
1672 * @return array
1673 * array of ufgroups for a module
6a488035 1674 */
2141efbf 1675 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission::VIEW, $returnFields = NULL) {
290d4ccc
DS
1676 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1677
eed7e803 1678 if (CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_uf_group', 'description')) {
290d4ccc
DS
1679 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1680 $selectFields[] = 'description';
ce1a9db4
SL
1681 }
1682
eed7e803 1683 if (CRM_Core_BAO_SchemaHandler::checkIfFieldExists('civicrm_uf_group', 'frontend_title')) {
ce1a9db4 1684 $selectFields[] = 'frontend_title';
290d4ccc 1685 }
7ba38389 1686
1687 if (!empty($returnFields)) {
1688 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
2141efbf 1689 }
7ba38389 1690
1691 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
6a488035
TO
1692 FROM civicrm_uf_group
1693 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1694 $p = array();
1695 if ($moduleName) {
1696 $queryString .= ' AND civicrm_uf_group.is_active = 1
1697 WHERE civicrm_uf_join.module = %2';
1698 $p[2] = array($moduleName, 'String');
1699 }
1700
6a488035
TO
1701 // add permissioning for profiles only if not registration
1702 if (!$skipPermission) {
1703 $permissionClause = CRM_Core_Permission::ufGroupClause($op, 'civicrm_uf_group.');
1704 if (strpos($queryString, 'WHERE') !== FALSE) {
1705 $queryString .= " AND $permissionClause ";
1706 }
1707 else {
1708 $queryString .= " $permissionClause ";
1709 }
1710 }
1711
1712 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1713 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1714
1715 $ufGroups = array();
1716 while ($dao->fetch()) {
1717 //skip mix profiles in user Registration / User Account
1718 if (($moduleName == 'User Registration' || $moduleName == 'User Account') &&
1719 CRM_Core_BAO_UFField::checkProfileType($dao->id)
1720 ) {
1721 continue;
1722 }
7ba38389 1723 foreach ($selectFields as $key => $field) {
5d6ac993 1724 if ($field == 'id') {
7ba38389 1725 continue;
1726 }
7ba38389 1727 $ufGroups[$dao->id][$field] = $dao->$field;
1728 }
6a488035
TO
1729 }
1730
1731 // Allow other modules to alter/override the UFGroups.
1732 CRM_Utils_Hook::buildUFGroupsForModule($moduleName, $ufGroups);
1733
1734 return $ufGroups;
1735 }
1736
1737 /**
fe482240 1738 * Filter ufgroups based on logged in user contact type.
6a488035 1739 *
6a0b768e
TO
1740 * @param int $ufGroupId
1741 * Uf group id (profile id).
c490a46a 1742 * @param int $contactID
77b97be7 1743 *
e7483cbe 1744 * @return bool
a6c01b45 1745 * true or false
6a488035 1746 */
00be9182 1747 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
6a488035
TO
1748 if (!$contactID) {
1749 $session = CRM_Core_Session::singleton();
1750 $contactID = $session->get('userID');
1751 }
1752
1753 if ($contactID) {
1754 //get the contact type
1755 $contactType = CRM_Contact_BAO_Contact::getContactType($contactID);
1756
1757 //match if exixting contact type is same as profile contact type
1758 $profileType = CRM_Core_BAO_UFField::getProfileType($ufGroupId);
1759
1760 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1761 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
34daab76
M
1762
1763 //in some cases getBasicType() returns a cached array instead of string. Example: array ('sponsor' => 'organization')
1764 if (is_array($profileType)) {
1765 $profileType = array_shift($profileType);
1766 }
6a488035
TO
1767 }
1768
1769 //allow special mix profiles for Contribution and Participant
1770 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1771
1772 if (in_array($profileType, $specialProfiles)) {
1773 return TRUE;
1774 }
1775
1776 if (($contactType == $profileType) || $profileType == 'Contact') {
1777 return TRUE;
1778 }
1779 }
1780
1781 return FALSE;
1782 }
1783
1784 /**
fe482240 1785 * Add profile field to a form.
6a488035 1786 *
c927c151 1787 * @param CRM_Core_Form $form
6a0b768e
TO
1788 * @param array $field
1789 * Properties.
1790 * @param int $mode
1791 * Profile mode.
1f177c6b 1792 * @param int $contactId
77b97be7 1793 * @param bool $online
6a0b768e
TO
1794 * @param string $usedFor
1795 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1f177c6b 1796 * @param int $rowNumber
77b97be7
EM
1797 * @param string $prefix
1798 *
6a488035 1799 * @return null
6a488035 1800 */
e7483cbe 1801 public static function buildProfile(
6a488035
TO
1802 &$form,
1803 &$field,
1804 $mode,
1805 $contactId = NULL,
1806 $online = FALSE,
133e2c99 1807 $usedFor = NULL,
5d6ac993 1808 $rowNumber = NULL,
6a488035
TO
1809 $prefix = ''
1810 ) {
1811 $defaultValues = array();
1f177c6b
CW
1812 $fieldName = $field['name'];
1813 $title = $field['title'];
1814 $attributes = $field['attributes'];
1815 $rule = $field['rule'];
1816 $view = $field['is_view'];
1817 $required = ($mode == CRM_Profile_Form::MODE_SEARCH) ? FALSE : $field['is_required'];
1818 $search = ($mode == CRM_Profile_Form::MODE_SEARCH) ? TRUE : FALSE;
1819 $isShared = CRM_Utils_Array::value('is_shared', $field, 0);
6a488035
TO
1820
1821 // do not display view fields in drupal registration form
1822 // CRM-4632
1823 if ($view && $mode == CRM_Profile_Form::MODE_REGISTER) {
e7483cbe 1824 return NULL;
6a488035
TO
1825 }
1826
133e2c99 1827 if ($usedFor == 'onbehalf') {
6a488035
TO
1828 $name = "onbehalf[$fieldName]";
1829 }
133e2c99 1830 elseif ($usedFor == 'honor') {
1831 $name = "honor[$fieldName]";
1832 }
6a488035
TO
1833 elseif ($contactId && !$online) {
1834 $name = "field[$contactId][$fieldName]";
1835 }
1836 elseif ($rowNumber) {
1837 $name = "field[$rowNumber][$fieldName]";
1838 }
1839 elseif (!empty($prefix)) {
5d6ac993 1840 $name = $prefix . "[$fieldName]";
6a488035
TO
1841 }
1842 else {
1843 $name = $fieldName;
1844 }
9e1854a1 1845
1f177c6b 1846 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
6a488035
TO
1847
1848 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form::MODE_EDIT) {
e8fb9449 1849 $deleteExtra = json_encode(ts('Are you sure you want to delete contact image.'));
6a488035 1850 $deleteURL = array(
e7483cbe
J
1851 CRM_Core_Action::DELETE => array(
1852 'name' => ts('Delete Contact Image'),
1853 'url' => 'civicrm/contact/image',
1854 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
e8fb9449 1855 'extra' => 'onclick = "' . htmlspecialchars("if (confirm($deleteExtra)) this.href+='&confirmed=1'; else return false;") . '"',
e7483cbe 1856 ),
6a488035
TO
1857 );
1858 $deleteURL = CRM_Core_Action::formLink($deleteURL,
1859 CRM_Core_Action::DELETE,
5d6ac993
TO
1860 array(
1861 'id' => $form->get('id'),
6a488035 1862 'gid' => $form->get('gid'),
87dab4a4
AH
1863 ),
1864 ts('more'),
1865 FALSE,
1866 'contact.profileimage.delete',
1867 'Contact',
1868 $form->get('id')
6a488035
TO
1869 );
1870 $form->assign('deleteURL', $deleteURL);
1871 }
1872 $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
1873 'address_options', TRUE, NULL, TRUE
1874 );
1875
1876 if (substr($fieldName, 0, 14) === 'state_province') {
8f9c3cbe 1877 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
6a488035
TO
1878 $config = CRM_Core_Config::singleton();
1879 if (!in_array($mode, array(
5d6ac993 1880 CRM_Profile_Form::MODE_EDIT,
21dfd5f5 1881 CRM_Profile_Form::MODE_SEARCH,
5d6ac993 1882 )) &&
6a488035
TO
1883 $config->defaultContactStateProvince
1884 ) {
1885 $defaultValues[$name] = $config->defaultContactStateProvince;
1886 $form->setDefaults($defaultValues);
1887 }
1888 }
1889 elseif (substr($fieldName, 0, 7) === 'country') {
1f177c6b 1890 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant::country(), $required, $selectAttributes);
6a488035
TO
1891 $config = CRM_Core_Config::singleton();
1892 if (!in_array($mode, array(
5d6ac993 1893 CRM_Profile_Form::MODE_EDIT,
21dfd5f5 1894 CRM_Profile_Form::MODE_SEARCH,
5d6ac993 1895 )) &&
6a488035
TO
1896 $config->defaultContactCountry
1897 ) {
1898 $defaultValues[$name] = $config->defaultContactCountry;
1899 $form->setDefaults($defaultValues);
1900 }
1901 }
1902 elseif (substr($fieldName, 0, 6) === 'county') {
1903 if ($addressOptions['county']) {
8f9c3cbe 1904 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
6a488035
TO
1905 }
1906 }
1907 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1908 $form->add('file', $name, $title, $attributes, $required);
1909 $form->addUploadElement($name);
1910 }
1911 elseif (substr($fieldName, 0, 2) === 'im') {
1912 $form->add('text', $name, $title, $attributes, $required);
1913 if (!$contactId) {
133e2c99 1914 if ($usedFor) {
6a488035
TO
1915 if (substr($name, -1) == ']') {
1916 $providerName = substr($name, 0, -1) . '-provider_id]';
1917 }
1918 $form->add('select', $providerName, NULL,
1919 array(
21dfd5f5 1920 '' => ts('- select -'),
5d6ac993 1921 ) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1922 );
1923 }
1924 else {
1925 $form->add('select', $name . '-provider_id', $title,
1926 array(
21dfd5f5 1927 '' => ts('- select -'),
5d6ac993 1928 ) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1929 );
1930 }
1931
1932 if ($view && $mode != CRM_Profile_Form::MODE_SEARCH) {
1933 $form->freeze($name . '-provider_id');
1934 }
1935 }
1936 }
5d6ac993 1937 elseif (CRM_Utils_Array::value('name', $field) == 'membership_type') {
6a488035
TO
1938 list($orgInfo, $types) = CRM_Member_BAO_MembershipType::getMembershipTypeInfo();
1939 $sel = &$form->addElement('hierselect', $name, $title);
5d6ac993
TO
1940 $select = array('' => ts('- select -'));
1941 if (count($orgInfo) == 1 && $field['is_required']) {
53cfc93c 1942 // we only have one org - so we should default to it. Not sure about defaulting to first type
1943 // as it could be missed - so adding a select
1944 // however, possibly that is more similar to the membership form
5d6ac993 1945 if (count($types[1]) > 1) {
53cfc93c 1946 $types[1] = $select + $types[1];
1947 }
1948 }
1949 else {
1950 $orgInfo = $select + $orgInfo;
1951 }
1952 $sel->setOptions(array($orgInfo, $types));
6a488035 1953 }
5d6ac993 1954 elseif (CRM_Utils_Array::value('name', $field) == 'membership_status') {
6a488035
TO
1955 $form->add('select', $name, $title,
1956 array(
21dfd5f5 1957 '' => ts('- select -'),
5d6ac993 1958 ) + CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label'), $required
6a488035
TO
1959 );
1960 }
ee015de4 1961 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1962 $options = array();
1963 $pseudoValues = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', $fieldName);
1964 foreach ($pseudoValues as $key => $var) {
1965 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
6a488035 1966 }
ee015de4 1967 $group = $form->addGroup($options, $name, $title);
d4dcd180 1968 if ($required) {
1969 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
6a488035 1970 }
8a4f27dc 1971 else {
b847e6e7 1972 $group->setAttribute('allowClear', TRUE);
8a4f27dc 1973 }
6a488035 1974 }
f45334bd 1975 elseif ($fieldName === 'prefix_id' || $fieldName === 'suffix_id') {
1f177c6b
CW
1976 $form->addSelect($name, array(
1977 'label' => $title,
1978 'entity' => 'contact',
1979 'field' => $fieldName,
1980 'class' => 'six',
1981 'placeholder' => '',
1982 ), $required);
6a488035
TO
1983 }
1984 elseif ($fieldName === 'contact_sub_type') {
1985 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
133e2c99 1986 if ($usedFor == 'onbehalf') {
6a488035
TO
1987 $profileType = 'Organization';
1988 }
133e2c99 1989 elseif ($usedFor == 'honor') {
1990 $profileType = CRM_Core_BAO_UFField::getProfileType($form->_params['honoree_profile_id']);
1991 }
6a488035
TO
1992 else {
1993 $profileType = $gId ? CRM_Core_BAO_UFField::getProfileType($gId) : NULL;
1994 if ($profileType == 'Contact') {
1995 $profileType = 'Individual';
1996 }
1997 }
1998
1999 $setSubtype = FALSE;
2000 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
2001 $setSubtype = $profileType;
2002 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
2003 }
2004
2005 $subtypes = $profileType ? CRM_Contact_BAO_ContactType::subTypePairs($profileType) : array();
2006
2007 if ($setSubtype) {
2008 $subtypeList = array();
2009 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2010 }
2011 else {
2012 $subtypeList = $subtypes;
2013 }
2014
7ca3d518 2015 $form->add('select', $name, $title, $subtypeList, $required, array('class' => 'crm-select2', 'multiple' => TRUE));
6a488035
TO
2016 }
2017 elseif (in_array($fieldName, CRM_Contact_BAO_Contact::$_greetingTypes)) {
2018 //add email greeting, postal greeting, addressee, CRM-4575
2019 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
2020 $profileType = CRM_Core_BAO_UFField::getProfileType($gId, TRUE, FALSE, TRUE);
2021
2022 if (empty($profileType) || in_array($profileType, array(
5d6ac993
TO
2023 'Contact',
2024 'Contribution',
2025 'Participant',
21dfd5f5 2026 'Membership',
5d6ac993
TO
2027 ))
2028 ) {
6a488035
TO
2029 $profileType = 'Individual';
2030 }
2031 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
2032 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
2033 }
2034 $greeting = array(
2035 'contact_type' => $profileType,
2036 'greeting_type' => $fieldName,
2037 );
2038 $form->add('select', $name, $title,
2039 array(
21dfd5f5 2040 '' => ts('- select -'),
5d6ac993 2041 ) + CRM_Core_PseudoConstant::greeting($greeting), $required
6a488035
TO
2042 );
2043 // add custom greeting element
2044 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2045 NULL, FALSE
2046 );
2047 }
2048 elseif ($fieldName === 'preferred_communication_method') {
e7e657f0 2049 $communicationFields = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
6a488035
TO
2050 foreach ($communicationFields as $key => $var) {
2051 if ($key == '') {
2052 continue;
2053 }
2054 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2055 }
2056 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2057 }
2058 elseif ($fieldName === 'preferred_mail_format') {
2059 $form->add('select', $name, $title, CRM_Core_SelectValues::pmf());
2060 }
2061 elseif ($fieldName === 'preferred_language') {
c0c9cd82 2062 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact::buildOptions('preferred_language'));
6a488035
TO
2063 }
2064 elseif ($fieldName == 'external_identifier') {
2065 $form->add('text', $name, $title, $attributes, $required);
2066 $contID = $contactId;
2067 if (!$contID) {
2068 $contID = $form->get('id');
2069 }
2070 $form->addRule($name,
2071 ts('External ID already exists in Database.'),
2072 'objectExists',
2073 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2074 );
2075 }
2076 elseif ($fieldName === 'group') {
2077 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
2078 CRM_Contact_Form_Edit_TagsAndGroups::GROUP,
2079 TRUE, $required,
2080 $title, NULL, $name
2081 );
2082 }
2083 elseif ($fieldName === 'tag') {
2084 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
2085 CRM_Contact_Form_Edit_TagsAndGroups::TAG,
2086 FALSE, $required,
2087 NULL, $title, $name
2088 );
2089 }
2090 elseif (substr($fieldName, 0, 4) === 'url-') {
eef9a6da
J
2091 $form->add('text', $name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Website', 'url'), $required);
2092 $form->addRule($name, ts('Enter a valid web address beginning with \'http://\' or \'https://\'.'), 'url');
6a488035
TO
2093 }
2094 // Note should be rendered as textarea
2095 elseif (substr($fieldName, -4) == 'note') {
2096 $form->add('textarea', $name, $title, $attributes, $required);
2097 }
2098 elseif (substr($fieldName, 0, 6) === 'custom') {
2099 $customFieldID = CRM_Core_BAO_CustomField::getKeyID($fieldName);
2100 if ($customFieldID) {
3a7773be 2101 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
6a488035
TO
2102 }
2103 }
2104 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2105 list($fName, $locTypeId) = CRM_Utils_System::explode('-', $fieldName, 2);
2106 $customFieldID = CRM_Core_BAO_CustomField::getKeyID(substr($fName, 8));
2107 if ($customFieldID) {
3a7773be 2108 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
6a488035
TO
2109 }
2110 }
6a488035
TO
2111 elseif ($fieldName == 'send_receipt') {
2112 $form->addElement('checkbox', $name, $title);
2113 }
2114 elseif ($fieldName == 'soft_credit') {
ccec9d6b 2115 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
5ee60152 2116 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
6a488035
TO
2117 }
2118 elseif ($fieldName == 'product_name') {
2119 list($products, $options) = CRM_Contribute_BAO_Premium::getPremiumProductInfo();
2120 $sel = &$form->addElement('hierselect', $name, $title);
2121 $products = array(
e7483cbe
J
2122 '0' => ts('- select -'),
2123 ) + $products;
6a488035
TO
2124 $sel->setOptions(array($products, $options));
2125 }
2126 elseif ($fieldName == 'payment_instrument') {
2127 $form->add('select', $name, $title,
5d6ac993 2128 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::paymentInstrument(), $required);
6a488035 2129 }
4c9b6178 2130 elseif ($fieldName == 'financial_type') {
6a488035
TO
2131 $form->add('select', $name, $title,
2132 array(
21dfd5f5 2133 '' => ts('- select -'),
5d6ac993 2134 ) + CRM_Contribute_PseudoConstant::financialType(), $required
6a488035
TO
2135 );
2136 }
2137 elseif ($fieldName == 'contribution_status_id') {
aaf5ca44
DG
2138 $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus();
2139 $statusName = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
2140 foreach (array(
2141 'In Progress',
2142 'Overdue',
21dfd5f5 2143 'Refunded',
aaf5ca44
DG
2144 ) as $suppress) {
2145 unset($contributionStatuses[CRM_Utils_Array::key($suppress, $statusName)]);
2146 }
6a73ef3f 2147
6a488035
TO
2148 $form->add('select', $name, $title,
2149 array(
21dfd5f5 2150 '' => ts('- select -'),
5d6ac993 2151 ) + $contributionStatuses, $required
6a488035
TO
2152 );
2153 }
51fa20cb 2154 elseif ($fieldName == 'soft_credit_type') {
9e1854a1 2155 $name = "soft_credit_type[$rowNumber]";
51fa20cb 2156 $form->add('select', $name, $title,
2157 array(
21dfd5f5 2158 '' => ts('- select -'),
5d6ac993 2159 ) + CRM_Core_OptionGroup::values("soft_credit_type")
51fa20cb 2160 );
9e1854a1 2161 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2162 //else (for contribution), use configured SCT default value
2163 $SCTDefaultValue = CRM_Core_OptionGroup::getDefaultValue("soft_credit_type");
2164 if ($field['field_type'] == 'Membership') {
233319bf 2165 $SCTDefaultValue = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_ContributionSoft', 'soft_credit_type_id', 'gift');
9e1854a1 2166 }
2167 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
51fa20cb 2168 }
a4a361c9 2169 elseif ($fieldName == 'contribution_soft_credit_pcp_id') {
03ad81ae 2170 CRM_Contribute_Form_SoftCredit::addPCPFields($form, "[$rowNumber]");
51fa20cb 2171 }
6a488035 2172 elseif ($fieldName == 'currency') {
483a53a8 2173 $form->addCurrency($name, $title, $required, NULL, FALSE, FALSE);
6a488035
TO
2174 }
2175 elseif ($fieldName == 'contribution_page_id') {
2176 $form->add('select', $name, $title,
2177 array(
21dfd5f5 2178 '' => ts('- select -'),
5d6ac993 2179 ) + CRM_Contribute_PseudoConstant::contributionPage(), $required, 'class="big"'
6a488035
TO
2180 );
2181 }
6a488035
TO
2182 elseif ($fieldName == 'activity_status_id') {
2183 $form->add('select', $name, $title,
2184 array(
21dfd5f5 2185 '' => ts('- select -'),
5d6ac993 2186 ) + CRM_Core_PseudoConstant::activityStatus(), $required
6a488035
TO
2187 );
2188 }
2189 elseif ($fieldName == 'activity_engagement_level') {
2190 $form->add('select', $name, $title,
2191 array(
21dfd5f5 2192 '' => ts('- select -'),
5d6ac993 2193 ) + CRM_Campaign_PseudoConstant::engagementLevel(), $required
6a488035
TO
2194 );
2195 }
6a488035
TO
2196 elseif ($fieldName == 'participant_status') {
2197 $cond = NULL;
2198 if ($online == TRUE) {
2199 $cond = 'visibility_id = 1';
2200 }
2201 $form->add('select', $name, $title,
2202 array(
21dfd5f5 2203 '' => ts('- select -'),
5d6ac993 2204 ) + CRM_Event_PseudoConstant::participantStatus(NULL, $cond, 'label'), $required
6a488035
TO
2205 );
2206 }
2207 elseif ($fieldName == 'participant_role') {
a7488080 2208 if (!empty($field['is_multiple'])) {
6a488035
TO
2209 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant::participantRole(), NULL, NULL, NULL, NULL, '&nbsp', TRUE);
2210 }
2211 else {
2212 $form->add('select', $name, $title,
2213 array(
21dfd5f5 2214 '' => ts('- select -'),
5d6ac993 2215 ) + CRM_Event_PseudoConstant::participantRole(), $required
6a488035
TO
2216 );
2217 }
2218 }
2219 elseif ($fieldName == 'world_region') {
1f177c6b 2220 $form->add('select', $name, $title, CRM_Core_PseudoConstant::worldRegion(), $required, $selectAttributes);
6a488035
TO
2221 }
2222 elseif ($fieldName == 'signature_html') {
5d51a2f9 2223 $form->add('wysiwyg', $name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
6a488035
TO
2224 }
2225 elseif ($fieldName == 'signature_text') {
2226 $form->add('textarea', $name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
2227 }
2228 elseif (substr($fieldName, -11) == 'campaign_id') {
2229 if (CRM_Campaign_BAO_Campaign::isCampaignEnable()) {
2230 $campaigns = CRM_Campaign_BAO_Campaign::getCampaigns(CRM_Utils_Array::value($contactId,
2231 $form->_componentCampaigns
2232 ));
2233 $form->add('select', $name, $title,
2234 array(
21dfd5f5 2235 '' => ts('- select -'),
5d6ac993 2236 ) + $campaigns, $required, 'class="crm-select2 big"'
6a488035
TO
2237 );
2238 }
2239 }
2240 elseif ($fieldName == 'activity_details') {
5d51a2f9 2241 $form->add('wysiwyg', $fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
6a488035
TO
2242 }
2243 elseif ($fieldName == 'activity_duration') {
2244 $form->add('text', $name, $title, $attributes, $required);
2245 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2246 }
888da08c
MW
2247 elseif ($fieldName == 'case_status') {
2248 $form->add('select', $name, $title,
2249 array(
2250 '' => ts('- select -'),
2251 ) + CRM_Case_BAO_Case::buildOptions('case_status_id', 'create'),
2252 $required
2253 );
2254 }
6a488035
TO
2255 else {
2256 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2257 $form->add('advcheckbox', $name, $title, $attributes, $required);
2258 }
2732685b 2259 elseif (CRM_Utils_Array::value('html_type', $field) === 'Select Date') {
2260 $extra = isset($field['datepicker']) ? $field['datepicker']['extra'] : CRM_Utils_Date::getDatePickerExtra($field);
2261 $attributes = isset($field['datepicker']) ? $field['datepicker']['attributes'] : CRM_Utils_Date::getDatePickerAttributes($field);
2262 $form->add('datepicker', $name, $title, $attributes, $required, $extra);
2263 }
6a488035
TO
2264 else {
2265 $form->add('text', $name, $title, $attributes, $required);
2266 }
2267 }
2268
2269 static $hiddenSubtype = FALSE;
2270 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType::isaSubType($field['field_type'])) {
2271 // In registration mode params are submitted via POST and we don't have any clue
2272 // about profile-id or the profile-type (which could be a subtype)
2273 // To generalize the behavior and simplify the process,
2274 // lets always add the hidden
2275 //subtype value if there is any, and we won't have to
2276 // compute it while processing.
133e2c99 2277 if ($usedFor) {
2278 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
6a488035
TO
2279 }
2280 else {
2281 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2282 }
2283 $hiddenSubtype = TRUE;
2284 }
2285
2286 if (($view && $mode != CRM_Profile_Form::MODE_SEARCH) || $isShared) {
2287 $form->freeze($name);
2288 }
2289
2290 //add the rules
2291 if (in_array($fieldName, array(
5d6ac993
TO
2292 'non_deductible_amount',
2293 'total_amount',
2294 'fee_amount',
21dfd5f5 2295 'net_amount',
5d6ac993 2296 ))) {
6a488035
TO
2297 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2298 }
6a488035
TO
2299 if ($rule) {
2300 if (!($rule == 'email' && $mode == CRM_Profile_Form::MODE_SEARCH)) {
2301 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2302 }
2303 }
2304 }
2305
2306 /**
fe482240 2307 * Set profile defaults.
6a488035 2308 *
6a0b768e
TO
2309 * @param int $contactId
2310 * Contact id.
2311 * @param array $fields
2312 * Associative array of fields.
2313 * @param array $defaults
2314 * Defaults array.
2315 * @param bool $singleProfile
b581842f 2316 * True for single profile else false(Update multiple items).
6a0b768e
TO
2317 * @param int $componentId
2318 * Id for specific components like contribute, event etc.
2319 * @param null $component
6a488035 2320 */
e7483cbe 2321 public static function setProfileDefaults(
f9f40af3
TO
2322 $contactId, &$fields, &$defaults,
2323 $singleProfile = TRUE, $componentId = NULL, $component = NULL
6a488035
TO
2324 ) {
2325 if (!$componentId) {
2326 //get the contact details
2327 list($contactDetails, $options) = CRM_Contact_BAO_Contact::getHierContactDetails($contactId, $fields);
2328 $details = CRM_Utils_Array::value($contactId, $contactDetails);
2329 $multipleFields = array('website' => 'url');
2330
2331 //start of code to set the default values
2332 foreach ($fields as $name => $field) {
2333 // skip pseudo fields
2334 if (substr($name, 0, 9) == 'phone_ext') {
2335 continue;
2336 }
2337
b581842f 2338 //set the field name depending upon the profile mode(single/multiple)
6a488035
TO
2339 if ($singleProfile) {
2340 $fldName = $name;
2341 }
2342 else {
2343 $fldName = "field[$contactId][$name]";
2344 }
2345
2346 if ($name == 'group') {
2347 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::GROUP, $fldName);
2348 }
2349 if ($name == 'tag') {
2350 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::TAG, $fldName);
2351 }
2352
a7488080 2353 if (!empty($details[$name]) || isset($details[$name])) {
6a488035 2354 //to handle custom data (checkbox) to be written
58f00377 2355 // to handle birth/deceased date, greeting_type and few other fields
2732685b 2356 if (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)) {
6a488035
TO
2357 $defaults[$fldName] = $details[$name . '_id'];
2358 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2359 }
2360 elseif ($name == 'preferred_communication_method') {
d5a9068c
PN
2361 $v = $details[$name];
2362 if (!is_array($details[$name])) {
2363 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $v);
2364 }
6a488035
TO
2365 foreach ($v as $item) {
2366 if ($item) {
2367 $defaults[$fldName . "[$item]"] = 1;
2368 }
2369 }
2370 }
8aefc657
RK
2371 elseif ($name == 'contact_sub_type') {
2372 $defaults[$fldName] = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($details[$name], CRM_Core_DAO::VALUE_SEPARATOR));
2373 }
6a488035
TO
2374 elseif ($name == 'world_region') {
2375 $defaults[$fldName] = $details['worldregion_id'];
2376 }
2377 elseif ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($name)) {
363544d7 2378 // @todo retrieving the custom fields here seems obsolete - $field holds more data for the fields.
6a488035
TO
2379 $customFields = CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $details));
2380
2381 // hack to add custom data for components
2382 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2383 foreach ($components as $value) {
2384 $customFields = CRM_Utils_Array::crmArrayMerge($customFields,
2385 CRM_Core_BAO_CustomField::getFieldsForImport($value)
2386 );
2387 }
2388
2389 switch ($customFields[$customFieldId]['html_type']) {
2390 case 'Multi-Select State/Province':
2391 case 'Multi-Select Country':
6a488035
TO
2392 case 'Multi-Select':
2393 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2394 foreach ($v as $item) {
2395 if ($item) {
2396 $defaults[$fldName][$item] = $item;
2397 }
2398 }
2399 break;
2400
2401 case 'CheckBox':
2402 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2403 foreach ($v as $item) {
2404 if ($item) {
2405 $defaults[$fldName][$item] = 1;
2406 // seems like we need this for QF style checkboxes in profile where its multiindexed
2407 // CRM-2969
2408 $defaults["{$fldName}[{$item}]"] = 1;
2409 }
2410 }
2411 break;
2412
6a488035
TO
2413 default:
2414 $defaults[$fldName] = $details[$name];
2415 break;
2416 }
2417 }
2418 else {
2419 $defaults[$fldName] = $details[$name];
2420 }
2421 }
2422 else {
2423 $blocks = array('email', 'phone', 'im', 'openid');
2424 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System::explode('-', $name, 3);
2425 if (!in_array($fieldName, $multipleFields)) {
2426 if (is_array($details)) {
2427 foreach ($details as $key => $value) {
2428 // when we fixed CRM-5319 - get primary loc
2429 // type as per loc field and removed below code.
2430 $primaryLocationType = FALSE;
2431 if ($locTypeId == 'Primary') {
5d6ac993 2432 if (is_array($value) && array_key_exists($fieldName, $value)) {
6a488035 2433 $primaryLocationType = TRUE;
5d6ac993 2434 if (in_array($fieldName, $blocks)) {
6a488035
TO
2435 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, $fieldName);
2436 }
5d6ac993 2437 else {
6a488035
TO
2438 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, 'address');
2439 }
2440 }
2441 }
2442
2443 // fixed for CRM-665
2444 if (is_numeric($locTypeId)) {
2445 if ($primaryLocationType || $locTypeId == CRM_Utils_Array::value('location_type_id', $value)) {
a7488080 2446 if (!empty($value[$fieldName])) {
6a488035
TO
2447 //to handle stateprovince and country
2448 if ($fieldName == 'state_province') {
2449 $defaults[$fldName] = $value['state_province_id'];
2450 }
2451 elseif ($fieldName == 'county') {
2452 $defaults[$fldName] = $value['county_id'];
2453 }
2454 elseif ($fieldName == 'country') {
6a488035
TO
2455 if (!isset($value['country_id']) || !$value['country_id']) {
2456 $config = CRM_Core_Config::singleton();
2457 if ($config->defaultContactCountry) {
2458 $defaults[$fldName] = $config->defaultContactCountry;
2459 }
2460 }
b3071092
DL
2461 else {
2462 $defaults[$fldName] = $value['country_id'];
2463 }
6a488035
TO
2464 }
2465 elseif ($fieldName == 'phone') {
2466 if ($phoneTypeId) {
2467 if (isset($value['phone'][$phoneTypeId])) {
2468 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2469 }
2470 if (isset($value['phone_ext'][$phoneTypeId])) {
2471 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2472 }
2473 }
2474 else {
2475 $phoneDefault = CRM_Utils_Array::value('phone', $value);
2476 // CRM-9216
2477 if (!is_array($phoneDefault)) {
2478 $defaults[$fldName] = $phoneDefault;
2479 }
2480 }
2481 }
2482 elseif ($fieldName == 'email') {
2483 //adding the first email (currently we don't support multiple emails of same location type)
2484 $defaults[$fldName] = $value['email'];
2485 }
2486 elseif ($fieldName == 'im') {
2487 //adding the first im (currently we don't support multiple ims of same location type)
2488 $defaults[$fldName] = $value['im'];
2489 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2490 }
2491 else {
2492 $defaults[$fldName] = $value[$fieldName];
2493 }
2494 }
2495 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2496 CRM_Utils_Array::value(substr($fieldName, 8), $value)
2497 ) {
2498 $defaults[$fldName] = $value[substr($fieldName, 8)];
2499 }
2500 }
2501 }
2502 }
2503 }
2504 }
2505 else {
2506 if (is_array($details)) {
1fd63589
EM
2507 if ($fieldName === 'url'
2508 && !empty($details['website'])
5d6ac993
TO
2509 && !empty($details['website'][$locTypeId])
2510 ) {
887e764d 2511 $defaults[$fldName] = CRM_Utils_Array::value('url', $details['website'][$locTypeId]);
6a488035
TO
2512 }
2513 }
2514 }
2515 }
2516 }
2517 }
2518
888da08c 2519 // Handling Contribution Part of the batch profile
6a488035
TO
2520 if (CRM_Core_Permission::access('CiviContribute') && $component == 'Contribute') {
2521 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2522 }
2523
888da08c 2524 // Handling Event Participation Part of the batch profile
6a488035
TO
2525 if (CRM_Core_Permission::access('CiviEvent') && $component == 'Event') {
2526 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2527 }
2528
888da08c 2529 // Handling membership Part of the batch profile
6a488035
TO
2530 if (CRM_Core_Permission::access('CiviMember') && $component == 'Membership') {
2531 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2532 }
2533
888da08c 2534 // Handling Activity Part of the batch profile
6a488035
TO
2535 if ($component == 'Activity') {
2536 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2537 }
888da08c
MW
2538
2539 // Handling Case Part of the batch profile
2540 if (CRM_Core_Permission::access('CiviCase') && $component == 'Case') {
2541 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2542 }
6a488035
TO
2543 }
2544
2545 /**
100fef9d 2546 * Get profiles by type eg: pure Individual etc
6a488035 2547 *
6a0b768e
TO
2548 * @param array $types
2549 * Associative array of types eg: types('Individual').
2550 * @param bool $onlyPure
2551 * True if only pure profiles are required.
6a488035 2552 *
a6c01b45
CW
2553 * @return array
2554 * associative array of profiles
6a488035 2555 */
00be9182 2556 public static function getProfiles($types, $onlyPure = FALSE) {
6a488035 2557 $profiles = array();
ff4f7744 2558 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
2559
2560 CRM_Utils_Hook::aclGroup(CRM_Core_Permission::ADMIN, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2561
2562 // Exclude Batch Data Entry profiles - CRM-10901
2563 $batchProfiles = CRM_Core_BAO_UFGroup::getBatchProfiles();
2564
2565 foreach ($ufGroups as $id => $title) {
2566 $ptype = CRM_Core_BAO_UFField::getProfileType($id, FALSE, $onlyPure);
2567 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2568 $profiles[$id] = $title;
2569 }
2570 }
2571 return $profiles;
2572 }
2573
2574 /**
100fef9d 2575 * Check whether a profile is valid combination of
6a488035
TO
2576 * required and/or optional profile types
2577 *
6a0b768e
TO
2578 * @param array $required
2579 * Array of types those are required.
2580 * @param array $optional
2581 * Array of types those are optional.
6a488035 2582 *
a6c01b45
CW
2583 * @return array
2584 * associative array of profiles
6a488035 2585 */
00be9182 2586 public static function getValidProfiles($required, $optional = NULL) {
6a488035 2587 if (!is_array($required) || empty($required)) {
e7483cbe 2588 return NULL;
6a488035
TO
2589 }
2590
2591 $profiles = array();
ff4f7744 2592 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
2593
2594 CRM_Utils_Hook::aclGroup(CRM_Core_Permission::ADMIN, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2595
2596 foreach ($ufGroups as $id => $title) {
2597 $type = CRM_Core_BAO_UFField::checkValidProfileType($id, $required, $optional);
2598 if ($type) {
2599 $profiles[$id] = $title;
2600 }
2601 }
2602
2603 return $profiles;
2604 }
2605
2606 /**
100fef9d 2607 * Check whether a profile is valid combination of
6a488035
TO
2608 * required profile fields
2609 *
6a0b768e
TO
2610 * @param array $ufId
2611 * Integer id of the profile.
2612 * @param array $required
2613 * Array of fields those are required in the profile.
6a488035 2614 *
a6c01b45
CW
2615 * @return array
2616 * associative array of profiles
6a488035 2617 */
00be9182 2618 public static function checkValidProfile($ufId, $required = NULL) {
6a488035
TO
2619 $validProfile = FALSE;
2620 if (!$ufId) {
2621 return $validProfile;
2622 }
2623
2624 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2625 return $validProfile;
2626 }
2627
2628 $profileFields = self::getFields($ufId, FALSE, CRM_Core_Action::VIEW, NULL,
2629 NULL, FALSE, NULL, FALSE, NULL,
2630 CRM_Core_Permission::CREATE, NULL
2631 );
2632
2633 $validProfile = array();
2634 if (!empty($profileFields)) {
2635 $fields = array_keys($profileFields);
2636 foreach ($fields as $val) {
2637 foreach ($required as $key => $field) {
2638 if (strpos($val, $field) === 0) {
2639 unset($required[$key]);
2640 }
2641 }
2642 }
2643
2644 $validProfile = (empty($required)) ? TRUE : FALSE;
2645 }
2646
2647 return $validProfile;
2648 }
2649
2650 /**
100fef9d 2651 * Get default value for Register.
6a488035 2652 *
72b3a70c
CW
2653 * @param array $fields
2654 * @param array $defaults
77b97be7 2655 *
72b3a70c 2656 * @return array
6a488035 2657 */
00be9182 2658 public static function setRegisterDefaults(&$fields, &$defaults) {
b525f1cc 2659 $config = CRM_Core_Config::singleton();
6a488035
TO
2660 foreach ($fields as $name => $field) {
2661 if (substr($name, 0, 8) == 'country-') {
b525f1cc 2662 if (!empty($config->defaultContactCountry)) {
6a488035
TO
2663 $defaults[$name] = $config->defaultContactCountry;
2664 }
2665 }
2666 elseif (substr($name, 0, 15) == 'state_province-') {
b525f1cc 2667 if (!empty($config->defaultContactStateProvince)) {
6a488035
TO
2668 $defaults[$name] = $config->defaultContactStateProvince;
2669 }
2670 }
2671 }
2672 return $defaults;
2673 }
2674
2675 /**
dc195289 2676 * make a copy of a profile, including
6a488035
TO
2677 * all the fields in the profile
2678 *
6a0b768e
TO
2679 * @param int $id
2680 * The profile id to copy.
6a488035 2681 *
8eedd10a 2682 * @return \CRM_Core_DAO
6a488035 2683 */
00be9182 2684 public static function copy($id) {
9739890f 2685 $maxId = CRM_Core_DAO::singleValueQuery("SELECT max(id) FROM civicrm_uf_group");
2686
2687 $title = ts('[Copy id %1]', array(1 => $maxId + 1));
2688 $fieldsFix = array(
2689 'suffix' => array(
2690 'title' => ' ' . $title,
2691 'name' => '__Copy_id_' . ($maxId + 1) . '_',
2692 ),
2693 );
2694
6a488035
TO
2695 $copy = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFGroup',
2696 array('id' => $id),
2697 NULL,
2698 $fieldsFix
2699 );
2700
2701 if ($pos = strrpos($copy->name, "_{$id}")) {
2702 $copy->name = substr_replace($copy->name, '', $pos);
2703 }
2704 $copy->name = CRM_Utils_String::munge($copy->name, '_', 56) . "_{$copy->id}";
2705 $copy->save();
2706
2707 $copyUFJoin = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFJoin',
2708 array('uf_group_id' => $id),
2709 array('uf_group_id' => $copy->id),
2710 NULL,
2711 'entity_table'
2712 );
2713
2714 $copyUFField = &CRM_Core_DAO::copyGeneric('CRM_Core_BAO_UFField',
2715 array('uf_group_id' => $id),
2716 array('uf_group_id' => $copy->id)
2717 );
2718
2719 $maxWeight = CRM_Utils_Weight::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2720
2721 //update the weight
2722 $query = "
2723UPDATE civicrm_uf_join
2724SET weight = %1
2725WHERE uf_group_id = %2
2726AND ( entity_id IS NULL OR entity_id <= 0 )
2727";
5d6ac993
TO
2728 $p = array(
2729 1 => array($maxWeight + 1, 'Integer'),
6a488035
TO
2730 2 => array($copy->id, 'Integer'),
2731 );
2732 CRM_Core_DAO::executeQuery($query, $p);
2733 if ($copy->is_reserved) {
2734 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2735 $params = array(1 => array($copy->id, 'Integer'));
2736 CRM_Core_DAO::executeQuery($query, $params);
2737 }
2738 CRM_Utils_Hook::copy('UFGroup', $copy);
2739
2740 return $copy;
2741 }
2742
2743 /**
2744 * Process that send notification e-mails
2745 *
6a0b768e
TO
2746 * @param int $contactID
2747 * Contact id.
2748 * @param array $values
2749 * Associative array of name/value pair.
6a488035 2750 */
00be9182 2751 public static function commonSendMail($contactID, &$values) {
6a488035
TO
2752 if (!$contactID || !$values) {
2753 return;
2754
2755 }
2756 $template = CRM_Core_Smarty::singleton();
2757
2758 $displayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
2759 $contactID,
2760 'display_name'
2761 );
2762
2763 self::profileDisplay($values['id'], $values['values'], $template);
2764 $emailList = explode(',', $values['email']);
2765
2766 $contactLink = CRM_Utils_System::url('civicrm/contact/view',
2767 "reset=1&cid=$contactID",
5d6ac993 2768 TRUE, NULL, FALSE, FALSE, TRUE
6a488035
TO
2769 );
2770
2771 //get the default domain email address.
2772 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
2773
2774 if (!$domainEmailAddress || $domainEmailAddress == 'info@EXAMPLE.ORG') {
2775 $fixUrl = CRM_Utils_System::url('civicrm/admin/domain', 'action=update&reset=1');
2776 CRM_Core_Error::fatal(ts('The site administrator needs to enter a valid \'FROM Email Address\' in <a href="%1">Administer CiviCRM &raquo; Communications &raquo; FROM Email Addresses</a>. The email address used may need to be a valid mail account with your email service provider.', array(1 => $fixUrl)));
2777 }
2778
2779 foreach ($emailList as $emailTo) {
2780 // FIXME: take the below out of the foreach loop
c6327d7d 2781 CRM_Core_BAO_MessageTemplate::sendTemplate(
6a488035
TO
2782 array(
2783 'groupName' => 'msg_tpl_workflow_uf',
2784 'valueName' => 'uf_notify',
2785 'contactId' => $contactID,
2786 'tplParams' => array(
2787 'displayName' => $displayName,
2788 'currentDate' => date('r'),
2789 'contactLink' => $contactLink,
2790 ),
2791 'from' => "$domainEmailName <$domainEmailAddress>",
2792 'toEmail' => $emailTo,
2793 )
2794 );
2795 }
2796 }
2797
2798 /**
2799 * Given a contact id and a group id, returns the field values from the db
2800 * for this group and notify email only if group's notify field is
2801 * set and field values are not empty
2802 *
6a0b768e
TO
2803 * @param int $gid
2804 * Group id.
2805 * @param int $cid
2806 * Contact id.
c490a46a 2807 * @param array $params
1fd63589
EM
2808 * @param bool $skipCheck
2809 *
6a488035 2810 * @return array
6a488035 2811 */
00be9182 2812 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
6a488035
TO
2813 if ($gid) {
2814 if (CRM_Core_BAO_UFGroup::filterUFGroups($gid, $cid) || $skipCheck) {
2815 $values = array();
2816 $fields = CRM_Core_BAO_UFGroup::getFields($gid, FALSE, CRM_Core_Action::VIEW);
2817 CRM_Core_BAO_UFGroup::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2818
2819 $email = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2820
2821 if (!empty($values) &&
2822 !empty($email)
2823 ) {
2824 $val = array(
2825 'id' => $gid,
2826 'values' => $values,
2827 'email' => $email,
2828 );
2829 return $val;
2830 }
2831 }
2832 }
2833 return NULL;
2834 }
2835
2836 /**
fe482240 2837 * Assign uf fields to template.
6a488035 2838 *
6a0b768e
TO
2839 * @param int $gid
2840 * Group id.
c490a46a
CW
2841 * @param array $values
2842 * @param CRM_Core_Smarty $template
6a488035 2843 */
59b36d14 2844 static public function profileDisplay($gid, $values, $template) {
6a488035
TO
2845 $groupTitle = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2846 $template->assign('grouptitle', $groupTitle);
2847 if (count($values)) {
2848 $template->assign('values', $values);
2849 }
2850 }
2851
2852 /**
fe482240 2853 * Format fields for dupe Contact Matching.
6a488035 2854 *
6a0b768e 2855 * @param array $params
6a488035 2856 *
100fef9d 2857 * @param int $contactId
1fd63589 2858 *
a6c01b45 2859 * @return array
b44e3f84 2860 * associated formatted array
6a488035 2861 */
00be9182 2862 public static function formatFields($params, $contactId = NULL) {
6a488035
TO
2863 if ($contactId) {
2864 // get the primary location type id and email
2865 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactId);
2866 }
2867 else {
2868 $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
2869 $primaryLocationType = $defaultLocationType->id;
2870 }
2871
5d6ac993
TO
2872 $data = array();
2873 $locationType = array();
2874 $count = 1;
6a488035
TO
2875 $primaryLocation = 0;
2876 foreach ($params as $key => $value) {
2877 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2878
2879 if ($locTypeId == 'Primary') {
2880 $locTypeId = $primaryLocationType;
2881 }
2882
2883 if (is_numeric($locTypeId)) {
2884 if (!in_array($locTypeId, $locationType)) {
2885 $locationType[$count] = $locTypeId;
2886 $count++;
2887 }
2888 $loc = CRM_Utils_Array::key($locTypeId, $locationType);
2889
2890 $data['location'][$loc]['location_type_id'] = $locTypeId;
2891
2892 // if we are getting in a new primary email, dont overwrite the new one
2893 if ($locTypeId == $primaryLocationType) {
a7488080 2894 if (!empty($params['email-' . $primaryLocationType])) {
6a488035
TO
2895 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2896 }
2897 elseif (isset($primaryEmail)) {
2898 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2899 }
2900 $primaryLocation++;
2901 }
2902
2903 if ($loc == 1) {
2904 $data['location'][$loc]['is_primary'] = 1;
2905 }
2906 if ($fieldName == 'phone') {
2907 if ($phoneTypeId) {
2908 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2909 }
2910 else {
2911 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2912 }
2913 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2914 }
2915 elseif ($fieldName == 'email') {
2916 $data['location'][$loc]['email'][$loc]['email'] = $value;
2917 }
2918 elseif ($fieldName == 'im') {
2919 $data['location'][$loc]['im'][$loc]['name'] = $value;
2920 }
2921 else {
2922 if ($fieldName === 'state_province') {
2923 $data['location'][$loc]['address']['state_province_id'] = $value;
2924 }
2925 elseif ($fieldName === 'country') {
2926 $data['location'][$loc]['address']['country_id'] = $value;
2927 }
2928 else {
2929 $data['location'][$loc]['address'][$fieldName] = $value;
2930 }
2931 }
2932 }
2933 else {
67744c4e 2934 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
6a488035
TO
2935 if ($key === 'individual_suffix') {
2936 $data['suffix_id'] = $value;
2937 }
2938 elseif ($key === 'individual_prefix') {
2939 $data['prefix_id'] = $value;
2940 }
2941 elseif ($key === 'gender') {
2942 $data['gender_id'] = $value;
2943 }
2944 elseif (substr($key, 0, 6) === 'custom') {
2945 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
2946 //fix checkbox
2947 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2948 $value = implode(CRM_Core_DAO::VALUE_SEPARATOR, array_keys($value));
2949 }
2950 // fix the date field
2951 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2952 $date = CRM_Utils_Date::format($value);
2953 if (!$date) {
2954 $date = '';
2955 }
2956 $value = $date;
2957 }
2958
2959 $data['custom'][$customFieldID] = array(
2960 'id' => $id,
2961 'value' => $value,
2962 'extends' => $customFields[$customFieldID]['extends'],
2963 'type' => $customFields[$customFieldID]['data_type'],
2964 'custom_field_id' => $customFieldID,
2965 );
2966 }
2967 }
2968 elseif ($key == 'edit') {
2969 continue;
2970 }
2971 else {
2972 $data[$key] = $value;
2973 }
2974 }
2975 }
2976
2977 if (!$primaryLocation) {
2978 $loc++;
2979 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2980 }
2981
6a488035
TO
2982 return $data;
2983 }
2984
2985 /**
100fef9d 2986 * Calculate the profile type 'group_type' as per profile fields.
6a488035 2987 *
6a0b768e
TO
2988 * @param int $gId
2989 * Profile id.
1fd63589 2990 * @param bool $includeTypeValues
6a0b768e
TO
2991 * @param int $ignoreFieldId
2992 * Ignore particular profile field.
6a488035 2993 *
a6c01b45
CW
2994 * @return array
2995 * list of calculated group type
6a488035 2996 */
00be9182 2997 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
6a488035
TO
2998 //get the profile fields.
2999 $ufFields = self::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3000 return self::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3001 }
3002
3003 /**
100fef9d 3004 * Calculate the profile type 'group_type' as per profile fields.
6a488035 3005 *
1fd63589
EM
3006 * @param $ufFields
3007 * @param bool $includeTypeValues
6a0b768e
TO
3008 * @param int $ignoreFieldId
3009 * Ignore perticular profile field.
6a488035 3010 *
a6c01b45
CW
3011 * @return array
3012 * list of calculated group type
6a488035 3013 */
00be9182 3014 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
6a488035
TO
3015 $groupType = $groupTypeValues = $customFieldIds = array();
3016 if (!empty($ufFields)) {
3017 foreach ($ufFields as $fieldName => $fieldValue) {
3018 //ignore field from group type when provided.
3019 //in case of update profile field.
3020 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3021 continue;
3022 }
3023 if (!in_array($fieldValue['field_type'], $groupType)) {
3024 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3025 }
3026
3027 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField::getKeyID($fieldName))) {
3028 $customFieldIds[$fldId] = $fldId;
3029 }
3030 }
3031 }
3032
3033 if (!empty($customFieldIds)) {
3034 $query = 'SELECT DISTINCT(cg.id), cg.extends, cg.extends_entity_column_id, cg.extends_entity_column_value FROM civicrm_custom_group cg LEFT JOIN civicrm_custom_field cf ON cf.custom_group_id = cg.id WHERE cg.extends_entity_column_value IS NOT NULL AND cf.id IN (' . implode(',', $customFieldIds) . ')';
3035
3036 $customGroups = CRM_Core_DAO::executeQuery($query);
3037 while ($customGroups->fetch()) {
3038 if (!$customGroups->extends_entity_column_value) {
3039 continue;
3040 }
3041
3042 $groupTypeName = "{$customGroups->extends}Type";
3043 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id) {
233319bf 3044 $groupTypeName = CRM_Core_PseudoConstant::getName('CRM_Core_DAO_CustomGroup', 'extends_entity_column_id', $customGroups->extends_entity_column_id);
6a488035
TO
3045 }
3046
3047 foreach (explode(CRM_Core_DAO::VALUE_SEPARATOR, $customGroups->extends_entity_column_value) as $val) {
3048 if ($val) {
3049 $groupTypeValues[$groupTypeName][$val] = $val;
3050 }
3051 }
3052 }
3053
3054 if (!empty($groupTypeValues)) {
3055 $groupType = array_merge($groupType, $groupTypeValues);
3056 }
3057 }
3058
3059 return $groupType;
3060 }
3061
3062 /**
3063 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3064 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3065 *
3066 * FIELDS GROUP_TYPE
3067 * BirthDate + Email Individual,Contact
3068 * BirthDate + Subject Individual,Activity
3069 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3070 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3071 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3072 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3073 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3074 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3075 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3076 *
c490a46a 3077 * @param int $gId
6a0b768e
TO
3078 * @param array $groupTypes
3079 * With key having group type names.
6a488035 3080 *
e7483cbe 3081 * @return bool
6a488035 3082 */
00be9182 3083 public static function updateGroupTypes($gId, $groupTypes = array()) {
6a488035
TO
3084 if (!is_array($groupTypes) || !$gId) {
3085 return FALSE;
3086 }
3087
3088 // If empty group types set group_type as 'null'
3089 if (empty($groupTypes)) {
3090 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3091 }
3092
1cb28d5d 3093 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
5d6ac993
TO
3094 $validGroupTypes = array_merge(array(
3095 'Contact',
3096 'Individual',
3097 'Organization',
21dfd5f5 3098 'Household',
5d6ac993 3099 ), $componentGroupTypes, CRM_Contact_BAO_ContactType::subTypes());
6a488035
TO
3100
3101 $gTypes = $gTypeValues = array();
3102
3103 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3104 // Get valid group type and group subtypes
3105 foreach ($groupTypes as $groupType => $value) {
3106 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3107 $gTypes[] = $groupType;
3108 }
3109
3110 $subTypesOf = NULL;
3111
3112 if (in_array($groupType, $participantExtends)) {
3113 $subTypesOf = $groupType;
3114 }
3115 elseif (strpos($groupType, 'Type') > 0) {
3116 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3117 }
3118 else {
3119 continue;
3120 }
3121
3122 if (!empty($value) &&
3123 (in_array($subTypesOf, $componentGroupTypes) ||
3124 in_array($subTypesOf, $participantExtends)
3125 )
3126 ) {
3127 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3128 }
3129 }
3130
3131 if (empty($gTypes)) {
3132 return FALSE;
3133 }
3134
3135 // Build String to store group types and group subtypes
3136 $groupTypeString = implode(',', $gTypes);
3137 if (!empty($gTypeValues)) {
3138 $groupTypeString .= CRM_Core_DAO::VALUE_SEPARATOR . implode(',', $gTypeValues);
3139 }
3140
3141 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3142 }
3143
3144 /**
fe482240 3145 * Create a "group_type" string.
6a488035 3146 *
6a0b768e
TO
3147 * @param array $coreTypes
3148 * E.g. array('Individual','Contact','Student').
3149 * @param array $subTypes
3150 * E.g. array('ActivityType' => array(7, 11)).
6a488035 3151 * @param string $delim
1fd63589
EM
3152 *
3153 * @return string
6a488035
TO
3154 * @throws CRM_Core_Exception
3155 */
00be9182 3156 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO::VALUE_SEPARATOR) {
6a488035
TO
3157 $groupTypeExpr = '';
3158 if ($coreTypes) {
3159 $groupTypeExpr .= implode(',', $coreTypes);
3160 }
3161 if ($subTypes) {
99e239bc 3162 //CRM-15427 Allow Multiple subtype filtering
3163 //if (count($subTypes) > 1) {
5d6ac993 3164 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
99e239bc 3165 //}
6a488035
TO
3166 foreach ($subTypes as $subType => $subTypeIds) {
3167 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3168 }
3169 }
3170 return $groupTypeExpr;
3171 }
3172
3173 /**
dc195289 3174 * setDefault componet specific profile fields.
6a488035 3175 *
6a0b768e
TO
3176 * @param array $fields
3177 * Profile fields.
3178 * @param int $componentId
3179 * ComponetID.
3180 * @param string $component
3181 * Component name.
3182 * @param array $defaults
3183 * An array of default values.
1fd63589
EM
3184 *
3185 * @param bool $isStandalone
6a488035 3186 */
f0385140 3187 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
6a488035 3188 if (!$componentId ||
888da08c 3189 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity', 'Case'))
6a488035
TO
3190 ) {
3191 return;
3192 }
3193
3194 $componentBAO = $componentSubType = NULL;
3195 switch ($component) {
3196 case 'Membership':
5d6ac993 3197 $componentBAO = 'CRM_Member_BAO_Membership';
6a488035
TO
3198 $componentBAOName = 'Membership';
3199 $componentSubType = array('membership_type_id');
3200 break;
3201
3202 case 'Contribute':
5d6ac993 3203 $componentBAO = 'CRM_Contribute_BAO_Contribution';
6a488035 3204 $componentBAOName = 'Contribution';
5d6ac993 3205 $componentSubType = array('financial_type_id');
6a488035
TO
3206 break;
3207
3208 case 'Event':
5d6ac993 3209 $componentBAO = 'CRM_Event_BAO_Participant';
6a488035 3210 $componentBAOName = 'Participant';
d623de42 3211 $componentSubType = array('role_id', 'event_id', 'event_type_id');
6a488035
TO
3212 break;
3213
3214 case 'Activity':
5d6ac993 3215 $componentBAO = 'CRM_Activity_BAO_Activity';
6a488035
TO
3216 $componentBAOName = 'Activity';
3217 $componentSubType = array('activity_type_id');
3218 break;
888da08c
MW
3219
3220 case 'Case':
3221 $componentBAO = 'CRM_Case_BAO_Case';
3222 $componentBAOName = 'Case';
3223 $componentSubType = array('case_type_id');
3224 break;
6a488035
TO
3225 }
3226
3227 $values = array();
3228 $params = array('id' => $componentId);
3229
3230 //get the component values.
3231 CRM_Core_DAO::commonRetrieve($componentBAO, $params, $values);
d623de42
M
3232 if ($componentBAOName == 'Participant') {
3233 $values += array('event_type_id' => CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3234 }
6a488035
TO
3235
3236 $formattedGroupTree = array();
a86839e7 3237
6a488035
TO
3238 foreach ($fields as $name => $field) {
3239 $fldName = $isStandalone ? $name : "field[$componentId][$name]";
3d927ee7 3240 if (array_key_exists($name, $values)) {
6a488035
TO
3241 $defaults[$fldName] = $values[$name];
3242 }
3243 elseif ($name == 'participant_note') {
5d6ac993 3244 $noteDetails = CRM_Core_BAO_Note::getNote($componentId, 'civicrm_participant');
6a488035
TO
3245 $defaults[$fldName] = array_pop($noteDetails);
3246 }
3247 elseif (in_array($name, array(
5d6ac993
TO
3248 'financial_type',
3249 'payment_instrument',
3250 'participant_status',
21dfd5f5 3251 'participant_role',
5d6ac993 3252 ))) {
6a488035
TO
3253 $defaults[$fldName] = $values["{$name}_id"];
3254 }
3255 elseif ($name == 'membership_type') {
3256 // since membership_type field is a hierselect -
e7483cbe
J
3257 $defaults[$fldName][0]
3258 = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
6a488035
TO
3259 $defaults[$fldName][1] = $values['membership_type_id'];
3260 }
3261 elseif ($name == 'membership_status') {
3262 $defaults[$fldName] = $values['status_id'];
3263 }
888da08c
MW
3264 elseif ($name == 'case_status') {
3265 $defaults[$fldName] = $values['case_status_id'];
3266 }
04b40eab 3267 elseif (CRM_Core_BAO_CustomField::getKeyID($name, TRUE) !== array(NULL, NULL)) {
6a488035
TO
3268 if (empty($formattedGroupTree)) {
3269 //get the groupTree as per subTypes.
3270 $groupTree = array();
3271 foreach ($componentSubType as $subType) {
0b330e6d 3272 $subTree = CRM_Core_BAO_CustomGroup::getTree($componentBAOName, NULL,
6a488035
TO
3273 $componentId, 0, $values[$subType]
3274 );
3275 $groupTree = CRM_Utils_Array::crmArrayMerge($groupTree, $subTree);
3276 }
1273d77c 3277 $formattedGroupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree, 1);
6a488035
TO
3278 CRM_Core_BAO_CustomGroup::setDefaults($formattedGroupTree, $defaults);
3279 }
3280
3281 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3282 foreach ($defaults as $customKey => $customValue) {
3283 if ($customFieldDetails = CRM_Core_BAO_CustomField::getKeyID($customKey, TRUE)) {
3284 if ($name == 'custom_' . $customFieldDetails[0]) {
3285
3286 //hack to set default for checkbox
3287 //basically this is for weired field name like field[33][custom_19]
3288 //we are converting this field name to array structure and assign value.
3289 $skipValue = FALSE;
3290
3291 foreach ($formattedGroupTree as $tree) {
d623de42
M
3292 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3293 if ('CheckBox' == CRM_Utils_Array::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3294 $skipValue = TRUE;
3295 $defaults['field'][$componentId][$name] = $customValue;
3296 break;
3297 }
3298 elseif (CRM_Utils_Array::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3299 $skipValue = TRUE;
6a488035 3300
d623de42
M
3301 // CRM-6681, $default contains formatted date, time values.
3302 $defaults[$fldName] = $customValue;
3303 if (!empty($defaults[$customKey . '_time'])) {
3304 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3305 }
6a488035
TO
3306 }
3307 }
3308 }
3309
3310 if (!$skipValue || $isStandalone) {
3311 $defaults[$fldName] = $customValue;
3312 }
3313 unset($defaults[$customKey]);
3314 break;
3315 }
3316 }
3317 }
3318 }
04b40eab 3319 elseif (isset($values[$fldName])) {
3320 $defaults[$fldName] = $values[$fldName];
3321 }
6a488035
TO
3322 }
3323 }
3324
6a488035 3325 /**
fe482240 3326 * Retrieve groups of profiles.
6a488035 3327 *
6a0b768e
TO
3328 * @param int $profileID
3329 * Id of the profile.
6a488035 3330 *
a6c01b45
CW
3331 * @return array
3332 * returns array
6a488035 3333 */
00be9182 3334 public static function profileGroups($profileID) {
6a488035
TO
3335 $groupTypes = array();
3336 $profileTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3337 if ($profileTypes) {
3338 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $profileTypes);
3339 $groupTypes = explode(',', $groupTypeParts[0]);
3340 }
3341 return $groupTypes;
3342 }
3343
3344 /**
100fef9d 3345 * Alter contact params by filtering existing subscribed groups and returns
6a488035
TO
3346 * unsubscribed groups array for subscription.
3347 *
6a0b768e
TO
3348 * @param array $params
3349 * Contact params.
3350 * @param int $contactId
3351 * User contact id.
6a488035 3352 *
a6c01b45
CW
3353 * @return array
3354 * This contains array of groups for subscription
6a488035 3355 */
00be9182 3356 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
6a488035
TO
3357 $config = CRM_Core_Config::singleton();
3358 $subscribeGroupIds = array();
3359
3360 // process further only if profileDoubleOptIn enabled and if groups exist
3361 if (!array_key_exists('group', $params) ||
3362 !self::isProfileDoubleOptin() ||
3363 CRM_Utils_System::isNull($params['group'])
3364 ) {
3365 return $subscribeGroupIds;
3366 }
3367
3368 //check if contact email exist.
3369 $hasEmails = FALSE;
3370 foreach ($params as $name => $value) {
3371 if (strpos($name, 'email-') !== FALSE) {
3372 $hasEmails = TRUE;
3373 break;
3374 }
3375 }
3376
3377 //Proceed furthur only if email present
3378 if (!$hasEmails) {
3379 return $subscribeGroupIds;
3380 }
3381
3382 //do check for already subscriptions.
3383 $contactGroups = array();
3384 if ($contactId) {
3385 $query = "
3386SELECT group_id
3387 FROM civicrm_group_contact
3388 WHERE status = 'Added'
3389 AND contact_id = %1";
3390
3391 $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($contactId, 'Integer')));
3392 while ($dao->fetch()) {
3393 $contactGroups[$dao->group_id] = $dao->group_id;
3394 }
3395 }
3396
3397 //since we don't have names, compare w/ label.
3398 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup::values('group_type'));
3399
3400 //actual processing start.
3401 foreach ($params['group'] as $groupId => $isSelected) {
3402 //unset group those are not selected.
3403 if (!$isSelected) {
3404 unset($params['group'][$groupId]);
3405 continue;
3406 }
3407
3408 $groupTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR,
3409 CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3410 );
3411 //get only mailing type group and unset it from params
3412 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3413 $subscribeGroupIds[$groupId] = $groupId;
3414 unset($params['group'][$groupId]);
3415 }
3416 }
3417
3418 return $subscribeGroupIds;
3419 }
3420
3421 /**
fe482240 3422 * Check if we are rendering mixed profiles.
6a488035 3423 *
6a0b768e
TO
3424 * @param array $profileIds
3425 * Associated array of profile ids.
6a488035 3426 *
e7483cbe 3427 * @return bool
a6c01b45 3428 * true if profile is mixed
6a488035 3429 */
00be9182 3430 public static function checkForMixProfiles($profileIds) {
6a488035
TO
3431 $mixProfile = FALSE;
3432
3433 $contactTypes = array('Individual', 'Household', 'Organization');
3434 $subTypes = CRM_Contact_BAO_ContactType::subTypes();
3435
3436 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3437
3438 $typeCount = array('ctype' => array(), 'subtype' => array());
3439 foreach ($profileIds as $gid) {
3440 $profileType = CRM_Core_BAO_UFField::getProfileType($gid);
3441 // ignore profile of type Contact
3442 if ($profileType == 'Contact') {
3443 continue;
3444 }
3445 if (in_array($profileType, $contactTypes)) {
3446 if (!isset($typeCount['ctype'][$profileType])) {
3447 $typeCount['ctype'][$profileType] = 1;
3448 }
3449
3450 // check if we are rendering profile of different contact types
3451 if (count($typeCount['ctype']) == 2) {
3452 $mixProfile = TRUE;
3453 break;
3454 }
3455 }
3456 elseif (in_array($profileType, $components)) {
3457 $mixProfile = TRUE;
3458 break;
3459 }
3460 else {
3461 if (!isset($typeCount['subtype'][$profileType])) {
3462 $typeCount['subtype'][$profileType] = 1;
3463 }
3464 // check if we are rendering profile of different contact sub types
3465 if (count($typeCount['subtype']) == 2) {
3466 $mixProfile = TRUE;
3467 break;
3468 }
3469 }
3470 }
3471 return $mixProfile;
3472 }
3473
3474 /**
fe482240 3475 * Determine of we show overlay profile or not.
6a488035 3476 *
e7483cbe 3477 * @return bool
a6c01b45 3478 * true if profile should be shown else false
6a488035 3479 */
00be9182 3480 public static function showOverlayProfile() {
6a488035
TO
3481 $showOverlay = TRUE;
3482
3483 // get the id of overlay profile
3484 $overlayProfileId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3485 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3486
3487 $count = CRM_Core_DAO::singleValueQuery($query);
3488
3489 //check if there are no public fields and use is anonymous
3490 $session = CRM_Core_Session::singleton();
3491 if (!$count && !$session->get('userID')) {
3492 $showOverlay = FALSE;
3493 }
3494
3495 return $showOverlay;
3496 }
3497
3498 /**
fe482240 3499 * Get group type values of the profile.
6a488035 3500 *
c490a46a
CW
3501 * @param int $profileId
3502 * @param string $groupType
1fd63589 3503 *
e7483cbe 3504 * @return array
a6c01b45 3505 * group type values
6a488035 3506 */
00be9182 3507 public static function groupTypeValues($profileId, $groupType = NULL) {
6a488035
TO
3508 $groupTypeValue = array();
3509 $groupTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3510
3511 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $groupTypes);
a7488080 3512 if (empty($groupTypeParts[1])) {
6a488035
TO
3513 return $groupTypeValue;
3514 }
3515 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3516
3517 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3518 $values = array();
3519 $valueParts = explode(':', $groupTypeValues);
3520 if ($groupType &&
3521 ($valueParts[0] != "{$groupType}Type" ||
3522 ($groupType == 'Participant' &&
3523 !in_array($valueParts[0], $participantExtends)
3524 )
3525 )
3526 ) {
3527 continue;
3528 }
3529 foreach ($valueParts as $val) {
3530 if (CRM_Utils_Rule::integer($val)) {
3531 $values[$val] = $val;
3532 }
3533 }
3534 if (!empty($values)) {
3535 $typeName = substr($valueParts[0], 0, -4);
3536 if (in_array($valueParts[0], $participantExtends)) {
3537 $typeName = $valueParts[0];
3538 }
3539 $groupTypeValue[$typeName] = $values;
3540 }
3541 }
3542
3543 return $groupTypeValue;
3544 }
3545
b5c2afd0
EM
3546 /**
3547 * @return bool|object
3548 */
00be9182 3549 public static function isProfileDoubleOptin() {
6a488035
TO
3550 // check for double optin
3551 $config = CRM_Core_Config::singleton();
3552 if (in_array('CiviMail', $config->enableComponents)) {
aaffa79f 3553 return Civi::settings()->get('profile_double_optin');
6a488035
TO
3554 }
3555 return FALSE;
3556 }
3557
b5c2afd0
EM
3558 /**
3559 * @return bool|object
3560 */
00be9182 3561 public static function isProfileAddToGroupDoubleOptin() {
6a488035
TO
3562 // check for add to group double optin
3563 $config = CRM_Core_Config::singleton();
3564 if (in_array('CiviMail', $config->enableComponents)) {
aaffa79f 3565 return Civi::settings()->get('profile_add_to_group_double_optin');
6a488035
TO
3566 }
3567 return FALSE;
3568 }
3569
3570 /**
fe482240 3571 * Get profiles used for batch entry.
6a488035 3572 *
a6c01b45
CW
3573 * @return array
3574 * profileIds profile ids
6a488035 3575 */
00be9182 3576 public static function getBatchProfiles() {
6a488035
TO
3577 $query = "SELECT id
3578 FROM civicrm_uf_group
3579 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
5d6ac993 3580 $dao = CRM_Core_DAO::executeQuery($query);
6a488035 3581 $profileIds = array();
5d6ac993 3582 while ($dao->fetch()) {
6a488035
TO
3583 $profileIds[$dao->id] = $dao->id;
3584 }
3585 return $profileIds;
3586 }
3587
1fd63589
EM
3588 /**
3589 * @todo what do I do?
3590 * @param $source
3591 * @param $destination
3592 * @param bool $returnMultiSummaryFields
3593 *
3594 * @return array|null
3595 */
00be9182 3596 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
5d6ac993 3597 $multiSummaryFields = $returnMultiSummaryFields ? array() : NULL;
6a488035
TO
3598 foreach ($source as $field => $properties) {
3599 if (!CRM_Core_BAO_CustomField::getKeyID($field)) {
3600 continue;
3601 }
3602 if (CRM_Core_BAO_CustomField::isMultiRecordField($field)) {
3603 $destination[$field] = $properties;
3604 if ($returnMultiSummaryFields) {
3605 if ($properties['is_multi_summary']) {
3606 $multiSummaryFields[$field] = $properties;
3607 }
3608 }
3609 unset($source[$field]);
3610 }
3611 }
3612 return $multiSummaryFields;
3613 }
3614
3615 /**
fe482240 3616 * This is function is used to format pseudo fields.
6a488035 3617 *
6a0b768e
TO
3618 * @param array $fields
3619 * Associated array of profile fields.
6a488035 3620 *
6a488035 3621 */
00be9182 3622 public static function reformatProfileFields(&$fields) {
6a488035
TO
3623 //reformat fields array
3624 foreach ($fields as $name => $field) {
3625 //reformat phone and extension field
5d6ac993 3626 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
6a488035
TO
3627 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3628
3629 // retain existing element properties and just update and replace key
3630 CRM_Utils_Array::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3631 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3632 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3633
3634 // add additional phone extension field
3635 $fields["phone_ext-{$fieldSuffix}"] = $field;
5d6ac993 3636 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
6a488035
TO
3637 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3638 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3639 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3640 //ignore required for extension field
3641 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;
3642 }
3643 }
3644 }
96025800 3645
6a488035 3646}