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