CRM-16354 - Migrate forms to new wysiwyg code
[civicrm-core.git] / CRM / Core / BAO / UFGroup.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
6a488035 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
e7112fa7 31 * @copyright CiviCRM LLC (c) 2004-2015
6a488035
TO
32 * $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 /**
fe482240 45 * Cache the match clause used in this transaction.
6a488035
TO
46 *
47 * @var string
48 */
49 static $_matchFields = NULL;
50
51 /**
fe482240 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 58 *
a6c01b45
CW
59 * @return object
60 * CRM_Core_DAO_UFGroup object
6a488035 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 71 *
a6c01b45
CW
72 * @return string
73 * contact type
6a488035 74 */
00be9182 75 public static function getContactType($id) {
6a488035
TO
76
77 $validTypes = array_filter(array_keys(CRM_Core_SelectValues::contactType()));
78 $validSubTypes = CRM_Contact_BAO_ContactType::subTypeInfo();
79
80 $typesParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
81 $types = explode(',', $typesParts[0]);
82
83 $cType = NULL;
84 foreach ($types as $type) {
85 if (in_array($type, $validTypes)) {
86 $cType = $type;
87 }
88 elseif (array_key_exists($type, $validSubTypes)) {
89 $cType = CRM_Utils_Array::value('parent', $validSubTypes[$type]);
90 }
2aa397bc 91 if ($cType) {
5d6ac993 92 break;
2aa397bc 93 }
6a488035
TO
94 }
95
96 return $cType;
97 }
98
99 /**
100 * Get the form title.
101 *
6a0b768e
TO
102 * @param int $id
103 * Id of uf_form.
6a488035 104 *
a6c01b45
CW
105 * @return string
106 * title
6a488035 107 *
6a488035
TO
108 */
109 public static function getTitle($id) {
110 return CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
111 }
112
113 /**
fe482240 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 120 *
a6c01b45
CW
121 * @return Object
122 * CRM_Core_DAO_UFGroup object on success, null otherwise
6a488035 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 /**
fe482240 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 137 *
a6c01b45
CW
138 * @return array
139 * the fields that are needed for registration
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 /**
fe482240 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
a6c01b45
CW
199 * @return array
200 * the fields that are listings related
6a488035 201 */
e7483cbe 202 public static function getListingFields(
6a488035
TO
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 *
a6c01b45
CW
278 * @return array
279 * the fields that belong to this ufgroup(s)
6a488035 280 */
e7483cbe 281 public static function getFields(
6a488035
TO
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
e7483cbe 425 * @param array $customFields
6a488035
TO
426 * @param array $addressCustomFields
427 * @param array $importableFields
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 /**
fe482240 538 * Create a query to find all visible UFFields in a UFGroup.
6a488035
TO
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 /**
fe482240 586 * Create a query to find all visible UFFields in a UFGroup.
6a488035
TO
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
a6c01b45
CW
594 * @return bool
595 * TRUE if field is displayable
6a488035
TO
596 */
597 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
598 if ($searchable && $field->is_searchable != 1) {
599 return FALSE;
600 }
601
602 if (!$showAll && $field->is_active != 1) {
603 return FALSE;
604 }
605
606 if ($visibility) {
607 $allowedVisibilities = array();
608 if ($visibility & self::PUBLIC_VISIBILITY) {
609 $allowedVisibilities[] = 'Public Pages';
610 }
611 if ($visibility & self::ADMIN_VISIBILITY) {
612 $allowedVisibilities[] = 'User and User Admin Only';
613 }
614 if ($visibility & self::LISTINGS_VISIBILITY) {
615 $allowedVisibilities[] = 'Public Pages and Listings';
616 }
617 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
618 if (!empty($allowedVisibilities) && !in_array($field->visibility, $allowedVisibilities)) {
619 return FALSE;
620 }
621 }
622
623 return TRUE;
624 }
625
b5c2afd0
EM
626 /**
627 * @param $showAll
628 * @param $profileType
629 * @param $contactActivityProfile
630 *
631 * @return array
632 */
6a488035
TO
633 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
634 if (!$showAll) {
635 $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
636 }
637 else {
638 $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
639 }
640
641 if ($profileType == 'Activity' || $contactActivityProfile) {
642 $componentFields = CRM_Activity_BAO_Activity::getProfileFields();
643 }
644 else {
645 $componentFields = CRM_Core_Component::getQueryFields();
646 }
647
648 $importableFields = array_merge($importableFields, $componentFields);
649
650 $importableFields['group']['title'] = ts('Group(s)');
651 $importableFields['group']['where'] = NULL;
652 $importableFields['tag']['title'] = ts('Tag(s)');
653 $importableFields['tag']['where'] = NULL;
654 return $importableFields;
655 }
656
657 public static function getLocationFields() {
658 static $locationFields = array(
659 'street_address',
660 'supplemental_address_1',
661 'supplemental_address_2',
662 'city',
663 'postal_code',
664 'postal_code_suffix',
665 'geo_code_1',
666 'geo_code_2',
667 'state_province',
668 'country',
669 'county',
670 'phone',
671 'phone_and_ext',
672 'email',
673 'im',
674 'address_name',
675 'phone_ext',
676 );
677 return $locationFields;
678 }
679
b5c2afd0
EM
680 /**
681 * @param $ctype
682 *
683 * @return mixed
684 */
6a488035
TO
685 protected static function getCustomFields($ctype) {
686 static $customFieldCache = array();
687 if (!isset($customFieldCache[$ctype])) {
688 $customFields = CRM_Core_BAO_CustomField::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
689
690 // hack to add custom data for components
1cb28d5d 691 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
6a488035
TO
692 foreach ($components as $value) {
693 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField::getFieldsForImport($value));
694 }
695 $addressCustomFields = CRM_Core_BAO_CustomField::getFieldsForImport('Address');
696 $customFields = array_merge($customFields, $addressCustomFields);
697 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
698 }
699 return $customFieldCache[$ctype];
700 }
701
702 /**
fe482240 703 * Check the data validity.
6a488035 704 *
6a0b768e
TO
705 * @param int $userID
706 * The user id that we are actually editing.
707 * @param string $title
708 * The title of the group we are interested in.
2a6da8d7 709 * @param bool $register
6a0b768e
TO
710 * @param int $action
711 * The action of the form.
6a488035 712 *
2a6da8d7 713 * @pram boolean $register is this the registrtion form
e7483cbe 714 * @return bool
a6c01b45 715 * true if form is valid
6a488035 716 */
00be9182 717 public static function isValid($userID, $title, $register = FALSE, $action = NULL) {
6a488035
TO
718 if ($register) {
719 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
720 ts('Dynamic Form Creator'),
721 $action
722 );
723 $controller->set('id', $userID);
724 $controller->set('register', 1);
725 $controller->process();
726 return $controller->validate();
727 }
728 else {
729 // make sure we have a valid group
730 $group = new CRM_Core_DAO_UFGroup();
731
732 $group->title = $title;
733
734 if ($group->find(TRUE) && $userID) {
735 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
736 $controller->set('gid', $group->id);
737 $controller->set('id', $userID);
738 $controller->set('register', 0);
739 $controller->process();
740 return $controller->validate();
741 }
742 return TRUE;
743 }
744 }
745
746 /**
fe482240 747 * Get the html for the form that represents this particular group.
6a488035 748 *
6a0b768e
TO
749 * @param int $userID
750 * The user id that we are actually editing.
751 * @param string $title
752 * The title of the group we are interested in.
753 * @param int $action
754 * The action of the form.
755 * @param bool $register
756 * Is this the registration form.
757 * @param bool $reset
758 * Should we reset the form?.
759 * @param int $profileID
760 * Do we have the profile ID?.
2a6da8d7
EM
761 *
762 * @param bool $doNotProcess
763 * @param null $ctype
6a488035 764 *
a6c01b45
CW
765 * @return string
766 * the html for the form on success, otherwise empty string
6a488035 767 */
e7483cbe 768 public static function getEditHTML(
5d6ac993 769 $userID,
6a488035 770 $title,
5d6ac993
TO
771 $action = NULL,
772 $register = FALSE,
773 $reset = FALSE,
774 $profileID = NULL,
6a488035 775 $doNotProcess = FALSE,
5d6ac993 776 $ctype = NULL
6a488035
TO
777 ) {
778
779 if ($register) {
780 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
781 ts('Dynamic Form Creator'),
782 $action
783 );
784 if ($reset || $doNotProcess) {
785 // hack to make sure we do not process this form
786 $oldQFDefault = CRM_Utils_Array::value('_qf_default',
787 $_POST
788 );
789 unset($_POST['_qf_default']);
790 unset($_REQUEST['_qf_default']);
791 if ($reset) {
792 $controller->reset();
793 }
794 }
795
796 $controller->set('id', $userID);
797 $controller->set('register', 1);
798 $controller->set('skipPermission', 1);
799 $controller->set('ctype', $ctype);
800 $controller->process();
801 if ($doNotProcess || !empty($_POST)) {
802 $controller->validate();
803 }
804 $controller->setEmbedded(TRUE);
805
806 //CRM-5839 - though we want to process form, get the control back.
807 $controller->setSkipRedirection(($doNotProcess) ? FALSE : TRUE);
808
809 $controller->run();
810
811 // we are done processing so restore the POST/REQUEST vars
812 if (($reset || $doNotProcess) && $oldQFDefault) {
813 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
814 }
815
816 $template = CRM_Core_Smarty::singleton();
817
818 // Hide CRM error messages if they are displayed using drupal form_set_error.
819 if (!empty($_POST)) {
820 $template->assign('suppressForm', TRUE);
821 }
822
823 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
824 }
825 else {
826 if (!$profileID) {
827 // make sure we have a valid group
828 $group = new CRM_Core_DAO_UFGroup();
829
830 $group->title = $title;
831
832 if ($group->find(TRUE)) {
833 $profileID = $group->id;
834 }
835 }
836
837 if ($profileID) {
838 // make sure profileID and ctype match if ctype exists
839 if ($ctype) {
840 $profileType = CRM_Core_BAO_UFField::getProfileType($profileID);
841 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
842 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
843 }
844
845 if (($profileType != 'Contact') && ($profileType != $ctype)) {
846 return NULL;
847 }
848 }
849
850 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
851 ts('Dynamic Form Creator'),
852 $action
853 );
854 if ($reset) {
855 $controller->reset();
856 }
857 $controller->set('gid', $profileID);
858 $controller->set('id', $userID);
859 $controller->set('register', 0);
860 $controller->set('skipPermission', 1);
861 if ($ctype) {
862 $controller->set('ctype', $ctype);
863 }
864 $controller->process();
865 $controller->setEmbedded(TRUE);
866
867 //CRM-5846 - give the control back to drupal.
868 $controller->setSkipRedirection(($doNotProcess) ? FALSE : TRUE);
869 $controller->run();
870
871 $template = CRM_Core_Smarty::singleton();
872
873 // Hide CRM error messages if they are displayed using drupal form_set_error.
874 if (!empty($_POST) && CRM_Core_Config::singleton()->userFramework == 'Drupal') {
875 if (arg(0) == 'user' || (arg(0) == 'admin' && arg(1) == 'people')) {
876 $template->assign('suppressForm', TRUE);
877 }
878 }
879
880 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
881 if (!$template->template_exists($templateFile)) {
882 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
883 }
884 return trim($template->fetch($templateFile));
885 }
886 else {
887 $userEmail = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID);
888
889 // if post not empty then only proceed
890 if (!empty($_POST)) {
891 // get the new email
892 $config = CRM_Core_Config::singleton();
893 $email = CRM_Utils_Array::value('mail', $_POST);
894
895 if (CRM_Utils_Rule::email($email) && ($email != $userEmail[1])) {
896 CRM_Core_BAO_UFMatch::updateContactEmail($userID, $email);
897 }
898 }
899 }
900 }
901 return '';
902 }
903
904 /**
fe482240 905 * Searches for a contact in the db with similar attributes.
6a488035 906 *
6a0b768e
TO
907 * @param array $params
908 * The list of values to be used in the where clause.
909 * @param int $id
910 * The current contact id (hence excluded from matching).
2a6da8d7
EM
911 * @param string $contactType
912 *
72b3a70c
CW
913 * @return int|null
914 * contact_id if found, null otherwise
6a488035
TO
915 */
916 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
917 $dedupeParams = CRM_Dedupe_Finder::formatParams($params, $contactType);
918 $dedupeParams['check_permission'] = CRM_Utils_Array::value('check_permission', $params, TRUE);
919 $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
920 if (!empty($ids)) {
921 return implode(',', $ids);
922 }
923 else {
924 return NULL;
925 }
926 }
927
928 /**
929 * Given a contact id and a field set, return the values from the db
930 * for this contact
931 *
100fef9d 932 * @param int $cid
6a0b768e
TO
933 * @param array $fields
934 * The profile fields of interest.
935 * @param array $values
936 * The values for the above fields.
937 * @param bool $searchable
938 * Searchable or not.
939 * @param array $componentWhere
940 * Component condition.
941 * @param bool $absolute
942 * Return urls in absolute form (useful when sending an email).
2a6da8d7 943 * @param null $additionalWhereClause
6a488035
TO
944 *
945 * @return void
6a488035 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 1378 *
e7483cbe 1379 * @return bool
6a488035 1380 *
6a488035
TO
1381 */
1382 public static function usedByModule($id) {
1383 //check whether this group is used by any module(check uf join records)
1384 $sql = "SELECT id
1385 FROM civicrm_uf_join
1386 WHERE civicrm_uf_join.uf_group_id=$id";
1387
1388 $dao = new CRM_Core_DAO();
1389 $dao->query($sql);
1390 if ($dao->fetch()) {
1391 return TRUE;
1392 }
1393 else {
1394 return FALSE;
1395 }
1396 }
1397
1398 /**
1399 * Delete the profile Group.
1400 *
6a0b768e
TO
1401 * @param int $id
1402 * Profile Id.
6a488035 1403 *
e7483cbe 1404 * @return bool
6a488035 1405 *
6a488035
TO
1406 */
1407 public static function del($id) {
1408 //check whether this group contains any profile fields
1409 $profileField = new CRM_Core_DAO_UFField();
1410 $profileField->uf_group_id = $id;
1411 $profileField->find();
1412 while ($profileField->fetch()) {
1413 CRM_Core_BAO_UFField::del($profileField->id);
1414 }
1415
1416 //delete records from uf join table
1417 $ufJoin = new CRM_Core_DAO_UFJoin();
1418 $ufJoin->uf_group_id = $id;
1419 $ufJoin->delete();
1420
1421 //delete profile group
1422 $group = new CRM_Core_DAO_UFGroup();
1423 $group->id = $id;
1424 $group->delete();
1425 return 1;
1426 }
1427
1428 /**
fe482240 1429 * Add the UF Group.
6a488035 1430 *
6a0b768e
TO
1431 * @param array $params
1432 * Reference array contains the values submitted by the form.
1433 * @param array $ids
1434 * Reference array contains the id.
6a488035 1435 *
6a488035
TO
1436 *
1437 * @return object
1438 */
00be9182 1439 public static function add(&$params, $ids = array()) {
5d6ac993
TO
1440 $fields = array(
1441 'is_active',
1442 'add_captcha',
1443 'is_map',
1444 'is_update_dupe',
1445 'is_edit_link',
1446 'is_uf_link',
21dfd5f5 1447 'is_cms_user',
5d6ac993 1448 );
6a488035
TO
1449 foreach ($fields as $field) {
1450 $params[$field] = CRM_Utils_Array::value($field, $params, FALSE);
1451 }
1452
1453 $params['limit_listings_group_id'] = CRM_Utils_Array::value('group', $params);
1454 $params['add_to_group_id'] = CRM_Utils_Array::value('add_contact_to_group', $params);
1455
f80ef0e2 1456 //CRM-15427
1457 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1458 $params['group_type'] = implode(',', $params['group_type']);
1459 }
6a488035
TO
1460 $ufGroup = new CRM_Core_DAO_UFGroup();
1461 $ufGroup->copyValues($params);
1462
6a73ef3f 1463 $ufGroupID = CRM_Utils_Array::value('ufgroup', $ids, CRM_Utils_Array::value('id', $params));
6a488035
TO
1464 if (!$ufGroupID) {
1465 $ufGroup->name = CRM_Utils_String::munge($ufGroup->title, '_', 56);
1466 }
1467 $ufGroup->id = $ufGroupID;
1468
1469 $ufGroup->save();
1470
1471 if (!$ufGroupID) {
1472 $ufGroup->name = $ufGroup->name . "_{$ufGroup->id}";
1473 $ufGroup->save();
1474 }
1475
1476 return $ufGroup;
1477 }
1478
1479 /**
fe482240 1480 * Make uf join entries for an uf group.
6a488035 1481 *
6a0b768e
TO
1482 * @param array $params
1483 * (reference) an assoc array of name/value pairs.
1484 * @param int $ufGroupId
1485 * Ufgroup id.
6a488035
TO
1486 *
1487 * @return void
6a488035 1488 */
00be9182 1489 public static function createUFJoin(&$params, $ufGroupId) {
6a488035
TO
1490 $groupTypes = CRM_Utils_Array::value('uf_group_type', $params);
1491
1492 // get ufjoin records for uf group
1493 $ufGroupRecord = CRM_Core_BAO_UFGroup::getUFJoinRecord($ufGroupId);
1494
1495 // get the list of all ufgroup types
1496 $allUFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1497
1498 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1499 if (!is_array($groupTypes)) {
1500 $groupTypes = array();
1501 }
1502
1503 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1504 if (!is_array($ufGroupRecord)) {
1505 $ufGroupRecord = array();
1506 }
1507
1508 // check which values has to be inserted/deleted for contact
1509 $menuRebuild = FALSE;
1510 foreach ($allUFGroupType as $key => $value) {
1511 $joinParams = array();
1512 $joinParams['uf_group_id'] = $ufGroupId;
1513 $joinParams['module'] = $key;
1514 if ($key == 'User Account') {
1515 $menuRebuild = TRUE;
1516 }
1517 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1518 // insert a new record
1519 CRM_Core_BAO_UFGroup::addUFJoin($joinParams);
1520 }
1521 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1522 // delete a record for existing ufgroup
1523 CRM_Core_BAO_UFGroup::delUFJoin($joinParams);
1524 }
1525 }
1526
1527 //update the weight
1528 $query = "
1529UPDATE civicrm_uf_join
1530SET weight = %1
1531WHERE uf_group_id = %2
1532AND ( entity_id IS NULL OR entity_id <= 0 )
1533";
5d6ac993
TO
1534 $p = array(
1535 1 => array($params['weight'], 'Integer'),
6a488035
TO
1536 2 => array($ufGroupId, 'Integer'),
1537 );
1538 CRM_Core_DAO::executeQuery($query, $p);
1539
1540 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1541 // for user account
1542 $config = CRM_Core_Config::singleton();
1543 if ($menuRebuild &&
1544 $config->userSystem->is_drupal
1545 ) {
1546 menu_rebuild();
1547 }
1548 }
1549
1550 /**
fe482240 1551 * Get the UF Join records for an ufgroup id.
6a488035 1552 *
6a0b768e
TO
1553 * @param int $ufGroupId
1554 * Uf group id.
1555 * @param int $displayName
1556 * If set return display name in array.
1557 * @param int $status
1558 * If set return module other than default modules (User Account/User registration/Profile).
77b97be7 1559 *
a6c01b45 1560 * @return array
6a488035 1561 *
6a488035
TO
1562 */
1563 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1564 if ($displayName) {
1565 $UFGroupType = array();
1566 $UFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1567 }
1568
1569 $ufJoin = array();
1570 $dao = new CRM_Core_DAO_UFJoin();
1571
1572 if ($ufGroupId) {
1573 $dao->uf_group_id = $ufGroupId;
1574 }
1575
1576 $dao->find();
1577 $ufJoin = array();
1578
1579 while ($dao->fetch()) {
1580 if (!$displayName) {
1581 $ufJoin[$dao->id] = $dao->module;
1582 }
1583 else {
1584 if (isset($UFGroupType[$dao->module])) {
1585 // skip the default modules
1586 if (!$status) {
1587 $ufJoin[$dao->id] = $UFGroupType[$dao->module];
1588 }
1589 // added for CRM-1475
1590 }
1591 elseif (!CRM_Utils_Array::key($dao->module, $ufJoin)) {
1592 $ufJoin[$dao->id] = $dao->module;
1593 }
1594 }
1595 }
1596 return $ufJoin;
1597 }
1598
1599 /**
fe482240 1600 * Function takes an associative array and creates a ufjoin record for ufgroup.
6a488035 1601 *
6a0b768e
TO
1602 * @param array $params
1603 * (reference) an assoc array of name/value pairs.
6a488035 1604 *
16b10e64 1605 * @return CRM_Core_BAO_UFJoin
6a488035 1606 */
00be9182 1607 public static function addUFJoin(&$params) {
6a488035
TO
1608 $ufJoin = new CRM_Core_DAO_UFJoin();
1609 $ufJoin->copyValues($params);
1610 $ufJoin->save();
1611 return $ufJoin;
1612 }
1613
1614 /**
fe482240 1615 * Delete the uf join record for an uf group.
6a488035 1616 *
6a0b768e
TO
1617 * @param array $params
1618 * (reference) an assoc array of name/value pairs.
6a488035
TO
1619 *
1620 * @return void
6a488035 1621 */
00be9182 1622 public static function delUFJoin(&$params) {
6a488035
TO
1623 $ufJoin = new CRM_Core_DAO_UFJoin();
1624 $ufJoin->copyValues($params);
1625 $ufJoin->delete();
1626 }
1627
1628 /**
fe482240 1629 * Get the weight for ufjoin record.
6a488035 1630 *
6a0b768e
TO
1631 * @param int $ufGroupId
1632 * If $ufGroupId get update weight or add weight.
6a488035 1633 *
a6c01b45
CW
1634 * @return int
1635 * weight of the UFGroup
6a488035 1636 */
00be9182 1637 public static function getWeight($ufGroupId = NULL) {
6a488035
TO
1638 //calculate the weight
1639 $p = array();
1640 if (!$ufGroupId) {
1641 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1642 FROM civicrm_uf_join
1643 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1644 }
1645 else {
1646 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1647 FROM civicrm_uf_join
1648 WHERE civicrm_uf_join.uf_group_id = %1
1649 AND ( entity_id IS NULL OR entity_id <= 0 )";
1650 $p[1] = array($ufGroupId, 'Integer');
1651 }
1652
1653 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1654 $dao->fetch();
1655 return ($dao->new_weight) ? $dao->new_weight : 1;
1656 }
1657
1658 /**
fe482240 1659 * Get the uf group for a module.
6a488035 1660 *
6a0b768e
TO
1661 * @param string $moduleName
1662 * Module name.
1663 * @param int $count
1664 * No to increment the weight.
77b97be7 1665 * @param bool $skipPermission
6a0b768e
TO
1666 * @param int $op
1667 * Which operation (view, edit, create, etc) to check permission for.
2141efbf 1668 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
6a488035 1669 *
a6c01b45
CW
1670 * @return array
1671 * array of ufgroups for a module
6a488035 1672 */
2141efbf 1673 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission::VIEW, $returnFields = NULL) {
290d4ccc
DS
1674 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1675
1676 if (!CRM_Core_Config::isUpgradeMode()) {
1677 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1678 $selectFields[] = 'description';
1679 }
7ba38389 1680
1681 if (!empty($returnFields)) {
1682 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
2141efbf 1683 }
7ba38389 1684
1685 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
6a488035
TO
1686 FROM civicrm_uf_group
1687 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1688 $p = array();
1689 if ($moduleName) {
1690 $queryString .= ' AND civicrm_uf_group.is_active = 1
1691 WHERE civicrm_uf_join.module = %2';
1692 $p[2] = array($moduleName, 'String');
1693 }
1694
6a488035
TO
1695 // add permissioning for profiles only if not registration
1696 if (!$skipPermission) {
1697 $permissionClause = CRM_Core_Permission::ufGroupClause($op, 'civicrm_uf_group.');
1698 if (strpos($queryString, 'WHERE') !== FALSE) {
1699 $queryString .= " AND $permissionClause ";
1700 }
1701 else {
1702 $queryString .= " $permissionClause ";
1703 }
1704 }
1705
1706 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1707 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1708
1709 $ufGroups = array();
1710 while ($dao->fetch()) {
1711 //skip mix profiles in user Registration / User Account
1712 if (($moduleName == 'User Registration' || $moduleName == 'User Account') &&
1713 CRM_Core_BAO_UFField::checkProfileType($dao->id)
1714 ) {
1715 continue;
1716 }
7ba38389 1717 foreach ($selectFields as $key => $field) {
5d6ac993 1718 if ($field == 'id') {
7ba38389 1719 continue;
1720 }
7ba38389 1721 $ufGroups[$dao->id][$field] = $dao->$field;
1722 }
6a488035
TO
1723 }
1724
1725 // Allow other modules to alter/override the UFGroups.
1726 CRM_Utils_Hook::buildUFGroupsForModule($moduleName, $ufGroups);
1727
1728 return $ufGroups;
1729 }
1730
1731 /**
fe482240 1732 * Filter ufgroups based on logged in user contact type.
6a488035 1733 *
6a0b768e
TO
1734 * @param int $ufGroupId
1735 * Uf group id (profile id).
c490a46a 1736 * @param int $contactID
77b97be7 1737 *
e7483cbe 1738 * @return bool
a6c01b45 1739 * true or false
6a488035 1740 */
00be9182 1741 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
6a488035
TO
1742 if (!$contactID) {
1743 $session = CRM_Core_Session::singleton();
1744 $contactID = $session->get('userID');
1745 }
1746
1747 if ($contactID) {
1748 //get the contact type
1749 $contactType = CRM_Contact_BAO_Contact::getContactType($contactID);
1750
1751 //match if exixting contact type is same as profile contact type
1752 $profileType = CRM_Core_BAO_UFField::getProfileType($ufGroupId);
1753
1754 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1755 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
1756 }
1757
1758 //allow special mix profiles for Contribution and Participant
1759 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1760
1761 if (in_array($profileType, $specialProfiles)) {
1762 return TRUE;
1763 }
1764
1765 if (($contactType == $profileType) || $profileType == 'Contact') {
1766 return TRUE;
1767 }
1768 }
1769
1770 return FALSE;
1771 }
1772
1773 /**
fe482240 1774 * Add profile field to a form.
6a488035 1775 *
c927c151 1776 * @param CRM_Core_Form $form
6a0b768e
TO
1777 * @param array $field
1778 * Properties.
1779 * @param int $mode
1780 * Profile mode.
1f177c6b 1781 * @param int $contactId
77b97be7 1782 * @param bool $online
6a0b768e
TO
1783 * @param string $usedFor
1784 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1f177c6b 1785 * @param int $rowNumber
77b97be7
EM
1786 * @param string $prefix
1787 *
6a488035 1788 * @return null
6a488035 1789 */
e7483cbe 1790 public static function buildProfile(
6a488035
TO
1791 &$form,
1792 &$field,
1793 $mode,
1794 $contactId = NULL,
1795 $online = FALSE,
133e2c99 1796 $usedFor = NULL,
5d6ac993 1797 $rowNumber = NULL,
6a488035
TO
1798 $prefix = ''
1799 ) {
1800 $defaultValues = array();
1f177c6b
CW
1801 $fieldName = $field['name'];
1802 $title = $field['title'];
1803 $attributes = $field['attributes'];
1804 $rule = $field['rule'];
1805 $view = $field['is_view'];
1806 $required = ($mode == CRM_Profile_Form::MODE_SEARCH) ? FALSE : $field['is_required'];
1807 $search = ($mode == CRM_Profile_Form::MODE_SEARCH) ? TRUE : FALSE;
1808 $isShared = CRM_Utils_Array::value('is_shared', $field, 0);
6a488035
TO
1809
1810 // do not display view fields in drupal registration form
1811 // CRM-4632
1812 if ($view && $mode == CRM_Profile_Form::MODE_REGISTER) {
e7483cbe 1813 return NULL;
6a488035
TO
1814 }
1815
133e2c99 1816 if ($usedFor == 'onbehalf') {
6a488035
TO
1817 $name = "onbehalf[$fieldName]";
1818 }
133e2c99 1819 elseif ($usedFor == 'honor') {
1820 $name = "honor[$fieldName]";
1821 }
6a488035
TO
1822 elseif ($contactId && !$online) {
1823 $name = "field[$contactId][$fieldName]";
1824 }
1825 elseif ($rowNumber) {
1826 $name = "field[$rowNumber][$fieldName]";
1827 }
1828 elseif (!empty($prefix)) {
5d6ac993 1829 $name = $prefix . "[$fieldName]";
6a488035
TO
1830 }
1831 else {
1832 $name = $fieldName;
1833 }
9e1854a1 1834
1f177c6b 1835 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
6a488035
TO
1836
1837 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form::MODE_EDIT) {
1838 $deleteExtra = ts('Are you sure you want to delete contact image.');
1839 $deleteURL = array(
e7483cbe
J
1840 CRM_Core_Action::DELETE => array(
1841 'name' => ts('Delete Contact Image'),
1842 'url' => 'civicrm/contact/image',
1843 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1844 'extra' =>
1845 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&amp;confirmed=1\'; else return false;"',
1846 ),
6a488035
TO
1847 );
1848 $deleteURL = CRM_Core_Action::formLink($deleteURL,
1849 CRM_Core_Action::DELETE,
5d6ac993
TO
1850 array(
1851 'id' => $form->get('id'),
6a488035 1852 'gid' => $form->get('gid'),
87dab4a4
AH
1853 ),
1854 ts('more'),
1855 FALSE,
1856 'contact.profileimage.delete',
1857 'Contact',
1858 $form->get('id')
6a488035
TO
1859 );
1860 $form->assign('deleteURL', $deleteURL);
1861 }
1862 $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
1863 'address_options', TRUE, NULL, TRUE
1864 );
1865
1866 if (substr($fieldName, 0, 14) === 'state_province') {
8f9c3cbe 1867 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
6a488035
TO
1868 $config = CRM_Core_Config::singleton();
1869 if (!in_array($mode, array(
5d6ac993 1870 CRM_Profile_Form::MODE_EDIT,
21dfd5f5 1871 CRM_Profile_Form::MODE_SEARCH,
5d6ac993 1872 )) &&
6a488035
TO
1873 $config->defaultContactStateProvince
1874 ) {
1875 $defaultValues[$name] = $config->defaultContactStateProvince;
1876 $form->setDefaults($defaultValues);
1877 }
1878 }
1879 elseif (substr($fieldName, 0, 7) === 'country') {
1f177c6b 1880 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant::country(), $required, $selectAttributes);
6a488035
TO
1881 $config = CRM_Core_Config::singleton();
1882 if (!in_array($mode, array(
5d6ac993 1883 CRM_Profile_Form::MODE_EDIT,
21dfd5f5 1884 CRM_Profile_Form::MODE_SEARCH,
5d6ac993 1885 )) &&
6a488035
TO
1886 $config->defaultContactCountry
1887 ) {
1888 $defaultValues[$name] = $config->defaultContactCountry;
1889 $form->setDefaults($defaultValues);
1890 }
1891 }
1892 elseif (substr($fieldName, 0, 6) === 'county') {
1893 if ($addressOptions['county']) {
8f9c3cbe 1894 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
6a488035
TO
1895 }
1896 }
1897 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1898 $form->add('file', $name, $title, $attributes, $required);
1899 $form->addUploadElement($name);
1900 }
1901 elseif (substr($fieldName, 0, 2) === 'im') {
1902 $form->add('text', $name, $title, $attributes, $required);
1903 if (!$contactId) {
133e2c99 1904 if ($usedFor) {
6a488035
TO
1905 if (substr($name, -1) == ']') {
1906 $providerName = substr($name, 0, -1) . '-provider_id]';
1907 }
1908 $form->add('select', $providerName, NULL,
1909 array(
21dfd5f5 1910 '' => ts('- select -'),
5d6ac993 1911 ) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1912 );
1913 }
1914 else {
1915 $form->add('select', $name . '-provider_id', $title,
1916 array(
21dfd5f5 1917 '' => ts('- select -'),
5d6ac993 1918 ) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1919 );
1920 }
1921
1922 if ($view && $mode != CRM_Profile_Form::MODE_SEARCH) {
1923 $form->freeze($name . '-provider_id');
1924 }
1925 }
1926 }
1927 elseif (($fieldName === 'birth_date') || ($fieldName === 'deceased_date')) {
1928 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1929 }
1930 elseif (in_array($fieldName, array(
5d6ac993
TO
1931 'membership_start_date',
1932 'membership_end_date',
21dfd5f5 1933 'join_date',
5d6ac993 1934 ))) {
5f80762f 1935 $form->addDate($name, $title, $required, array('formatType' => 'activityDate'));
6a488035 1936 }
5d6ac993 1937 elseif (CRM_Utils_Array::value('name', $field) == 'membership_type') {
6a488035
TO
1938 list($orgInfo, $types) = CRM_Member_BAO_MembershipType::getMembershipTypeInfo();
1939 $sel = &$form->addElement('hierselect', $name, $title);
5d6ac993
TO
1940 $select = array('' => ts('- select -'));
1941 if (count($orgInfo) == 1 && $field['is_required']) {
53cfc93c 1942 // we only have one org - so we should default to it. Not sure about defaulting to first type
1943 // as it could be missed - so adding a select
1944 // however, possibly that is more similar to the membership form
5d6ac993 1945 if (count($types[1]) > 1) {
53cfc93c 1946 $types[1] = $select + $types[1];
1947 }
1948 }
1949 else {
1950 $orgInfo = $select + $orgInfo;
1951 }
1952 $sel->setOptions(array($orgInfo, $types));
6a488035 1953 }
5d6ac993 1954 elseif (CRM_Utils_Array::value('name', $field) == 'membership_status') {
6a488035
TO
1955 $form->add('select', $name, $title,
1956 array(
21dfd5f5 1957 '' => ts('- select -'),
5d6ac993 1958 ) + CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label'), $required
6a488035
TO
1959 );
1960 }
ee015de4 1961 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1962 $options = array();
1963 $pseudoValues = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', $fieldName);
1964 foreach ($pseudoValues as $key => $var) {
1965 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
6a488035 1966 }
ee015de4 1967 $group = $form->addGroup($options, $name, $title);
d4dcd180 1968 if ($required) {
1969 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
6a488035 1970 }
8a4f27dc 1971 else {
b847e6e7 1972 $group->setAttribute('allowClear', TRUE);
8a4f27dc 1973 }
6a488035 1974 }
f45334bd 1975 elseif ($fieldName === 'prefix_id' || $fieldName === 'suffix_id') {
1f177c6b
CW
1976 $form->addSelect($name, array(
1977 'label' => $title,
1978 'entity' => 'contact',
1979 'field' => $fieldName,
1980 'class' => 'six',
1981 'placeholder' => '',
1982 ), $required);
6a488035
TO
1983 }
1984 elseif ($fieldName === 'contact_sub_type') {
1985 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
133e2c99 1986 if ($usedFor == 'onbehalf') {
6a488035
TO
1987 $profileType = 'Organization';
1988 }
133e2c99 1989 elseif ($usedFor == 'honor') {
1990 $profileType = CRM_Core_BAO_UFField::getProfileType($form->_params['honoree_profile_id']);
1991 }
6a488035
TO
1992 else {
1993 $profileType = $gId ? CRM_Core_BAO_UFField::getProfileType($gId) : NULL;
1994 if ($profileType == 'Contact') {
1995 $profileType = 'Individual';
1996 }
1997 }
1998
1999 $setSubtype = FALSE;
2000 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
2001 $setSubtype = $profileType;
2002 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
2003 }
2004
2005 $subtypes = $profileType ? CRM_Contact_BAO_ContactType::subTypePairs($profileType) : array();
2006
2007 if ($setSubtype) {
2008 $subtypeList = array();
2009 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2010 }
2011 else {
2012 $subtypeList = $subtypes;
2013 }
2014
2015 $sel = $form->add('select', $name, $title, $subtypeList, $required);
2016 $sel->setMultiple(TRUE);
2017 }
2018 elseif (in_array($fieldName, CRM_Contact_BAO_Contact::$_greetingTypes)) {
2019 //add email greeting, postal greeting, addressee, CRM-4575
2020 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
2021 $profileType = CRM_Core_BAO_UFField::getProfileType($gId, TRUE, FALSE, TRUE);
2022
2023 if (empty($profileType) || in_array($profileType, array(
5d6ac993
TO
2024 'Contact',
2025 'Contribution',
2026 'Participant',
21dfd5f5 2027 'Membership',
5d6ac993
TO
2028 ))
2029 ) {
6a488035
TO
2030 $profileType = 'Individual';
2031 }
2032 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
2033 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
2034 }
2035 $greeting = array(
2036 'contact_type' => $profileType,
2037 'greeting_type' => $fieldName,
2038 );
2039 $form->add('select', $name, $title,
2040 array(
21dfd5f5 2041 '' => ts('- select -'),
5d6ac993 2042 ) + CRM_Core_PseudoConstant::greeting($greeting), $required
6a488035
TO
2043 );
2044 // add custom greeting element
2045 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2046 NULL, FALSE
2047 );
2048 }
2049 elseif ($fieldName === 'preferred_communication_method') {
e7e657f0 2050 $communicationFields = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
6a488035
TO
2051 foreach ($communicationFields as $key => $var) {
2052 if ($key == '') {
2053 continue;
2054 }
2055 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2056 }
2057 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2058 }
2059 elseif ($fieldName === 'preferred_mail_format') {
2060 $form->add('select', $name, $title, CRM_Core_SelectValues::pmf());
2061 }
2062 elseif ($fieldName === 'preferred_language') {
c0c9cd82 2063 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact::buildOptions('preferred_language'));
6a488035
TO
2064 }
2065 elseif ($fieldName == 'external_identifier') {
2066 $form->add('text', $name, $title, $attributes, $required);
2067 $contID = $contactId;
2068 if (!$contID) {
2069 $contID = $form->get('id');
2070 }
2071 $form->addRule($name,
2072 ts('External ID already exists in Database.'),
2073 'objectExists',
2074 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2075 );
2076 }
2077 elseif ($fieldName === 'group') {
2078 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
2079 CRM_Contact_Form_Edit_TagsAndGroups::GROUP,
2080 TRUE, $required,
2081 $title, NULL, $name
2082 );
2083 }
2084 elseif ($fieldName === 'tag') {
2085 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
2086 CRM_Contact_Form_Edit_TagsAndGroups::TAG,
2087 FALSE, $required,
2088 NULL, $title, $name
2089 );
2090 }
2091 elseif (substr($fieldName, 0, 4) === 'url-') {
2092 $form->add('text', $name, $title,
2093 array_merge(CRM_Core_DAO::getAttribute('CRM_Core_DAO_Website', 'url'),
2094 array(
2095 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2096 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2097 )
5d6ac993 2098 ), $required
6a488035
TO
2099 );
2100
2101 $form->addRule($name, ts('Enter a valid Website.'), 'url');
6a488035
TO
2102 }
2103 // Note should be rendered as textarea
2104 elseif (substr($fieldName, -4) == 'note') {
2105 $form->add('textarea', $name, $title, $attributes, $required);
2106 }
2107 elseif (substr($fieldName, 0, 6) === 'custom') {
2108 $customFieldID = CRM_Core_BAO_CustomField::getKeyID($fieldName);
2109 if ($customFieldID) {
2110 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2111 }
2112 }
2113 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2114 list($fName, $locTypeId) = CRM_Utils_System::explode('-', $fieldName, 2);
2115 $customFieldID = CRM_Core_BAO_CustomField::getKeyID(substr($fName, 8));
2116 if ($customFieldID) {
2117 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2118 }
2119 }
2120 elseif (in_array($fieldName, array(
5d6ac993
TO
2121 'receive_date',
2122 'receipt_date',
2123 'thankyou_date',
21dfd5f5 2124 'cancel_date',
5d6ac993 2125 ))) {
6a488035
TO
2126 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2127 }
2128 elseif ($fieldName == 'send_receipt') {
2129 $form->addElement('checkbox', $name, $title);
2130 }
2131 elseif ($fieldName == 'soft_credit') {
ccec9d6b 2132 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
5ee60152 2133 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
6a488035
TO
2134 }
2135 elseif ($fieldName == 'product_name') {
2136 list($products, $options) = CRM_Contribute_BAO_Premium::getPremiumProductInfo();
2137 $sel = &$form->addElement('hierselect', $name, $title);
2138 $products = array(
e7483cbe
J
2139 '0' => ts('- select -'),
2140 ) + $products;
6a488035
TO
2141 $sel->setOptions(array($products, $options));
2142 }
2143 elseif ($fieldName == 'payment_instrument') {
2144 $form->add('select', $name, $title,
5d6ac993 2145 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::paymentInstrument(), $required);
6a488035 2146 }
4c9b6178 2147 elseif ($fieldName == 'financial_type') {
6a488035
TO
2148 $form->add('select', $name, $title,
2149 array(
21dfd5f5 2150 '' => ts('- select -'),
5d6ac993 2151 ) + CRM_Contribute_PseudoConstant::financialType(), $required
6a488035
TO
2152 );
2153 }
2154 elseif ($fieldName == 'contribution_status_id') {
aaf5ca44
DG
2155 $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus();
2156 $statusName = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
2157 foreach (array(
2158 'In Progress',
2159 'Overdue',
21dfd5f5 2160 'Refunded',
aaf5ca44
DG
2161 ) as $suppress) {
2162 unset($contributionStatuses[CRM_Utils_Array::key($suppress, $statusName)]);
2163 }
6a73ef3f 2164
6a488035
TO
2165 $form->add('select', $name, $title,
2166 array(
21dfd5f5 2167 '' => ts('- select -'),
5d6ac993 2168 ) + $contributionStatuses, $required
6a488035
TO
2169 );
2170 }
51fa20cb 2171 elseif ($fieldName == 'soft_credit_type') {
9e1854a1 2172 $name = "soft_credit_type[$rowNumber]";
51fa20cb 2173 $form->add('select', $name, $title,
2174 array(
21dfd5f5 2175 '' => ts('- select -'),
5d6ac993 2176 ) + CRM_Core_OptionGroup::values("soft_credit_type")
51fa20cb 2177 );
9e1854a1 2178 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2179 //else (for contribution), use configured SCT default value
2180 $SCTDefaultValue = CRM_Core_OptionGroup::getDefaultValue("soft_credit_type");
2181 if ($field['field_type'] == 'Membership') {
2182 $SCTDefaultValue = CRM_Core_OptionGroup::getValue('soft_credit_type', 'Gift', 'name');
2183 }
2184 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
51fa20cb 2185 }
6a488035
TO
2186 elseif ($fieldName == 'currency') {
2187 $form->addCurrency($name, $title, $required);
2188 }
2189 elseif ($fieldName == 'contribution_page_id') {
2190 $form->add('select', $name, $title,
2191 array(
21dfd5f5 2192 '' => ts('- select -'),
5d6ac993 2193 ) + CRM_Contribute_PseudoConstant::contributionPage(), $required, 'class="big"'
6a488035
TO
2194 );
2195 }
2196 elseif ($fieldName == 'participant_register_date') {
2197 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2198 }
2199 elseif ($fieldName == 'activity_status_id') {
2200 $form->add('select', $name, $title,
2201 array(
21dfd5f5 2202 '' => ts('- select -'),
5d6ac993 2203 ) + CRM_Core_PseudoConstant::activityStatus(), $required
6a488035
TO
2204 );
2205 }
2206 elseif ($fieldName == 'activity_engagement_level') {
2207 $form->add('select', $name, $title,
2208 array(
21dfd5f5 2209 '' => ts('- select -'),
5d6ac993 2210 ) + CRM_Campaign_PseudoConstant::engagementLevel(), $required
6a488035
TO
2211 );
2212 }
2213 elseif ($fieldName == 'activity_date_time') {
2214 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2215 }
2216 elseif ($fieldName == 'participant_status') {
2217 $cond = NULL;
2218 if ($online == TRUE) {
2219 $cond = 'visibility_id = 1';
2220 }
2221 $form->add('select', $name, $title,
2222 array(
21dfd5f5 2223 '' => ts('- select -'),
5d6ac993 2224 ) + CRM_Event_PseudoConstant::participantStatus(NULL, $cond, 'label'), $required
6a488035
TO
2225 );
2226 }
2227 elseif ($fieldName == 'participant_role') {
a7488080 2228 if (!empty($field['is_multiple'])) {
6a488035
TO
2229 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant::participantRole(), NULL, NULL, NULL, NULL, '&nbsp', TRUE);
2230 }
2231 else {
2232 $form->add('select', $name, $title,
2233 array(
21dfd5f5 2234 '' => ts('- select -'),
5d6ac993 2235 ) + CRM_Event_PseudoConstant::participantRole(), $required
6a488035
TO
2236 );
2237 }
2238 }
2239 elseif ($fieldName == 'world_region') {
1f177c6b 2240 $form->add('select', $name, $title, CRM_Core_PseudoConstant::worldRegion(), $required, $selectAttributes);
6a488035
TO
2241 }
2242 elseif ($fieldName == 'signature_html') {
5d51a2f9 2243 $form->add('wysiwyg', $name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
6a488035
TO
2244 }
2245 elseif ($fieldName == 'signature_text') {
2246 $form->add('textarea', $name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
2247 }
2248 elseif (substr($fieldName, -11) == 'campaign_id') {
2249 if (CRM_Campaign_BAO_Campaign::isCampaignEnable()) {
2250 $campaigns = CRM_Campaign_BAO_Campaign::getCampaigns(CRM_Utils_Array::value($contactId,
2251 $form->_componentCampaigns
2252 ));
2253 $form->add('select', $name, $title,
2254 array(
21dfd5f5 2255 '' => ts('- select -'),
5d6ac993 2256 ) + $campaigns, $required, 'class="crm-select2 big"'
6a488035
TO
2257 );
2258 }
2259 }
2260 elseif ($fieldName == 'activity_details') {
5d51a2f9 2261 $form->add('wysiwyg', $fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
6a488035
TO
2262 }
2263 elseif ($fieldName == 'activity_duration') {
2264 $form->add('text', $name, $title, $attributes, $required);
2265 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2266 }
2267 else {
2268 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2269 $form->add('advcheckbox', $name, $title, $attributes, $required);
2270 }
2271 else {
2272 $form->add('text', $name, $title, $attributes, $required);
2273 }
2274 }
2275
2276 static $hiddenSubtype = FALSE;
2277 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType::isaSubType($field['field_type'])) {
2278 // In registration mode params are submitted via POST and we don't have any clue
2279 // about profile-id or the profile-type (which could be a subtype)
2280 // To generalize the behavior and simplify the process,
2281 // lets always add the hidden
2282 //subtype value if there is any, and we won't have to
2283 // compute it while processing.
133e2c99 2284 if ($usedFor) {
2285 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
6a488035
TO
2286 }
2287 else {
2288 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2289 }
2290 $hiddenSubtype = TRUE;
2291 }
2292
2293 if (($view && $mode != CRM_Profile_Form::MODE_SEARCH) || $isShared) {
2294 $form->freeze($name);
2295 }
2296
2297 //add the rules
2298 if (in_array($fieldName, array(
5d6ac993
TO
2299 'non_deductible_amount',
2300 'total_amount',
2301 'fee_amount',
21dfd5f5 2302 'net_amount',
5d6ac993 2303 ))) {
6a488035
TO
2304 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2305 }
6a488035
TO
2306 if ($rule) {
2307 if (!($rule == 'email' && $mode == CRM_Profile_Form::MODE_SEARCH)) {
2308 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2309 }
2310 }
2311 }
2312
2313 /**
fe482240 2314 * Set profile defaults.
6a488035 2315 *
6a0b768e
TO
2316 * @param int $contactId
2317 * Contact id.
2318 * @param array $fields
2319 * Associative array of fields.
2320 * @param array $defaults
2321 * Defaults array.
2322 * @param bool $singleProfile
2323 * True for single profile else false(batch update).
2324 * @param int $componentId
2325 * Id for specific components like contribute, event etc.
2326 * @param null $component
6a488035 2327 */
e7483cbe 2328 public static function setProfileDefaults(
f9f40af3
TO
2329 $contactId, &$fields, &$defaults,
2330 $singleProfile = TRUE, $componentId = NULL, $component = NULL
6a488035
TO
2331 ) {
2332 if (!$componentId) {
2333 //get the contact details
2334 list($contactDetails, $options) = CRM_Contact_BAO_Contact::getHierContactDetails($contactId, $fields);
2335 $details = CRM_Utils_Array::value($contactId, $contactDetails);
2336 $multipleFields = array('website' => 'url');
2337
2338 //start of code to set the default values
2339 foreach ($fields as $name => $field) {
2340 // skip pseudo fields
2341 if (substr($name, 0, 9) == 'phone_ext') {
2342 continue;
2343 }
2344
2345 //set the field name depending upon the profile mode(single/batch)
2346 if ($singleProfile) {
2347 $fldName = $name;
2348 }
2349 else {
2350 $fldName = "field[$contactId][$name]";
2351 }
2352
2353 if ($name == 'group') {
2354 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::GROUP, $fldName);
2355 }
2356 if ($name == 'tag') {
2357 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::TAG, $fldName);
2358 }
2359
a7488080 2360 if (!empty($details[$name]) || isset($details[$name])) {
6a488035 2361 //to handle custom data (checkbox) to be written
58f00377 2362 // to handle birth/deceased date, greeting_type and few other fields
2363 if (($name == 'birth_date') || ($name == 'deceased_date')) {
6a488035
TO
2364 list($defaults[$fldName]) = CRM_Utils_Date::setDateDefaults($details[$name], 'birth');
2365 }
2366 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)) {
2367 $defaults[$fldName] = $details[$name . '_id'];
2368 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2369 }
2370 elseif ($name == 'preferred_communication_method') {
2371 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2372 foreach ($v as $item) {
2373 if ($item) {
2374 $defaults[$fldName . "[$item]"] = 1;
2375 }
2376 }
2377 }
8aefc657
RK
2378 elseif ($name == 'contact_sub_type') {
2379 $defaults[$fldName] = explode(CRM_Core_DAO::VALUE_SEPARATOR, trim($details[$name], CRM_Core_DAO::VALUE_SEPARATOR));
2380 }
6a488035
TO
2381 elseif ($name == 'world_region') {
2382 $defaults[$fldName] = $details['worldregion_id'];
2383 }
2384 elseif ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($name)) {
2385 //fix for custom fields
2386 $customFields = CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $details));
2387
2388 // hack to add custom data for components
2389 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2390 foreach ($components as $value) {
2391 $customFields = CRM_Utils_Array::crmArrayMerge($customFields,
2392 CRM_Core_BAO_CustomField::getFieldsForImport($value)
2393 );
2394 }
2395
2396 switch ($customFields[$customFieldId]['html_type']) {
2397 case 'Multi-Select State/Province':
2398 case 'Multi-Select Country':
2399 case 'AdvMulti-Select':
2400 case 'Multi-Select':
2401 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2402 foreach ($v as $item) {
2403 if ($item) {
2404 $defaults[$fldName][$item] = $item;
2405 }
2406 }
2407 break;
2408
2409 case 'CheckBox':
2410 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2411 foreach ($v as $item) {
2412 if ($item) {
2413 $defaults[$fldName][$item] = 1;
2414 // seems like we need this for QF style checkboxes in profile where its multiindexed
2415 // CRM-2969
2416 $defaults["{$fldName}[{$item}]"] = 1;
2417 }
2418 }
2419 break;
2420
6a488035
TO
2421 case 'Select Date':
2422 // CRM-6681, set defult values according to date and time format (if any).
2423 $dateFormat = NULL;
a7488080 2424 if (!empty($customFields[$customFieldId]['date_format'])) {
fd933dc5 2425 $dateFormat = $customFields[$customFieldId]['date_format'];
6a488035
TO
2426 }
2427
a7488080 2428 if (empty($customFields[$customFieldId]['time_format'])) {
6a488035
TO
2429 list($defaults[$fldName]) = CRM_Utils_Date::setDateDefaults($details[$name], NULL,
2430 $dateFormat
2431 );
2432 }
2433 else {
2434 $timeElement = $fldName . '_time';
2435 if (substr($fldName, -1) == ']') {
2436 $timeElement = substr($fldName, 0, -1) . '_time]';
2437 }
fd933dc5
KJ
2438 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date::setDateDefaults($details[$name],
2439 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
6a488035
TO
2440 }
2441 break;
2442
2443 default:
2444 $defaults[$fldName] = $details[$name];
2445 break;
2446 }
2447 }
2448 else {
2449 $defaults[$fldName] = $details[$name];
2450 }
2451 }
2452 else {
2453 $blocks = array('email', 'phone', 'im', 'openid');
2454 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System::explode('-', $name, 3);
2455 if (!in_array($fieldName, $multipleFields)) {
2456 if (is_array($details)) {
2457 foreach ($details as $key => $value) {
2458 // when we fixed CRM-5319 - get primary loc
2459 // type as per loc field and removed below code.
2460 $primaryLocationType = FALSE;
2461 if ($locTypeId == 'Primary') {
5d6ac993 2462 if (is_array($value) && array_key_exists($fieldName, $value)) {
6a488035 2463 $primaryLocationType = TRUE;
5d6ac993 2464 if (in_array($fieldName, $blocks)) {
6a488035
TO
2465 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, $fieldName);
2466 }
5d6ac993 2467 else {
6a488035
TO
2468 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, 'address');
2469 }
2470 }
2471 }
2472
2473 // fixed for CRM-665
2474 if (is_numeric($locTypeId)) {
2475 if ($primaryLocationType || $locTypeId == CRM_Utils_Array::value('location_type_id', $value)) {
a7488080 2476 if (!empty($value[$fieldName])) {
6a488035
TO
2477 //to handle stateprovince and country
2478 if ($fieldName == 'state_province') {
2479 $defaults[$fldName] = $value['state_province_id'];
2480 }
2481 elseif ($fieldName == 'county') {
2482 $defaults[$fldName] = $value['county_id'];
2483 }
2484 elseif ($fieldName == 'country') {
6a488035
TO
2485 if (!isset($value['country_id']) || !$value['country_id']) {
2486 $config = CRM_Core_Config::singleton();
2487 if ($config->defaultContactCountry) {
2488 $defaults[$fldName] = $config->defaultContactCountry;
2489 }
2490 }
b3071092
DL
2491 else {
2492 $defaults[$fldName] = $value['country_id'];
2493 }
6a488035
TO
2494 }
2495 elseif ($fieldName == 'phone') {
2496 if ($phoneTypeId) {
2497 if (isset($value['phone'][$phoneTypeId])) {
2498 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2499 }
2500 if (isset($value['phone_ext'][$phoneTypeId])) {
2501 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2502 }
2503 }
2504 else {
2505 $phoneDefault = CRM_Utils_Array::value('phone', $value);
2506 // CRM-9216
2507 if (!is_array($phoneDefault)) {
2508 $defaults[$fldName] = $phoneDefault;
2509 }
2510 }
2511 }
2512 elseif ($fieldName == 'email') {
2513 //adding the first email (currently we don't support multiple emails of same location type)
2514 $defaults[$fldName] = $value['email'];
2515 }
2516 elseif ($fieldName == 'im') {
2517 //adding the first im (currently we don't support multiple ims of same location type)
2518 $defaults[$fldName] = $value['im'];
2519 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2520 }
2521 else {
2522 $defaults[$fldName] = $value[$fieldName];
2523 }
2524 }
2525 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2526 CRM_Utils_Array::value(substr($fieldName, 8), $value)
2527 ) {
2528 $defaults[$fldName] = $value[substr($fieldName, 8)];
2529 }
2530 }
2531 }
2532 }
2533 }
2534 }
2535 else {
2536 if (is_array($details)) {
1fd63589
EM
2537 if ($fieldName === 'url'
2538 && !empty($details['website'])
5d6ac993
TO
2539 && !empty($details['website'][$locTypeId])
2540 ) {
887e764d 2541 $defaults[$fldName] = CRM_Utils_Array::value('url', $details['website'][$locTypeId]);
6a488035
TO
2542 }
2543 }
2544 }
2545 }
2546 }
2547 }
2548
2549 //Handling Contribution Part of the batch profile
2550 if (CRM_Core_Permission::access('CiviContribute') && $component == 'Contribute') {
2551 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2552 }
2553
2554 //Handling Event Participation Part of the batch profile
2555 if (CRM_Core_Permission::access('CiviEvent') && $component == 'Event') {
2556 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2557 }
2558
2559 //Handling membership Part of the batch profile
2560 if (CRM_Core_Permission::access('CiviMember') && $component == 'Membership') {
2561 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2562 }
2563
2564 //Handling Activity Part of the batch profile
2565 if ($component == 'Activity') {
2566 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2567 }
2568 }
2569
2570 /**
100fef9d 2571 * Get profiles by type eg: pure Individual etc
6a488035 2572 *
6a0b768e
TO
2573 * @param array $types
2574 * Associative array of types eg: types('Individual').
2575 * @param bool $onlyPure
2576 * True if only pure profiles are required.
6a488035 2577 *
a6c01b45
CW
2578 * @return array
2579 * associative array of profiles
6a488035 2580 */
00be9182 2581 public static function getProfiles($types, $onlyPure = FALSE) {
6a488035 2582 $profiles = array();
ff4f7744 2583 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
2584
2585 CRM_Utils_Hook::aclGroup(CRM_Core_Permission::ADMIN, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2586
2587 // Exclude Batch Data Entry profiles - CRM-10901
2588 $batchProfiles = CRM_Core_BAO_UFGroup::getBatchProfiles();
2589
2590 foreach ($ufGroups as $id => $title) {
2591 $ptype = CRM_Core_BAO_UFField::getProfileType($id, FALSE, $onlyPure);
2592 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2593 $profiles[$id] = $title;
2594 }
2595 }
2596 return $profiles;
2597 }
2598
2599 /**
100fef9d 2600 * Check whether a profile is valid combination of
6a488035
TO
2601 * required and/or optional profile types
2602 *
6a0b768e
TO
2603 * @param array $required
2604 * Array of types those are required.
2605 * @param array $optional
2606 * Array of types those are optional.
6a488035 2607 *
a6c01b45
CW
2608 * @return array
2609 * associative array of profiles
6a488035 2610 */
00be9182 2611 public static function getValidProfiles($required, $optional = NULL) {
6a488035 2612 if (!is_array($required) || empty($required)) {
e7483cbe 2613 return NULL;
6a488035
TO
2614 }
2615
2616 $profiles = array();
ff4f7744 2617 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
2618
2619 CRM_Utils_Hook::aclGroup(CRM_Core_Permission::ADMIN, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2620
2621 foreach ($ufGroups as $id => $title) {
2622 $type = CRM_Core_BAO_UFField::checkValidProfileType($id, $required, $optional);
2623 if ($type) {
2624 $profiles[$id] = $title;
2625 }
2626 }
2627
2628 return $profiles;
2629 }
2630
2631 /**
100fef9d 2632 * Check whether a profile is valid combination of
6a488035
TO
2633 * required profile fields
2634 *
6a0b768e
TO
2635 * @param array $ufId
2636 * Integer id of the profile.
2637 * @param array $required
2638 * Array of fields those are required in the profile.
6a488035 2639 *
a6c01b45
CW
2640 * @return array
2641 * associative array of profiles
6a488035 2642 */
00be9182 2643 public static function checkValidProfile($ufId, $required = NULL) {
6a488035
TO
2644 $validProfile = FALSE;
2645 if (!$ufId) {
2646 return $validProfile;
2647 }
2648
2649 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2650 return $validProfile;
2651 }
2652
2653 $profileFields = self::getFields($ufId, FALSE, CRM_Core_Action::VIEW, NULL,
2654 NULL, FALSE, NULL, FALSE, NULL,
2655 CRM_Core_Permission::CREATE, NULL
2656 );
2657
2658 $validProfile = array();
2659 if (!empty($profileFields)) {
2660 $fields = array_keys($profileFields);
2661 foreach ($fields as $val) {
2662 foreach ($required as $key => $field) {
2663 if (strpos($val, $field) === 0) {
2664 unset($required[$key]);
2665 }
2666 }
2667 }
2668
2669 $validProfile = (empty($required)) ? TRUE : FALSE;
2670 }
2671
2672 return $validProfile;
2673 }
2674
2675 /**
100fef9d 2676 * Get default value for Register.
6a488035 2677 *
72b3a70c
CW
2678 * @param array $fields
2679 * @param array $defaults
77b97be7 2680 *
72b3a70c 2681 * @return array
6a488035 2682 */
00be9182 2683 public static function setRegisterDefaults(&$fields, &$defaults) {
b525f1cc 2684 $config = CRM_Core_Config::singleton();
6a488035
TO
2685 foreach ($fields as $name => $field) {
2686 if (substr($name, 0, 8) == 'country-') {
b525f1cc 2687 if (!empty($config->defaultContactCountry)) {
6a488035
TO
2688 $defaults[$name] = $config->defaultContactCountry;
2689 }
2690 }
2691 elseif (substr($name, 0, 15) == 'state_province-') {
b525f1cc 2692 if (!empty($config->defaultContactStateProvince)) {
6a488035
TO
2693 $defaults[$name] = $config->defaultContactStateProvince;
2694 }
2695 }
2696 }
2697 return $defaults;
2698 }
2699
2700 /**
dc195289 2701 * make a copy of a profile, including
6a488035
TO
2702 * all the fields in the profile
2703 *
6a0b768e
TO
2704 * @param int $id
2705 * The profile id to copy.
6a488035
TO
2706 *
2707 * @return void
6a488035 2708 */
00be9182 2709 public static function copy($id) {
6a488035
TO
2710 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2711 $copy = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFGroup',
2712 array('id' => $id),
2713 NULL,
2714 $fieldsFix
2715 );
2716
2717 if ($pos = strrpos($copy->name, "_{$id}")) {
2718 $copy->name = substr_replace($copy->name, '', $pos);
2719 }
2720 $copy->name = CRM_Utils_String::munge($copy->name, '_', 56) . "_{$copy->id}";
2721 $copy->save();
2722
2723 $copyUFJoin = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFJoin',
2724 array('uf_group_id' => $id),
2725 array('uf_group_id' => $copy->id),
2726 NULL,
2727 'entity_table'
2728 );
2729
2730 $copyUFField = &CRM_Core_DAO::copyGeneric('CRM_Core_BAO_UFField',
2731 array('uf_group_id' => $id),
2732 array('uf_group_id' => $copy->id)
2733 );
2734
2735 $maxWeight = CRM_Utils_Weight::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2736
2737 //update the weight
2738 $query = "
2739UPDATE civicrm_uf_join
2740SET weight = %1
2741WHERE uf_group_id = %2
2742AND ( entity_id IS NULL OR entity_id <= 0 )
2743";
5d6ac993
TO
2744 $p = array(
2745 1 => array($maxWeight + 1, 'Integer'),
6a488035
TO
2746 2 => array($copy->id, 'Integer'),
2747 );
2748 CRM_Core_DAO::executeQuery($query, $p);
2749 if ($copy->is_reserved) {
2750 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2751 $params = array(1 => array($copy->id, 'Integer'));
2752 CRM_Core_DAO::executeQuery($query, $params);
2753 }
2754 CRM_Utils_Hook::copy('UFGroup', $copy);
2755
2756 return $copy;
2757 }
2758
2759 /**
2760 * Process that send notification e-mails
2761 *
6a0b768e
TO
2762 * @param int $contactID
2763 * Contact id.
2764 * @param array $values
2765 * Associative array of name/value pair.
1fd63589 2766 *
6a488035 2767 * @return void
6a488035 2768 */
00be9182 2769 public static function commonSendMail($contactID, &$values) {
6a488035
TO
2770 if (!$contactID || !$values) {
2771 return;
2772
2773 }
2774 $template = CRM_Core_Smarty::singleton();
2775
2776 $displayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
2777 $contactID,
2778 'display_name'
2779 );
2780
2781 self::profileDisplay($values['id'], $values['values'], $template);
2782 $emailList = explode(',', $values['email']);
2783
2784 $contactLink = CRM_Utils_System::url('civicrm/contact/view',
2785 "reset=1&cid=$contactID",
5d6ac993 2786 TRUE, NULL, FALSE, FALSE, TRUE
6a488035
TO
2787 );
2788
2789 //get the default domain email address.
2790 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
2791
2792 if (!$domainEmailAddress || $domainEmailAddress == 'info@EXAMPLE.ORG') {
2793 $fixUrl = CRM_Utils_System::url('civicrm/admin/domain', 'action=update&reset=1');
2794 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)));
2795 }
2796
2797 foreach ($emailList as $emailTo) {
2798 // FIXME: take the below out of the foreach loop
c6327d7d 2799 CRM_Core_BAO_MessageTemplate::sendTemplate(
6a488035
TO
2800 array(
2801 'groupName' => 'msg_tpl_workflow_uf',
2802 'valueName' => 'uf_notify',
2803 'contactId' => $contactID,
2804 'tplParams' => array(
2805 'displayName' => $displayName,
2806 'currentDate' => date('r'),
2807 'contactLink' => $contactLink,
2808 ),
2809 'from' => "$domainEmailName <$domainEmailAddress>",
2810 'toEmail' => $emailTo,
2811 )
2812 );
2813 }
2814 }
2815
2816 /**
2817 * Given a contact id and a group id, returns the field values from the db
2818 * for this group and notify email only if group's notify field is
2819 * set and field values are not empty
2820 *
6a0b768e
TO
2821 * @param int $gid
2822 * Group id.
2823 * @param int $cid
2824 * Contact id.
c490a46a 2825 * @param array $params
1fd63589
EM
2826 * @param bool $skipCheck
2827 *
6a488035 2828 * @return array
6a488035 2829 */
00be9182 2830 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
6a488035
TO
2831 if ($gid) {
2832 if (CRM_Core_BAO_UFGroup::filterUFGroups($gid, $cid) || $skipCheck) {
2833 $values = array();
2834 $fields = CRM_Core_BAO_UFGroup::getFields($gid, FALSE, CRM_Core_Action::VIEW);
2835 CRM_Core_BAO_UFGroup::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2836
2837 $email = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2838
2839 if (!empty($values) &&
2840 !empty($email)
2841 ) {
2842 $val = array(
2843 'id' => $gid,
2844 'values' => $values,
2845 'email' => $email,
2846 );
2847 return $val;
2848 }
2849 }
2850 }
2851 return NULL;
2852 }
2853
2854 /**
fe482240 2855 * Assign uf fields to template.
6a488035 2856 *
6a0b768e
TO
2857 * @param int $gid
2858 * Group id.
c490a46a
CW
2859 * @param array $values
2860 * @param CRM_Core_Smarty $template
1fd63589 2861 *
6a488035 2862 * @return void
6a488035 2863 */
00be9182 2864 public function profileDisplay($gid, $values, $template) {
6a488035
TO
2865 $groupTitle = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2866 $template->assign('grouptitle', $groupTitle);
2867 if (count($values)) {
2868 $template->assign('values', $values);
2869 }
2870 }
2871
2872 /**
fe482240 2873 * Format fields for dupe Contact Matching.
6a488035 2874 *
6a0b768e 2875 * @param array $params
6a488035 2876 *
100fef9d 2877 * @param int $contactId
1fd63589 2878 *
a6c01b45
CW
2879 * @return array
2880 * assoicated formatted array
6a488035 2881 */
00be9182 2882 public static function formatFields($params, $contactId = NULL) {
6a488035
TO
2883 if ($contactId) {
2884 // get the primary location type id and email
2885 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactId);
2886 }
2887 else {
2888 $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
2889 $primaryLocationType = $defaultLocationType->id;
2890 }
2891
5d6ac993
TO
2892 $data = array();
2893 $locationType = array();
2894 $count = 1;
6a488035
TO
2895 $primaryLocation = 0;
2896 foreach ($params as $key => $value) {
2897 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2898
2899 if ($locTypeId == 'Primary') {
2900 $locTypeId = $primaryLocationType;
2901 }
2902
2903 if (is_numeric($locTypeId)) {
2904 if (!in_array($locTypeId, $locationType)) {
2905 $locationType[$count] = $locTypeId;
2906 $count++;
2907 }
2908 $loc = CRM_Utils_Array::key($locTypeId, $locationType);
2909
2910 $data['location'][$loc]['location_type_id'] = $locTypeId;
2911
2912 // if we are getting in a new primary email, dont overwrite the new one
2913 if ($locTypeId == $primaryLocationType) {
a7488080 2914 if (!empty($params['email-' . $primaryLocationType])) {
6a488035
TO
2915 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2916 }
2917 elseif (isset($primaryEmail)) {
2918 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2919 }
2920 $primaryLocation++;
2921 }
2922
2923 if ($loc == 1) {
2924 $data['location'][$loc]['is_primary'] = 1;
2925 }
2926 if ($fieldName == 'phone') {
2927 if ($phoneTypeId) {
2928 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2929 }
2930 else {
2931 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2932 }
2933 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2934 }
2935 elseif ($fieldName == 'email') {
2936 $data['location'][$loc]['email'][$loc]['email'] = $value;
2937 }
2938 elseif ($fieldName == 'im') {
2939 $data['location'][$loc]['im'][$loc]['name'] = $value;
2940 }
2941 else {
2942 if ($fieldName === 'state_province') {
2943 $data['location'][$loc]['address']['state_province_id'] = $value;
2944 }
2945 elseif ($fieldName === 'country') {
2946 $data['location'][$loc]['address']['country_id'] = $value;
2947 }
2948 else {
2949 $data['location'][$loc]['address'][$fieldName] = $value;
2950 }
2951 }
2952 }
2953 else {
67744c4e 2954 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
6a488035
TO
2955 if ($key === 'individual_suffix') {
2956 $data['suffix_id'] = $value;
2957 }
2958 elseif ($key === 'individual_prefix') {
2959 $data['prefix_id'] = $value;
2960 }
2961 elseif ($key === 'gender') {
2962 $data['gender_id'] = $value;
2963 }
2964 elseif (substr($key, 0, 6) === 'custom') {
2965 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
2966 //fix checkbox
2967 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2968 $value = implode(CRM_Core_DAO::VALUE_SEPARATOR, array_keys($value));
2969 }
2970 // fix the date field
2971 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2972 $date = CRM_Utils_Date::format($value);
2973 if (!$date) {
2974 $date = '';
2975 }
2976 $value = $date;
2977 }
2978
2979 $data['custom'][$customFieldID] = array(
2980 'id' => $id,
2981 'value' => $value,
2982 'extends' => $customFields[$customFieldID]['extends'],
2983 'type' => $customFields[$customFieldID]['data_type'],
2984 'custom_field_id' => $customFieldID,
2985 );
2986 }
2987 }
2988 elseif ($key == 'edit') {
2989 continue;
2990 }
2991 else {
2992 $data[$key] = $value;
2993 }
2994 }
2995 }
2996
2997 if (!$primaryLocation) {
2998 $loc++;
2999 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
3000 }
3001
6a488035
TO
3002 return $data;
3003 }
3004
3005 /**
100fef9d 3006 * Calculate the profile type 'group_type' as per profile fields.
6a488035 3007 *
6a0b768e
TO
3008 * @param int $gId
3009 * Profile id.
1fd63589 3010 * @param bool $includeTypeValues
6a0b768e
TO
3011 * @param int $ignoreFieldId
3012 * Ignore particular profile field.
6a488035 3013 *
a6c01b45
CW
3014 * @return array
3015 * list of calculated group type
6a488035 3016 */
00be9182 3017 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
6a488035
TO
3018 //get the profile fields.
3019 $ufFields = self::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3020 return self::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3021 }
3022
3023 /**
100fef9d 3024 * Calculate the profile type 'group_type' as per profile fields.
6a488035 3025 *
1fd63589
EM
3026 * @param $ufFields
3027 * @param bool $includeTypeValues
6a0b768e
TO
3028 * @param int $ignoreFieldId
3029 * Ignore perticular profile field.
6a488035 3030 *
a6c01b45
CW
3031 * @return array
3032 * list of calculated group type
6a488035 3033 */
00be9182 3034 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
6a488035
TO
3035 $groupType = $groupTypeValues = $customFieldIds = array();
3036 if (!empty($ufFields)) {
3037 foreach ($ufFields as $fieldName => $fieldValue) {
3038 //ignore field from group type when provided.
3039 //in case of update profile field.
3040 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3041 continue;
3042 }
3043 if (!in_array($fieldValue['field_type'], $groupType)) {
3044 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3045 }
3046
3047 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField::getKeyID($fieldName))) {
3048 $customFieldIds[$fldId] = $fldId;
3049 }
3050 }
3051 }
3052
3053 if (!empty($customFieldIds)) {
3054 $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) . ')';
3055
3056 $customGroups = CRM_Core_DAO::executeQuery($query);
3057 while ($customGroups->fetch()) {
3058 if (!$customGroups->extends_entity_column_value) {
3059 continue;
3060 }
3061
3062 $groupTypeName = "{$customGroups->extends}Type";
3063 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id) {
3064 $groupTypeName = CRM_Core_OptionGroup::getValue('custom_data_type', $customGroups->extends_entity_column_id, 'value', 'String', 'name');
3065 }
3066
3067 foreach (explode(CRM_Core_DAO::VALUE_SEPARATOR, $customGroups->extends_entity_column_value) as $val) {
3068 if ($val) {
3069 $groupTypeValues[$groupTypeName][$val] = $val;
3070 }
3071 }
3072 }
3073
3074 if (!empty($groupTypeValues)) {
3075 $groupType = array_merge($groupType, $groupTypeValues);
3076 }
3077 }
3078
3079 return $groupType;
3080 }
3081
3082 /**
3083 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3084 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3085 *
3086 * FIELDS GROUP_TYPE
3087 * BirthDate + Email Individual,Contact
3088 * BirthDate + Subject Individual,Activity
3089 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3090 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3091 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3092 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3093 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3094 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3095 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3096 *
c490a46a 3097 * @param int $gId
6a0b768e
TO
3098 * @param array $groupTypes
3099 * With key having group type names.
6a488035 3100 *
e7483cbe 3101 * @return bool
6a488035 3102 */
00be9182 3103 public static function updateGroupTypes($gId, $groupTypes = array()) {
6a488035
TO
3104 if (!is_array($groupTypes) || !$gId) {
3105 return FALSE;
3106 }
3107
3108 // If empty group types set group_type as 'null'
3109 if (empty($groupTypes)) {
3110 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3111 }
3112
1cb28d5d 3113 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
5d6ac993
TO
3114 $validGroupTypes = array_merge(array(
3115 'Contact',
3116 'Individual',
3117 'Organization',
21dfd5f5 3118 'Household',
5d6ac993 3119 ), $componentGroupTypes, CRM_Contact_BAO_ContactType::subTypes());
6a488035
TO
3120
3121 $gTypes = $gTypeValues = array();
3122
3123 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3124 // Get valid group type and group subtypes
3125 foreach ($groupTypes as $groupType => $value) {
3126 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3127 $gTypes[] = $groupType;
3128 }
3129
3130 $subTypesOf = NULL;
3131
3132 if (in_array($groupType, $participantExtends)) {
3133 $subTypesOf = $groupType;
3134 }
3135 elseif (strpos($groupType, 'Type') > 0) {
3136 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3137 }
3138 else {
3139 continue;
3140 }
3141
3142 if (!empty($value) &&
3143 (in_array($subTypesOf, $componentGroupTypes) ||
3144 in_array($subTypesOf, $participantExtends)
3145 )
3146 ) {
3147 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3148 }
3149 }
3150
3151 if (empty($gTypes)) {
3152 return FALSE;
3153 }
3154
3155 // Build String to store group types and group subtypes
3156 $groupTypeString = implode(',', $gTypes);
3157 if (!empty($gTypeValues)) {
3158 $groupTypeString .= CRM_Core_DAO::VALUE_SEPARATOR . implode(',', $gTypeValues);
3159 }
3160
3161 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3162 }
3163
3164 /**
fe482240 3165 * Create a "group_type" string.
6a488035 3166 *
6a0b768e
TO
3167 * @param array $coreTypes
3168 * E.g. array('Individual','Contact','Student').
3169 * @param array $subTypes
3170 * E.g. array('ActivityType' => array(7, 11)).
6a488035 3171 * @param string $delim
1fd63589
EM
3172 *
3173 * @return string
6a488035
TO
3174 * @throws CRM_Core_Exception
3175 */
00be9182 3176 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO::VALUE_SEPARATOR) {
6a488035
TO
3177 $groupTypeExpr = '';
3178 if ($coreTypes) {
3179 $groupTypeExpr .= implode(',', $coreTypes);
3180 }
3181 if ($subTypes) {
99e239bc 3182 //CRM-15427 Allow Multiple subtype filtering
3183 //if (count($subTypes) > 1) {
5d6ac993 3184 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
99e239bc 3185 //}
6a488035
TO
3186 foreach ($subTypes as $subType => $subTypeIds) {
3187 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3188 }
3189 }
3190 return $groupTypeExpr;
3191 }
3192
3193 /**
dc195289 3194 * setDefault componet specific profile fields.
6a488035 3195 *
6a0b768e
TO
3196 * @param array $fields
3197 * Profile fields.
3198 * @param int $componentId
3199 * ComponetID.
3200 * @param string $component
3201 * Component name.
3202 * @param array $defaults
3203 * An array of default values.
1fd63589
EM
3204 *
3205 * @param bool $isStandalone
6a488035 3206 *
a6c01b45 3207 * @return void
6a488035 3208 */
f0385140 3209 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
6a488035
TO
3210 if (!$componentId ||
3211 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3212 ) {
3213 return;
3214 }
3215
3216 $componentBAO = $componentSubType = NULL;
3217 switch ($component) {
3218 case 'Membership':
5d6ac993 3219 $componentBAO = 'CRM_Member_BAO_Membership';
6a488035
TO
3220 $componentBAOName = 'Membership';
3221 $componentSubType = array('membership_type_id');
3222 break;
3223
3224 case 'Contribute':
5d6ac993 3225 $componentBAO = 'CRM_Contribute_BAO_Contribution';
6a488035 3226 $componentBAOName = 'Contribution';
5d6ac993 3227 $componentSubType = array('financial_type_id');
6a488035
TO
3228 break;
3229
3230 case 'Event':
5d6ac993 3231 $componentBAO = 'CRM_Event_BAO_Participant';
6a488035 3232 $componentBAOName = 'Participant';
d623de42 3233 $componentSubType = array('role_id', 'event_id', 'event_type_id');
6a488035
TO
3234 break;
3235
3236 case 'Activity':
5d6ac993 3237 $componentBAO = 'CRM_Activity_BAO_Activity';
6a488035
TO
3238 $componentBAOName = 'Activity';
3239 $componentSubType = array('activity_type_id');
3240 break;
3241 }
3242
3243 $values = array();
3244 $params = array('id' => $componentId);
3245
3246 //get the component values.
3247 CRM_Core_DAO::commonRetrieve($componentBAO, $params, $values);
d623de42
M
3248 if ($componentBAOName == 'Participant') {
3249 $values += array('event_type_id' => CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3250 }
6a488035
TO
3251
3252 $formattedGroupTree = array();
5d6ac993
TO
3253 $dateTimeFields = array(
3254 'participant_register_date',
3255 'activity_date_time',
3256 'receive_date',
3257 'receipt_date',
3258 'cancel_date',
3259 'thankyou_date',
3260 'membership_start_date',
3261 'membership_end_date',
21dfd5f5 3262 'join_date',
5d6ac993 3263 );
6a488035
TO
3264 foreach ($fields as $name => $field) {
3265 $fldName = $isStandalone ? $name : "field[$componentId][$name]";
3266 if (in_array($name, $dateTimeFields)) {
3267 $timefldName = $isStandalone ? "{$name}_time" : "field[$componentId][{$name}_time]";
a7488080 3268 if (!empty($values[$name])) {
6a488035
TO
3269 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date::setDateDefaults($values[$name]);
3270 }
3271 }
3272 elseif (array_key_exists($name, $values)) {
3273 $defaults[$fldName] = $values[$name];
3274 }
3275 elseif ($name == 'participant_note') {
5d6ac993 3276 $noteDetails = CRM_Core_BAO_Note::getNote($componentId, 'civicrm_participant');
6a488035
TO
3277 $defaults[$fldName] = array_pop($noteDetails);
3278 }
3279 elseif (in_array($name, array(
5d6ac993
TO
3280 'financial_type',
3281 'payment_instrument',
3282 'participant_status',
21dfd5f5 3283 'participant_role',
5d6ac993 3284 ))) {
6a488035
TO
3285 $defaults[$fldName] = $values["{$name}_id"];
3286 }
3287 elseif ($name == 'membership_type') {
3288 // since membership_type field is a hierselect -
e7483cbe
J
3289 $defaults[$fldName][0]
3290 = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
6a488035
TO
3291 $defaults[$fldName][1] = $values['membership_type_id'];
3292 }
3293 elseif ($name == 'membership_status') {
3294 $defaults[$fldName] = $values['status_id'];
3295 }
3296 elseif ($customFieldInfo = CRM_Core_BAO_CustomField::getKeyID($name, TRUE)) {
3297 if (empty($formattedGroupTree)) {
3298 //get the groupTree as per subTypes.
3299 $groupTree = array();
3300 foreach ($componentSubType as $subType) {
3301 $subTree = CRM_Core_BAO_CustomGroup::getTree($componentBAOName, CRM_Core_DAO::$_nullObject,
3302 $componentId, 0, $values[$subType]
3303 );
3304 $groupTree = CRM_Utils_Array::crmArrayMerge($groupTree, $subTree);
3305 }
3306 $formattedGroupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree, 1, CRM_Core_DAO::$_nullObject);
3307 CRM_Core_BAO_CustomGroup::setDefaults($formattedGroupTree, $defaults);
3308 }
3309
3310 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3311 foreach ($defaults as $customKey => $customValue) {
3312 if ($customFieldDetails = CRM_Core_BAO_CustomField::getKeyID($customKey, TRUE)) {
3313 if ($name == 'custom_' . $customFieldDetails[0]) {
3314
3315 //hack to set default for checkbox
3316 //basically this is for weired field name like field[33][custom_19]
3317 //we are converting this field name to array structure and assign value.
3318 $skipValue = FALSE;
3319
3320 foreach ($formattedGroupTree as $tree) {
d623de42
M
3321 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3322 if ('CheckBox' == CRM_Utils_Array::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3323 $skipValue = TRUE;
3324 $defaults['field'][$componentId][$name] = $customValue;
3325 break;
3326 }
3327 elseif (CRM_Utils_Array::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3328 $skipValue = TRUE;
6a488035 3329
d623de42
M
3330 // CRM-6681, $default contains formatted date, time values.
3331 $defaults[$fldName] = $customValue;
3332 if (!empty($defaults[$customKey . '_time'])) {
3333 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3334 }
6a488035
TO
3335 }
3336 }
3337 }
3338
3339 if (!$skipValue || $isStandalone) {
3340 $defaults[$fldName] = $customValue;
3341 }
3342 unset($defaults[$customKey]);
3343 break;
3344 }
3345 }
3346 }
3347 }
3348 }
3349 }
3350
79ae07d9
CW
3351 /**
3352 * @param array|string $profiles - name of profile(s) to create links for
6a0b768e
TO
3353 * @param array $appendProfiles
3354 * Name of profile(s) to append to each link.
1fd63589
EM
3355 *
3356 * @return array
79ae07d9 3357 */
00be9182 3358 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
a4799f04
CW
3359 // Default to contact profiles
3360 if (!$profiles) {
3361 $profiles = array('new_individual', 'new_organization', 'new_household');
3362 }
79ae07d9 3363 $profiles = (array) $profiles;
1a90e0dd 3364 $toGet = array_merge($profiles, (array) $appendProfiles);
79ae07d9
CW
3365 $retrieved = civicrm_api3('uf_group', 'get', array(
3366 'name' => array('IN' => $toGet),
3367 'is_active' => 1,
3368 ));
3369 $links = $append = array();
3370 if (!empty($retrieved['values'])) {
5d6ac993 3371 foreach ($retrieved['values'] as $id => $profile) {
79ae07d9
CW
3372 if (in_array($profile['name'], $profiles)) {
3373 $links[] = array(
3374 'label' => $profile['title'],
a4799f04 3375 'url' => CRM_Utils_System::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
5d6ac993 3376 NULL, NULL, FALSE, FALSE, TRUE),
a4799f04 3377 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
79ae07d9
CW
3378 );
3379 }
3380 else {
3381 $append[] = $id;
3382 }
3383 }
3384 foreach ($append as $id) {
3385 foreach ($links as &$link) {
3386 $link['url'] .= ",$id";
3387 }
3388 }
3389 }
3390 return $links;
3391 }
3392
6a488035 3393 /**
fe482240 3394 * Retrieve groups of profiles.
6a488035 3395 *
6a0b768e
TO
3396 * @param int $profileID
3397 * Id of the profile.
6a488035 3398 *
a6c01b45
CW
3399 * @return array
3400 * returns array
6a488035 3401 */
00be9182 3402 public static function profileGroups($profileID) {
6a488035
TO
3403 $groupTypes = array();
3404 $profileTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3405 if ($profileTypes) {
3406 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $profileTypes);
3407 $groupTypes = explode(',', $groupTypeParts[0]);
3408 }
3409 return $groupTypes;
3410 }
3411
3412 /**
100fef9d 3413 * Alter contact params by filtering existing subscribed groups and returns
6a488035
TO
3414 * unsubscribed groups array for subscription.
3415 *
6a0b768e
TO
3416 * @param array $params
3417 * Contact params.
3418 * @param int $contactId
3419 * User contact id.
6a488035 3420 *
a6c01b45
CW
3421 * @return array
3422 * This contains array of groups for subscription
6a488035 3423 */
00be9182 3424 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
6a488035
TO
3425 $config = CRM_Core_Config::singleton();
3426 $subscribeGroupIds = array();
3427
3428 // process further only if profileDoubleOptIn enabled and if groups exist
3429 if (!array_key_exists('group', $params) ||
3430 !self::isProfileDoubleOptin() ||
3431 CRM_Utils_System::isNull($params['group'])
3432 ) {
3433 return $subscribeGroupIds;
3434 }
3435
3436 //check if contact email exist.
3437 $hasEmails = FALSE;
3438 foreach ($params as $name => $value) {
3439 if (strpos($name, 'email-') !== FALSE) {
3440 $hasEmails = TRUE;
3441 break;
3442 }
3443 }
3444
3445 //Proceed furthur only if email present
3446 if (!$hasEmails) {
3447 return $subscribeGroupIds;
3448 }
3449
3450 //do check for already subscriptions.
3451 $contactGroups = array();
3452 if ($contactId) {
3453 $query = "
3454SELECT group_id
3455 FROM civicrm_group_contact
3456 WHERE status = 'Added'
3457 AND contact_id = %1";
3458
3459 $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($contactId, 'Integer')));
3460 while ($dao->fetch()) {
3461 $contactGroups[$dao->group_id] = $dao->group_id;
3462 }
3463 }
3464
3465 //since we don't have names, compare w/ label.
3466 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup::values('group_type'));
3467
3468 //actual processing start.
3469 foreach ($params['group'] as $groupId => $isSelected) {
3470 //unset group those are not selected.
3471 if (!$isSelected) {
3472 unset($params['group'][$groupId]);
3473 continue;
3474 }
3475
3476 $groupTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR,
3477 CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3478 );
3479 //get only mailing type group and unset it from params
3480 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3481 $subscribeGroupIds[$groupId] = $groupId;
3482 unset($params['group'][$groupId]);
3483 }
3484 }
3485
3486 return $subscribeGroupIds;
3487 }
3488
3489 /**
fe482240 3490 * Check if we are rendering mixed profiles.
6a488035 3491 *
6a0b768e
TO
3492 * @param array $profileIds
3493 * Associated array of profile ids.
6a488035 3494 *
e7483cbe 3495 * @return bool
a6c01b45 3496 * true if profile is mixed
6a488035 3497 */
00be9182 3498 public static function checkForMixProfiles($profileIds) {
6a488035
TO
3499 $mixProfile = FALSE;
3500
3501 $contactTypes = array('Individual', 'Household', 'Organization');
3502 $subTypes = CRM_Contact_BAO_ContactType::subTypes();
3503
3504 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3505
3506 $typeCount = array('ctype' => array(), 'subtype' => array());
3507 foreach ($profileIds as $gid) {
3508 $profileType = CRM_Core_BAO_UFField::getProfileType($gid);
3509 // ignore profile of type Contact
3510 if ($profileType == 'Contact') {
3511 continue;
3512 }
3513 if (in_array($profileType, $contactTypes)) {
3514 if (!isset($typeCount['ctype'][$profileType])) {
3515 $typeCount['ctype'][$profileType] = 1;
3516 }
3517
3518 // check if we are rendering profile of different contact types
3519 if (count($typeCount['ctype']) == 2) {
3520 $mixProfile = TRUE;
3521 break;
3522 }
3523 }
3524 elseif (in_array($profileType, $components)) {
3525 $mixProfile = TRUE;
3526 break;
3527 }
3528 else {
3529 if (!isset($typeCount['subtype'][$profileType])) {
3530 $typeCount['subtype'][$profileType] = 1;
3531 }
3532 // check if we are rendering profile of different contact sub types
3533 if (count($typeCount['subtype']) == 2) {
3534 $mixProfile = TRUE;
3535 break;
3536 }
3537 }
3538 }
3539 return $mixProfile;
3540 }
3541
3542 /**
fe482240 3543 * Determine of we show overlay profile or not.
6a488035 3544 *
e7483cbe 3545 * @return bool
a6c01b45 3546 * true if profile should be shown else false
6a488035 3547 */
00be9182 3548 public static function showOverlayProfile() {
6a488035
TO
3549 $showOverlay = TRUE;
3550
3551 // get the id of overlay profile
3552 $overlayProfileId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3553 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3554
3555 $count = CRM_Core_DAO::singleValueQuery($query);
3556
3557 //check if there are no public fields and use is anonymous
3558 $session = CRM_Core_Session::singleton();
3559 if (!$count && !$session->get('userID')) {
3560 $showOverlay = FALSE;
3561 }
3562
3563 return $showOverlay;
3564 }
3565
3566 /**
fe482240 3567 * Get group type values of the profile.
6a488035 3568 *
c490a46a
CW
3569 * @param int $profileId
3570 * @param string $groupType
1fd63589 3571 *
e7483cbe 3572 * @return array
a6c01b45 3573 * group type values
6a488035 3574 */
00be9182 3575 public static function groupTypeValues($profileId, $groupType = NULL) {
6a488035
TO
3576 $groupTypeValue = array();
3577 $groupTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3578
3579 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $groupTypes);
a7488080 3580 if (empty($groupTypeParts[1])) {
6a488035
TO
3581 return $groupTypeValue;
3582 }
3583 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3584
3585 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3586 $values = array();
3587 $valueParts = explode(':', $groupTypeValues);
3588 if ($groupType &&
3589 ($valueParts[0] != "{$groupType}Type" ||
3590 ($groupType == 'Participant' &&
3591 !in_array($valueParts[0], $participantExtends)
3592 )
3593 )
3594 ) {
3595 continue;
3596 }
3597 foreach ($valueParts as $val) {
3598 if (CRM_Utils_Rule::integer($val)) {
3599 $values[$val] = $val;
3600 }
3601 }
3602 if (!empty($values)) {
3603 $typeName = substr($valueParts[0], 0, -4);
3604 if (in_array($valueParts[0], $participantExtends)) {
3605 $typeName = $valueParts[0];
3606 }
3607 $groupTypeValue[$typeName] = $values;
3608 }
3609 }
3610
3611 return $groupTypeValue;
3612 }
3613
b5c2afd0
EM
3614 /**
3615 * @return bool|object
3616 */
00be9182 3617 public static function isProfileDoubleOptin() {
6a488035
TO
3618 // check for double optin
3619 $config = CRM_Core_Config::singleton();
3620 if (in_array('CiviMail', $config->enableComponents)) {
3621 return CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
3622 'profile_double_optin', NULL, FALSE
3623 );
3624 }
3625 return FALSE;
3626 }
3627
b5c2afd0
EM
3628 /**
3629 * @return bool|object
3630 */
00be9182 3631 public static function isProfileAddToGroupDoubleOptin() {
6a488035
TO
3632 // check for add to group double optin
3633 $config = CRM_Core_Config::singleton();
3634 if (in_array('CiviMail', $config->enableComponents)) {
3635 return CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
3636 'profile_add_to_group_double_optin', NULL, FALSE
3637 );
3638 }
3639 return FALSE;
3640 }
3641
3642 /**
fe482240 3643 * Get profiles used for batch entry.
6a488035 3644 *
a6c01b45
CW
3645 * @return array
3646 * profileIds profile ids
6a488035 3647 */
00be9182 3648 public static function getBatchProfiles() {
6a488035
TO
3649 $query = "SELECT id
3650 FROM civicrm_uf_group
3651 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
5d6ac993 3652 $dao = CRM_Core_DAO::executeQuery($query);
6a488035 3653 $profileIds = array();
5d6ac993 3654 while ($dao->fetch()) {
6a488035
TO
3655 $profileIds[$dao->id] = $dao->id;
3656 }
3657 return $profileIds;
3658 }
3659
1fd63589
EM
3660 /**
3661 * @todo what do I do?
3662 * @param $source
3663 * @param $destination
3664 * @param bool $returnMultiSummaryFields
3665 *
3666 * @return array|null
3667 */
00be9182 3668 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
5d6ac993 3669 $multiSummaryFields = $returnMultiSummaryFields ? array() : NULL;
6a488035
TO
3670 foreach ($source as $field => $properties) {
3671 if (!CRM_Core_BAO_CustomField::getKeyID($field)) {
3672 continue;
3673 }
3674 if (CRM_Core_BAO_CustomField::isMultiRecordField($field)) {
3675 $destination[$field] = $properties;
3676 if ($returnMultiSummaryFields) {
3677 if ($properties['is_multi_summary']) {
3678 $multiSummaryFields[$field] = $properties;
3679 }
3680 }
3681 unset($source[$field]);
3682 }
3683 }
3684 return $multiSummaryFields;
3685 }
3686
3687 /**
fe482240 3688 * This is function is used to format pseudo fields.
6a488035 3689 *
6a0b768e
TO
3690 * @param array $fields
3691 * Associated array of profile fields.
6a488035 3692 *
6a488035 3693 */
00be9182 3694 public static function reformatProfileFields(&$fields) {
6a488035
TO
3695 //reformat fields array
3696 foreach ($fields as $name => $field) {
3697 //reformat phone and extension field
5d6ac993 3698 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
6a488035
TO
3699 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3700
3701 // retain existing element properties and just update and replace key
3702 CRM_Utils_Array::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3703 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3704 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3705
3706 // add additional phone extension field
3707 $fields["phone_ext-{$fieldSuffix}"] = $field;
5d6ac993 3708 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
6a488035
TO
3709 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3710 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3711 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3712 //ignore required for extension field
3713 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;
3714 }
3715 }
3716 }
96025800 3717
6a488035 3718}