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