3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2017
37 class CRM_Core_BAO_UFGroup
extends CRM_Core_DAO_UFGroup
{
38 const PUBLIC_VISIBILITY
= 1,
40 LISTINGS_VISIBILITY
= 4;
43 * Cache the match clause used in this transaction.
47 static $_matchFields = NULL;
50 * Fetch object based on array of properties.
52 * @param array $params
53 * (reference) an assoc array of name/value pairs.
54 * @param array $defaults
55 * (reference) an assoc array to hold the flattened values.
58 * CRM_Core_DAO_UFGroup object
60 public static function retrieve(&$params, &$defaults) {
61 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
65 * Retrieve the first non-generic contact type
73 public static function getContactType($id) {
75 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
76 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
78 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
79 $types = explode(',', $typesParts[0]);
82 foreach ($types as $type) {
83 if (in_array($type, $validTypes)) {
86 elseif (array_key_exists($type, $validSubTypes)) {
87 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
107 public static function getTitle($id) {
108 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
112 * Update the is_active flag in the db.
115 * Id of the database record.
116 * @param bool $is_active
117 * Value we want to set the is_active field.
120 * CRM_Core_DAO_UFGroup object on success, null otherwise
122 public static function setIsActive($id, $is_active) {
123 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
127 * Get all the registration fields.
130 * What action are we doing.
137 * the fields that are needed for registration
139 public static function getRegistrationFields($action, $mode, $ctype = NULL) {
140 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
141 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
144 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
147 if (!is_array($ufGroups)) {
153 foreach ($ufGroups as $id => $title) {
155 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
156 if (($fieldType != 'Contact') &&
157 ($fieldType != $ctype) &&
158 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
162 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
163 $profileSubType = $fieldType;
167 $subset = self
::getFields($id, TRUE, $action,
168 NULL, NULL, FALSE, NULL, TRUE, $ctype
171 // we do not allow duplicates. the first field is the winner
172 foreach ($subset as $name => $field) {
173 if (empty($fields[$name])) {
174 $fields[$name] = $field;
183 * Get all the listing fields.
186 * What action are we doing.
187 * @param int $visibility
188 * Visibility of fields we are interested in.
189 * @param bool $considerSelector
190 * Whether to consider the in_selector parameter.
191 * @param array $ufGroupIds
192 * @param bool $searchable
194 * @param null $restrict
195 * @param bool $skipPermission
196 * @param int $permissionType
198 * the fields that are listings related
200 public static function getListingFields(
203 $considerSelector = FALSE,
207 $skipPermission = FALSE,
208 $permissionType = CRM_Core_Permission
::SEARCH
211 $subset = self
::getFields($ufGroupIds, FALSE, $action,
212 $visibility, $searchable,
218 if ($considerSelector) {
219 // drop the fields not meant for the selector
220 foreach ($subset as $name => $field) {
221 if (!$field['in_selector']) {
222 unset($subset[$name]);
229 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
232 foreach ($ufGroups as $id => $title) {
233 $subset = self
::getFields($id, FALSE, $action,
234 $visibility, $searchable,
240 if ($considerSelector) {
241 // drop the fields not meant for the selector
242 foreach ($subset as $name => $field) {
243 if (!$field['in_selector']) {
244 unset($subset[$name]);
248 $fields = array_merge($fields, $subset);
255 * Get all the fields that belong to the group with the name title,
256 * and format for use with buildProfile. This is the SQL analog of
260 * The id of the UF group or ids of ufgroup.
261 * @param bool|int $register are we interested in registration fields
263 * What action are we doing.
264 * @param int $visibility
265 * Visibility of fields we are interested in.
267 * @param bool $showAll
268 * @param string $restrict
269 * Should we restrict based on a specified profile type.
270 * @param bool $skipPermission
272 * @param int $permissionType
273 * @param string $orderBy
274 * @param null $orderProfiles
276 * @param bool $eventProfile
279 * The fields that belong to this ufgroup(s)
282 public static function getFields(
290 $skipPermission = FALSE,
292 $permissionType = CRM_Core_Permission
::CREATE
,
293 $orderBy = 'field_name',
294 $orderProfiles = NULL,
295 $eventProfile = FALSE
297 if (!is_array($id)) {
298 $id = CRM_Utils_Type
::escape($id, 'Positive');
299 $profileIds = array($id);
305 $gids = implode(',', $profileIds);
308 $query = "SELECT g.* from civicrm_uf_group g
309 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
310 WHERE g.id IN ( {$gids} )
311 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
313 $params = array(1 => array($restrict, 'String'));
316 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
320 $query .= " AND g.is_active = 1";
323 $checkPermission = array(
325 'administer CiviCRM',
326 'manage event profiles',
329 if ($eventProfile && CRM_Core_Permission
::check($checkPermission)) {
330 $skipPermission = TRUE;
333 // add permissioning for profiles only if not registration
334 if (!$skipPermission) {
335 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
336 $query .= " AND $permissionClause ";
339 if ($orderProfiles AND count($profileIds) > 1) {
340 $query .= " ORDER BY FIELD( g.id, {$gids} )";
342 $group = CRM_Core_DAO
::executeQuery($query, $params);
346 while ($group->fetch()) {
348 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
349 $field = CRM_Core_DAO
::executeQuery($query);
351 $importableFields = self
::getProfileFieldMetadata($showAll);
352 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
354 while ($field->fetch()) {
355 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
356 if ($formattedField !== NULL) {
357 $fields[$name] = $formattedField;
363 if (empty($fields) && !$validGroup) {
364 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.',
365 array(1 => implode(',', $profileIds))
369 self
::reformatProfileFields($fields);
376 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
379 * @param array $groupArr
380 * (mimic CRM_UF_DAO_UFGroup).
381 * @param array $fieldArrs
382 * List of fields (each mimics CRM_UF_DAO_UFField).
383 * @param bool $visibility
384 * Visibility of fields we are interested in.
385 * @param bool $searchable
386 * @param bool $showAll
388 * @param int $permissionType
391 * @see self::getFields
393 public static function formatUFFields(
400 $permissionType = CRM_Core_Permission
::CREATE
402 // $group = new CRM_Core_DAO_UFGroup();
403 // $group->copyValues($groupArr); // no... converts string('') to string('null')
404 $group = (object) $groupArr;
406 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
407 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
408 // they did -- the obvious fix would produce mutual recursion.
409 $ufGroupType = self
::_calculateGroupType($fieldArrs);
410 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',', $ufGroupType));
411 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',', $ufGroupType));
412 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
413 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
415 $formattedFields = array();
416 foreach ($fieldArrs as $fieldArr) {
417 $field = (object) $fieldArr;
418 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
422 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
423 if ($formattedField !== NULL) {
424 $formattedFields[$name] = $formattedField;
427 return $formattedFields;
431 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
433 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
434 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
435 * @param array $customFields
436 * @param array $addressCustomFields
437 * @param array $importableFields
438 * @param int $permissionType
439 * Eg CRM_Core_Permission::CREATE.
442 protected static function formatUFField(
446 $addressCustomFields,
448 $permissionType = CRM_Core_Permission
::CREATE
450 $name = $field->field_name
;
451 $title = $field->label
;
453 $addressCustom = FALSE;
454 if (in_array($permissionType, array(
455 CRM_Core_Permission
::CREATE
,
456 CRM_Core_Permission
::EDIT
,
458 in_array($field->field_name
, array_keys($addressCustomFields))
460 $addressCustom = TRUE;
461 $name = "address_{$name}";
463 if ($field->field_name
== 'url') {
464 $name .= "-{$field->website_type_id}";
466 elseif (!empty($field->location_type_id
)) {
467 $name .= "-{$field->location_type_id}";
470 $locationFields = self
::getLocationFields();
471 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
476 if (isset($field->phone_type_id
)) {
477 $name .= "-{$field->phone_type_id}";
479 $fieldMetaData = CRM_Utils_Array
::value($name, $importableFields, (isset($importableFields[$field->field_name
]) ?
$importableFields[$field->field_name
] : array()));
481 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
482 // I guess to make field self sufficient with all the required data and avoid additional calls
483 $formattedField = array(
485 'groupTitle' => $group->title
,
486 'groupName' => $group->name
,
487 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
488 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
490 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
491 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
492 'is_required' => $field->is_required
,
493 'is_view' => $field->is_view
,
494 'help_pre' => $field->help_pre
,
495 'help_post' => $field->help_post
,
496 'visibility' => $field->visibility
,
497 'in_selector' => $field->in_selector
,
498 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
499 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
500 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
501 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
502 'group_id' => $group->id
,
503 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
504 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
505 'field_type' => $field->field_type
,
506 'field_id' => $field->id
,
507 'pseudoconstant' => CRM_Utils_Array
::value(
509 CRM_Utils_Array
::value($field->field_name
, $importableFields)
511 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
512 'dbName' => CRM_Utils_Array
::value(
514 CRM_Utils_Array
::value($field->field_name
, $importableFields)
517 'data_type' => CRM_Utils_Type
::getDataTypeFromFieldMetadata($fieldMetaData),
518 'bao' => CRM_Utils_Array
::value('bao', $fieldMetaData),
521 $formattedField = CRM_Utils_Date
::addDateMetadataToField($fieldMetaData, $formattedField);
523 //adding custom field property
524 if (substr($field->field_name
, 0, 6) == 'custom' ||
525 substr($field->field_name
, 0, 14) === 'address_custom'
527 // if field is not present in customFields, that means the user
528 // DOES NOT HAVE permission to access that field
529 if (array_key_exists($field->field_name
, $customFields)) {
530 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
532 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
533 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
535 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
536 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
537 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
538 $formattedField['is_datetime_field'] = TRUE;
539 $formattedField['smarty_view_format'] = CRM_Utils_Date
::getDateFieldViewFormat($formattedField['date_format']);
542 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
543 return array($name, $formattedField);
546 $formattedField = NULL;
547 return array($name, $formattedField);
550 return array($name, $formattedField);
554 * Create a query to find all visible UFFields in a UFGroup.
556 * This is the SQL-variant of checkUFFieldDisplayable().
558 * @param int $groupId
559 * @param bool $searchable
560 * @param bool $showAll
561 * @param int $visibility
562 * @param string $orderBy
563 * Comma-delimited list of SQL columns.
566 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
567 $where = " WHERE uf_group_id = {$groupId}";
570 $where .= " AND is_searchable = 1";
574 $where .= " AND is_active = 1";
579 if ($visibility & self
::PUBLIC_VISIBILITY
) {
580 $clause[] = 'visibility = "Public Pages"';
582 if ($visibility & self
::ADMIN_VISIBILITY
) {
583 $clause[] = 'visibility = "User and User Admin Only"';
585 if ($visibility & self
::LISTINGS_VISIBILITY
) {
586 $clause[] = 'visibility = "Public Pages and Listings"';
588 if (!empty($clause)) {
589 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
593 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
595 $query .= ", " . $orderBy;
602 * Create a query to find all visible UFFields in a UFGroup.
604 * This is the PHP in-memory variant of createUFFieldQuery().
606 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
607 * @param bool $searchable
608 * @param bool $showAll
609 * @param int $visibility
611 * TRUE if field is displayable
613 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
614 if ($searchable && $field->is_searchable
!= 1) {
618 if (!$showAll && $field->is_active
!= 1) {
623 $allowedVisibilities = array();
624 if ($visibility & self
::PUBLIC_VISIBILITY
) {
625 $allowedVisibilities[] = 'Public Pages';
627 if ($visibility & self
::ADMIN_VISIBILITY
) {
628 $allowedVisibilities[] = 'User and User Admin Only';
630 if ($visibility & self
::LISTINGS_VISIBILITY
) {
631 $allowedVisibilities[] = 'Public Pages and Listings';
633 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
634 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
643 * Get a list of filtered field metadata.
645 * @deprecated use getProfileFieldMetadata
648 * @param $profileType
649 * @param $contactActivityProfile
650 * @param bool $filterMode
651 * Filter mode means you are using importable fields for filtering rather than just getting metadata.
652 * With filter mode = FALSE BOTH activity fields and component fields are returned.
653 * I can't see why you would ever want to use this function in filter mode as the component fields are
654 * still unfiltered. However, I feel scared enough to leave it as it is. I have marked this function as
655 * deprecated and am recommending the wrapper 'getProfileFieldMetadata' in order to try to
656 * send this confusion to history.
660 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile, $filterMode = TRUE) {
662 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
665 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
668 $activityFields = CRM_Activity_BAO_Activity
::getProfileFields();
669 $componentFields = CRM_Core_Component
::getQueryFields();
670 if ($filterMode == TRUE) {
671 if ($profileType == 'Activity' ||
$contactActivityProfile) {
672 $importableFields = array_merge($importableFields, $activityFields);
675 $importableFields = array_merge($importableFields, $componentFields);
679 $importableFields = array_merge($importableFields, $activityFields, $componentFields);
682 $importableFields['group']['title'] = ts('Group(s)');
683 $importableFields['group']['where'] = NULL;
684 $importableFields['tag']['title'] = ts('Tag(s)');
685 $importableFields['tag']['where'] = NULL;
686 return $importableFields;
690 * Get the metadata for all potential profile fields.
692 * @param bool $isIncludeInactive
693 * Should disabled fields be included.
696 * Field metadata for all fields that might potentially be in a profile.
698 protected static function getProfileFieldMetadata($isIncludeInactive) {
699 return self
::getImportableFields($isIncludeInactive, NULL, NULL, NULL, TRUE);
703 * Get the fields relating to locations.
707 public static function getLocationFields() {
708 static $locationFields = array(
710 'supplemental_address_1',
711 'supplemental_address_2',
712 'supplemental_address_3',
715 'postal_code_suffix',
728 return $locationFields;
736 protected static function getCustomFields($ctype) {
737 static $customFieldCache = array();
738 if (!isset($customFieldCache[$ctype])) {
739 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
741 // hack to add custom data for components
742 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
743 foreach ($components as $value) {
744 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
746 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
747 $customFields = array_merge($customFields, $addressCustomFields);
748 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
750 return $customFieldCache[$ctype];
754 * Check the data validity.
757 * The user id that we are actually editing.
758 * @param string $name
759 * The machine-name of the group we are interested in.
760 * @param bool $register
762 * The action of the form.
764 * @pram boolean $register is this the registrtion form
766 * true if form is valid
768 public static function isValid($userID, $name, $register = FALSE, $action = NULL) {
770 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
771 ts('Dynamic Form Creator'),
774 $controller->set('id', $userID);
775 $controller->set('register', 1);
776 $controller->process();
777 return $controller->validate();
780 // make sure we have a valid group
781 $group = new CRM_Core_DAO_UFGroup();
783 $group->name
= $name;
785 if ($group->find(TRUE) && $userID) {
786 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
787 $controller->set('gid', $group->id
);
788 $controller->set('id', $userID);
789 $controller->set('register', 0);
790 $controller->process();
791 return $controller->validate();
798 * Get the html for the form that represents this particular group.
801 * The user id that we are actually editing.
802 * @param string $title
803 * The title of the group we are interested in.
805 * The action of the form.
806 * @param bool $register
807 * Is this the registration form.
809 * Should we reset the form?.
810 * @param int $profileID
811 * Do we have the profile ID?.
813 * @param bool $doNotProcess
817 * the html for the form on success, otherwise empty string
819 public static function getEditHTML(
826 $doNotProcess = FALSE,
831 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
832 ts('Dynamic Form Creator'),
835 if ($reset ||
$doNotProcess) {
836 // hack to make sure we do not process this form
837 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
840 unset($_POST['_qf_default']);
841 unset($_REQUEST['_qf_default']);
843 $controller->reset();
847 $controller->set('id', $userID);
848 $controller->set('register', 1);
849 $controller->set('skipPermission', 1);
850 $controller->set('ctype', $ctype);
851 $controller->process();
852 if ($doNotProcess ||
!empty($_POST)) {
853 $controller->validate();
855 $controller->setEmbedded(TRUE);
857 //CRM-5839 - though we want to process form, get the control back.
858 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
862 // we are done processing so restore the POST/REQUEST vars
863 if (($reset ||
$doNotProcess) && $oldQFDefault) {
864 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
867 $template = CRM_Core_Smarty
::singleton();
869 // Hide CRM error messages if they are displayed using drupal form_set_error.
870 if (!empty($_POST)) {
871 $template->assign('suppressForm', TRUE);
874 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
878 // make sure we have a valid group
879 $group = new CRM_Core_DAO_UFGroup();
881 $group->title
= $title;
883 if ($group->find(TRUE)) {
884 $profileID = $group->id
;
889 // make sure profileID and ctype match if ctype exists
891 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
892 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
893 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
896 if (($profileType != 'Contact') && ($profileType != $ctype)) {
901 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
902 ts('Dynamic Form Creator'),
906 $controller->reset();
908 $controller->set('gid', $profileID);
909 $controller->set('id', $userID);
910 $controller->set('register', 0);
911 $controller->set('skipPermission', 1);
913 $controller->set('ctype', $ctype);
915 $controller->process();
916 $controller->setEmbedded(TRUE);
918 //CRM-5846 - give the control back to drupal.
919 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
922 $template = CRM_Core_Smarty
::singleton();
924 // Hide CRM error messages if they are displayed using drupal form_set_error.
925 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
926 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
927 $template->assign('suppressForm', TRUE);
931 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
932 if (!$template->template_exists($templateFile)) {
933 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
935 return trim($template->fetch($templateFile));
938 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
940 // if post not empty then only proceed
941 if (!empty($_POST)) {
943 $config = CRM_Core_Config
::singleton();
944 $email = CRM_Utils_Array
::value('mail', $_POST);
946 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
947 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
956 * Given a contact id and a field set, return the values from the db.
959 * @param array $fields
960 * The profile fields of interest.
961 * @param array $values
962 * The values for the above fields.
963 * @param bool $searchable
965 * @param array $componentWhere
966 * Component condition.
967 * @param bool $absolute
968 * Return urls in absolute form (useful when sending an email).
969 * @param null $additionalWhereClause
973 public static function getValues(
974 $cid, &$fields, &$values,
975 $searchable = TRUE, $componentWhere = NULL,
976 $absolute = FALSE, $additionalWhereClause = NULL
978 if (empty($cid) && empty($componentWhere)) {
982 // get the contact details (hier)
983 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
984 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
986 // add conditions specified by components. eg partcipant_id etc
987 if (!empty($componentWhere)) {
988 $params = array_merge($params, $componentWhere);
991 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
993 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
994 FALSE, FALSE, FALSE, $additionalWhereClause);
995 if (!$details->fetch()) {
998 $query->convertToPseudoNames($details);
999 $config = CRM_Core_Config
::singleton();
1001 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
1002 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
1003 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
1005 $multipleFields = array('url');
1007 //start of code to set the default values
1008 foreach ($fields as $name => $field) {
1010 if ($name == 'id') {
1011 $name = 'contact_id';
1014 // skip fields that should not be displayed separately
1015 if (!empty($field['skipDisplay'])) {
1019 // Create a unique, non-empty index for each field.
1020 $index = $field['title'];
1021 if ($index === '') {
1024 while (array_key_exists($index, $values)) {
1028 $params[$index] = $values[$index] = '';
1029 $customFieldName = NULL;
1031 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
1032 // to handle gender / suffix / prefix
1033 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
1034 $params[$index] = $details->$name;
1035 $values[$index] = $details->$name;
1037 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1038 $dname = $name . '_display';
1039 $values[$index] = $details->$dname;
1040 $name = $name . '_id';
1041 $params[$index] = $details->$name;
1043 elseif (in_array($name, array(
1048 $values[$index] = $details->$name;
1049 $idx = $name . '_id';
1050 $params[$index] = $details->$idx;
1052 elseif ($name === 'preferred_language') {
1053 $params[$index] = $details->$name;
1054 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1056 elseif ($name == 'group') {
1057 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1058 $title = $ids = array();
1060 foreach ($groups as $g) {
1061 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1062 // VIEW permission on that group
1063 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], TRUE);
1065 if ($g['visibility'] != 'User and User Admin Only' ||
1066 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1068 $title[] = $g['title'];
1069 if ($g['visibility'] == 'Public Pages') {
1070 $ids[] = $g['group_id'];
1074 $values[$index] = implode(', ', $title);
1075 $params[$index] = implode(',', $ids);
1077 elseif ($name == 'tag') {
1078 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1079 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1081 foreach ($entityTags as $tagId) {
1082 $title[] = $allTags[$tagId];
1084 $values[$index] = implode(', ', $title);
1085 $params[$index] = implode(',', $entityTags);
1087 elseif ($name == 'activity_status_id') {
1088 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1089 $values[$index] = $activityStatus[$details->$name];
1090 $params[$index] = $details->$name;
1092 elseif ($name == 'activity_date_time') {
1093 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1094 $params[$index] = $details->$name;
1096 elseif ($name == 'contact_sub_type') {
1097 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1098 if (!empty($contactSubTypeNames)) {
1099 $contactSubTypeLabels = array();
1100 // get all contact subtypes
1101 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1102 // build contact subtype labels array
1103 foreach ($contactSubTypeNames as $cstName) {
1105 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1108 $values[$index] = implode(',', $contactSubTypeLabels);
1111 $params[$index] = $details->$name;
1114 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1115 if ($details->$name) {
1116 $values[$index] = '[ x ]';
1120 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1121 $htmlType = $field['html_type'];
1123 // field_type is only set when we are retrieving profile values
1124 // when sending email, we call the same function to get custom field
1125 // values etc, i.e. emulating a profile
1126 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1128 if ($htmlType == 'File') {
1131 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1133 $entityId = $componentWhere[0][2];
1136 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1140 $additionalWhereClause
1142 $params[$index] = $values[$index] = $fileURL['file_url'];
1146 if (isset($dao) && property_exists($dao, 'data_type') &&
1147 ($dao->data_type
== 'Int' ||
1148 $dao->data_type
== 'Boolean'
1151 $customVal = (int ) ($details->{$name});
1153 elseif (isset($dao) && property_exists($dao, 'data_type')
1154 && $dao->data_type
== 'Float'
1156 $customVal = (float ) ($details->{$name});
1158 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1162 $customVal = $details->{$name};
1166 if (CRM_Utils_System
::isNull($customVal)) {
1170 $params[$index] = $customVal;
1171 $values[$index] = CRM_Core_BAO_CustomField
::displayValue($customVal, $cfID);
1172 if ($field['data_type'] == 'ContactReference') {
1173 $params[$index] = $values[$index];
1175 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1176 $cfID, 'is_search_range'
1179 $customFieldName = "{$name}_from";
1183 elseif ($name == 'image_URL') {
1184 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1185 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1187 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1188 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1190 elseif (in_array($name, array(
1194 // @todo this set should be determined from metadata, not hard-coded.
1195 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1196 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1200 if ($index == 'Campaign') {
1201 $dao = 'CRM_Campaign_DAO_Campaign';
1203 elseif ($index == 'Contribution Page') {
1204 $dao = 'CRM_Contribute_DAO_ContributionPage';
1207 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1210 $value = $details->$name;
1212 $values[$index] = $value;
1217 elseif (strpos($name, '-') !== FALSE) {
1218 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1220 if (!in_array($fieldName, $multipleFields)) {
1221 if ($id == 'Primary') {
1223 // not sure why we'd every use Primary location type id
1224 // we need to fix the source if we are using it
1225 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1226 $locationTypeName = 1;
1229 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1232 if (!$locationTypeName) {
1236 $detailName = "{$locationTypeName}-{$fieldName}";
1237 $detailName = str_replace(' ', '_', $detailName);
1239 if (in_array($fieldName, array(
1246 $detailName .= "-{$type}";
1250 if (in_array($fieldName, array(
1255 $values[$index] = $details->$detailName;
1256 $idx = $detailName . '_id';
1257 $params[$index] = $details->$idx;
1259 elseif ($fieldName == 'im') {
1260 $providerId = $detailName . '-provider_id';
1261 if (isset($imProviders[$details->$providerId])) {
1262 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1265 $values[$index] = $details->$detailName;
1267 $params[$index] = $details->$detailName;
1269 elseif ($fieldName == 'phone') {
1270 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1271 if (isset($details->$phoneExtField)) {
1272 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1275 $values[$index] = $details->$detailName;
1277 $params[$index] = $details->$detailName;
1280 $values[$index] = $params[$index] = $details->$detailName;
1284 $detailName = "website-{$id}-{$fieldName}";
1285 $url = CRM_Utils_System
::fixURL($details->$detailName);
1286 if ($details->$detailName) {
1287 $websiteTypeId = "website-{$id}-website_type_id";
1288 $websiteType = $websiteTypes[$details->$websiteTypeId];
1289 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1292 $values[$index] = '';
1297 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1298 CRM_Core_Permission
::check('profile listings and forms')
1301 if (CRM_Utils_System
::isNull($params[$index])) {
1302 $params[$index] = $values[$index];
1304 if (!isset($params[$index])) {
1307 if (!$customFieldName) {
1308 $fieldName = $field['name'];
1311 $fieldName = $customFieldName;
1315 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1316 $htmlType = $field['html_type'];
1317 if ($htmlType == 'Link') {
1318 $url = $params[$index];
1320 elseif (in_array($htmlType, array(
1324 'Multi-Select State/Province',
1325 'Multi-Select Country',
1327 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1328 $selectedOptions = explode($valSeperator, $params[$index]);
1330 foreach ($selectedOptions as $key => $multiOption) {
1332 $url[] = CRM_Utils_System
::url('civicrm/profile',
1333 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1334 urlencode($fieldName) .
1336 urlencode($multiOption)
1342 $url = CRM_Utils_System
::url('civicrm/profile',
1343 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1344 urlencode($fieldName) .
1346 urlencode($params[$index])
1351 $url = CRM_Utils_System
::url('civicrm/profile',
1352 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1353 urlencode($fieldName) .
1355 urlencode($params[$index])
1360 !empty($values[$index]) &&
1364 if (is_array($url) && !empty($url)) {
1366 $eachMultiValue = explode(', ', $values[$index]);
1367 foreach ($eachMultiValue as $key => $valueLabel) {
1368 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1370 $values[$index] = implode(', ', $links);
1373 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1381 * Check if profile Group used by any module.
1389 public static function usedByModule($id) {
1390 //check whether this group is used by any module(check uf join records)
1392 FROM civicrm_uf_join
1393 WHERE civicrm_uf_join.uf_group_id=$id";
1395 $dao = new CRM_Core_DAO();
1397 if ($dao->fetch()) {
1406 * Delete the profile Group.
1414 public static function del($id) {
1415 //check whether this group contains any profile fields
1416 $profileField = new CRM_Core_DAO_UFField();
1417 $profileField->uf_group_id
= $id;
1418 $profileField->find();
1419 while ($profileField->fetch()) {
1420 CRM_Core_BAO_UFField
::del($profileField->id
);
1423 //delete records from uf join table
1424 $ufJoin = new CRM_Core_DAO_UFJoin();
1425 $ufJoin->uf_group_id
= $id;
1428 //delete profile group
1429 $group = new CRM_Core_DAO_UFGroup();
1438 * @param array $params
1439 * Reference array contains the values submitted by the form.
1441 * Reference array contains the id.
1446 public static function add(&$params, $ids = array()) {
1456 foreach ($fields as $field) {
1457 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1460 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1461 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1464 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1465 $params['group_type'] = implode(',', $params['group_type']);
1467 $ufGroup = new CRM_Core_DAO_UFGroup();
1468 $ufGroup->copyValues($params);
1470 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1471 if (!$ufGroupID && empty($params['name'])) {
1472 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1474 $ufGroup->id
= $ufGroupID;
1478 if (!$ufGroupID && empty($params['name'])) {
1479 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1487 * Make uf join entries for an uf group.
1489 * @param array $params
1490 * (reference) an assoc array of name/value pairs.
1491 * @param int $ufGroupId
1494 public static function createUFJoin(&$params, $ufGroupId) {
1495 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1497 // get ufjoin records for uf group
1498 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1500 // get the list of all ufgroup types
1501 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1503 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1504 if (!is_array($groupTypes)) {
1505 $groupTypes = array();
1508 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1509 if (!is_array($ufGroupRecord)) {
1510 $ufGroupRecord = array();
1513 // check which values has to be inserted/deleted for contact
1514 $menuRebuild = FALSE;
1515 foreach ($allUFGroupType as $key => $value) {
1516 $joinParams = array();
1517 $joinParams['uf_group_id'] = $ufGroupId;
1518 $joinParams['module'] = $key;
1519 if ($key == 'User Account') {
1520 $menuRebuild = TRUE;
1522 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1523 // insert a new record
1524 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1526 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1527 // delete a record for existing ufgroup
1528 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1534 UPDATE civicrm_uf_join
1536 WHERE uf_group_id = %2
1537 AND ( entity_id IS NULL OR entity_id <= 0 )
1540 1 => array($params['weight'], 'Integer'),
1541 2 => array($ufGroupId, 'Integer'),
1543 CRM_Core_DAO
::executeQuery($query, $p);
1545 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1547 $config = CRM_Core_Config
::singleton();
1549 $config->userSystem
->is_drupal
1556 * Get the UF Join records for an ufgroup id.
1558 * @param int $ufGroupId
1560 * @param int $displayName
1561 * If set return display name in array.
1562 * @param int $status
1563 * If set return module other than default modules (User Account/User registration/Profile).
1568 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1570 $UFGroupType = array();
1571 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1575 $dao = new CRM_Core_DAO_UFJoin();
1578 $dao->uf_group_id
= $ufGroupId;
1584 while ($dao->fetch()) {
1585 if (!$displayName) {
1586 $ufJoin[$dao->id
] = $dao->module
;
1589 if (isset($UFGroupType[$dao->module
])) {
1590 // skip the default modules
1592 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1594 // added for CRM-1475
1596 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1597 $ufJoin[$dao->id
] = $dao->module
;
1605 * Function takes an associative array and creates a ufjoin record for ufgroup.
1607 * @param array $params
1608 * (reference) an assoc array of name/value pairs.
1610 * @return CRM_Core_BAO_UFJoin
1612 public static function addUFJoin(&$params) {
1613 $ufJoin = new CRM_Core_DAO_UFJoin();
1614 $ufJoin->copyValues($params);
1620 * Delete the uf join record for an uf group.
1622 * @param array $params
1623 * (reference) an assoc array of name/value pairs.
1625 public static function delUFJoin(&$params) {
1626 $ufJoin = new CRM_Core_DAO_UFJoin();
1627 $ufJoin->copyValues($params);
1632 * Get the weight for ufjoin record.
1634 * @param int $ufGroupId
1635 * If $ufGroupId get update weight or add weight.
1638 * weight of the UFGroup
1640 public static function getWeight($ufGroupId = NULL) {
1641 //calculate the weight
1644 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1645 FROM civicrm_uf_join
1646 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1649 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1650 FROM civicrm_uf_join
1651 WHERE civicrm_uf_join.uf_group_id = %1
1652 AND ( entity_id IS NULL OR entity_id <= 0 )";
1653 $p[1] = array($ufGroupId, 'Integer');
1656 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1658 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1662 * Get the uf group for a module.
1664 * @param string $moduleName
1667 * No to increment the weight.
1668 * @param bool $skipPermission
1670 * Which operation (view, edit, create, etc) to check permission for.
1671 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1674 * array of ufgroups for a module
1676 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1677 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1679 if (!CRM_Core_Config
::isUpgradeMode()) {
1680 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1681 $selectFields[] = 'description';
1684 if (!empty($returnFields)) {
1685 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1688 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1689 FROM civicrm_uf_group
1690 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1693 $queryString .= ' AND civicrm_uf_group.is_active = 1
1694 WHERE civicrm_uf_join.module = %2';
1695 $p[2] = array($moduleName, 'String');
1698 // add permissioning for profiles only if not registration
1699 if (!$skipPermission) {
1700 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1701 if (strpos($queryString, 'WHERE') !== FALSE) {
1702 $queryString .= " AND $permissionClause ";
1705 $queryString .= " $permissionClause ";
1709 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1710 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1712 $ufGroups = array();
1713 while ($dao->fetch()) {
1714 //skip mix profiles in user Registration / User Account
1715 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1716 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1720 foreach ($selectFields as $key => $field) {
1721 if ($field == 'id') {
1724 $ufGroups[$dao->id
][$field] = $dao->$field;
1728 // Allow other modules to alter/override the UFGroups.
1729 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1735 * Filter ufgroups based on logged in user contact type.
1737 * @param int $ufGroupId
1738 * Uf group id (profile id).
1739 * @param int $contactID
1744 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1746 $session = CRM_Core_Session
::singleton();
1747 $contactID = $session->get('userID');
1751 //get the contact type
1752 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1754 //match if exixting contact type is same as profile contact type
1755 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1757 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1758 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1761 //allow special mix profiles for Contribution and Participant
1762 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1764 if (in_array($profileType, $specialProfiles)) {
1768 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1777 * Add profile field to a form.
1779 * @param CRM_Core_Form $form
1780 * @param array $field
1784 * @param int $contactId
1785 * @param bool $online
1786 * @param string $usedFor
1787 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1788 * @param int $rowNumber
1789 * @param string $prefix
1793 public static function buildProfile(
1803 $defaultValues = array();
1804 $fieldName = $field['name'];
1805 $title = $field['title'];
1806 $attributes = $field['attributes'];
1807 $rule = $field['rule'];
1808 $view = $field['is_view'];
1809 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1810 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1811 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1813 // do not display view fields in drupal registration form
1815 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1819 if ($usedFor == 'onbehalf') {
1820 $name = "onbehalf[$fieldName]";
1822 elseif ($usedFor == 'honor') {
1823 $name = "honor[$fieldName]";
1825 elseif ($contactId && !$online) {
1826 $name = "field[$contactId][$fieldName]";
1828 elseif ($rowNumber) {
1829 $name = "field[$rowNumber][$fieldName]";
1831 elseif (!empty($prefix)) {
1832 $name = $prefix . "[$fieldName]";
1838 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1840 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1841 $deleteExtra = json_encode(ts('Are you sure you want to delete contact image.'));
1843 CRM_Core_Action
::DELETE
=> array(
1844 'name' => ts('Delete Contact Image'),
1845 'url' => 'civicrm/contact/image',
1846 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1847 'extra' => 'onclick = "' . htmlspecialchars("if (confirm($deleteExtra)) this.href+='&confirmed=1'; else return false;") . '"',
1850 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1851 CRM_Core_Action
::DELETE
,
1853 'id' => $form->get('id'),
1854 'gid' => $form->get('gid'),
1858 'contact.profileimage.delete',
1862 $form->assign('deleteURL', $deleteURL);
1864 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1865 'address_options', TRUE, NULL, TRUE
1868 if (substr($fieldName, 0, 14) === 'state_province') {
1869 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1870 $config = CRM_Core_Config
::singleton();
1871 if (!in_array($mode, array(
1872 CRM_Profile_Form
::MODE_EDIT
,
1873 CRM_Profile_Form
::MODE_SEARCH
,
1875 $config->defaultContactStateProvince
1877 $defaultValues[$name] = $config->defaultContactStateProvince
;
1878 $form->setDefaults($defaultValues);
1881 elseif (substr($fieldName, 0, 7) === 'country') {
1882 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1883 $config = CRM_Core_Config
::singleton();
1884 if (!in_array($mode, array(
1885 CRM_Profile_Form
::MODE_EDIT
,
1886 CRM_Profile_Form
::MODE_SEARCH
,
1888 $config->defaultContactCountry
1890 $defaultValues[$name] = $config->defaultContactCountry
;
1891 $form->setDefaults($defaultValues);
1894 elseif (substr($fieldName, 0, 6) === 'county') {
1895 if ($addressOptions['county']) {
1896 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1899 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1900 $form->add('file', $name, $title, $attributes, $required);
1901 $form->addUploadElement($name);
1903 elseif (substr($fieldName, 0, 2) === 'im') {
1904 $form->add('text', $name, $title, $attributes, $required);
1907 if (substr($name, -1) == ']') {
1908 $providerName = substr($name, 0, -1) . '-provider_id]';
1910 $form->add('select', $providerName, NULL,
1912 '' => ts('- select -'),
1913 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1917 $form->add('select', $name . '-provider_id', $title,
1919 '' => ts('- select -'),
1920 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1924 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1925 $form->freeze($name . '-provider_id');
1929 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1930 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1931 $sel = &$form->addElement('hierselect', $name, $title);
1932 $select = array('' => ts('- select -'));
1933 if (count($orgInfo) == 1 && $field['is_required']) {
1934 // we only have one org - so we should default to it. Not sure about defaulting to first type
1935 // as it could be missed - so adding a select
1936 // however, possibly that is more similar to the membership form
1937 if (count($types[1]) > 1) {
1938 $types[1] = $select +
$types[1];
1942 $orgInfo = $select +
$orgInfo;
1944 $sel->setOptions(array($orgInfo, $types));
1946 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1947 $form->add('select', $name, $title,
1949 '' => ts('- select -'),
1950 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1953 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1955 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1956 foreach ($pseudoValues as $key => $var) {
1957 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1959 $group = $form->addGroup($options, $name, $title);
1961 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1964 $group->setAttribute('allowClear', TRUE);
1967 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1968 $form->addSelect($name, array(
1970 'entity' => 'contact',
1971 'field' => $fieldName,
1973 'placeholder' => '',
1976 elseif ($fieldName === 'contact_sub_type') {
1977 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1978 if ($usedFor == 'onbehalf') {
1979 $profileType = 'Organization';
1981 elseif ($usedFor == 'honor') {
1982 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1985 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1986 if ($profileType == 'Contact') {
1987 $profileType = 'Individual';
1991 $setSubtype = FALSE;
1992 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1993 $setSubtype = $profileType;
1994 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1997 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2000 $subtypeList = array();
2001 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2004 $subtypeList = $subtypes;
2007 $form->add('select', $name, $title, $subtypeList, $required, array('class' => 'crm-select2', 'multiple' => TRUE));
2009 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2010 //add email greeting, postal greeting, addressee, CRM-4575
2011 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2012 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2014 if (empty($profileType) ||
in_array($profileType, array(
2021 $profileType = 'Individual';
2023 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2024 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2027 'contact_type' => $profileType,
2028 'greeting_type' => $fieldName,
2030 $form->add('select', $name, $title,
2032 '' => ts('- select -'),
2033 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2035 // add custom greeting element
2036 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2040 elseif ($fieldName === 'preferred_communication_method') {
2041 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2042 foreach ($communicationFields as $key => $var) {
2046 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2048 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2050 elseif ($fieldName === 'preferred_mail_format') {
2051 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2053 elseif ($fieldName === 'preferred_language') {
2054 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2056 elseif ($fieldName == 'external_identifier') {
2057 $form->add('text', $name, $title, $attributes, $required);
2058 $contID = $contactId;
2060 $contID = $form->get('id');
2062 $form->addRule($name,
2063 ts('External ID already exists in Database.'),
2065 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2068 elseif ($fieldName === 'group') {
2069 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2070 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2075 elseif ($fieldName === 'tag') {
2076 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2077 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2082 elseif (substr($fieldName, 0, 4) === 'url-') {
2083 $form->add('text', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'), $required);
2084 $form->addRule($name, ts('Enter a valid web address beginning with \'http://\' or \'https://\'.'), 'url');
2086 // Note should be rendered as textarea
2087 elseif (substr($fieldName, -4) == 'note') {
2088 $form->add('textarea', $name, $title, $attributes, $required);
2090 elseif (substr($fieldName, 0, 6) === 'custom') {
2091 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2092 if ($customFieldID) {
2093 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
2096 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2097 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2098 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2099 if ($customFieldID) {
2100 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
2103 elseif ($fieldName == 'send_receipt') {
2104 $form->addElement('checkbox', $name, $title);
2106 elseif ($fieldName == 'soft_credit') {
2107 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2108 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2110 elseif ($fieldName == 'product_name') {
2111 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2112 $sel = &$form->addElement('hierselect', $name, $title);
2114 '0' => ts('- select -'),
2116 $sel->setOptions(array($products, $options));
2118 elseif ($fieldName == 'payment_instrument') {
2119 $form->add('select', $name, $title,
2120 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2122 elseif ($fieldName == 'financial_type') {
2123 $form->add('select', $name, $title,
2125 '' => ts('- select -'),
2126 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2129 elseif ($fieldName == 'contribution_status_id') {
2130 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2131 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2137 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2140 $form->add('select', $name, $title,
2142 '' => ts('- select -'),
2143 ) +
$contributionStatuses, $required
2146 elseif ($fieldName == 'soft_credit_type') {
2147 $name = "soft_credit_type[$rowNumber]";
2148 $form->add('select', $name, $title,
2150 '' => ts('- select -'),
2151 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2153 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2154 //else (for contribution), use configured SCT default value
2155 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2156 if ($field['field_type'] == 'Membership') {
2157 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2159 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2161 elseif ($fieldName == 'contribution_soft_credit_pcp_id') {
2162 CRM_Contribute_Form_SoftCredit
::addPCPFields($form, "[$rowNumber]");
2164 elseif ($fieldName == 'currency') {
2165 $form->addCurrency($name, $title, $required, NULL, FALSE, FALSE);
2167 elseif ($fieldName == 'contribution_page_id') {
2168 $form->add('select', $name, $title,
2170 '' => ts('- select -'),
2171 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2174 elseif ($fieldName == 'activity_status_id') {
2175 $form->add('select', $name, $title,
2177 '' => ts('- select -'),
2178 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2181 elseif ($fieldName == 'activity_engagement_level') {
2182 $form->add('select', $name, $title,
2184 '' => ts('- select -'),
2185 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2188 elseif ($fieldName == 'participant_status') {
2190 if ($online == TRUE) {
2191 $cond = 'visibility_id = 1';
2193 $form->add('select', $name, $title,
2195 '' => ts('- select -'),
2196 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2199 elseif ($fieldName == 'participant_role') {
2200 if (!empty($field['is_multiple'])) {
2201 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2204 $form->add('select', $name, $title,
2206 '' => ts('- select -'),
2207 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2211 elseif ($fieldName == 'world_region') {
2212 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2214 elseif ($fieldName == 'signature_html') {
2215 $form->add('wysiwyg', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2217 elseif ($fieldName == 'signature_text') {
2218 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2220 elseif (substr($fieldName, -11) == 'campaign_id') {
2221 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2222 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2223 $form->_componentCampaigns
2225 $form->add('select', $name, $title,
2227 '' => ts('- select -'),
2228 ) +
$campaigns, $required, 'class="crm-select2 big"'
2232 elseif ($fieldName == 'activity_details') {
2233 $form->add('wysiwyg', $fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2235 elseif ($fieldName == 'activity_duration') {
2236 $form->add('text', $name, $title, $attributes, $required);
2237 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2240 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2241 $form->add('advcheckbox', $name, $title, $attributes, $required);
2243 elseif (CRM_Utils_Array
::value('html_type', $field) === 'Select Date') {
2244 $extra = isset($field['datepicker']) ?
$field['datepicker']['extra'] : CRM_Utils_Date
::getDatePickerExtra($field);
2245 $attributes = isset($field['datepicker']) ?
$field['datepicker']['attributes'] : CRM_Utils_Date
::getDatePickerAttributes($field);
2246 $form->add('datepicker', $name, $title, $attributes, $required, $extra);
2249 $form->add('text', $name, $title, $attributes, $required);
2253 static $hiddenSubtype = FALSE;
2254 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2255 // In registration mode params are submitted via POST and we don't have any clue
2256 // about profile-id or the profile-type (which could be a subtype)
2257 // To generalize the behavior and simplify the process,
2258 // lets always add the hidden
2259 //subtype value if there is any, and we won't have to
2260 // compute it while processing.
2262 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2265 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2267 $hiddenSubtype = TRUE;
2270 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2271 $form->freeze($name);
2275 if (in_array($fieldName, array(
2276 'non_deductible_amount',
2281 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2284 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2285 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2291 * Set profile defaults.
2293 * @param int $contactId
2295 * @param array $fields
2296 * Associative array of fields.
2297 * @param array $defaults
2299 * @param bool $singleProfile
2300 * True for single profile else false(Update multiple items).
2301 * @param int $componentId
2302 * Id for specific components like contribute, event etc.
2303 * @param null $component
2305 public static function setProfileDefaults(
2306 $contactId, &$fields, &$defaults,
2307 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2309 if (!$componentId) {
2310 //get the contact details
2311 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2312 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2313 $multipleFields = array('website' => 'url');
2315 //start of code to set the default values
2316 foreach ($fields as $name => $field) {
2317 // skip pseudo fields
2318 if (substr($name, 0, 9) == 'phone_ext') {
2322 //set the field name depending upon the profile mode(single/multiple)
2323 if ($singleProfile) {
2327 $fldName = "field[$contactId][$name]";
2330 if ($name == 'group') {
2331 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2333 if ($name == 'tag') {
2334 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2337 if (!empty($details[$name]) ||
isset($details[$name])) {
2338 //to handle custom data (checkbox) to be written
2339 // to handle birth/deceased date, greeting_type and few other fields
2340 if (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2341 $defaults[$fldName] = $details[$name . '_id'];
2342 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2344 elseif ($name == 'preferred_communication_method') {
2345 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2346 foreach ($v as $item) {
2348 $defaults[$fldName . "[$item]"] = 1;
2352 elseif ($name == 'contact_sub_type') {
2353 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2355 elseif ($name == 'world_region') {
2356 $defaults[$fldName] = $details['worldregion_id'];
2358 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2359 // @todo retrieving the custom fields here seems obsolete - $field holds more data for the fields.
2360 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2362 // hack to add custom data for components
2363 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2364 foreach ($components as $value) {
2365 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2366 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2370 switch ($customFields[$customFieldId]['html_type']) {
2371 case 'Multi-Select State/Province':
2372 case 'Multi-Select Country':
2373 case 'AdvMulti-Select':
2374 case 'Multi-Select':
2375 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2376 foreach ($v as $item) {
2378 $defaults[$fldName][$item] = $item;
2384 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2385 foreach ($v as $item) {
2387 $defaults[$fldName][$item] = 1;
2388 // seems like we need this for QF style checkboxes in profile where its multiindexed
2390 $defaults["{$fldName}[{$item}]"] = 1;
2396 $defaults[$fldName] = $details[$name];
2401 $defaults[$fldName] = $details[$name];
2405 $blocks = array('email', 'phone', 'im', 'openid');
2406 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2407 if (!in_array($fieldName, $multipleFields)) {
2408 if (is_array($details)) {
2409 foreach ($details as $key => $value) {
2410 // when we fixed CRM-5319 - get primary loc
2411 // type as per loc field and removed below code.
2412 $primaryLocationType = FALSE;
2413 if ($locTypeId == 'Primary') {
2414 if (is_array($value) && array_key_exists($fieldName, $value)) {
2415 $primaryLocationType = TRUE;
2416 if (in_array($fieldName, $blocks)) {
2417 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2420 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2425 // fixed for CRM-665
2426 if (is_numeric($locTypeId)) {
2427 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2428 if (!empty($value[$fieldName])) {
2429 //to handle stateprovince and country
2430 if ($fieldName == 'state_province') {
2431 $defaults[$fldName] = $value['state_province_id'];
2433 elseif ($fieldName == 'county') {
2434 $defaults[$fldName] = $value['county_id'];
2436 elseif ($fieldName == 'country') {
2437 if (!isset($value['country_id']) ||
!$value['country_id']) {
2438 $config = CRM_Core_Config
::singleton();
2439 if ($config->defaultContactCountry
) {
2440 $defaults[$fldName] = $config->defaultContactCountry
;
2444 $defaults[$fldName] = $value['country_id'];
2447 elseif ($fieldName == 'phone') {
2449 if (isset($value['phone'][$phoneTypeId])) {
2450 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2452 if (isset($value['phone_ext'][$phoneTypeId])) {
2453 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2457 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2459 if (!is_array($phoneDefault)) {
2460 $defaults[$fldName] = $phoneDefault;
2464 elseif ($fieldName == 'email') {
2465 //adding the first email (currently we don't support multiple emails of same location type)
2466 $defaults[$fldName] = $value['email'];
2468 elseif ($fieldName == 'im') {
2469 //adding the first im (currently we don't support multiple ims of same location type)
2470 $defaults[$fldName] = $value['im'];
2471 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2474 $defaults[$fldName] = $value[$fieldName];
2477 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2478 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2480 $defaults[$fldName] = $value[substr($fieldName, 8)];
2488 if (is_array($details)) {
2489 if ($fieldName === 'url'
2490 && !empty($details['website'])
2491 && !empty($details['website'][$locTypeId])
2493 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2501 //Handling Contribution Part of the batch profile
2502 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2503 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2506 //Handling Event Participation Part of the batch profile
2507 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2508 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2511 //Handling membership Part of the batch profile
2512 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2513 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2516 //Handling Activity Part of the batch profile
2517 if ($component == 'Activity') {
2518 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2523 * Get profiles by type eg: pure Individual etc
2525 * @param array $types
2526 * Associative array of types eg: types('Individual').
2527 * @param bool $onlyPure
2528 * True if only pure profiles are required.
2531 * associative array of profiles
2533 public static function getProfiles($types, $onlyPure = FALSE) {
2534 $profiles = array();
2535 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2537 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2539 // Exclude Batch Data Entry profiles - CRM-10901
2540 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2542 foreach ($ufGroups as $id => $title) {
2543 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2544 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2545 $profiles[$id] = $title;
2552 * Check whether a profile is valid combination of
2553 * required and/or optional profile types
2555 * @param array $required
2556 * Array of types those are required.
2557 * @param array $optional
2558 * Array of types those are optional.
2561 * associative array of profiles
2563 public static function getValidProfiles($required, $optional = NULL) {
2564 if (!is_array($required) ||
empty($required)) {
2568 $profiles = array();
2569 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2571 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2573 foreach ($ufGroups as $id => $title) {
2574 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2576 $profiles[$id] = $title;
2584 * Check whether a profile is valid combination of
2585 * required profile fields
2587 * @param array $ufId
2588 * Integer id of the profile.
2589 * @param array $required
2590 * Array of fields those are required in the profile.
2593 * associative array of profiles
2595 public static function checkValidProfile($ufId, $required = NULL) {
2596 $validProfile = FALSE;
2598 return $validProfile;
2601 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2602 return $validProfile;
2605 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2606 NULL, FALSE, NULL, FALSE, NULL,
2607 CRM_Core_Permission
::CREATE
, NULL
2610 $validProfile = array();
2611 if (!empty($profileFields)) {
2612 $fields = array_keys($profileFields);
2613 foreach ($fields as $val) {
2614 foreach ($required as $key => $field) {
2615 if (strpos($val, $field) === 0) {
2616 unset($required[$key]);
2621 $validProfile = (empty($required)) ?
TRUE : FALSE;
2624 return $validProfile;
2628 * Get default value for Register.
2630 * @param array $fields
2631 * @param array $defaults
2635 public static function setRegisterDefaults(&$fields, &$defaults) {
2636 $config = CRM_Core_Config
::singleton();
2637 foreach ($fields as $name => $field) {
2638 if (substr($name, 0, 8) == 'country-') {
2639 if (!empty($config->defaultContactCountry
)) {
2640 $defaults[$name] = $config->defaultContactCountry
;
2643 elseif (substr($name, 0, 15) == 'state_province-') {
2644 if (!empty($config->defaultContactStateProvince
)) {
2645 $defaults[$name] = $config->defaultContactStateProvince
;
2653 * make a copy of a profile, including
2654 * all the fields in the profile
2657 * The profile id to copy.
2659 * @return \CRM_Core_DAO
2661 public static function copy($id) {
2662 $maxId = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_uf_group");
2664 $title = ts('[Copy id %1]', array(1 => $maxId +
1));
2667 'title' => ' ' . $title,
2668 'name' => '__Copy_id_' . ($maxId +
1) . '_',
2672 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2678 if ($pos = strrpos($copy->name
, "_{$id}")) {
2679 $copy->name
= substr_replace($copy->name
, '', $pos);
2681 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2684 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2685 array('uf_group_id' => $id),
2686 array('uf_group_id' => $copy->id
),
2691 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2692 array('uf_group_id' => $id),
2693 array('uf_group_id' => $copy->id
)
2696 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2700 UPDATE civicrm_uf_join
2702 WHERE uf_group_id = %2
2703 AND ( entity_id IS NULL OR entity_id <= 0 )
2706 1 => array($maxWeight +
1, 'Integer'),
2707 2 => array($copy->id
, 'Integer'),
2709 CRM_Core_DAO
::executeQuery($query, $p);
2710 if ($copy->is_reserved
) {
2711 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2712 $params = array(1 => array($copy->id
, 'Integer'));
2713 CRM_Core_DAO
::executeQuery($query, $params);
2715 CRM_Utils_Hook
::copy('UFGroup', $copy);
2721 * Process that send notification e-mails
2723 * @param int $contactID
2725 * @param array $values
2726 * Associative array of name/value pair.
2728 public static function commonSendMail($contactID, &$values) {
2729 if (!$contactID ||
!$values) {
2733 $template = CRM_Core_Smarty
::singleton();
2735 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2740 self
::profileDisplay($values['id'], $values['values'], $template);
2741 $emailList = explode(',', $values['email']);
2743 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2744 "reset=1&cid=$contactID",
2745 TRUE, NULL, FALSE, FALSE, TRUE
2748 //get the default domain email address.
2749 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2751 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2752 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2753 CRM_Core_Error
::fatal(ts('The site administrator needs to enter a valid \'FROM Email Address\' in <a href="%1">Administer CiviCRM » Communications » FROM Email Addresses</a>. The email address used may need to be a valid mail account with your email service provider.', array(1 => $fixUrl)));
2756 foreach ($emailList as $emailTo) {
2757 // FIXME: take the below out of the foreach loop
2758 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2760 'groupName' => 'msg_tpl_workflow_uf',
2761 'valueName' => 'uf_notify',
2762 'contactId' => $contactID,
2763 'tplParams' => array(
2764 'displayName' => $displayName,
2765 'currentDate' => date('r'),
2766 'contactLink' => $contactLink,
2768 'from' => "$domainEmailName <$domainEmailAddress>",
2769 'toEmail' => $emailTo,
2776 * Given a contact id and a group id, returns the field values from the db
2777 * for this group and notify email only if group's notify field is
2778 * set and field values are not empty
2784 * @param array $params
2785 * @param bool $skipCheck
2789 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2791 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2793 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2794 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2796 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2798 if (!empty($values) &&
2803 'values' => $values,
2814 * Assign uf fields to template.
2818 * @param array $values
2819 * @param CRM_Core_Smarty $template
2821 static public function profileDisplay($gid, $values, $template) {
2822 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2823 $template->assign('grouptitle', $groupTitle);
2824 if (count($values)) {
2825 $template->assign('values', $values);
2830 * Format fields for dupe Contact Matching.
2832 * @param array $params
2834 * @param int $contactId
2837 * associated formatted array
2839 public static function formatFields($params, $contactId = NULL) {
2841 // get the primary location type id and email
2842 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2845 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2846 $primaryLocationType = $defaultLocationType->id
;
2850 $locationType = array();
2852 $primaryLocation = 0;
2853 foreach ($params as $key => $value) {
2854 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2856 if ($locTypeId == 'Primary') {
2857 $locTypeId = $primaryLocationType;
2860 if (is_numeric($locTypeId)) {
2861 if (!in_array($locTypeId, $locationType)) {
2862 $locationType[$count] = $locTypeId;
2865 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2867 $data['location'][$loc]['location_type_id'] = $locTypeId;
2869 // if we are getting in a new primary email, dont overwrite the new one
2870 if ($locTypeId == $primaryLocationType) {
2871 if (!empty($params['email-' . $primaryLocationType])) {
2872 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2874 elseif (isset($primaryEmail)) {
2875 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2881 $data['location'][$loc]['is_primary'] = 1;
2883 if ($fieldName == 'phone') {
2885 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2888 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2890 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2892 elseif ($fieldName == 'email') {
2893 $data['location'][$loc]['email'][$loc]['email'] = $value;
2895 elseif ($fieldName == 'im') {
2896 $data['location'][$loc]['im'][$loc]['name'] = $value;
2899 if ($fieldName === 'state_province') {
2900 $data['location'][$loc]['address']['state_province_id'] = $value;
2902 elseif ($fieldName === 'country') {
2903 $data['location'][$loc]['address']['country_id'] = $value;
2906 $data['location'][$loc]['address'][$fieldName] = $value;
2911 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2912 if ($key === 'individual_suffix') {
2913 $data['suffix_id'] = $value;
2915 elseif ($key === 'individual_prefix') {
2916 $data['prefix_id'] = $value;
2918 elseif ($key === 'gender') {
2919 $data['gender_id'] = $value;
2921 elseif (substr($key, 0, 6) === 'custom') {
2922 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2924 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2925 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2927 // fix the date field
2928 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2929 $date = CRM_Utils_Date
::format($value);
2936 $data['custom'][$customFieldID] = array(
2939 'extends' => $customFields[$customFieldID]['extends'],
2940 'type' => $customFields[$customFieldID]['data_type'],
2941 'custom_field_id' => $customFieldID,
2945 elseif ($key == 'edit') {
2949 $data[$key] = $value;
2954 if (!$primaryLocation) {
2956 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2963 * Calculate the profile type 'group_type' as per profile fields.
2967 * @param bool $includeTypeValues
2968 * @param int $ignoreFieldId
2969 * Ignore particular profile field.
2972 * list of calculated group type
2974 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2975 //get the profile fields.
2976 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2977 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2981 * Calculate the profile type 'group_type' as per profile fields.
2984 * @param bool $includeTypeValues
2985 * @param int $ignoreFieldId
2986 * Ignore perticular profile field.
2989 * list of calculated group type
2991 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2992 $groupType = $groupTypeValues = $customFieldIds = array();
2993 if (!empty($ufFields)) {
2994 foreach ($ufFields as $fieldName => $fieldValue) {
2995 //ignore field from group type when provided.
2996 //in case of update profile field.
2997 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3000 if (!in_array($fieldValue['field_type'], $groupType)) {
3001 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3004 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3005 $customFieldIds[$fldId] = $fldId;
3010 if (!empty($customFieldIds)) {
3011 $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) . ')';
3013 $customGroups = CRM_Core_DAO
::executeQuery($query);
3014 while ($customGroups->fetch()) {
3015 if (!$customGroups->extends_entity_column_value
) {
3019 $groupTypeName = "{$customGroups->extends}Type";
3020 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3021 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3024 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3026 $groupTypeValues[$groupTypeName][$val] = $val;
3031 if (!empty($groupTypeValues)) {
3032 $groupType = array_merge($groupType, $groupTypeValues);
3040 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3041 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3044 * BirthDate + Email Individual,Contact
3045 * BirthDate + Subject Individual,Activity
3046 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3047 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3048 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3049 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3050 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3051 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3052 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3055 * @param array $groupTypes
3056 * With key having group type names.
3060 public static function updateGroupTypes($gId, $groupTypes = array()) {
3061 if (!is_array($groupTypes) ||
!$gId) {
3065 // If empty group types set group_type as 'null'
3066 if (empty($groupTypes)) {
3067 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3070 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3071 $validGroupTypes = array_merge(array(
3076 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3078 $gTypes = $gTypeValues = array();
3080 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3081 // Get valid group type and group subtypes
3082 foreach ($groupTypes as $groupType => $value) {
3083 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3084 $gTypes[] = $groupType;
3089 if (in_array($groupType, $participantExtends)) {
3090 $subTypesOf = $groupType;
3092 elseif (strpos($groupType, 'Type') > 0) {
3093 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3099 if (!empty($value) &&
3100 (in_array($subTypesOf, $componentGroupTypes) ||
3101 in_array($subTypesOf, $participantExtends)
3104 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3108 if (empty($gTypes)) {
3112 // Build String to store group types and group subtypes
3113 $groupTypeString = implode(',', $gTypes);
3114 if (!empty($gTypeValues)) {
3115 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3118 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3122 * Create a "group_type" string.
3124 * @param array $coreTypes
3125 * E.g. array('Individual','Contact','Student').
3126 * @param array $subTypes
3127 * E.g. array('ActivityType' => array(7, 11)).
3128 * @param string $delim
3131 * @throws CRM_Core_Exception
3133 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3134 $groupTypeExpr = '';
3136 $groupTypeExpr .= implode(',', $coreTypes);
3139 //CRM-15427 Allow Multiple subtype filtering
3140 //if (count($subTypes) > 1) {
3141 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3143 foreach ($subTypes as $subType => $subTypeIds) {
3144 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3147 return $groupTypeExpr;
3151 * setDefault componet specific profile fields.
3153 * @param array $fields
3155 * @param int $componentId
3157 * @param string $component
3159 * @param array $defaults
3160 * An array of default values.
3162 * @param bool $isStandalone
3164 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3165 if (!$componentId ||
3166 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3171 $componentBAO = $componentSubType = NULL;
3172 switch ($component) {
3174 $componentBAO = 'CRM_Member_BAO_Membership';
3175 $componentBAOName = 'Membership';
3176 $componentSubType = array('membership_type_id');
3180 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3181 $componentBAOName = 'Contribution';
3182 $componentSubType = array('financial_type_id');
3186 $componentBAO = 'CRM_Event_BAO_Participant';
3187 $componentBAOName = 'Participant';
3188 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3192 $componentBAO = 'CRM_Activity_BAO_Activity';
3193 $componentBAOName = 'Activity';
3194 $componentSubType = array('activity_type_id');
3199 $params = array('id' => $componentId);
3201 //get the component values.
3202 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3203 if ($componentBAOName == 'Participant') {
3204 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3207 $formattedGroupTree = array();
3209 foreach ($fields as $name => $field) {
3210 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3211 if (array_key_exists($name, $values)) {
3212 $defaults[$fldName] = $values[$name];
3214 elseif ($name == 'participant_note') {
3215 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3216 $defaults[$fldName] = array_pop($noteDetails);
3218 elseif (in_array($name, array(
3220 'payment_instrument',
3221 'participant_status',
3224 $defaults[$fldName] = $values["{$name}_id"];
3226 elseif ($name == 'membership_type') {
3227 // since membership_type field is a hierselect -
3228 $defaults[$fldName][0]
3229 = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3230 $defaults[$fldName][1] = $values['membership_type_id'];
3232 elseif ($name == 'membership_status') {
3233 $defaults[$fldName] = $values['status_id'];
3235 elseif (CRM_Core_BAO_CustomField
::getKeyID($name, TRUE) !== array(NULL, NULL)) {
3236 if (empty($formattedGroupTree)) {
3237 //get the groupTree as per subTypes.
3238 $groupTree = array();
3239 foreach ($componentSubType as $subType) {
3240 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, NULL,
3241 $componentId, 0, $values[$subType]
3243 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3245 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1);
3246 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3249 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3250 foreach ($defaults as $customKey => $customValue) {
3251 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3252 if ($name == 'custom_' . $customFieldDetails[0]) {
3254 //hack to set default for checkbox
3255 //basically this is for weired field name like field[33][custom_19]
3256 //we are converting this field name to array structure and assign value.
3259 foreach ($formattedGroupTree as $tree) {
3260 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3261 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3263 $defaults['field'][$componentId][$name] = $customValue;
3266 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3269 // CRM-6681, $default contains formatted date, time values.
3270 $defaults[$fldName] = $customValue;
3271 if (!empty($defaults[$customKey . '_time'])) {
3272 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3278 if (!$skipValue ||
$isStandalone) {
3279 $defaults[$fldName] = $customValue;
3281 unset($defaults[$customKey]);
3287 elseif (isset($values[$fldName])) {
3288 $defaults[$fldName] = $values[$fldName];
3294 * @param array|string $profiles - name of profile(s) to create links for
3295 * @param array $appendProfiles
3296 * Name of profile(s) to append to each link.
3300 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3301 // Default to contact profiles
3303 $profiles = array('new_individual', 'new_organization', 'new_household');
3305 $profiles = (array) $profiles;
3306 $toGet = array_merge($profiles, (array) $appendProfiles);
3307 $retrieved = civicrm_api3('uf_group', 'get', array(
3308 'name' => array('IN' => $toGet),
3311 $links = $append = array();
3312 if (!empty($retrieved['values'])) {
3313 foreach ($retrieved['values'] as $id => $profile) {
3314 if (in_array($profile['name'], $profiles)) {
3316 'label' => $profile['title'],
3317 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3318 NULL, NULL, FALSE, FALSE, TRUE),
3319 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3326 foreach ($append as $id) {
3327 foreach ($links as &$link) {
3328 $link['url'] .= ",$id";
3336 * Retrieve groups of profiles.
3338 * @param int $profileID
3339 * Id of the profile.
3344 public static function profileGroups($profileID) {
3345 $groupTypes = array();
3346 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3347 if ($profileTypes) {
3348 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3349 $groupTypes = explode(',', $groupTypeParts[0]);
3355 * Alter contact params by filtering existing subscribed groups and returns
3356 * unsubscribed groups array for subscription.
3358 * @param array $params
3360 * @param int $contactId
3364 * This contains array of groups for subscription
3366 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3367 $config = CRM_Core_Config
::singleton();
3368 $subscribeGroupIds = array();
3370 // process further only if profileDoubleOptIn enabled and if groups exist
3371 if (!array_key_exists('group', $params) ||
3372 !self
::isProfileDoubleOptin() ||
3373 CRM_Utils_System
::isNull($params['group'])
3375 return $subscribeGroupIds;
3378 //check if contact email exist.
3380 foreach ($params as $name => $value) {
3381 if (strpos($name, 'email-') !== FALSE) {
3387 //Proceed furthur only if email present
3389 return $subscribeGroupIds;
3392 //do check for already subscriptions.
3393 $contactGroups = array();
3397 FROM civicrm_group_contact
3398 WHERE status = 'Added'
3399 AND contact_id = %1";
3401 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3402 while ($dao->fetch()) {
3403 $contactGroups[$dao->group_id
] = $dao->group_id
;
3407 //since we don't have names, compare w/ label.
3408 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3410 //actual processing start.
3411 foreach ($params['group'] as $groupId => $isSelected) {
3412 //unset group those are not selected.
3414 unset($params['group'][$groupId]);
3418 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3419 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3421 //get only mailing type group and unset it from params
3422 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3423 $subscribeGroupIds[$groupId] = $groupId;
3424 unset($params['group'][$groupId]);
3428 return $subscribeGroupIds;
3432 * Check if we are rendering mixed profiles.
3434 * @param array $profileIds
3435 * Associated array of profile ids.
3438 * true if profile is mixed
3440 public static function checkForMixProfiles($profileIds) {
3441 $mixProfile = FALSE;
3443 $contactTypes = array('Individual', 'Household', 'Organization');
3444 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3446 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3448 $typeCount = array('ctype' => array(), 'subtype' => array());
3449 foreach ($profileIds as $gid) {
3450 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3451 // ignore profile of type Contact
3452 if ($profileType == 'Contact') {
3455 if (in_array($profileType, $contactTypes)) {
3456 if (!isset($typeCount['ctype'][$profileType])) {
3457 $typeCount['ctype'][$profileType] = 1;
3460 // check if we are rendering profile of different contact types
3461 if (count($typeCount['ctype']) == 2) {
3466 elseif (in_array($profileType, $components)) {
3471 if (!isset($typeCount['subtype'][$profileType])) {
3472 $typeCount['subtype'][$profileType] = 1;
3474 // check if we are rendering profile of different contact sub types
3475 if (count($typeCount['subtype']) == 2) {
3485 * Determine of we show overlay profile or not.
3488 * true if profile should be shown else false
3490 public static function showOverlayProfile() {
3491 $showOverlay = TRUE;
3493 // get the id of overlay profile
3494 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3495 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3497 $count = CRM_Core_DAO
::singleValueQuery($query);
3499 //check if there are no public fields and use is anonymous
3500 $session = CRM_Core_Session
::singleton();
3501 if (!$count && !$session->get('userID')) {
3502 $showOverlay = FALSE;
3505 return $showOverlay;
3509 * Get group type values of the profile.
3511 * @param int $profileId
3512 * @param string $groupType
3517 public static function groupTypeValues($profileId, $groupType = NULL) {
3518 $groupTypeValue = array();
3519 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3521 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3522 if (empty($groupTypeParts[1])) {
3523 return $groupTypeValue;
3525 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3527 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3529 $valueParts = explode(':', $groupTypeValues);
3531 ($valueParts[0] != "{$groupType}Type" ||
3532 ($groupType == 'Participant' &&
3533 !in_array($valueParts[0], $participantExtends)
3539 foreach ($valueParts as $val) {
3540 if (CRM_Utils_Rule
::integer($val)) {
3541 $values[$val] = $val;
3544 if (!empty($values)) {
3545 $typeName = substr($valueParts[0], 0, -4);
3546 if (in_array($valueParts[0], $participantExtends)) {
3547 $typeName = $valueParts[0];
3549 $groupTypeValue[$typeName] = $values;
3553 return $groupTypeValue;
3557 * @return bool|object
3559 public static function isProfileDoubleOptin() {
3560 // check for double optin
3561 $config = CRM_Core_Config
::singleton();
3562 if (in_array('CiviMail', $config->enableComponents
)) {
3563 return Civi
::settings()->get('profile_double_optin');
3569 * @return bool|object
3571 public static function isProfileAddToGroupDoubleOptin() {
3572 // check for add to group double optin
3573 $config = CRM_Core_Config
::singleton();
3574 if (in_array('CiviMail', $config->enableComponents
)) {
3575 return Civi
::settings()->get('profile_add_to_group_double_optin');
3581 * Get profiles used for batch entry.
3584 * profileIds profile ids
3586 public static function getBatchProfiles() {
3588 FROM civicrm_uf_group
3589 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3590 $dao = CRM_Core_DAO
::executeQuery($query);
3591 $profileIds = array();
3592 while ($dao->fetch()) {
3593 $profileIds[$dao->id
] = $dao->id
;
3599 * @todo what do I do?
3601 * @param $destination
3602 * @param bool $returnMultiSummaryFields
3604 * @return array|null
3606 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3607 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3608 foreach ($source as $field => $properties) {
3609 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3612 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3613 $destination[$field] = $properties;
3614 if ($returnMultiSummaryFields) {
3615 if ($properties['is_multi_summary']) {
3616 $multiSummaryFields[$field] = $properties;
3619 unset($source[$field]);
3622 return $multiSummaryFields;
3626 * This is function is used to format pseudo fields.
3628 * @param array $fields
3629 * Associated array of profile fields.
3632 public static function reformatProfileFields(&$fields) {
3633 //reformat fields array
3634 foreach ($fields as $name => $field) {
3635 //reformat phone and extension field
3636 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3637 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3639 // retain existing element properties and just update and replace key
3640 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3641 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3642 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3644 // add additional phone extension field
3645 $fields["phone_ext-{$fieldSuffix}"] = $field;
3646 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3647 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3648 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3649 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3650 //ignore required for extension field
3651 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;