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