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