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 'groupDisplayTitle' => (!empty($group->frontend_title
)) ?
$group->frontend_title
: $group->title
,
488 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
489 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
491 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
492 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
493 'is_required' => $field->is_required
,
494 'is_view' => $field->is_view
,
495 'help_pre' => $field->help_pre
,
496 'help_post' => $field->help_post
,
497 'visibility' => $field->visibility
,
498 'in_selector' => $field->in_selector
,
499 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
500 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
501 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
502 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
503 'group_id' => $group->id
,
504 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
505 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
506 'field_type' => $field->field_type
,
507 'field_id' => $field->id
,
508 'pseudoconstant' => CRM_Utils_Array
::value(
510 CRM_Utils_Array
::value($field->field_name
, $importableFields)
512 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
513 'dbName' => CRM_Utils_Array
::value(
515 CRM_Utils_Array
::value($field->field_name
, $importableFields)
518 'data_type' => CRM_Utils_Type
::getDataTypeFromFieldMetadata($fieldMetaData),
519 'bao' => CRM_Utils_Array
::value('bao', $fieldMetaData),
522 $formattedField = CRM_Utils_Date
::addDateMetadataToField($fieldMetaData, $formattedField);
524 //adding custom field property
525 if (substr($field->field_name
, 0, 6) == 'custom' ||
526 substr($field->field_name
, 0, 14) === 'address_custom'
528 // if field is not present in customFields, that means the user
529 // DOES NOT HAVE permission to access that field
530 if (array_key_exists($field->field_name
, $customFields)) {
531 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
533 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
534 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
536 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
537 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
538 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
539 $formattedField['is_datetime_field'] = TRUE;
540 $formattedField['smarty_view_format'] = CRM_Utils_Date
::getDateFieldViewFormat($formattedField['date_format']);
543 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
544 return array($name, $formattedField);
547 $formattedField = NULL;
548 return array($name, $formattedField);
551 return array($name, $formattedField);
555 * Create a query to find all visible UFFields in a UFGroup.
557 * This is the SQL-variant of checkUFFieldDisplayable().
559 * @param int $groupId
560 * @param bool $searchable
561 * @param bool $showAll
562 * @param int $visibility
563 * @param string $orderBy
564 * Comma-delimited list of SQL columns.
567 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
568 $where = " WHERE uf_group_id = {$groupId}";
571 $where .= " AND is_searchable = 1";
575 $where .= " AND is_active = 1";
580 if ($visibility & self
::PUBLIC_VISIBILITY
) {
581 $clause[] = 'visibility = "Public Pages"';
583 if ($visibility & self
::ADMIN_VISIBILITY
) {
584 $clause[] = 'visibility = "User and User Admin Only"';
586 if ($visibility & self
::LISTINGS_VISIBILITY
) {
587 $clause[] = 'visibility = "Public Pages and Listings"';
589 if (!empty($clause)) {
590 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
594 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
596 $query .= ", " . $orderBy;
603 * Create a query to find all visible UFFields in a UFGroup.
605 * This is the PHP in-memory variant of createUFFieldQuery().
607 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
608 * @param bool $searchable
609 * @param bool $showAll
610 * @param int $visibility
612 * TRUE if field is displayable
614 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
615 if ($searchable && $field->is_searchable
!= 1) {
619 if (!$showAll && $field->is_active
!= 1) {
624 $allowedVisibilities = array();
625 if ($visibility & self
::PUBLIC_VISIBILITY
) {
626 $allowedVisibilities[] = 'Public Pages';
628 if ($visibility & self
::ADMIN_VISIBILITY
) {
629 $allowedVisibilities[] = 'User and User Admin Only';
631 if ($visibility & self
::LISTINGS_VISIBILITY
) {
632 $allowedVisibilities[] = 'Public Pages and Listings';
634 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
635 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
644 * Get a list of filtered field metadata.
646 * @deprecated use getProfileFieldMetadata
649 * @param $profileType
650 * @param $contactActivityProfile
651 * @param bool $filterMode
652 * Filter mode means you are using importable fields for filtering rather than just getting metadata.
653 * With filter mode = FALSE BOTH activity fields and component fields are returned.
654 * I can't see why you would ever want to use this function in filter mode as the component fields are
655 * still unfiltered. However, I feel scared enough to leave it as it is. I have marked this function as
656 * deprecated and am recommending the wrapper 'getProfileFieldMetadata' in order to try to
657 * send this confusion to history.
661 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile, $filterMode = TRUE) {
663 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
666 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
669 $activityFields = CRM_Activity_BAO_Activity
::getProfileFields();
670 $componentFields = CRM_Core_Component
::getQueryFields();
671 if ($filterMode == TRUE) {
672 if ($profileType == 'Activity' ||
$contactActivityProfile) {
673 $importableFields = array_merge($importableFields, $activityFields);
676 $importableFields = array_merge($importableFields, $componentFields);
680 $importableFields = array_merge($importableFields, $activityFields, $componentFields);
683 $importableFields['group']['title'] = ts('Group(s)');
684 $importableFields['group']['where'] = NULL;
685 $importableFields['tag']['title'] = ts('Tag(s)');
686 $importableFields['tag']['where'] = NULL;
687 return $importableFields;
691 * Get the metadata for all potential profile fields.
693 * @param bool $isIncludeInactive
694 * Should disabled fields be included.
697 * Field metadata for all fields that might potentially be in a profile.
699 protected static function getProfileFieldMetadata($isIncludeInactive) {
700 return self
::getImportableFields($isIncludeInactive, NULL, NULL, NULL, TRUE);
704 * Get the fields relating to locations.
708 public static function getLocationFields() {
709 static $locationFields = array(
711 'supplemental_address_1',
712 'supplemental_address_2',
713 'supplemental_address_3',
716 'postal_code_suffix',
729 return $locationFields;
737 protected static function getCustomFields($ctype) {
738 static $customFieldCache = array();
739 if (!isset($customFieldCache[$ctype])) {
740 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
742 // hack to add custom data for components
743 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
744 foreach ($components as $value) {
745 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
747 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
748 $customFields = array_merge($customFields, $addressCustomFields);
749 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
751 return $customFieldCache[$ctype];
755 * Check the data validity.
758 * The user id that we are actually editing.
759 * @param string $name
760 * The machine-name of the group we are interested in.
761 * @param bool $register
763 * The action of the form.
765 * @pram boolean $register is this the registrtion form
767 * true if form is valid
769 public static function isValid($userID, $name, $register = FALSE, $action = NULL) {
771 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
772 ts('Dynamic Form Creator'),
775 $controller->set('id', $userID);
776 $controller->set('register', 1);
777 $controller->process();
778 return $controller->validate();
781 // make sure we have a valid group
782 $group = new CRM_Core_DAO_UFGroup();
784 $group->name
= $name;
786 if ($group->find(TRUE) && $userID) {
787 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
788 $controller->set('gid', $group->id
);
789 $controller->set('id', $userID);
790 $controller->set('register', 0);
791 $controller->process();
792 return $controller->validate();
799 * Get the html for the form that represents this particular group.
802 * The user id that we are actually editing.
803 * @param string $title
804 * The title of the group we are interested in.
806 * The action of the form.
807 * @param bool $register
808 * Is this the registration form.
810 * Should we reset the form?.
811 * @param int $profileID
812 * Do we have the profile ID?.
814 * @param bool $doNotProcess
818 * the html for the form on success, otherwise empty string
820 public static function getEditHTML(
827 $doNotProcess = FALSE,
832 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
833 ts('Dynamic Form Creator'),
836 if ($reset ||
$doNotProcess) {
837 // hack to make sure we do not process this form
838 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
841 unset($_POST['_qf_default']);
842 unset($_REQUEST['_qf_default']);
844 $controller->reset();
848 $controller->set('id', $userID);
849 $controller->set('register', 1);
850 $controller->set('skipPermission', 1);
851 $controller->set('ctype', $ctype);
852 $controller->process();
853 if ($doNotProcess ||
!empty($_POST)) {
854 $controller->validate();
856 $controller->setEmbedded(TRUE);
858 //CRM-5839 - though we want to process form, get the control back.
859 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
863 // we are done processing so restore the POST/REQUEST vars
864 if (($reset ||
$doNotProcess) && $oldQFDefault) {
865 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
868 $template = CRM_Core_Smarty
::singleton();
870 // Hide CRM error messages if they are displayed using drupal form_set_error.
871 if (!empty($_POST)) {
872 $template->assign('suppressForm', TRUE);
875 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
879 // make sure we have a valid group
880 $group = new CRM_Core_DAO_UFGroup();
882 $group->title
= $title;
884 if ($group->find(TRUE)) {
885 $profileID = $group->id
;
890 // make sure profileID and ctype match if ctype exists
892 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
893 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
894 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
897 if (($profileType != 'Contact') && ($profileType != $ctype)) {
902 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
903 ts('Dynamic Form Creator'),
907 $controller->reset();
909 $controller->set('gid', $profileID);
910 $controller->set('id', $userID);
911 $controller->set('register', 0);
912 $controller->set('skipPermission', 1);
914 $controller->set('ctype', $ctype);
916 $controller->process();
917 $controller->setEmbedded(TRUE);
919 //CRM-5846 - give the control back to drupal.
920 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
923 $template = CRM_Core_Smarty
::singleton();
925 // Hide CRM error messages if they are displayed using drupal form_set_error.
926 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
927 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
928 $template->assign('suppressForm', TRUE);
932 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
933 if (!$template->template_exists($templateFile)) {
934 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
936 return trim($template->fetch($templateFile));
939 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
941 // if post not empty then only proceed
942 if (!empty($_POST)) {
944 $config = CRM_Core_Config
::singleton();
945 $email = CRM_Utils_Array
::value('mail', $_POST);
947 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
948 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
957 * Given a contact id and a field set, return the values from the db.
960 * @param array $fields
961 * The profile fields of interest.
962 * @param array $values
963 * The values for the above fields.
964 * @param bool $searchable
966 * @param array $componentWhere
967 * Component condition.
968 * @param bool $absolute
969 * Return urls in absolute form (useful when sending an email).
970 * @param null $additionalWhereClause
974 public static function getValues(
975 $cid, &$fields, &$values,
976 $searchable = TRUE, $componentWhere = NULL,
977 $absolute = FALSE, $additionalWhereClause = NULL
979 if (empty($cid) && empty($componentWhere)) {
983 // get the contact details (hier)
984 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
985 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
987 // add conditions specified by components. eg partcipant_id etc
988 if (!empty($componentWhere)) {
989 $params = array_merge($params, $componentWhere);
992 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
994 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
995 FALSE, FALSE, FALSE, $additionalWhereClause);
996 if (!$details->fetch()) {
999 $query->convertToPseudoNames($details);
1000 $config = CRM_Core_Config
::singleton();
1002 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
1003 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
1004 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
1006 $multipleFields = array('url');
1008 //start of code to set the default values
1009 foreach ($fields as $name => $field) {
1011 if ($name == 'id') {
1012 $name = 'contact_id';
1015 // skip fields that should not be displayed separately
1016 if (!empty($field['skipDisplay'])) {
1020 // Create a unique, non-empty index for each field.
1021 $index = $field['title'];
1022 if ($index === '') {
1025 while (array_key_exists($index, $values)) {
1029 $params[$index] = $values[$index] = '';
1030 $customFieldName = NULL;
1032 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
1033 // to handle gender / suffix / prefix
1034 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
1035 $params[$index] = $details->$name;
1036 $values[$index] = $details->$name;
1038 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1039 $dname = $name . '_display';
1040 $values[$index] = $details->$dname;
1041 $name = $name . '_id';
1042 $params[$index] = $details->$name;
1044 elseif (in_array($name, array(
1049 $values[$index] = $details->$name;
1050 $idx = $name . '_id';
1051 $params[$index] = $details->$idx;
1053 elseif ($name === 'preferred_language') {
1054 $params[$index] = $details->$name;
1055 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1057 elseif ($name == 'group') {
1058 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1059 $title = $ids = array();
1061 foreach ($groups as $g) {
1062 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1063 // VIEW permission on that group
1064 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], TRUE);
1066 if ($g['visibility'] != 'User and User Admin Only' ||
1067 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1069 $title[] = $g['title'];
1070 if ($g['visibility'] == 'Public Pages') {
1071 $ids[] = $g['group_id'];
1075 $values[$index] = implode(', ', $title);
1076 $params[$index] = implode(',', $ids);
1078 elseif ($name == 'tag') {
1079 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1080 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1082 foreach ($entityTags as $tagId) {
1083 $title[] = $allTags[$tagId];
1085 $values[$index] = implode(', ', $title);
1086 $params[$index] = implode(',', $entityTags);
1088 elseif ($name == 'activity_status_id') {
1089 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1090 $values[$index] = $activityStatus[$details->$name];
1091 $params[$index] = $details->$name;
1093 elseif ($name == 'activity_date_time') {
1094 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1095 $params[$index] = $details->$name;
1097 elseif ($name == 'contact_sub_type') {
1098 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1099 if (!empty($contactSubTypeNames)) {
1100 $contactSubTypeLabels = array();
1101 // get all contact subtypes
1102 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1103 // build contact subtype labels array
1104 foreach ($contactSubTypeNames as $cstName) {
1106 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1109 $values[$index] = implode(',', $contactSubTypeLabels);
1112 $params[$index] = $details->$name;
1115 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1116 if ($details->$name) {
1117 $values[$index] = '[ x ]';
1121 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1122 $htmlType = $field['html_type'];
1124 // field_type is only set when we are retrieving profile values
1125 // when sending email, we call the same function to get custom field
1126 // values etc, i.e. emulating a profile
1127 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1129 if ($htmlType == 'File') {
1132 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1134 $entityId = $componentWhere[0][2];
1137 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1141 $additionalWhereClause
1143 $params[$index] = $values[$index] = $fileURL['file_url'];
1147 if (isset($dao) && property_exists($dao, 'data_type') &&
1148 ($dao->data_type
== 'Int' ||
1149 $dao->data_type
== 'Boolean'
1152 $customVal = (int ) ($details->{$name});
1154 elseif (isset($dao) && property_exists($dao, 'data_type')
1155 && $dao->data_type
== 'Float'
1157 $customVal = (float ) ($details->{$name});
1159 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1163 $customVal = $details->{$name};
1167 if (CRM_Utils_System
::isNull($customVal)) {
1171 $params[$index] = $customVal;
1172 $values[$index] = CRM_Core_BAO_CustomField
::displayValue($customVal, $cfID);
1173 if ($field['data_type'] == 'ContactReference') {
1174 $params[$index] = $values[$index];
1176 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1177 $cfID, 'is_search_range'
1180 $customFieldName = "{$name}_from";
1184 elseif ($name == 'image_URL') {
1185 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1186 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1188 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1189 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1191 elseif (in_array($name, array(
1195 // @todo this set should be determined from metadata, not hard-coded.
1196 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1197 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1201 if ($index == 'Campaign') {
1202 $dao = 'CRM_Campaign_DAO_Campaign';
1204 elseif ($index == 'Contribution Page') {
1205 $dao = 'CRM_Contribute_DAO_ContributionPage';
1208 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1211 $value = $details->$name;
1213 $values[$index] = $value;
1218 elseif (strpos($name, '-') !== FALSE) {
1219 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1221 if (!in_array($fieldName, $multipleFields)) {
1222 if ($id == 'Primary') {
1224 // not sure why we'd every use Primary location type id
1225 // we need to fix the source if we are using it
1226 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1227 $locationTypeName = 1;
1230 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1233 if (!$locationTypeName) {
1237 $detailName = "{$locationTypeName}-{$fieldName}";
1238 $detailName = str_replace(' ', '_', $detailName);
1240 if (in_array($fieldName, array(
1247 $detailName .= "-{$type}";
1251 if (in_array($fieldName, array(
1256 $values[$index] = $details->$detailName;
1257 $idx = $detailName . '_id';
1258 $params[$index] = $details->$idx;
1260 elseif ($fieldName == 'im') {
1261 $providerId = $detailName . '-provider_id';
1262 if (isset($imProviders[$details->$providerId])) {
1263 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1266 $values[$index] = $details->$detailName;
1268 $params[$index] = $details->$detailName;
1270 elseif ($fieldName == 'phone') {
1271 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1272 if (isset($details->$phoneExtField)) {
1273 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1276 $values[$index] = $details->$detailName;
1278 $params[$index] = $details->$detailName;
1281 $values[$index] = $params[$index] = $details->$detailName;
1285 $detailName = "website-{$id}-{$fieldName}";
1286 $url = CRM_Utils_System
::fixURL($details->$detailName);
1287 if ($details->$detailName) {
1288 $websiteTypeId = "website-{$id}-website_type_id";
1289 $websiteType = $websiteTypes[$details->$websiteTypeId];
1290 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1293 $values[$index] = '';
1298 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1299 CRM_Core_Permission
::check('profile listings and forms')
1302 if (CRM_Utils_System
::isNull($params[$index])) {
1303 $params[$index] = $values[$index];
1305 if (!isset($params[$index])) {
1308 if (!$customFieldName) {
1309 $fieldName = $field['name'];
1312 $fieldName = $customFieldName;
1316 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1317 $htmlType = $field['html_type'];
1318 if ($htmlType == 'Link') {
1319 $url = $params[$index];
1321 elseif (in_array($htmlType, array(
1325 'Multi-Select State/Province',
1326 'Multi-Select Country',
1328 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1329 $selectedOptions = explode($valSeperator, $params[$index]);
1331 foreach ($selectedOptions as $key => $multiOption) {
1333 $url[] = CRM_Utils_System
::url('civicrm/profile',
1334 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1335 urlencode($fieldName) .
1337 urlencode($multiOption)
1343 $url = CRM_Utils_System
::url('civicrm/profile',
1344 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1345 urlencode($fieldName) .
1347 urlencode($params[$index])
1352 $url = CRM_Utils_System
::url('civicrm/profile',
1353 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1354 urlencode($fieldName) .
1356 urlencode($params[$index])
1361 !empty($values[$index]) &&
1365 if (is_array($url) && !empty($url)) {
1367 $eachMultiValue = explode(', ', $values[$index]);
1368 foreach ($eachMultiValue as $key => $valueLabel) {
1369 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1371 $values[$index] = implode(', ', $links);
1374 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1382 * Check if profile Group used by any module.
1390 public static function usedByModule($id) {
1391 //check whether this group is used by any module(check uf join records)
1393 FROM civicrm_uf_join
1394 WHERE civicrm_uf_join.uf_group_id=$id";
1396 $dao = new CRM_Core_DAO();
1398 if ($dao->fetch()) {
1407 * Delete the profile Group.
1415 public static function del($id) {
1416 //check whether this group contains any profile fields
1417 $profileField = new CRM_Core_DAO_UFField();
1418 $profileField->uf_group_id
= $id;
1419 $profileField->find();
1420 while ($profileField->fetch()) {
1421 CRM_Core_BAO_UFField
::del($profileField->id
);
1424 //delete records from uf join table
1425 $ufJoin = new CRM_Core_DAO_UFJoin();
1426 $ufJoin->uf_group_id
= $id;
1429 //delete profile group
1430 $group = new CRM_Core_DAO_UFGroup();
1439 * @param array $params
1440 * Reference array contains the values submitted by the form.
1442 * Reference array contains the id.
1447 public static function add(&$params, $ids = array()) {
1457 foreach ($fields as $field) {
1458 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1461 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1462 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1465 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1466 $params['group_type'] = implode(',', $params['group_type']);
1468 $ufGroup = new CRM_Core_DAO_UFGroup();
1469 $ufGroup->copyValues($params);
1471 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1472 if (!$ufGroupID && empty($params['name'])) {
1473 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1475 $ufGroup->id
= $ufGroupID;
1479 if (!$ufGroupID && empty($params['name'])) {
1480 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1488 * Make uf join entries for an uf group.
1490 * @param array $params
1491 * (reference) an assoc array of name/value pairs.
1492 * @param int $ufGroupId
1495 public static function createUFJoin(&$params, $ufGroupId) {
1496 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1498 // get ufjoin records for uf group
1499 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1501 // get the list of all ufgroup types
1502 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1504 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1505 if (!is_array($groupTypes)) {
1506 $groupTypes = array();
1509 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1510 if (!is_array($ufGroupRecord)) {
1511 $ufGroupRecord = array();
1514 // check which values has to be inserted/deleted for contact
1515 $menuRebuild = FALSE;
1516 foreach ($allUFGroupType as $key => $value) {
1517 $joinParams = array();
1518 $joinParams['uf_group_id'] = $ufGroupId;
1519 $joinParams['module'] = $key;
1520 if ($key == 'User Account') {
1521 $menuRebuild = TRUE;
1523 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1524 // insert a new record
1525 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1527 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1528 // delete a record for existing ufgroup
1529 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1535 UPDATE civicrm_uf_join
1537 WHERE uf_group_id = %2
1538 AND ( entity_id IS NULL OR entity_id <= 0 )
1541 1 => array($params['weight'], 'Integer'),
1542 2 => array($ufGroupId, 'Integer'),
1544 CRM_Core_DAO
::executeQuery($query, $p);
1546 // Do a menu rebuild, so it gets all the new menu entries for user account
1548 $config = CRM_Core_Config
::singleton();
1549 $config->userSystem
->updateCategories();
1554 * Get the UF Join records for an ufgroup id.
1556 * @param int $ufGroupId
1558 * @param int $displayName
1559 * If set return display name in array.
1560 * @param int $status
1561 * If set return module other than default modules (User Account/User registration/Profile).
1566 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1568 $UFGroupType = array();
1569 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1573 $dao = new CRM_Core_DAO_UFJoin();
1576 $dao->uf_group_id
= $ufGroupId;
1582 while ($dao->fetch()) {
1583 if (!$displayName) {
1584 $ufJoin[$dao->id
] = $dao->module
;
1587 if (isset($UFGroupType[$dao->module
])) {
1588 // skip the default modules
1590 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1592 // added for CRM-1475
1594 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1595 $ufJoin[$dao->id
] = $dao->module
;
1603 * Function takes an associative array and creates a ufjoin record for ufgroup.
1605 * @param array $params
1606 * (reference) an assoc array of name/value pairs.
1608 * @return CRM_Core_BAO_UFJoin
1610 public static function addUFJoin(&$params) {
1611 $ufJoin = new CRM_Core_DAO_UFJoin();
1612 $ufJoin->copyValues($params);
1618 * Delete the uf join record for an uf group.
1620 * @param array $params
1621 * (reference) an assoc array of name/value pairs.
1623 public static function delUFJoin(&$params) {
1624 $ufJoin = new CRM_Core_DAO_UFJoin();
1625 $ufJoin->copyValues($params);
1630 * Get the weight for ufjoin record.
1632 * @param int $ufGroupId
1633 * If $ufGroupId get update weight or add weight.
1636 * weight of the UFGroup
1638 public static function getWeight($ufGroupId = NULL) {
1639 //calculate the weight
1642 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1643 FROM civicrm_uf_join
1644 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1647 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1648 FROM civicrm_uf_join
1649 WHERE civicrm_uf_join.uf_group_id = %1
1650 AND ( entity_id IS NULL OR entity_id <= 0 )";
1651 $p[1] = array($ufGroupId, 'Integer');
1654 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1656 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1660 * Get the uf group for a module.
1662 * @param string $moduleName
1665 * No to increment the weight.
1666 * @param bool $skipPermission
1668 * Which operation (view, edit, create, etc) to check permission for.
1669 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1672 * array of ufgroups for a module
1674 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1675 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1677 if (CRM_Core_DAO
::checkFieldExists('civicrm_uf_group', 'description')) {
1678 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1679 $selectFields[] = 'description';
1682 if (CRM_Core_DAO
::checkFieldExists('civicrm_uf_group', 'frontend_title')) {
1683 $selectFields[] = 'frontend_title';
1686 if (!empty($returnFields)) {
1687 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1690 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1691 FROM civicrm_uf_group
1692 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1695 $queryString .= ' AND civicrm_uf_group.is_active = 1
1696 WHERE civicrm_uf_join.module = %2';
1697 $p[2] = array($moduleName, 'String');
1700 // add permissioning for profiles only if not registration
1701 if (!$skipPermission) {
1702 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1703 if (strpos($queryString, 'WHERE') !== FALSE) {
1704 $queryString .= " AND $permissionClause ";
1707 $queryString .= " $permissionClause ";
1711 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1712 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1714 $ufGroups = array();
1715 while ($dao->fetch()) {
1716 //skip mix profiles in user Registration / User Account
1717 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1718 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1722 foreach ($selectFields as $key => $field) {
1723 if ($field == 'id') {
1726 $ufGroups[$dao->id
][$field] = $dao->$field;
1730 // Allow other modules to alter/override the UFGroups.
1731 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1737 * Filter ufgroups based on logged in user contact type.
1739 * @param int $ufGroupId
1740 * Uf group id (profile id).
1741 * @param int $contactID
1746 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1748 $session = CRM_Core_Session
::singleton();
1749 $contactID = $session->get('userID');
1753 //get the contact type
1754 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1756 //match if exixting contact type is same as profile contact type
1757 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1759 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1760 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1762 //in some cases getBasicType() returns a cached array instead of string. Example: array ('sponsor' => 'organization')
1763 if (is_array($profileType)) {
1764 $profileType = array_shift($profileType);
1768 //allow special mix profiles for Contribution and Participant
1769 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1771 if (in_array($profileType, $specialProfiles)) {
1775 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1784 * Add profile field to a form.
1786 * @param CRM_Core_Form $form
1787 * @param array $field
1791 * @param int $contactId
1792 * @param bool $online
1793 * @param string $usedFor
1794 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1795 * @param int $rowNumber
1796 * @param string $prefix
1800 public static function buildProfile(
1810 $defaultValues = array();
1811 $fieldName = $field['name'];
1812 $title = $field['title'];
1813 $attributes = $field['attributes'];
1814 $rule = $field['rule'];
1815 $view = $field['is_view'];
1816 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1817 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1818 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1820 // do not display view fields in drupal registration form
1822 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1826 if ($usedFor == 'onbehalf') {
1827 $name = "onbehalf[$fieldName]";
1829 elseif ($usedFor == 'honor') {
1830 $name = "honor[$fieldName]";
1832 elseif ($contactId && !$online) {
1833 $name = "field[$contactId][$fieldName]";
1835 elseif ($rowNumber) {
1836 $name = "field[$rowNumber][$fieldName]";
1838 elseif (!empty($prefix)) {
1839 $name = $prefix . "[$fieldName]";
1845 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1847 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1848 $deleteExtra = json_encode(ts('Are you sure you want to delete contact image.'));
1850 CRM_Core_Action
::DELETE
=> array(
1851 'name' => ts('Delete Contact Image'),
1852 'url' => 'civicrm/contact/image',
1853 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1854 'extra' => 'onclick = "' . htmlspecialchars("if (confirm($deleteExtra)) this.href+='&confirmed=1'; else return false;") . '"',
1857 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1858 CRM_Core_Action
::DELETE
,
1860 'id' => $form->get('id'),
1861 'gid' => $form->get('gid'),
1865 'contact.profileimage.delete',
1869 $form->assign('deleteURL', $deleteURL);
1871 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1872 'address_options', TRUE, NULL, TRUE
1875 if (substr($fieldName, 0, 14) === 'state_province') {
1876 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1877 $config = CRM_Core_Config
::singleton();
1878 if (!in_array($mode, array(
1879 CRM_Profile_Form
::MODE_EDIT
,
1880 CRM_Profile_Form
::MODE_SEARCH
,
1882 $config->defaultContactStateProvince
1884 $defaultValues[$name] = $config->defaultContactStateProvince
;
1885 $form->setDefaults($defaultValues);
1888 elseif (substr($fieldName, 0, 7) === 'country') {
1889 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1890 $config = CRM_Core_Config
::singleton();
1891 if (!in_array($mode, array(
1892 CRM_Profile_Form
::MODE_EDIT
,
1893 CRM_Profile_Form
::MODE_SEARCH
,
1895 $config->defaultContactCountry
1897 $defaultValues[$name] = $config->defaultContactCountry
;
1898 $form->setDefaults($defaultValues);
1901 elseif (substr($fieldName, 0, 6) === 'county') {
1902 if ($addressOptions['county']) {
1903 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1906 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1907 $form->add('file', $name, $title, $attributes, $required);
1908 $form->addUploadElement($name);
1910 elseif (substr($fieldName, 0, 2) === 'im') {
1911 $form->add('text', $name, $title, $attributes, $required);
1914 if (substr($name, -1) == ']') {
1915 $providerName = substr($name, 0, -1) . '-provider_id]';
1917 $form->add('select', $providerName, NULL,
1919 '' => ts('- select -'),
1920 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1924 $form->add('select', $name . '-provider_id', $title,
1926 '' => ts('- select -'),
1927 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1931 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1932 $form->freeze($name . '-provider_id');
1936 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1937 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1938 $sel = &$form->addElement('hierselect', $name, $title);
1939 $select = array('' => ts('- select -'));
1940 if (count($orgInfo) == 1 && $field['is_required']) {
1941 // we only have one org - so we should default to it. Not sure about defaulting to first type
1942 // as it could be missed - so adding a select
1943 // however, possibly that is more similar to the membership form
1944 if (count($types[1]) > 1) {
1945 $types[1] = $select +
$types[1];
1949 $orgInfo = $select +
$orgInfo;
1951 $sel->setOptions(array($orgInfo, $types));
1953 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1954 $form->add('select', $name, $title,
1956 '' => ts('- select -'),
1957 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1960 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1962 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1963 foreach ($pseudoValues as $key => $var) {
1964 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1966 $group = $form->addGroup($options, $name, $title);
1968 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1971 $group->setAttribute('allowClear', TRUE);
1974 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1975 $form->addSelect($name, array(
1977 'entity' => 'contact',
1978 'field' => $fieldName,
1980 'placeholder' => '',
1983 elseif ($fieldName === 'contact_sub_type') {
1984 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1985 if ($usedFor == 'onbehalf') {
1986 $profileType = 'Organization';
1988 elseif ($usedFor == 'honor') {
1989 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1992 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1993 if ($profileType == 'Contact') {
1994 $profileType = 'Individual';
1998 $setSubtype = FALSE;
1999 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2000 $setSubtype = $profileType;
2001 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2004 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2007 $subtypeList = array();
2008 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2011 $subtypeList = $subtypes;
2014 $form->add('select', $name, $title, $subtypeList, $required, array('class' => 'crm-select2', 'multiple' => TRUE));
2016 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2017 //add email greeting, postal greeting, addressee, CRM-4575
2018 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2019 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2021 if (empty($profileType) ||
in_array($profileType, array(
2028 $profileType = 'Individual';
2030 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2031 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2034 'contact_type' => $profileType,
2035 'greeting_type' => $fieldName,
2037 $form->add('select', $name, $title,
2039 '' => ts('- select -'),
2040 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2042 // add custom greeting element
2043 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2047 elseif ($fieldName === 'preferred_communication_method') {
2048 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2049 foreach ($communicationFields as $key => $var) {
2053 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2055 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2057 elseif ($fieldName === 'preferred_mail_format') {
2058 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2060 elseif ($fieldName === 'preferred_language') {
2061 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2063 elseif ($fieldName == 'external_identifier') {
2064 $form->add('text', $name, $title, $attributes, $required);
2065 $contID = $contactId;
2067 $contID = $form->get('id');
2069 $form->addRule($name,
2070 ts('External ID already exists in Database.'),
2072 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2075 elseif ($fieldName === 'group') {
2076 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2077 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2082 elseif ($fieldName === 'tag') {
2083 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2084 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2089 elseif (substr($fieldName, 0, 4) === 'url-') {
2090 $form->add('text', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'), $required);
2091 $form->addRule($name, ts('Enter a valid web address beginning with \'http://\' or \'https://\'.'), 'url');
2093 // Note should be rendered as textarea
2094 elseif (substr($fieldName, -4) == 'note') {
2095 $form->add('textarea', $name, $title, $attributes, $required);
2097 elseif (substr($fieldName, 0, 6) === 'custom') {
2098 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2099 if ($customFieldID) {
2100 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
2103 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2104 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2105 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2106 if ($customFieldID) {
2107 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
2110 elseif ($fieldName == 'send_receipt') {
2111 $form->addElement('checkbox', $name, $title);
2113 elseif ($fieldName == 'soft_credit') {
2114 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2115 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2117 elseif ($fieldName == 'product_name') {
2118 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2119 $sel = &$form->addElement('hierselect', $name, $title);
2121 '0' => ts('- select -'),
2123 $sel->setOptions(array($products, $options));
2125 elseif ($fieldName == 'payment_instrument') {
2126 $form->add('select', $name, $title,
2127 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2129 elseif ($fieldName == 'financial_type') {
2130 $form->add('select', $name, $title,
2132 '' => ts('- select -'),
2133 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2136 elseif ($fieldName == 'contribution_status_id') {
2137 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2138 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2144 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2147 $form->add('select', $name, $title,
2149 '' => ts('- select -'),
2150 ) +
$contributionStatuses, $required
2153 elseif ($fieldName == 'soft_credit_type') {
2154 $name = "soft_credit_type[$rowNumber]";
2155 $form->add('select', $name, $title,
2157 '' => ts('- select -'),
2158 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2160 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2161 //else (for contribution), use configured SCT default value
2162 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2163 if ($field['field_type'] == 'Membership') {
2164 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2166 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2168 elseif ($fieldName == 'contribution_soft_credit_pcp_id') {
2169 CRM_Contribute_Form_SoftCredit
::addPCPFields($form, "[$rowNumber]");
2171 elseif ($fieldName == 'currency') {
2172 $form->addCurrency($name, $title, $required, NULL, FALSE, FALSE);
2174 elseif ($fieldName == 'contribution_page_id') {
2175 $form->add('select', $name, $title,
2177 '' => ts('- select -'),
2178 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2181 elseif ($fieldName == 'activity_status_id') {
2182 $form->add('select', $name, $title,
2184 '' => ts('- select -'),
2185 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2188 elseif ($fieldName == 'activity_engagement_level') {
2189 $form->add('select', $name, $title,
2191 '' => ts('- select -'),
2192 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2195 elseif ($fieldName == 'participant_status') {
2197 if ($online == TRUE) {
2198 $cond = 'visibility_id = 1';
2200 $form->add('select', $name, $title,
2202 '' => ts('- select -'),
2203 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2206 elseif ($fieldName == 'participant_role') {
2207 if (!empty($field['is_multiple'])) {
2208 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2211 $form->add('select', $name, $title,
2213 '' => ts('- select -'),
2214 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2218 elseif ($fieldName == 'world_region') {
2219 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2221 elseif ($fieldName == 'signature_html') {
2222 $form->add('wysiwyg', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2224 elseif ($fieldName == 'signature_text') {
2225 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2227 elseif (substr($fieldName, -11) == 'campaign_id') {
2228 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2229 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2230 $form->_componentCampaigns
2232 $form->add('select', $name, $title,
2234 '' => ts('- select -'),
2235 ) +
$campaigns, $required, 'class="crm-select2 big"'
2239 elseif ($fieldName == 'activity_details') {
2240 $form->add('wysiwyg', $fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2242 elseif ($fieldName == 'activity_duration') {
2243 $form->add('text', $name, $title, $attributes, $required);
2244 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2247 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2248 $form->add('advcheckbox', $name, $title, $attributes, $required);
2250 elseif (CRM_Utils_Array
::value('html_type', $field) === 'Select Date') {
2251 $extra = isset($field['datepicker']) ?
$field['datepicker']['extra'] : CRM_Utils_Date
::getDatePickerExtra($field);
2252 $attributes = isset($field['datepicker']) ?
$field['datepicker']['attributes'] : CRM_Utils_Date
::getDatePickerAttributes($field);
2253 $form->add('datepicker', $name, $title, $attributes, $required, $extra);
2256 $form->add('text', $name, $title, $attributes, $required);
2260 static $hiddenSubtype = FALSE;
2261 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2262 // In registration mode params are submitted via POST and we don't have any clue
2263 // about profile-id or the profile-type (which could be a subtype)
2264 // To generalize the behavior and simplify the process,
2265 // lets always add the hidden
2266 //subtype value if there is any, and we won't have to
2267 // compute it while processing.
2269 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2272 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2274 $hiddenSubtype = TRUE;
2277 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2278 $form->freeze($name);
2282 if (in_array($fieldName, array(
2283 'non_deductible_amount',
2288 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2291 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2292 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2298 * Set profile defaults.
2300 * @param int $contactId
2302 * @param array $fields
2303 * Associative array of fields.
2304 * @param array $defaults
2306 * @param bool $singleProfile
2307 * True for single profile else false(Update multiple items).
2308 * @param int $componentId
2309 * Id for specific components like contribute, event etc.
2310 * @param null $component
2312 public static function setProfileDefaults(
2313 $contactId, &$fields, &$defaults,
2314 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2316 if (!$componentId) {
2317 //get the contact details
2318 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2319 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2320 $multipleFields = array('website' => 'url');
2322 //start of code to set the default values
2323 foreach ($fields as $name => $field) {
2324 // skip pseudo fields
2325 if (substr($name, 0, 9) == 'phone_ext') {
2329 //set the field name depending upon the profile mode(single/multiple)
2330 if ($singleProfile) {
2334 $fldName = "field[$contactId][$name]";
2337 if ($name == 'group') {
2338 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2340 if ($name == 'tag') {
2341 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2344 if (!empty($details[$name]) ||
isset($details[$name])) {
2345 //to handle custom data (checkbox) to be written
2346 // to handle birth/deceased date, greeting_type and few other fields
2347 if (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2348 $defaults[$fldName] = $details[$name . '_id'];
2349 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2351 elseif ($name == 'preferred_communication_method') {
2352 $v = $details[$name];
2353 if (!is_array($details[$name])) {
2354 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $v);
2356 foreach ($v as $item) {
2358 $defaults[$fldName . "[$item]"] = 1;
2362 elseif ($name == 'contact_sub_type') {
2363 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2365 elseif ($name == 'world_region') {
2366 $defaults[$fldName] = $details['worldregion_id'];
2368 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2369 // @todo retrieving the custom fields here seems obsolete - $field holds more data for the fields.
2370 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2372 // hack to add custom data for components
2373 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2374 foreach ($components as $value) {
2375 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2376 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2380 switch ($customFields[$customFieldId]['html_type']) {
2381 case 'Multi-Select State/Province':
2382 case 'Multi-Select Country':
2383 case 'AdvMulti-Select':
2384 case 'Multi-Select':
2385 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2386 foreach ($v as $item) {
2388 $defaults[$fldName][$item] = $item;
2394 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2395 foreach ($v as $item) {
2397 $defaults[$fldName][$item] = 1;
2398 // seems like we need this for QF style checkboxes in profile where its multiindexed
2400 $defaults["{$fldName}[{$item}]"] = 1;
2406 $defaults[$fldName] = $details[$name];
2411 $defaults[$fldName] = $details[$name];
2415 $blocks = array('email', 'phone', 'im', 'openid');
2416 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2417 if (!in_array($fieldName, $multipleFields)) {
2418 if (is_array($details)) {
2419 foreach ($details as $key => $value) {
2420 // when we fixed CRM-5319 - get primary loc
2421 // type as per loc field and removed below code.
2422 $primaryLocationType = FALSE;
2423 if ($locTypeId == 'Primary') {
2424 if (is_array($value) && array_key_exists($fieldName, $value)) {
2425 $primaryLocationType = TRUE;
2426 if (in_array($fieldName, $blocks)) {
2427 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2430 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2435 // fixed for CRM-665
2436 if (is_numeric($locTypeId)) {
2437 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2438 if (!empty($value[$fieldName])) {
2439 //to handle stateprovince and country
2440 if ($fieldName == 'state_province') {
2441 $defaults[$fldName] = $value['state_province_id'];
2443 elseif ($fieldName == 'county') {
2444 $defaults[$fldName] = $value['county_id'];
2446 elseif ($fieldName == 'country') {
2447 if (!isset($value['country_id']) ||
!$value['country_id']) {
2448 $config = CRM_Core_Config
::singleton();
2449 if ($config->defaultContactCountry
) {
2450 $defaults[$fldName] = $config->defaultContactCountry
;
2454 $defaults[$fldName] = $value['country_id'];
2457 elseif ($fieldName == 'phone') {
2459 if (isset($value['phone'][$phoneTypeId])) {
2460 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2462 if (isset($value['phone_ext'][$phoneTypeId])) {
2463 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2467 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2469 if (!is_array($phoneDefault)) {
2470 $defaults[$fldName] = $phoneDefault;
2474 elseif ($fieldName == 'email') {
2475 //adding the first email (currently we don't support multiple emails of same location type)
2476 $defaults[$fldName] = $value['email'];
2478 elseif ($fieldName == 'im') {
2479 //adding the first im (currently we don't support multiple ims of same location type)
2480 $defaults[$fldName] = $value['im'];
2481 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2484 $defaults[$fldName] = $value[$fieldName];
2487 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2488 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2490 $defaults[$fldName] = $value[substr($fieldName, 8)];
2498 if (is_array($details)) {
2499 if ($fieldName === 'url'
2500 && !empty($details['website'])
2501 && !empty($details['website'][$locTypeId])
2503 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2511 //Handling Contribution Part of the batch profile
2512 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2513 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2516 //Handling Event Participation Part of the batch profile
2517 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2518 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2521 //Handling membership Part of the batch profile
2522 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2523 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2526 //Handling Activity Part of the batch profile
2527 if ($component == 'Activity') {
2528 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2533 * Get profiles by type eg: pure Individual etc
2535 * @param array $types
2536 * Associative array of types eg: types('Individual').
2537 * @param bool $onlyPure
2538 * True if only pure profiles are required.
2541 * associative array of profiles
2543 public static function getProfiles($types, $onlyPure = FALSE) {
2544 $profiles = array();
2545 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2547 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2549 // Exclude Batch Data Entry profiles - CRM-10901
2550 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2552 foreach ($ufGroups as $id => $title) {
2553 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2554 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2555 $profiles[$id] = $title;
2562 * Check whether a profile is valid combination of
2563 * required and/or optional profile types
2565 * @param array $required
2566 * Array of types those are required.
2567 * @param array $optional
2568 * Array of types those are optional.
2571 * associative array of profiles
2573 public static function getValidProfiles($required, $optional = NULL) {
2574 if (!is_array($required) ||
empty($required)) {
2578 $profiles = array();
2579 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2581 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2583 foreach ($ufGroups as $id => $title) {
2584 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2586 $profiles[$id] = $title;
2594 * Check whether a profile is valid combination of
2595 * required profile fields
2597 * @param array $ufId
2598 * Integer id of the profile.
2599 * @param array $required
2600 * Array of fields those are required in the profile.
2603 * associative array of profiles
2605 public static function checkValidProfile($ufId, $required = NULL) {
2606 $validProfile = FALSE;
2608 return $validProfile;
2611 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2612 return $validProfile;
2615 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2616 NULL, FALSE, NULL, FALSE, NULL,
2617 CRM_Core_Permission
::CREATE
, NULL
2620 $validProfile = array();
2621 if (!empty($profileFields)) {
2622 $fields = array_keys($profileFields);
2623 foreach ($fields as $val) {
2624 foreach ($required as $key => $field) {
2625 if (strpos($val, $field) === 0) {
2626 unset($required[$key]);
2631 $validProfile = (empty($required)) ?
TRUE : FALSE;
2634 return $validProfile;
2638 * Get default value for Register.
2640 * @param array $fields
2641 * @param array $defaults
2645 public static function setRegisterDefaults(&$fields, &$defaults) {
2646 $config = CRM_Core_Config
::singleton();
2647 foreach ($fields as $name => $field) {
2648 if (substr($name, 0, 8) == 'country-') {
2649 if (!empty($config->defaultContactCountry
)) {
2650 $defaults[$name] = $config->defaultContactCountry
;
2653 elseif (substr($name, 0, 15) == 'state_province-') {
2654 if (!empty($config->defaultContactStateProvince
)) {
2655 $defaults[$name] = $config->defaultContactStateProvince
;
2663 * make a copy of a profile, including
2664 * all the fields in the profile
2667 * The profile id to copy.
2669 * @return \CRM_Core_DAO
2671 public static function copy($id) {
2672 $maxId = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_uf_group");
2674 $title = ts('[Copy id %1]', array(1 => $maxId +
1));
2677 'title' => ' ' . $title,
2678 'name' => '__Copy_id_' . ($maxId +
1) . '_',
2682 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2688 if ($pos = strrpos($copy->name
, "_{$id}")) {
2689 $copy->name
= substr_replace($copy->name
, '', $pos);
2691 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2694 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2695 array('uf_group_id' => $id),
2696 array('uf_group_id' => $copy->id
),
2701 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2702 array('uf_group_id' => $id),
2703 array('uf_group_id' => $copy->id
)
2706 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2710 UPDATE civicrm_uf_join
2712 WHERE uf_group_id = %2
2713 AND ( entity_id IS NULL OR entity_id <= 0 )
2716 1 => array($maxWeight +
1, 'Integer'),
2717 2 => array($copy->id
, 'Integer'),
2719 CRM_Core_DAO
::executeQuery($query, $p);
2720 if ($copy->is_reserved
) {
2721 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2722 $params = array(1 => array($copy->id
, 'Integer'));
2723 CRM_Core_DAO
::executeQuery($query, $params);
2725 CRM_Utils_Hook
::copy('UFGroup', $copy);
2731 * Process that send notification e-mails
2733 * @param int $contactID
2735 * @param array $values
2736 * Associative array of name/value pair.
2738 public static function commonSendMail($contactID, &$values) {
2739 if (!$contactID ||
!$values) {
2743 $template = CRM_Core_Smarty
::singleton();
2745 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2750 self
::profileDisplay($values['id'], $values['values'], $template);
2751 $emailList = explode(',', $values['email']);
2753 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2754 "reset=1&cid=$contactID",
2755 TRUE, NULL, FALSE, FALSE, TRUE
2758 //get the default domain email address.
2759 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2761 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2762 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2763 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)));
2766 foreach ($emailList as $emailTo) {
2767 // FIXME: take the below out of the foreach loop
2768 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2770 'groupName' => 'msg_tpl_workflow_uf',
2771 'valueName' => 'uf_notify',
2772 'contactId' => $contactID,
2773 'tplParams' => array(
2774 'displayName' => $displayName,
2775 'currentDate' => date('r'),
2776 'contactLink' => $contactLink,
2778 'from' => "$domainEmailName <$domainEmailAddress>",
2779 'toEmail' => $emailTo,
2786 * Given a contact id and a group id, returns the field values from the db
2787 * for this group and notify email only if group's notify field is
2788 * set and field values are not empty
2794 * @param array $params
2795 * @param bool $skipCheck
2799 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2801 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2803 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2804 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2806 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2808 if (!empty($values) &&
2813 'values' => $values,
2824 * Assign uf fields to template.
2828 * @param array $values
2829 * @param CRM_Core_Smarty $template
2831 static public function profileDisplay($gid, $values, $template) {
2832 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2833 $template->assign('grouptitle', $groupTitle);
2834 if (count($values)) {
2835 $template->assign('values', $values);
2840 * Format fields for dupe Contact Matching.
2842 * @param array $params
2844 * @param int $contactId
2847 * associated formatted array
2849 public static function formatFields($params, $contactId = NULL) {
2851 // get the primary location type id and email
2852 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2855 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2856 $primaryLocationType = $defaultLocationType->id
;
2860 $locationType = array();
2862 $primaryLocation = 0;
2863 foreach ($params as $key => $value) {
2864 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2866 if ($locTypeId == 'Primary') {
2867 $locTypeId = $primaryLocationType;
2870 if (is_numeric($locTypeId)) {
2871 if (!in_array($locTypeId, $locationType)) {
2872 $locationType[$count] = $locTypeId;
2875 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2877 $data['location'][$loc]['location_type_id'] = $locTypeId;
2879 // if we are getting in a new primary email, dont overwrite the new one
2880 if ($locTypeId == $primaryLocationType) {
2881 if (!empty($params['email-' . $primaryLocationType])) {
2882 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2884 elseif (isset($primaryEmail)) {
2885 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2891 $data['location'][$loc]['is_primary'] = 1;
2893 if ($fieldName == 'phone') {
2895 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2898 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2900 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2902 elseif ($fieldName == 'email') {
2903 $data['location'][$loc]['email'][$loc]['email'] = $value;
2905 elseif ($fieldName == 'im') {
2906 $data['location'][$loc]['im'][$loc]['name'] = $value;
2909 if ($fieldName === 'state_province') {
2910 $data['location'][$loc]['address']['state_province_id'] = $value;
2912 elseif ($fieldName === 'country') {
2913 $data['location'][$loc]['address']['country_id'] = $value;
2916 $data['location'][$loc]['address'][$fieldName] = $value;
2921 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2922 if ($key === 'individual_suffix') {
2923 $data['suffix_id'] = $value;
2925 elseif ($key === 'individual_prefix') {
2926 $data['prefix_id'] = $value;
2928 elseif ($key === 'gender') {
2929 $data['gender_id'] = $value;
2931 elseif (substr($key, 0, 6) === 'custom') {
2932 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2934 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2935 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2937 // fix the date field
2938 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2939 $date = CRM_Utils_Date
::format($value);
2946 $data['custom'][$customFieldID] = array(
2949 'extends' => $customFields[$customFieldID]['extends'],
2950 'type' => $customFields[$customFieldID]['data_type'],
2951 'custom_field_id' => $customFieldID,
2955 elseif ($key == 'edit') {
2959 $data[$key] = $value;
2964 if (!$primaryLocation) {
2966 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2973 * Calculate the profile type 'group_type' as per profile fields.
2977 * @param bool $includeTypeValues
2978 * @param int $ignoreFieldId
2979 * Ignore particular profile field.
2982 * list of calculated group type
2984 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2985 //get the profile fields.
2986 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2987 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2991 * Calculate the profile type 'group_type' as per profile fields.
2994 * @param bool $includeTypeValues
2995 * @param int $ignoreFieldId
2996 * Ignore perticular profile field.
2999 * list of calculated group type
3001 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3002 $groupType = $groupTypeValues = $customFieldIds = array();
3003 if (!empty($ufFields)) {
3004 foreach ($ufFields as $fieldName => $fieldValue) {
3005 //ignore field from group type when provided.
3006 //in case of update profile field.
3007 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3010 if (!in_array($fieldValue['field_type'], $groupType)) {
3011 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3014 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3015 $customFieldIds[$fldId] = $fldId;
3020 if (!empty($customFieldIds)) {
3021 $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) . ')';
3023 $customGroups = CRM_Core_DAO
::executeQuery($query);
3024 while ($customGroups->fetch()) {
3025 if (!$customGroups->extends_entity_column_value
) {
3029 $groupTypeName = "{$customGroups->extends}Type";
3030 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3031 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3034 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3036 $groupTypeValues[$groupTypeName][$val] = $val;
3041 if (!empty($groupTypeValues)) {
3042 $groupType = array_merge($groupType, $groupTypeValues);
3050 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3051 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3054 * BirthDate + Email Individual,Contact
3055 * BirthDate + Subject Individual,Activity
3056 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3057 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3058 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3059 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3060 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3061 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3062 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3065 * @param array $groupTypes
3066 * With key having group type names.
3070 public static function updateGroupTypes($gId, $groupTypes = array()) {
3071 if (!is_array($groupTypes) ||
!$gId) {
3075 // If empty group types set group_type as 'null'
3076 if (empty($groupTypes)) {
3077 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3080 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3081 $validGroupTypes = array_merge(array(
3086 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3088 $gTypes = $gTypeValues = array();
3090 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3091 // Get valid group type and group subtypes
3092 foreach ($groupTypes as $groupType => $value) {
3093 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3094 $gTypes[] = $groupType;
3099 if (in_array($groupType, $participantExtends)) {
3100 $subTypesOf = $groupType;
3102 elseif (strpos($groupType, 'Type') > 0) {
3103 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3109 if (!empty($value) &&
3110 (in_array($subTypesOf, $componentGroupTypes) ||
3111 in_array($subTypesOf, $participantExtends)
3114 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3118 if (empty($gTypes)) {
3122 // Build String to store group types and group subtypes
3123 $groupTypeString = implode(',', $gTypes);
3124 if (!empty($gTypeValues)) {
3125 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3128 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3132 * Create a "group_type" string.
3134 * @param array $coreTypes
3135 * E.g. array('Individual','Contact','Student').
3136 * @param array $subTypes
3137 * E.g. array('ActivityType' => array(7, 11)).
3138 * @param string $delim
3141 * @throws CRM_Core_Exception
3143 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3144 $groupTypeExpr = '';
3146 $groupTypeExpr .= implode(',', $coreTypes);
3149 //CRM-15427 Allow Multiple subtype filtering
3150 //if (count($subTypes) > 1) {
3151 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3153 foreach ($subTypes as $subType => $subTypeIds) {
3154 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3157 return $groupTypeExpr;
3161 * setDefault componet specific profile fields.
3163 * @param array $fields
3165 * @param int $componentId
3167 * @param string $component
3169 * @param array $defaults
3170 * An array of default values.
3172 * @param bool $isStandalone
3174 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3175 if (!$componentId ||
3176 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3181 $componentBAO = $componentSubType = NULL;
3182 switch ($component) {
3184 $componentBAO = 'CRM_Member_BAO_Membership';
3185 $componentBAOName = 'Membership';
3186 $componentSubType = array('membership_type_id');
3190 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3191 $componentBAOName = 'Contribution';
3192 $componentSubType = array('financial_type_id');
3196 $componentBAO = 'CRM_Event_BAO_Participant';
3197 $componentBAOName = 'Participant';
3198 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3202 $componentBAO = 'CRM_Activity_BAO_Activity';
3203 $componentBAOName = 'Activity';
3204 $componentSubType = array('activity_type_id');
3209 $params = array('id' => $componentId);
3211 //get the component values.
3212 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3213 if ($componentBAOName == 'Participant') {
3214 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3217 $formattedGroupTree = array();
3219 foreach ($fields as $name => $field) {
3220 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3221 if (array_key_exists($name, $values)) {
3222 $defaults[$fldName] = $values[$name];
3224 elseif ($name == 'participant_note') {
3225 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3226 $defaults[$fldName] = array_pop($noteDetails);
3228 elseif (in_array($name, array(
3230 'payment_instrument',
3231 'participant_status',
3234 $defaults[$fldName] = $values["{$name}_id"];
3236 elseif ($name == 'membership_type') {
3237 // since membership_type field is a hierselect -
3238 $defaults[$fldName][0]
3239 = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3240 $defaults[$fldName][1] = $values['membership_type_id'];
3242 elseif ($name == 'membership_status') {
3243 $defaults[$fldName] = $values['status_id'];
3245 elseif (CRM_Core_BAO_CustomField
::getKeyID($name, TRUE) !== array(NULL, NULL)) {
3246 if (empty($formattedGroupTree)) {
3247 //get the groupTree as per subTypes.
3248 $groupTree = array();
3249 foreach ($componentSubType as $subType) {
3250 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, NULL,
3251 $componentId, 0, $values[$subType]
3253 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3255 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1);
3256 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3259 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3260 foreach ($defaults as $customKey => $customValue) {
3261 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3262 if ($name == 'custom_' . $customFieldDetails[0]) {
3264 //hack to set default for checkbox
3265 //basically this is for weired field name like field[33][custom_19]
3266 //we are converting this field name to array structure and assign value.
3269 foreach ($formattedGroupTree as $tree) {
3270 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3271 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3273 $defaults['field'][$componentId][$name] = $customValue;
3276 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3279 // CRM-6681, $default contains formatted date, time values.
3280 $defaults[$fldName] = $customValue;
3281 if (!empty($defaults[$customKey . '_time'])) {
3282 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3288 if (!$skipValue ||
$isStandalone) {
3289 $defaults[$fldName] = $customValue;
3291 unset($defaults[$customKey]);
3297 elseif (isset($values[$fldName])) {
3298 $defaults[$fldName] = $values[$fldName];
3304 * @param array|string $profiles - name of profile(s) to create links for
3305 * @param array $appendProfiles
3306 * Name of profile(s) to append to each link.
3310 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3311 // Default to contact profiles
3313 $profiles = array('new_individual', 'new_organization', 'new_household');
3315 $profiles = (array) $profiles;
3316 $toGet = array_merge($profiles, (array) $appendProfiles);
3317 $retrieved = civicrm_api3('uf_group', 'get', array(
3318 'name' => array('IN' => $toGet),
3321 $links = $append = array();
3322 if (!empty($retrieved['values'])) {
3323 foreach ($retrieved['values'] as $id => $profile) {
3324 if (in_array($profile['name'], $profiles)) {
3326 'label' => $profile['title'],
3327 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3328 NULL, NULL, FALSE, FALSE, TRUE),
3329 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3336 foreach ($append as $id) {
3337 foreach ($links as &$link) {
3338 $link['url'] .= ",$id";
3346 * Retrieve groups of profiles.
3348 * @param int $profileID
3349 * Id of the profile.
3354 public static function profileGroups($profileID) {
3355 $groupTypes = array();
3356 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3357 if ($profileTypes) {
3358 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3359 $groupTypes = explode(',', $groupTypeParts[0]);
3365 * Alter contact params by filtering existing subscribed groups and returns
3366 * unsubscribed groups array for subscription.
3368 * @param array $params
3370 * @param int $contactId
3374 * This contains array of groups for subscription
3376 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3377 $config = CRM_Core_Config
::singleton();
3378 $subscribeGroupIds = array();
3380 // process further only if profileDoubleOptIn enabled and if groups exist
3381 if (!array_key_exists('group', $params) ||
3382 !self
::isProfileDoubleOptin() ||
3383 CRM_Utils_System
::isNull($params['group'])
3385 return $subscribeGroupIds;
3388 //check if contact email exist.
3390 foreach ($params as $name => $value) {
3391 if (strpos($name, 'email-') !== FALSE) {
3397 //Proceed furthur only if email present
3399 return $subscribeGroupIds;
3402 //do check for already subscriptions.
3403 $contactGroups = array();
3407 FROM civicrm_group_contact
3408 WHERE status = 'Added'
3409 AND contact_id = %1";
3411 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3412 while ($dao->fetch()) {
3413 $contactGroups[$dao->group_id
] = $dao->group_id
;
3417 //since we don't have names, compare w/ label.
3418 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3420 //actual processing start.
3421 foreach ($params['group'] as $groupId => $isSelected) {
3422 //unset group those are not selected.
3424 unset($params['group'][$groupId]);
3428 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3429 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3431 //get only mailing type group and unset it from params
3432 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3433 $subscribeGroupIds[$groupId] = $groupId;
3434 unset($params['group'][$groupId]);
3438 return $subscribeGroupIds;
3442 * Check if we are rendering mixed profiles.
3444 * @param array $profileIds
3445 * Associated array of profile ids.
3448 * true if profile is mixed
3450 public static function checkForMixProfiles($profileIds) {
3451 $mixProfile = FALSE;
3453 $contactTypes = array('Individual', 'Household', 'Organization');
3454 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3456 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3458 $typeCount = array('ctype' => array(), 'subtype' => array());
3459 foreach ($profileIds as $gid) {
3460 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3461 // ignore profile of type Contact
3462 if ($profileType == 'Contact') {
3465 if (in_array($profileType, $contactTypes)) {
3466 if (!isset($typeCount['ctype'][$profileType])) {
3467 $typeCount['ctype'][$profileType] = 1;
3470 // check if we are rendering profile of different contact types
3471 if (count($typeCount['ctype']) == 2) {
3476 elseif (in_array($profileType, $components)) {
3481 if (!isset($typeCount['subtype'][$profileType])) {
3482 $typeCount['subtype'][$profileType] = 1;
3484 // check if we are rendering profile of different contact sub types
3485 if (count($typeCount['subtype']) == 2) {
3495 * Determine of we show overlay profile or not.
3498 * true if profile should be shown else false
3500 public static function showOverlayProfile() {
3501 $showOverlay = TRUE;
3503 // get the id of overlay profile
3504 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3505 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3507 $count = CRM_Core_DAO
::singleValueQuery($query);
3509 //check if there are no public fields and use is anonymous
3510 $session = CRM_Core_Session
::singleton();
3511 if (!$count && !$session->get('userID')) {
3512 $showOverlay = FALSE;
3515 return $showOverlay;
3519 * Get group type values of the profile.
3521 * @param int $profileId
3522 * @param string $groupType
3527 public static function groupTypeValues($profileId, $groupType = NULL) {
3528 $groupTypeValue = array();
3529 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3531 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3532 if (empty($groupTypeParts[1])) {
3533 return $groupTypeValue;
3535 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3537 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3539 $valueParts = explode(':', $groupTypeValues);
3541 ($valueParts[0] != "{$groupType}Type" ||
3542 ($groupType == 'Participant' &&
3543 !in_array($valueParts[0], $participantExtends)
3549 foreach ($valueParts as $val) {
3550 if (CRM_Utils_Rule
::integer($val)) {
3551 $values[$val] = $val;
3554 if (!empty($values)) {
3555 $typeName = substr($valueParts[0], 0, -4);
3556 if (in_array($valueParts[0], $participantExtends)) {
3557 $typeName = $valueParts[0];
3559 $groupTypeValue[$typeName] = $values;
3563 return $groupTypeValue;
3567 * @return bool|object
3569 public static function isProfileDoubleOptin() {
3570 // check for double optin
3571 $config = CRM_Core_Config
::singleton();
3572 if (in_array('CiviMail', $config->enableComponents
)) {
3573 return Civi
::settings()->get('profile_double_optin');
3579 * @return bool|object
3581 public static function isProfileAddToGroupDoubleOptin() {
3582 // check for add to group double optin
3583 $config = CRM_Core_Config
::singleton();
3584 if (in_array('CiviMail', $config->enableComponents
)) {
3585 return Civi
::settings()->get('profile_add_to_group_double_optin');
3591 * Get profiles used for batch entry.
3594 * profileIds profile ids
3596 public static function getBatchProfiles() {
3598 FROM civicrm_uf_group
3599 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3600 $dao = CRM_Core_DAO
::executeQuery($query);
3601 $profileIds = array();
3602 while ($dao->fetch()) {
3603 $profileIds[$dao->id
] = $dao->id
;
3609 * @todo what do I do?
3611 * @param $destination
3612 * @param bool $returnMultiSummaryFields
3614 * @return array|null
3616 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3617 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3618 foreach ($source as $field => $properties) {
3619 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3622 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3623 $destination[$field] = $properties;
3624 if ($returnMultiSummaryFields) {
3625 if ($properties['is_multi_summary']) {
3626 $multiSummaryFields[$field] = $properties;
3629 unset($source[$field]);
3632 return $multiSummaryFields;
3636 * This is function is used to format pseudo fields.
3638 * @param array $fields
3639 * Associated array of profile fields.
3642 public static function reformatProfileFields(&$fields) {
3643 //reformat fields array
3644 foreach ($fields as $name => $field) {
3645 //reformat phone and extension field
3646 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3647 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3649 // retain existing element properties and just update and replace key
3650 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3651 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3652 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3654 // add additional phone extension field
3655 $fields["phone_ext-{$fieldSuffix}"] = $field;
3656 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3657 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3658 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3659 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3660 //ignore required for extension field
3661 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;