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