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