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