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