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