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