3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
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-2016
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 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
352 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
353 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
354 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
356 while ($field->fetch()) {
357 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
358 if ($formattedField !== NULL) {
359 $fields[$name] = $formattedField;
365 if (empty($fields) && !$validGroup) {
366 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.',
367 array(1 => implode(',', $profileIds))
371 self
::reformatProfileFields($fields);
378 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
381 * @param array $groupArr
382 * (mimic CRM_UF_DAO_UFGroup).
383 * @param array $fieldArrs
384 * List of fields (each mimics CRM_UF_DAO_UFField).
385 * @param bool $visibility
386 * Visibility of fields we are interested in.
387 * @param bool $searchable
388 * @param bool $showAll
390 * @param int $permissionType
393 * @see self::getFields
395 public static function formatUFFields(
402 $permissionType = CRM_Core_Permission
::CREATE
404 // $group = new CRM_Core_DAO_UFGroup();
405 // $group->copyValues($groupArr); // no... converts string('') to string('null')
406 $group = (object) $groupArr;
408 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
409 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
410 // they did -- the obvious fix would produce mutual recursion.
411 $ufGroupType = self
::_calculateGroupType($fieldArrs);
412 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',', $ufGroupType));
413 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',', $ufGroupType));
414 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
415 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
417 $formattedFields = array();
418 foreach ($fieldArrs as $fieldArr) {
419 $field = (object) $fieldArr;
420 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
424 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
425 if ($formattedField !== NULL) {
426 $formattedFields[$name] = $formattedField;
429 return $formattedFields;
433 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
435 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
436 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
437 * @param array $customFields
438 * @param array $addressCustomFields
439 * @param array $importableFields
440 * @param int $permissionType
441 * Eg CRM_Core_Permission::CREATE.
444 protected static function formatUFField(
448 $addressCustomFields,
450 $permissionType = CRM_Core_Permission
::CREATE
452 $name = $field->field_name
;
453 $title = $field->label
;
455 $addressCustom = FALSE;
456 if (in_array($permissionType, array(
457 CRM_Core_Permission
::CREATE
,
458 CRM_Core_Permission
::EDIT
,
460 in_array($field->field_name
, array_keys($addressCustomFields))
462 $addressCustom = TRUE;
463 $name = "address_{$name}";
465 if ($field->field_name
== 'url') {
466 $name .= "-{$field->website_type_id}";
468 elseif (!empty($field->location_type_id
)) {
469 $name .= "-{$field->location_type_id}";
472 $locationFields = self
::getLocationFields();
473 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
478 if (isset($field->phone_type_id
)) {
479 $name .= "-{$field->phone_type_id}";
482 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
483 // I guess to make field self sufficient with all the required data and avoid additional calls
484 $formattedField = array(
486 'groupTitle' => $group->title
,
487 'groupName' => $group->name
,
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)
520 //adding custom field property
521 if (substr($field->field_name
, 0, 6) == 'custom' ||
522 substr($field->field_name
, 0, 14) === 'address_custom'
524 // if field is not present in customFields, that means the user
525 // DOES NOT HAVE permission to access that field
526 if (array_key_exists($field->field_name
, $customFields)) {
527 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
529 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
530 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
531 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
533 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
534 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
535 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
538 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
539 return array($name, $formattedField);
542 $formattedField = NULL;
543 return array($name, $formattedField);
546 return array($name, $formattedField);
550 * Create a query to find all visible UFFields in a UFGroup.
552 * This is the SQL-variant of checkUFFieldDisplayable().
554 * @param int $groupId
555 * @param bool $searchable
556 * @param bool $showAll
557 * @param int $visibility
558 * @param string $orderBy
559 * Comma-delimited list of SQL columns.
562 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
563 $where = " WHERE uf_group_id = {$groupId}";
566 $where .= " AND is_searchable = 1";
570 $where .= " AND is_active = 1";
575 if ($visibility & self
::PUBLIC_VISIBILITY
) {
576 $clause[] = 'visibility = "Public Pages"';
578 if ($visibility & self
::ADMIN_VISIBILITY
) {
579 $clause[] = 'visibility = "User and User Admin Only"';
581 if ($visibility & self
::LISTINGS_VISIBILITY
) {
582 $clause[] = 'visibility = "Public Pages and Listings"';
584 if (!empty($clause)) {
585 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
589 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
591 $query .= ", " . $orderBy;
598 * Create a query to find all visible UFFields in a UFGroup.
600 * This is the PHP in-memory variant of createUFFieldQuery().
602 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
603 * @param bool $searchable
604 * @param bool $showAll
605 * @param int $visibility
607 * TRUE if field is displayable
609 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
610 if ($searchable && $field->is_searchable
!= 1) {
614 if (!$showAll && $field->is_active
!= 1) {
619 $allowedVisibilities = array();
620 if ($visibility & self
::PUBLIC_VISIBILITY
) {
621 $allowedVisibilities[] = 'Public Pages';
623 if ($visibility & self
::ADMIN_VISIBILITY
) {
624 $allowedVisibilities[] = 'User and User Admin Only';
626 if ($visibility & self
::LISTINGS_VISIBILITY
) {
627 $allowedVisibilities[] = 'Public Pages and Listings';
629 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
630 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
640 * @param $profileType
641 * @param $contactActivityProfile
645 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
647 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
650 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
653 if ($profileType == 'Activity' ||
$contactActivityProfile) {
654 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
657 $componentFields = CRM_Core_Component
::getQueryFields();
660 $importableFields = array_merge($importableFields, $componentFields);
662 $importableFields['group']['title'] = ts('Group(s)');
663 $importableFields['group']['where'] = NULL;
664 $importableFields['tag']['title'] = ts('Tag(s)');
665 $importableFields['tag']['where'] = NULL;
666 return $importableFields;
669 public static function getLocationFields() {
670 static $locationFields = array(
672 'supplemental_address_1',
673 'supplemental_address_2',
676 'postal_code_suffix',
689 return $locationFields;
697 protected static function getCustomFields($ctype) {
698 static $customFieldCache = array();
699 if (!isset($customFieldCache[$ctype])) {
700 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
702 // hack to add custom data for components
703 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
704 foreach ($components as $value) {
705 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
707 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
708 $customFields = array_merge($customFields, $addressCustomFields);
709 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
711 return $customFieldCache[$ctype];
715 * Check the data validity.
718 * The user id that we are actually editing.
719 * @param string $name
720 * The machine-name of the group we are interested in.
721 * @param bool $register
723 * The action of the form.
725 * @pram boolean $register is this the registrtion form
727 * true if form is valid
729 public static function isValid($userID, $name, $register = FALSE, $action = NULL) {
731 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
732 ts('Dynamic Form Creator'),
735 $controller->set('id', $userID);
736 $controller->set('register', 1);
737 $controller->process();
738 return $controller->validate();
741 // make sure we have a valid group
742 $group = new CRM_Core_DAO_UFGroup();
744 $group->name
= $name;
746 if ($group->find(TRUE) && $userID) {
747 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
748 $controller->set('gid', $group->id
);
749 $controller->set('id', $userID);
750 $controller->set('register', 0);
751 $controller->process();
752 return $controller->validate();
759 * Get the html for the form that represents this particular group.
762 * The user id that we are actually editing.
763 * @param string $title
764 * The title of the group we are interested in.
766 * The action of the form.
767 * @param bool $register
768 * Is this the registration form.
770 * Should we reset the form?.
771 * @param int $profileID
772 * Do we have the profile ID?.
774 * @param bool $doNotProcess
778 * the html for the form on success, otherwise empty string
780 public static function getEditHTML(
787 $doNotProcess = FALSE,
792 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
793 ts('Dynamic Form Creator'),
796 if ($reset ||
$doNotProcess) {
797 // hack to make sure we do not process this form
798 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
801 unset($_POST['_qf_default']);
802 unset($_REQUEST['_qf_default']);
804 $controller->reset();
808 $controller->set('id', $userID);
809 $controller->set('register', 1);
810 $controller->set('skipPermission', 1);
811 $controller->set('ctype', $ctype);
812 $controller->process();
813 if ($doNotProcess ||
!empty($_POST)) {
814 $controller->validate();
816 $controller->setEmbedded(TRUE);
818 //CRM-5839 - though we want to process form, get the control back.
819 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
823 // we are done processing so restore the POST/REQUEST vars
824 if (($reset ||
$doNotProcess) && $oldQFDefault) {
825 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
828 $template = CRM_Core_Smarty
::singleton();
830 // Hide CRM error messages if they are displayed using drupal form_set_error.
831 if (!empty($_POST)) {
832 $template->assign('suppressForm', TRUE);
835 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
839 // make sure we have a valid group
840 $group = new CRM_Core_DAO_UFGroup();
842 $group->title
= $title;
844 if ($group->find(TRUE)) {
845 $profileID = $group->id
;
850 // make sure profileID and ctype match if ctype exists
852 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
853 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
854 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
857 if (($profileType != 'Contact') && ($profileType != $ctype)) {
862 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
863 ts('Dynamic Form Creator'),
867 $controller->reset();
869 $controller->set('gid', $profileID);
870 $controller->set('id', $userID);
871 $controller->set('register', 0);
872 $controller->set('skipPermission', 1);
874 $controller->set('ctype', $ctype);
876 $controller->process();
877 $controller->setEmbedded(TRUE);
879 //CRM-5846 - give the control back to drupal.
880 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
883 $template = CRM_Core_Smarty
::singleton();
885 // Hide CRM error messages if they are displayed using drupal form_set_error.
886 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
887 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
888 $template->assign('suppressForm', TRUE);
892 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
893 if (!$template->template_exists($templateFile)) {
894 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
896 return trim($template->fetch($templateFile));
899 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
901 // if post not empty then only proceed
902 if (!empty($_POST)) {
904 $config = CRM_Core_Config
::singleton();
905 $email = CRM_Utils_Array
::value('mail', $_POST);
907 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
908 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
917 * Searches for a contact in the db with similar attributes.
919 * @param array $params
920 * The list of values to be used in the where clause.
922 * The current contact id (hence excluded from matching).
923 * @param string $contactType
926 * contact_id if found, null otherwise
928 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
929 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
930 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
931 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
933 return implode(',', $ids);
941 * Given a contact id and a field set, return the values from the db
945 * @param array $fields
946 * The profile fields of interest.
947 * @param array $values
948 * The values for the above fields.
949 * @param bool $searchable
951 * @param array $componentWhere
952 * Component condition.
953 * @param bool $absolute
954 * Return urls in absolute form (useful when sending an email).
955 * @param null $additionalWhereClause
957 public static function getValues(
958 $cid, &$fields, &$values,
959 $searchable = TRUE, $componentWhere = NULL,
960 $absolute = FALSE, $additionalWhereClause = NULL
962 if (empty($cid) && empty($componentWhere)) {
966 // get the contact details (hier)
967 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
968 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
970 // add conditions specified by components. eg partcipant_id etc
971 if (!empty($componentWhere)) {
972 $params = array_merge($params, $componentWhere);
975 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
977 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
978 FALSE, FALSE, FALSE, $additionalWhereClause);
979 if (!$details->fetch()) {
982 $query->convertToPseudoNames($details);
983 $config = CRM_Core_Config
::singleton();
985 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
986 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
987 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
989 $multipleFields = array('url');
991 //start of code to set the default values
992 foreach ($fields as $name => $field) {
995 $name = 'contact_id';
998 // skip fields that should not be displayed separately
999 if (!empty($field['skipDisplay'])) {
1003 // Create a unique, non-empty index for each field.
1004 $index = $field['title'];
1005 if ($index === '') {
1008 while (array_key_exists($index, $values)) {
1012 $params[$index] = $values[$index] = '';
1013 $customFieldName = NULL;
1015 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
1016 // to handle gender / suffix / prefix
1017 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
1018 $params[$index] = $details->$name;
1019 $values[$index] = $details->$name;
1021 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1022 $dname = $name . '_display';
1023 $values[$index] = $details->$dname;
1024 $name = $name . '_id';
1025 $params[$index] = $details->$name;
1027 elseif (in_array($name, array(
1032 $values[$index] = $details->$name;
1033 $idx = $name . '_id';
1034 $params[$index] = $details->$idx;
1036 elseif ($name === 'preferred_communication_method') {
1037 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1039 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1041 foreach ($pref as $k) {
1043 $compref[] = $communicationFields[$k];
1046 $params[$index] = $details->$name;
1047 $values[$index] = implode(',', $compref);
1049 elseif ($name === 'preferred_language') {
1050 $params[$index] = $details->$name;
1051 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1053 elseif ($name == 'group') {
1054 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1055 $title = $ids = array();
1057 foreach ($groups as $g) {
1058 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1059 // VIEW permission on that group
1060 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1062 if ($g['visibility'] != 'User and User Admin Only' ||
1063 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1065 $title[] = $g['title'];
1066 if ($g['visibility'] == 'Public Pages') {
1067 $ids[] = $g['group_id'];
1071 $values[$index] = implode(', ', $title);
1072 $params[$index] = implode(',', $ids);
1074 elseif ($name == 'tag') {
1075 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1076 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1078 foreach ($entityTags as $tagId) {
1079 $title[] = $allTags[$tagId];
1081 $values[$index] = implode(', ', $title);
1082 $params[$index] = implode(',', $entityTags);
1084 elseif ($name == 'activity_status_id') {
1085 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1086 $values[$index] = $activityStatus[$details->$name];
1087 $params[$index] = $details->$name;
1089 elseif ($name == 'activity_date_time') {
1090 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1091 $params[$index] = $details->$name;
1093 elseif ($name == 'contact_sub_type') {
1094 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1095 if (!empty($contactSubTypeNames)) {
1096 $contactSubTypeLabels = array();
1097 // get all contact subtypes
1098 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1099 // build contact subtype labels array
1100 foreach ($contactSubTypeNames as $cstName) {
1102 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1105 $values[$index] = implode(',', $contactSubTypeLabels);
1108 $params[$index] = $details->$name;
1111 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1112 if ($details->$name) {
1113 $values[$index] = '[ x ]';
1117 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1118 $htmlType = $field['html_type'];
1120 // field_type is only set when we are retrieving profile values
1121 // when sending email, we call the same function to get custom field
1122 // values etc, i.e. emulating a profile
1123 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1125 if ($htmlType == 'File') {
1128 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1130 $entityId = $componentWhere[0][2];
1133 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1137 $additionalWhereClause
1139 $params[$index] = $values[$index] = $fileURL['file_url'];
1143 if (isset($dao) && property_exists($dao, 'data_type') &&
1144 ($dao->data_type
== 'Int' ||
1145 $dao->data_type
== 'Boolean'
1148 $customVal = (int ) ($details->{$name});
1150 elseif (isset($dao) && property_exists($dao, 'data_type')
1151 && $dao->data_type
== 'Float'
1153 $customVal = (float ) ($details->{$name});
1155 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1159 $customVal = $details->{$name};
1163 if (CRM_Utils_System
::isNull($customVal)) {
1167 $params[$index] = $customVal;
1168 $values[$index] = CRM_Core_BAO_CustomField
::displayValue($customVal, $cfID);
1169 if ($field['data_type'] == 'ContactReference') {
1170 $params[$index] = $values[$index];
1172 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1173 $cfID, 'is_search_range'
1176 $customFieldName = "{$name}_from";
1180 elseif ($name == 'image_URL') {
1181 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1182 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1184 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1185 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1187 elseif (in_array($name, array(
1190 'membership_start_date',
1191 'membership_end_date',
1194 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1195 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1199 if ($index == 'Campaign') {
1200 $dao = 'CRM_Campaign_DAO_Campaign';
1202 elseif ($index == 'Contribution Page') {
1203 $dao = 'CRM_Contribute_DAO_ContributionPage';
1206 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1209 $value = $details->$name;
1211 $values[$index] = $value;
1216 elseif (strpos($name, '-') !== FALSE) {
1217 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1219 if (!in_array($fieldName, $multipleFields)) {
1220 if ($id == 'Primary') {
1222 // not sure why we'd every use Primary location type id
1223 // we need to fix the source if we are using it
1224 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1225 $locationTypeName = 1;
1228 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1231 if (!$locationTypeName) {
1235 $detailName = "{$locationTypeName}-{$fieldName}";
1236 $detailName = str_replace(' ', '_', $detailName);
1238 if (in_array($fieldName, array(
1245 $detailName .= "-{$type}";
1249 if (in_array($fieldName, array(
1254 $values[$index] = $details->$detailName;
1255 $idx = $detailName . '_id';
1256 $params[$index] = $details->$idx;
1258 elseif ($fieldName == 'im') {
1259 $providerId = $detailName . '-provider_id';
1260 if (isset($imProviders[$details->$providerId])) {
1261 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1264 $values[$index] = $details->$detailName;
1266 $params[$index] = $details->$detailName;
1268 elseif ($fieldName == 'phone') {
1269 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1270 if (isset($details->$phoneExtField)) {
1271 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1274 $values[$index] = $details->$detailName;
1276 $params[$index] = $details->$detailName;
1279 $values[$index] = $params[$index] = $details->$detailName;
1283 $detailName = "website-{$id}-{$fieldName}";
1284 $url = CRM_Utils_System
::fixURL($details->$detailName);
1285 if ($details->$detailName) {
1286 $websiteTypeId = "website-{$id}-website_type_id";
1287 $websiteType = $websiteTypes[$details->$websiteTypeId];
1288 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1291 $values[$index] = '';
1296 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1297 CRM_Core_Permission
::check('profile listings and forms')
1300 if (CRM_Utils_System
::isNull($params[$index])) {
1301 $params[$index] = $values[$index];
1303 if (!isset($params[$index])) {
1306 if (!$customFieldName) {
1307 $fieldName = $field['name'];
1310 $fieldName = $customFieldName;
1314 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1315 $htmlType = $field['html_type'];
1316 if ($htmlType == 'Link') {
1317 $url = $params[$index];
1319 elseif (in_array($htmlType, array(
1323 'Multi-Select State/Province',
1324 'Multi-Select Country',
1326 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1327 $selectedOptions = explode($valSeperator, $params[$index]);
1329 foreach ($selectedOptions as $key => $multiOption) {
1331 $url[] = CRM_Utils_System
::url('civicrm/profile',
1332 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1333 urlencode($fieldName) .
1335 urlencode($multiOption)
1341 $url = CRM_Utils_System
::url('civicrm/profile',
1342 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1343 urlencode($fieldName) .
1345 urlencode($params[$index])
1350 $url = CRM_Utils_System
::url('civicrm/profile',
1351 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1352 urlencode($fieldName) .
1354 urlencode($params[$index])
1359 !empty($values[$index]) &&
1363 if (is_array($url) && !empty($url)) {
1365 $eachMultiValue = explode(', ', $values[$index]);
1366 foreach ($eachMultiValue as $key => $valueLabel) {
1367 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1369 $values[$index] = implode(', ', $links);
1372 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1380 * Check if profile Group used by any module.
1388 public static function usedByModule($id) {
1389 //check whether this group is used by any module(check uf join records)
1391 FROM civicrm_uf_join
1392 WHERE civicrm_uf_join.uf_group_id=$id";
1394 $dao = new CRM_Core_DAO();
1396 if ($dao->fetch()) {
1405 * Delete the profile Group.
1413 public static function del($id) {
1414 //check whether this group contains any profile fields
1415 $profileField = new CRM_Core_DAO_UFField();
1416 $profileField->uf_group_id
= $id;
1417 $profileField->find();
1418 while ($profileField->fetch()) {
1419 CRM_Core_BAO_UFField
::del($profileField->id
);
1422 //delete records from uf join table
1423 $ufJoin = new CRM_Core_DAO_UFJoin();
1424 $ufJoin->uf_group_id
= $id;
1427 //delete profile group
1428 $group = new CRM_Core_DAO_UFGroup();
1437 * @param array $params
1438 * Reference array contains the values submitted by the form.
1440 * Reference array contains the id.
1445 public static function add(&$params, $ids = array()) {
1455 foreach ($fields as $field) {
1456 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1459 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1460 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1463 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1464 $params['group_type'] = implode(',', $params['group_type']);
1466 $ufGroup = new CRM_Core_DAO_UFGroup();
1467 $ufGroup->copyValues($params);
1469 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1470 if (!$ufGroupID && empty($params['name'])) {
1471 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1473 $ufGroup->id
= $ufGroupID;
1477 if (!$ufGroupID && empty($params['name'])) {
1478 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1486 * Make uf join entries for an uf group.
1488 * @param array $params
1489 * (reference) an assoc array of name/value pairs.
1490 * @param int $ufGroupId
1493 public static function createUFJoin(&$params, $ufGroupId) {
1494 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1496 // get ufjoin records for uf group
1497 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1499 // get the list of all ufgroup types
1500 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1502 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1503 if (!is_array($groupTypes)) {
1504 $groupTypes = array();
1507 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1508 if (!is_array($ufGroupRecord)) {
1509 $ufGroupRecord = array();
1512 // check which values has to be inserted/deleted for contact
1513 $menuRebuild = FALSE;
1514 foreach ($allUFGroupType as $key => $value) {
1515 $joinParams = array();
1516 $joinParams['uf_group_id'] = $ufGroupId;
1517 $joinParams['module'] = $key;
1518 if ($key == 'User Account') {
1519 $menuRebuild = TRUE;
1521 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1522 // insert a new record
1523 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1525 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1526 // delete a record for existing ufgroup
1527 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1533 UPDATE civicrm_uf_join
1535 WHERE uf_group_id = %2
1536 AND ( entity_id IS NULL OR entity_id <= 0 )
1539 1 => array($params['weight'], 'Integer'),
1540 2 => array($ufGroupId, 'Integer'),
1542 CRM_Core_DAO
::executeQuery($query, $p);
1544 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1546 $config = CRM_Core_Config
::singleton();
1548 $config->userSystem
->is_drupal
1555 * Get the UF Join records for an ufgroup id.
1557 * @param int $ufGroupId
1559 * @param int $displayName
1560 * If set return display name in array.
1561 * @param int $status
1562 * If set return module other than default modules (User Account/User registration/Profile).
1567 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1569 $UFGroupType = array();
1570 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1574 $dao = new CRM_Core_DAO_UFJoin();
1577 $dao->uf_group_id
= $ufGroupId;
1583 while ($dao->fetch()) {
1584 if (!$displayName) {
1585 $ufJoin[$dao->id
] = $dao->module
;
1588 if (isset($UFGroupType[$dao->module
])) {
1589 // skip the default modules
1591 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1593 // added for CRM-1475
1595 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1596 $ufJoin[$dao->id
] = $dao->module
;
1604 * Function takes an associative array and creates a ufjoin record for ufgroup.
1606 * @param array $params
1607 * (reference) an assoc array of name/value pairs.
1609 * @return CRM_Core_BAO_UFJoin
1611 public static function addUFJoin(&$params) {
1612 $ufJoin = new CRM_Core_DAO_UFJoin();
1613 $ufJoin->copyValues($params);
1619 * Delete the uf join record for an uf group.
1621 * @param array $params
1622 * (reference) an assoc array of name/value pairs.
1624 public static function delUFJoin(&$params) {
1625 $ufJoin = new CRM_Core_DAO_UFJoin();
1626 $ufJoin->copyValues($params);
1631 * Get the weight for ufjoin record.
1633 * @param int $ufGroupId
1634 * If $ufGroupId get update weight or add weight.
1637 * weight of the UFGroup
1639 public static function getWeight($ufGroupId = NULL) {
1640 //calculate the weight
1643 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1644 FROM civicrm_uf_join
1645 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1648 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1649 FROM civicrm_uf_join
1650 WHERE civicrm_uf_join.uf_group_id = %1
1651 AND ( entity_id IS NULL OR entity_id <= 0 )";
1652 $p[1] = array($ufGroupId, 'Integer');
1655 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1657 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1661 * Get the uf group for a module.
1663 * @param string $moduleName
1666 * No to increment the weight.
1667 * @param bool $skipPermission
1669 * Which operation (view, edit, create, etc) to check permission for.
1670 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1673 * array of ufgroups for a module
1675 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1676 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1678 if (!CRM_Core_Config
::isUpgradeMode()) {
1679 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1680 $selectFields[] = 'description';
1683 if (!empty($returnFields)) {
1684 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1687 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1688 FROM civicrm_uf_group
1689 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1692 $queryString .= ' AND civicrm_uf_group.is_active = 1
1693 WHERE civicrm_uf_join.module = %2';
1694 $p[2] = array($moduleName, 'String');
1697 // add permissioning for profiles only if not registration
1698 if (!$skipPermission) {
1699 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1700 if (strpos($queryString, 'WHERE') !== FALSE) {
1701 $queryString .= " AND $permissionClause ";
1704 $queryString .= " $permissionClause ";
1708 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1709 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1711 $ufGroups = array();
1712 while ($dao->fetch()) {
1713 //skip mix profiles in user Registration / User Account
1714 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1715 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1719 foreach ($selectFields as $key => $field) {
1720 if ($field == 'id') {
1723 $ufGroups[$dao->id
][$field] = $dao->$field;
1727 // Allow other modules to alter/override the UFGroups.
1728 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1734 * Filter ufgroups based on logged in user contact type.
1736 * @param int $ufGroupId
1737 * Uf group id (profile id).
1738 * @param int $contactID
1743 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1745 $session = CRM_Core_Session
::singleton();
1746 $contactID = $session->get('userID');
1750 //get the contact type
1751 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1753 //match if exixting contact type is same as profile contact type
1754 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1756 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1757 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1760 //allow special mix profiles for Contribution and Participant
1761 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1763 if (in_array($profileType, $specialProfiles)) {
1767 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1776 * Add profile field to a form.
1778 * @param CRM_Core_Form $form
1779 * @param array $field
1783 * @param int $contactId
1784 * @param bool $online
1785 * @param string $usedFor
1786 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1787 * @param int $rowNumber
1788 * @param string $prefix
1792 public static function buildProfile(
1802 $defaultValues = array();
1803 $fieldName = $field['name'];
1804 $title = $field['title'];
1805 $attributes = $field['attributes'];
1806 $rule = $field['rule'];
1807 $view = $field['is_view'];
1808 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1809 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1810 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1812 // do not display view fields in drupal registration form
1814 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1818 if ($usedFor == 'onbehalf') {
1819 $name = "onbehalf[$fieldName]";
1821 elseif ($usedFor == 'honor') {
1822 $name = "honor[$fieldName]";
1824 elseif ($contactId && !$online) {
1825 $name = "field[$contactId][$fieldName]";
1827 elseif ($rowNumber) {
1828 $name = "field[$rowNumber][$fieldName]";
1830 elseif (!empty($prefix)) {
1831 $name = $prefix . "[$fieldName]";
1837 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1839 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1840 $deleteExtra = json_encode(ts('Are you sure you want to delete contact image.'));
1842 CRM_Core_Action
::DELETE
=> array(
1843 'name' => ts('Delete Contact Image'),
1844 'url' => 'civicrm/contact/image',
1845 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1846 'extra' => 'onclick = "' . htmlspecialchars("if (confirm($deleteExtra)) this.href+='&confirmed=1'; else return false;") . '"',
1849 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1850 CRM_Core_Action
::DELETE
,
1852 'id' => $form->get('id'),
1853 'gid' => $form->get('gid'),
1857 'contact.profileimage.delete',
1861 $form->assign('deleteURL', $deleteURL);
1863 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1864 'address_options', TRUE, NULL, TRUE
1867 if (substr($fieldName, 0, 14) === 'state_province') {
1868 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1869 $config = CRM_Core_Config
::singleton();
1870 if (!in_array($mode, array(
1871 CRM_Profile_Form
::MODE_EDIT
,
1872 CRM_Profile_Form
::MODE_SEARCH
,
1874 $config->defaultContactStateProvince
1876 $defaultValues[$name] = $config->defaultContactStateProvince
;
1877 $form->setDefaults($defaultValues);
1880 elseif (substr($fieldName, 0, 7) === 'country') {
1881 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1882 $config = CRM_Core_Config
::singleton();
1883 if (!in_array($mode, array(
1884 CRM_Profile_Form
::MODE_EDIT
,
1885 CRM_Profile_Form
::MODE_SEARCH
,
1887 $config->defaultContactCountry
1889 $defaultValues[$name] = $config->defaultContactCountry
;
1890 $form->setDefaults($defaultValues);
1893 elseif (substr($fieldName, 0, 6) === 'county') {
1894 if ($addressOptions['county']) {
1895 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1898 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1899 $form->add('file', $name, $title, $attributes, $required);
1900 $form->addUploadElement($name);
1902 elseif (substr($fieldName, 0, 2) === 'im') {
1903 $form->add('text', $name, $title, $attributes, $required);
1906 if (substr($name, -1) == ']') {
1907 $providerName = substr($name, 0, -1) . '-provider_id]';
1909 $form->add('select', $providerName, NULL,
1911 '' => ts('- select -'),
1912 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1916 $form->add('select', $name . '-provider_id', $title,
1918 '' => ts('- select -'),
1919 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1923 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1924 $form->freeze($name . '-provider_id');
1928 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1929 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1931 elseif (in_array($fieldName, array(
1932 'membership_start_date',
1933 'membership_end_date',
1936 $form->addDate($name, $title, $required, array('formatType' => 'activityDate'));
1938 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1939 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1940 $sel = &$form->addElement('hierselect', $name, $title);
1941 $select = array('' => ts('- select -'));
1942 if (count($orgInfo) == 1 && $field['is_required']) {
1943 // we only have one org - so we should default to it. Not sure about defaulting to first type
1944 // as it could be missed - so adding a select
1945 // however, possibly that is more similar to the membership form
1946 if (count($types[1]) > 1) {
1947 $types[1] = $select +
$types[1];
1951 $orgInfo = $select +
$orgInfo;
1953 $sel->setOptions(array($orgInfo, $types));
1955 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1956 $form->add('select', $name, $title,
1958 '' => ts('- select -'),
1959 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1962 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1964 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1965 foreach ($pseudoValues as $key => $var) {
1966 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1968 $group = $form->addGroup($options, $name, $title);
1970 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1973 $group->setAttribute('allowClear', TRUE);
1976 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1977 $form->addSelect($name, array(
1979 'entity' => 'contact',
1980 'field' => $fieldName,
1982 'placeholder' => '',
1985 elseif ($fieldName === 'contact_sub_type') {
1986 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1987 if ($usedFor == 'onbehalf') {
1988 $profileType = 'Organization';
1990 elseif ($usedFor == 'honor') {
1991 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1994 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1995 if ($profileType == 'Contact') {
1996 $profileType = 'Individual';
2000 $setSubtype = FALSE;
2001 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2002 $setSubtype = $profileType;
2003 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2006 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2009 $subtypeList = array();
2010 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2013 $subtypeList = $subtypes;
2016 $form->add('select', $name, $title, $subtypeList, $required, array('class' => 'crm-select2', 'multiple' => TRUE));
2018 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2019 //add email greeting, postal greeting, addressee, CRM-4575
2020 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2021 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2023 if (empty($profileType) ||
in_array($profileType, array(
2030 $profileType = 'Individual';
2032 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2033 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2036 'contact_type' => $profileType,
2037 'greeting_type' => $fieldName,
2039 $form->add('select', $name, $title,
2041 '' => ts('- select -'),
2042 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2044 // add custom greeting element
2045 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2049 elseif ($fieldName === 'preferred_communication_method') {
2050 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2051 foreach ($communicationFields as $key => $var) {
2055 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2057 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2059 elseif ($fieldName === 'preferred_mail_format') {
2060 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2062 elseif ($fieldName === 'preferred_language') {
2063 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2065 elseif ($fieldName == 'external_identifier') {
2066 $form->add('text', $name, $title, $attributes, $required);
2067 $contID = $contactId;
2069 $contID = $form->get('id');
2071 $form->addRule($name,
2072 ts('External ID already exists in Database.'),
2074 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2077 elseif ($fieldName === 'group') {
2078 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2079 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2084 elseif ($fieldName === 'tag') {
2085 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2086 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2091 elseif (substr($fieldName, 0, 4) === 'url-') {
2092 $form->add('text', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'), $required);
2093 $form->addRule($name, ts('Enter a valid web address beginning with \'http://\' or \'https://\'.'), 'url');
2095 // Note should be rendered as textarea
2096 elseif (substr($fieldName, -4) == 'note') {
2097 $form->add('textarea', $name, $title, $attributes, $required);
2099 elseif (substr($fieldName, 0, 6) === 'custom') {
2100 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2101 if ($customFieldID) {
2102 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
2105 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2106 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2107 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2108 if ($customFieldID) {
2109 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, $required, $search, $title);
2112 elseif (in_array($fieldName, array(
2118 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2120 elseif ($fieldName == 'send_receipt') {
2121 $form->addElement('checkbox', $name, $title);
2123 elseif ($fieldName == 'soft_credit') {
2124 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2125 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2127 elseif ($fieldName == 'product_name') {
2128 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2129 $sel = &$form->addElement('hierselect', $name, $title);
2131 '0' => ts('- select -'),
2133 $sel->setOptions(array($products, $options));
2135 elseif ($fieldName == 'payment_instrument') {
2136 $form->add('select', $name, $title,
2137 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2139 elseif ($fieldName == 'financial_type') {
2140 $form->add('select', $name, $title,
2142 '' => ts('- select -'),
2143 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2146 elseif ($fieldName == 'contribution_status_id') {
2147 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2148 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2154 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2157 $form->add('select', $name, $title,
2159 '' => ts('- select -'),
2160 ) +
$contributionStatuses, $required
2163 elseif ($fieldName == 'soft_credit_type') {
2164 $name = "soft_credit_type[$rowNumber]";
2165 $form->add('select', $name, $title,
2167 '' => ts('- select -'),
2168 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2170 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2171 //else (for contribution), use configured SCT default value
2172 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2173 if ($field['field_type'] == 'Membership') {
2174 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2176 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2178 elseif ($fieldName == 'contribution_soft_credit_pcp_id') {
2179 CRM_Contribute_Form_SoftCredit
::addPCPFields($form, "[$rowNumber]");
2181 elseif ($fieldName == 'currency') {
2182 $form->addCurrency($name, $title, $required);
2184 elseif ($fieldName == 'contribution_page_id') {
2185 $form->add('select', $name, $title,
2187 '' => ts('- select -'),
2188 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2191 elseif ($fieldName == 'participant_register_date') {
2192 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2194 elseif ($fieldName == 'activity_status_id') {
2195 $form->add('select', $name, $title,
2197 '' => ts('- select -'),
2198 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2201 elseif ($fieldName == 'activity_engagement_level') {
2202 $form->add('select', $name, $title,
2204 '' => ts('- select -'),
2205 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2208 elseif ($fieldName == 'activity_date_time') {
2209 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2211 elseif ($fieldName == 'participant_status') {
2213 if ($online == TRUE) {
2214 $cond = 'visibility_id = 1';
2216 $form->add('select', $name, $title,
2218 '' => ts('- select -'),
2219 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2222 elseif ($fieldName == 'participant_role') {
2223 if (!empty($field['is_multiple'])) {
2224 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2227 $form->add('select', $name, $title,
2229 '' => ts('- select -'),
2230 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2234 elseif ($fieldName == 'world_region') {
2235 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2237 elseif ($fieldName == 'signature_html') {
2238 $form->add('wysiwyg', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2240 elseif ($fieldName == 'signature_text') {
2241 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2243 elseif (substr($fieldName, -11) == 'campaign_id') {
2244 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2245 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2246 $form->_componentCampaigns
2248 $form->add('select', $name, $title,
2250 '' => ts('- select -'),
2251 ) +
$campaigns, $required, 'class="crm-select2 big"'
2255 elseif ($fieldName == 'activity_details') {
2256 $form->add('wysiwyg', $fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2258 elseif ($fieldName == 'activity_duration') {
2259 $form->add('text', $name, $title, $attributes, $required);
2260 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2263 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2264 $form->add('advcheckbox', $name, $title, $attributes, $required);
2267 $form->add('text', $name, $title, $attributes, $required);
2271 static $hiddenSubtype = FALSE;
2272 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2273 // In registration mode params are submitted via POST and we don't have any clue
2274 // about profile-id or the profile-type (which could be a subtype)
2275 // To generalize the behavior and simplify the process,
2276 // lets always add the hidden
2277 //subtype value if there is any, and we won't have to
2278 // compute it while processing.
2280 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2283 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2285 $hiddenSubtype = TRUE;
2288 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2289 $form->freeze($name);
2293 if (in_array($fieldName, array(
2294 'non_deductible_amount',
2299 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2302 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2303 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2309 * Set profile defaults.
2311 * @param int $contactId
2313 * @param array $fields
2314 * Associative array of fields.
2315 * @param array $defaults
2317 * @param bool $singleProfile
2318 * True for single profile else false(Update multiple items).
2319 * @param int $componentId
2320 * Id for specific components like contribute, event etc.
2321 * @param null $component
2323 public static function setProfileDefaults(
2324 $contactId, &$fields, &$defaults,
2325 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2327 if (!$componentId) {
2328 //get the contact details
2329 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2330 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2331 $multipleFields = array('website' => 'url');
2333 //start of code to set the default values
2334 foreach ($fields as $name => $field) {
2335 // skip pseudo fields
2336 if (substr($name, 0, 9) == 'phone_ext') {
2340 //set the field name depending upon the profile mode(single/multiple)
2341 if ($singleProfile) {
2345 $fldName = "field[$contactId][$name]";
2348 if ($name == 'group') {
2349 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2351 if ($name == 'tag') {
2352 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2355 if (!empty($details[$name]) ||
isset($details[$name])) {
2356 //to handle custom data (checkbox) to be written
2357 // to handle birth/deceased date, greeting_type and few other fields
2358 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2359 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2361 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2362 $defaults[$fldName] = $details[$name . '_id'];
2363 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2365 elseif ($name == 'preferred_communication_method') {
2366 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2367 foreach ($v as $item) {
2369 $defaults[$fldName . "[$item]"] = 1;
2373 elseif ($name == 'contact_sub_type') {
2374 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2376 elseif ($name == 'world_region') {
2377 $defaults[$fldName] = $details['worldregion_id'];
2379 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2380 //fix for custom fields
2381 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2383 // hack to add custom data for components
2384 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2385 foreach ($components as $value) {
2386 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2387 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2391 switch ($customFields[$customFieldId]['html_type']) {
2392 case 'Multi-Select State/Province':
2393 case 'Multi-Select Country':
2394 case 'AdvMulti-Select':
2395 case 'Multi-Select':
2396 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2397 foreach ($v as $item) {
2399 $defaults[$fldName][$item] = $item;
2405 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2406 foreach ($v as $item) {
2408 $defaults[$fldName][$item] = 1;
2409 // seems like we need this for QF style checkboxes in profile where its multiindexed
2411 $defaults["{$fldName}[{$item}]"] = 1;
2417 // CRM-6681, set defult values according to date and time format (if any).
2419 if (!empty($customFields[$customFieldId]['date_format'])) {
2420 $dateFormat = $customFields[$customFieldId]['date_format'];
2423 if (empty($customFields[$customFieldId]['time_format'])) {
2424 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2429 $timeElement = $fldName . '_time';
2430 if (substr($fldName, -1) == ']') {
2431 $timeElement = substr($fldName, 0, -1) . '_time]';
2433 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2434 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2439 $defaults[$fldName] = $details[$name];
2444 $defaults[$fldName] = $details[$name];
2448 $blocks = array('email', 'phone', 'im', 'openid');
2449 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2450 if (!in_array($fieldName, $multipleFields)) {
2451 if (is_array($details)) {
2452 foreach ($details as $key => $value) {
2453 // when we fixed CRM-5319 - get primary loc
2454 // type as per loc field and removed below code.
2455 $primaryLocationType = FALSE;
2456 if ($locTypeId == 'Primary') {
2457 if (is_array($value) && array_key_exists($fieldName, $value)) {
2458 $primaryLocationType = TRUE;
2459 if (in_array($fieldName, $blocks)) {
2460 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2463 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2468 // fixed for CRM-665
2469 if (is_numeric($locTypeId)) {
2470 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2471 if (!empty($value[$fieldName])) {
2472 //to handle stateprovince and country
2473 if ($fieldName == 'state_province') {
2474 $defaults[$fldName] = $value['state_province_id'];
2476 elseif ($fieldName == 'county') {
2477 $defaults[$fldName] = $value['county_id'];
2479 elseif ($fieldName == 'country') {
2480 if (!isset($value['country_id']) ||
!$value['country_id']) {
2481 $config = CRM_Core_Config
::singleton();
2482 if ($config->defaultContactCountry
) {
2483 $defaults[$fldName] = $config->defaultContactCountry
;
2487 $defaults[$fldName] = $value['country_id'];
2490 elseif ($fieldName == 'phone') {
2492 if (isset($value['phone'][$phoneTypeId])) {
2493 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2495 if (isset($value['phone_ext'][$phoneTypeId])) {
2496 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2500 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2502 if (!is_array($phoneDefault)) {
2503 $defaults[$fldName] = $phoneDefault;
2507 elseif ($fieldName == 'email') {
2508 //adding the first email (currently we don't support multiple emails of same location type)
2509 $defaults[$fldName] = $value['email'];
2511 elseif ($fieldName == 'im') {
2512 //adding the first im (currently we don't support multiple ims of same location type)
2513 $defaults[$fldName] = $value['im'];
2514 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2517 $defaults[$fldName] = $value[$fieldName];
2520 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2521 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2523 $defaults[$fldName] = $value[substr($fieldName, 8)];
2531 if (is_array($details)) {
2532 if ($fieldName === 'url'
2533 && !empty($details['website'])
2534 && !empty($details['website'][$locTypeId])
2536 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2544 //Handling Contribution Part of the batch profile
2545 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2546 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2549 //Handling Event Participation Part of the batch profile
2550 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2551 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2554 //Handling membership Part of the batch profile
2555 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2556 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2559 //Handling Activity Part of the batch profile
2560 if ($component == 'Activity') {
2561 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2566 * Get profiles by type eg: pure Individual etc
2568 * @param array $types
2569 * Associative array of types eg: types('Individual').
2570 * @param bool $onlyPure
2571 * True if only pure profiles are required.
2574 * associative array of profiles
2576 public static function getProfiles($types, $onlyPure = FALSE) {
2577 $profiles = array();
2578 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2580 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2582 // Exclude Batch Data Entry profiles - CRM-10901
2583 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2585 foreach ($ufGroups as $id => $title) {
2586 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2587 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2588 $profiles[$id] = $title;
2595 * Check whether a profile is valid combination of
2596 * required and/or optional profile types
2598 * @param array $required
2599 * Array of types those are required.
2600 * @param array $optional
2601 * Array of types those are optional.
2604 * associative array of profiles
2606 public static function getValidProfiles($required, $optional = NULL) {
2607 if (!is_array($required) ||
empty($required)) {
2611 $profiles = array();
2612 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2614 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2616 foreach ($ufGroups as $id => $title) {
2617 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2619 $profiles[$id] = $title;
2627 * Check whether a profile is valid combination of
2628 * required profile fields
2630 * @param array $ufId
2631 * Integer id of the profile.
2632 * @param array $required
2633 * Array of fields those are required in the profile.
2636 * associative array of profiles
2638 public static function checkValidProfile($ufId, $required = NULL) {
2639 $validProfile = FALSE;
2641 return $validProfile;
2644 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2645 return $validProfile;
2648 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2649 NULL, FALSE, NULL, FALSE, NULL,
2650 CRM_Core_Permission
::CREATE
, NULL
2653 $validProfile = array();
2654 if (!empty($profileFields)) {
2655 $fields = array_keys($profileFields);
2656 foreach ($fields as $val) {
2657 foreach ($required as $key => $field) {
2658 if (strpos($val, $field) === 0) {
2659 unset($required[$key]);
2664 $validProfile = (empty($required)) ?
TRUE : FALSE;
2667 return $validProfile;
2671 * Get default value for Register.
2673 * @param array $fields
2674 * @param array $defaults
2678 public static function setRegisterDefaults(&$fields, &$defaults) {
2679 $config = CRM_Core_Config
::singleton();
2680 foreach ($fields as $name => $field) {
2681 if (substr($name, 0, 8) == 'country-') {
2682 if (!empty($config->defaultContactCountry
)) {
2683 $defaults[$name] = $config->defaultContactCountry
;
2686 elseif (substr($name, 0, 15) == 'state_province-') {
2687 if (!empty($config->defaultContactStateProvince
)) {
2688 $defaults[$name] = $config->defaultContactStateProvince
;
2696 * make a copy of a profile, including
2697 * all the fields in the profile
2700 * The profile id to copy.
2702 * @return \CRM_Core_DAO
2704 public static function copy($id) {
2705 $maxId = CRM_Core_DAO
::singleValueQuery("SELECT max(id) FROM civicrm_uf_group");
2707 $title = ts('[Copy id %1]', array(1 => $maxId +
1));
2710 'title' => ' ' . $title,
2711 'name' => '__Copy_id_' . ($maxId +
1) . '_',
2715 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2721 if ($pos = strrpos($copy->name
, "_{$id}")) {
2722 $copy->name
= substr_replace($copy->name
, '', $pos);
2724 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2727 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2728 array('uf_group_id' => $id),
2729 array('uf_group_id' => $copy->id
),
2734 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2735 array('uf_group_id' => $id),
2736 array('uf_group_id' => $copy->id
)
2739 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2743 UPDATE civicrm_uf_join
2745 WHERE uf_group_id = %2
2746 AND ( entity_id IS NULL OR entity_id <= 0 )
2749 1 => array($maxWeight +
1, 'Integer'),
2750 2 => array($copy->id
, 'Integer'),
2752 CRM_Core_DAO
::executeQuery($query, $p);
2753 if ($copy->is_reserved
) {
2754 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2755 $params = array(1 => array($copy->id
, 'Integer'));
2756 CRM_Core_DAO
::executeQuery($query, $params);
2758 CRM_Utils_Hook
::copy('UFGroup', $copy);
2764 * Process that send notification e-mails
2766 * @param int $contactID
2768 * @param array $values
2769 * Associative array of name/value pair.
2771 public static function commonSendMail($contactID, &$values) {
2772 if (!$contactID ||
!$values) {
2776 $template = CRM_Core_Smarty
::singleton();
2778 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2783 self
::profileDisplay($values['id'], $values['values'], $template);
2784 $emailList = explode(',', $values['email']);
2786 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2787 "reset=1&cid=$contactID",
2788 TRUE, NULL, FALSE, FALSE, TRUE
2791 //get the default domain email address.
2792 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2794 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2795 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2796 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)));
2799 foreach ($emailList as $emailTo) {
2800 // FIXME: take the below out of the foreach loop
2801 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2803 'groupName' => 'msg_tpl_workflow_uf',
2804 'valueName' => 'uf_notify',
2805 'contactId' => $contactID,
2806 'tplParams' => array(
2807 'displayName' => $displayName,
2808 'currentDate' => date('r'),
2809 'contactLink' => $contactLink,
2811 'from' => "$domainEmailName <$domainEmailAddress>",
2812 'toEmail' => $emailTo,
2819 * Given a contact id and a group id, returns the field values from the db
2820 * for this group and notify email only if group's notify field is
2821 * set and field values are not empty
2827 * @param array $params
2828 * @param bool $skipCheck
2832 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2834 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2836 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2837 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2839 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2841 if (!empty($values) &&
2846 'values' => $values,
2857 * Assign uf fields to template.
2861 * @param array $values
2862 * @param CRM_Core_Smarty $template
2864 static public function profileDisplay($gid, $values, $template) {
2865 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2866 $template->assign('grouptitle', $groupTitle);
2867 if (count($values)) {
2868 $template->assign('values', $values);
2873 * Format fields for dupe Contact Matching.
2875 * @param array $params
2877 * @param int $contactId
2880 * associated formatted array
2882 public static function formatFields($params, $contactId = NULL) {
2884 // get the primary location type id and email
2885 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2888 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2889 $primaryLocationType = $defaultLocationType->id
;
2893 $locationType = array();
2895 $primaryLocation = 0;
2896 foreach ($params as $key => $value) {
2897 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2899 if ($locTypeId == 'Primary') {
2900 $locTypeId = $primaryLocationType;
2903 if (is_numeric($locTypeId)) {
2904 if (!in_array($locTypeId, $locationType)) {
2905 $locationType[$count] = $locTypeId;
2908 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2910 $data['location'][$loc]['location_type_id'] = $locTypeId;
2912 // if we are getting in a new primary email, dont overwrite the new one
2913 if ($locTypeId == $primaryLocationType) {
2914 if (!empty($params['email-' . $primaryLocationType])) {
2915 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2917 elseif (isset($primaryEmail)) {
2918 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2924 $data['location'][$loc]['is_primary'] = 1;
2926 if ($fieldName == 'phone') {
2928 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2931 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2933 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2935 elseif ($fieldName == 'email') {
2936 $data['location'][$loc]['email'][$loc]['email'] = $value;
2938 elseif ($fieldName == 'im') {
2939 $data['location'][$loc]['im'][$loc]['name'] = $value;
2942 if ($fieldName === 'state_province') {
2943 $data['location'][$loc]['address']['state_province_id'] = $value;
2945 elseif ($fieldName === 'country') {
2946 $data['location'][$loc]['address']['country_id'] = $value;
2949 $data['location'][$loc]['address'][$fieldName] = $value;
2954 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2955 if ($key === 'individual_suffix') {
2956 $data['suffix_id'] = $value;
2958 elseif ($key === 'individual_prefix') {
2959 $data['prefix_id'] = $value;
2961 elseif ($key === 'gender') {
2962 $data['gender_id'] = $value;
2964 elseif (substr($key, 0, 6) === 'custom') {
2965 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2967 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2968 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2970 // fix the date field
2971 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2972 $date = CRM_Utils_Date
::format($value);
2979 $data['custom'][$customFieldID] = array(
2982 'extends' => $customFields[$customFieldID]['extends'],
2983 'type' => $customFields[$customFieldID]['data_type'],
2984 'custom_field_id' => $customFieldID,
2988 elseif ($key == 'edit') {
2992 $data[$key] = $value;
2997 if (!$primaryLocation) {
2999 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
3006 * Calculate the profile type 'group_type' as per profile fields.
3010 * @param bool $includeTypeValues
3011 * @param int $ignoreFieldId
3012 * Ignore particular profile field.
3015 * list of calculated group type
3017 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3018 //get the profile fields.
3019 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3020 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3024 * Calculate the profile type 'group_type' as per profile fields.
3027 * @param bool $includeTypeValues
3028 * @param int $ignoreFieldId
3029 * Ignore perticular profile field.
3032 * list of calculated group type
3034 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3035 $groupType = $groupTypeValues = $customFieldIds = array();
3036 if (!empty($ufFields)) {
3037 foreach ($ufFields as $fieldName => $fieldValue) {
3038 //ignore field from group type when provided.
3039 //in case of update profile field.
3040 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3043 if (!in_array($fieldValue['field_type'], $groupType)) {
3044 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3047 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3048 $customFieldIds[$fldId] = $fldId;
3053 if (!empty($customFieldIds)) {
3054 $query = 'SELECT DISTINCT(cg.id), cg.extends, cg.extends_entity_column_id, cg.extends_entity_column_value FROM civicrm_custom_group cg LEFT JOIN civicrm_custom_field cf ON cf.custom_group_id = cg.id WHERE cg.extends_entity_column_value IS NOT NULL AND cf.id IN (' . implode(',', $customFieldIds) . ')';
3056 $customGroups = CRM_Core_DAO
::executeQuery($query);
3057 while ($customGroups->fetch()) {
3058 if (!$customGroups->extends_entity_column_value
) {
3062 $groupTypeName = "{$customGroups->extends}Type";
3063 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3064 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3067 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3069 $groupTypeValues[$groupTypeName][$val] = $val;
3074 if (!empty($groupTypeValues)) {
3075 $groupType = array_merge($groupType, $groupTypeValues);
3083 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3084 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3087 * BirthDate + Email Individual,Contact
3088 * BirthDate + Subject Individual,Activity
3089 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3090 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3091 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3092 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3093 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3094 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3095 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3098 * @param array $groupTypes
3099 * With key having group type names.
3103 public static function updateGroupTypes($gId, $groupTypes = array()) {
3104 if (!is_array($groupTypes) ||
!$gId) {
3108 // If empty group types set group_type as 'null'
3109 if (empty($groupTypes)) {
3110 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3113 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3114 $validGroupTypes = array_merge(array(
3119 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3121 $gTypes = $gTypeValues = array();
3123 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3124 // Get valid group type and group subtypes
3125 foreach ($groupTypes as $groupType => $value) {
3126 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3127 $gTypes[] = $groupType;
3132 if (in_array($groupType, $participantExtends)) {
3133 $subTypesOf = $groupType;
3135 elseif (strpos($groupType, 'Type') > 0) {
3136 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3142 if (!empty($value) &&
3143 (in_array($subTypesOf, $componentGroupTypes) ||
3144 in_array($subTypesOf, $participantExtends)
3147 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3151 if (empty($gTypes)) {
3155 // Build String to store group types and group subtypes
3156 $groupTypeString = implode(',', $gTypes);
3157 if (!empty($gTypeValues)) {
3158 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3161 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3165 * Create a "group_type" string.
3167 * @param array $coreTypes
3168 * E.g. array('Individual','Contact','Student').
3169 * @param array $subTypes
3170 * E.g. array('ActivityType' => array(7, 11)).
3171 * @param string $delim
3174 * @throws CRM_Core_Exception
3176 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3177 $groupTypeExpr = '';
3179 $groupTypeExpr .= implode(',', $coreTypes);
3182 //CRM-15427 Allow Multiple subtype filtering
3183 //if (count($subTypes) > 1) {
3184 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3186 foreach ($subTypes as $subType => $subTypeIds) {
3187 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3190 return $groupTypeExpr;
3194 * setDefault componet specific profile fields.
3196 * @param array $fields
3198 * @param int $componentId
3200 * @param string $component
3202 * @param array $defaults
3203 * An array of default values.
3205 * @param bool $isStandalone
3207 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3208 if (!$componentId ||
3209 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3214 $componentBAO = $componentSubType = NULL;
3215 switch ($component) {
3217 $componentBAO = 'CRM_Member_BAO_Membership';
3218 $componentBAOName = 'Membership';
3219 $componentSubType = array('membership_type_id');
3223 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3224 $componentBAOName = 'Contribution';
3225 $componentSubType = array('financial_type_id');
3229 $componentBAO = 'CRM_Event_BAO_Participant';
3230 $componentBAOName = 'Participant';
3231 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3235 $componentBAO = 'CRM_Activity_BAO_Activity';
3236 $componentBAOName = 'Activity';
3237 $componentSubType = array('activity_type_id');
3242 $params = array('id' => $componentId);
3244 //get the component values.
3245 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3246 if ($componentBAOName == 'Participant') {
3247 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3250 $formattedGroupTree = array();
3251 $dateTimeFields = array(
3252 'participant_register_date',
3253 'activity_date_time',
3258 'membership_start_date',
3259 'membership_end_date',
3262 foreach ($fields as $name => $field) {
3263 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3264 if (in_array($name, $dateTimeFields)) {
3265 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3266 if (!empty($values[$name])) {
3267 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3270 elseif (array_key_exists($name, $values)) {
3271 $defaults[$fldName] = $values[$name];
3273 elseif ($name == 'participant_note') {
3274 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3275 $defaults[$fldName] = array_pop($noteDetails);
3277 elseif (in_array($name, array(
3279 'payment_instrument',
3280 'participant_status',
3283 $defaults[$fldName] = $values["{$name}_id"];
3285 elseif ($name == 'membership_type') {
3286 // since membership_type field is a hierselect -
3287 $defaults[$fldName][0]
3288 = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3289 $defaults[$fldName][1] = $values['membership_type_id'];
3291 elseif ($name == 'membership_status') {
3292 $defaults[$fldName] = $values['status_id'];
3294 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3295 if (empty($formattedGroupTree)) {
3296 //get the groupTree as per subTypes.
3297 $groupTree = array();
3298 foreach ($componentSubType as $subType) {
3299 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3300 $componentId, 0, $values[$subType]
3302 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3304 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1);
3305 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3308 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3309 foreach ($defaults as $customKey => $customValue) {
3310 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3311 if ($name == 'custom_' . $customFieldDetails[0]) {
3313 //hack to set default for checkbox
3314 //basically this is for weired field name like field[33][custom_19]
3315 //we are converting this field name to array structure and assign value.
3318 foreach ($formattedGroupTree as $tree) {
3319 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3320 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3322 $defaults['field'][$componentId][$name] = $customValue;
3325 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3328 // CRM-6681, $default contains formatted date, time values.
3329 $defaults[$fldName] = $customValue;
3330 if (!empty($defaults[$customKey . '_time'])) {
3331 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3337 if (!$skipValue ||
$isStandalone) {
3338 $defaults[$fldName] = $customValue;
3340 unset($defaults[$customKey]);
3350 * @param array|string $profiles - name of profile(s) to create links for
3351 * @param array $appendProfiles
3352 * Name of profile(s) to append to each link.
3356 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3357 // Default to contact profiles
3359 $profiles = array('new_individual', 'new_organization', 'new_household');
3361 $profiles = (array) $profiles;
3362 $toGet = array_merge($profiles, (array) $appendProfiles);
3363 $retrieved = civicrm_api3('uf_group', 'get', array(
3364 'name' => array('IN' => $toGet),
3367 $links = $append = array();
3368 if (!empty($retrieved['values'])) {
3369 foreach ($retrieved['values'] as $id => $profile) {
3370 if (in_array($profile['name'], $profiles)) {
3372 'label' => $profile['title'],
3373 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3374 NULL, NULL, FALSE, FALSE, TRUE),
3375 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3382 foreach ($append as $id) {
3383 foreach ($links as &$link) {
3384 $link['url'] .= ",$id";
3392 * Retrieve groups of profiles.
3394 * @param int $profileID
3395 * Id of the profile.
3400 public static function profileGroups($profileID) {
3401 $groupTypes = array();
3402 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3403 if ($profileTypes) {
3404 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3405 $groupTypes = explode(',', $groupTypeParts[0]);
3411 * Alter contact params by filtering existing subscribed groups and returns
3412 * unsubscribed groups array for subscription.
3414 * @param array $params
3416 * @param int $contactId
3420 * This contains array of groups for subscription
3422 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3423 $config = CRM_Core_Config
::singleton();
3424 $subscribeGroupIds = array();
3426 // process further only if profileDoubleOptIn enabled and if groups exist
3427 if (!array_key_exists('group', $params) ||
3428 !self
::isProfileDoubleOptin() ||
3429 CRM_Utils_System
::isNull($params['group'])
3431 return $subscribeGroupIds;
3434 //check if contact email exist.
3436 foreach ($params as $name => $value) {
3437 if (strpos($name, 'email-') !== FALSE) {
3443 //Proceed furthur only if email present
3445 return $subscribeGroupIds;
3448 //do check for already subscriptions.
3449 $contactGroups = array();
3453 FROM civicrm_group_contact
3454 WHERE status = 'Added'
3455 AND contact_id = %1";
3457 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3458 while ($dao->fetch()) {
3459 $contactGroups[$dao->group_id
] = $dao->group_id
;
3463 //since we don't have names, compare w/ label.
3464 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3466 //actual processing start.
3467 foreach ($params['group'] as $groupId => $isSelected) {
3468 //unset group those are not selected.
3470 unset($params['group'][$groupId]);
3474 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3475 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3477 //get only mailing type group and unset it from params
3478 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3479 $subscribeGroupIds[$groupId] = $groupId;
3480 unset($params['group'][$groupId]);
3484 return $subscribeGroupIds;
3488 * Check if we are rendering mixed profiles.
3490 * @param array $profileIds
3491 * Associated array of profile ids.
3494 * true if profile is mixed
3496 public static function checkForMixProfiles($profileIds) {
3497 $mixProfile = FALSE;
3499 $contactTypes = array('Individual', 'Household', 'Organization');
3500 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3502 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3504 $typeCount = array('ctype' => array(), 'subtype' => array());
3505 foreach ($profileIds as $gid) {
3506 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3507 // ignore profile of type Contact
3508 if ($profileType == 'Contact') {
3511 if (in_array($profileType, $contactTypes)) {
3512 if (!isset($typeCount['ctype'][$profileType])) {
3513 $typeCount['ctype'][$profileType] = 1;
3516 // check if we are rendering profile of different contact types
3517 if (count($typeCount['ctype']) == 2) {
3522 elseif (in_array($profileType, $components)) {
3527 if (!isset($typeCount['subtype'][$profileType])) {
3528 $typeCount['subtype'][$profileType] = 1;
3530 // check if we are rendering profile of different contact sub types
3531 if (count($typeCount['subtype']) == 2) {
3541 * Determine of we show overlay profile or not.
3544 * true if profile should be shown else false
3546 public static function showOverlayProfile() {
3547 $showOverlay = TRUE;
3549 // get the id of overlay profile
3550 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3551 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3553 $count = CRM_Core_DAO
::singleValueQuery($query);
3555 //check if there are no public fields and use is anonymous
3556 $session = CRM_Core_Session
::singleton();
3557 if (!$count && !$session->get('userID')) {
3558 $showOverlay = FALSE;
3561 return $showOverlay;
3565 * Get group type values of the profile.
3567 * @param int $profileId
3568 * @param string $groupType
3573 public static function groupTypeValues($profileId, $groupType = NULL) {
3574 $groupTypeValue = array();
3575 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3577 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3578 if (empty($groupTypeParts[1])) {
3579 return $groupTypeValue;
3581 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3583 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3585 $valueParts = explode(':', $groupTypeValues);
3587 ($valueParts[0] != "{$groupType}Type" ||
3588 ($groupType == 'Participant' &&
3589 !in_array($valueParts[0], $participantExtends)
3595 foreach ($valueParts as $val) {
3596 if (CRM_Utils_Rule
::integer($val)) {
3597 $values[$val] = $val;
3600 if (!empty($values)) {
3601 $typeName = substr($valueParts[0], 0, -4);
3602 if (in_array($valueParts[0], $participantExtends)) {
3603 $typeName = $valueParts[0];
3605 $groupTypeValue[$typeName] = $values;
3609 return $groupTypeValue;
3613 * @return bool|object
3615 public static function isProfileDoubleOptin() {
3616 // check for double optin
3617 $config = CRM_Core_Config
::singleton();
3618 if (in_array('CiviMail', $config->enableComponents
)) {
3619 return Civi
::settings()->get('profile_double_optin');
3625 * @return bool|object
3627 public static function isProfileAddToGroupDoubleOptin() {
3628 // check for add to group double optin
3629 $config = CRM_Core_Config
::singleton();
3630 if (in_array('CiviMail', $config->enableComponents
)) {
3631 return Civi
::settings()->get('profile_add_to_group_double_optin');
3637 * Get profiles used for batch entry.
3640 * profileIds profile ids
3642 public static function getBatchProfiles() {
3644 FROM civicrm_uf_group
3645 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3646 $dao = CRM_Core_DAO
::executeQuery($query);
3647 $profileIds = array();
3648 while ($dao->fetch()) {
3649 $profileIds[$dao->id
] = $dao->id
;
3655 * @todo what do I do?
3657 * @param $destination
3658 * @param bool $returnMultiSummaryFields
3660 * @return array|null
3662 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3663 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3664 foreach ($source as $field => $properties) {
3665 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3668 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3669 $destination[$field] = $properties;
3670 if ($returnMultiSummaryFields) {
3671 if ($properties['is_multi_summary']) {
3672 $multiSummaryFields[$field] = $properties;
3675 unset($source[$field]);
3678 return $multiSummaryFields;
3682 * This is function is used to format pseudo fields.
3684 * @param array $fields
3685 * Associated array of profile fields.
3688 public static function reformatProfileFields(&$fields) {
3689 //reformat fields array
3690 foreach ($fields as $name => $field) {
3691 //reformat phone and extension field
3692 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3693 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3695 // retain existing element properties and just update and replace key
3696 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3697 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3698 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3700 // add additional phone extension field
3701 $fields["phone_ext-{$fieldSuffix}"] = $field;
3702 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3703 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3704 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3705 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3706 //ignore required for extension field
3707 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;