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