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