3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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-2015
39 class CRM_Core_BAO_UFGroup
extends CRM_Core_DAO_UFGroup
{
40 const PUBLIC_VISIBILITY
= 1,
42 LISTINGS_VISIBILITY
= 4;
45 * Cache the match clause used in this transaction.
49 static $_matchFields = NULL;
52 * Fetch object based on array of properties.
54 * @param array $params
55 * (reference) an assoc array of name/value pairs.
56 * @param array $defaults
57 * (reference) an assoc array to hold the flattened values.
60 * CRM_Core_DAO_UFGroup object
62 public static function retrieve(&$params, &$defaults) {
63 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
67 * Retrieve the first non-generic contact type
75 public static function getContactType($id) {
77 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
78 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
80 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
81 $types = explode(',', $typesParts[0]);
84 foreach ($types as $type) {
85 if (in_array($type, $validTypes)) {
88 elseif (array_key_exists($type, $validSubTypes)) {
89 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
100 * Get the form title.
109 public static function getTitle($id) {
110 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
114 * Update the is_active flag in the db.
117 * Id of the database record.
118 * @param bool $is_active
119 * Value we want to set the is_active field.
122 * CRM_Core_DAO_UFGroup object on success, null otherwise
124 public static function setIsActive($id, $is_active) {
125 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
129 * Get all the registration fields.
132 * What action are we doing.
139 * the fields that are needed for registration
141 public static function getRegistrationFields($action, $mode, $ctype = NULL) {
142 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
143 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
146 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
149 if (!is_array($ufGroups)) {
155 foreach ($ufGroups as $id => $title) {
157 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
158 if (($fieldType != 'Contact') &&
159 ($fieldType != $ctype) &&
160 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
164 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
165 $profileSubType = $fieldType;
169 $subset = self
::getFields($id, TRUE, $action,
170 NULL, NULL, FALSE, NULL, TRUE, $ctype
173 // we do not allow duplicates. the first field is the winner
174 foreach ($subset as $name => $field) {
175 if (empty($fields[$name])) {
176 $fields[$name] = $field;
185 * Get all the listing fields.
188 * What action are we doing.
189 * @param int $visibility
190 * Visibility of fields we are interested in.
191 * @param bool $considerSelector
192 * Whether to consider the in_selector parameter.
193 * @param array $ufGroupIds
194 * @param bool $searchable
196 * @param null $restrict
197 * @param bool $skipPermission
198 * @param int $permissionType
200 * the fields that are listings related
202 public static function getListingFields(
205 $considerSelector = FALSE,
209 $skipPermission = FALSE,
210 $permissionType = CRM_Core_Permission
::SEARCH
213 $subset = self
::getFields($ufGroupIds, FALSE, $action,
214 $visibility, $searchable,
220 if ($considerSelector) {
221 // drop the fields not meant for the selector
222 foreach ($subset as $name => $field) {
223 if (!$field['in_selector']) {
224 unset($subset[$name]);
231 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
234 foreach ($ufGroups as $id => $title) {
235 $subset = self
::getFields($id, FALSE, $action,
236 $visibility, $searchable,
242 if ($considerSelector) {
243 // drop the fields not meant for the selector
244 foreach ($subset as $name => $field) {
245 if (!$field['in_selector']) {
246 unset($subset[$name]);
250 $fields = array_merge($fields, $subset);
257 * Get all the fields that belong to the group with the name title,
258 * and format for use with buildProfile. This is the SQL analog of
262 * The id of the UF group or ids of ufgroup.
263 * @param bool|int $register are we interested in registration fields
265 * What action are we doing.
266 * @param int $visibility
267 * Visibility of fields we are interested in.
269 * @param bool $showAll
270 * @param string $restrict
271 * Should we restrict based on a specified profile type.
272 * @param bool $skipPermission
274 * @param int $permissionType
275 * @param string $orderBy
276 * @param null $orderProfiles
279 * the fields that belong to this ufgroup(s)
281 public static function getFields(
289 $skipPermission = FALSE,
291 $permissionType = CRM_Core_Permission
::CREATE
,
292 $orderBy = 'field_name',
293 $orderProfiles = NULL,
294 $eventProfile = FALSE
296 if (!is_array($id)) {
297 $id = CRM_Utils_Type
::escape($id, 'Positive');
298 $profileIds = array($id);
304 $gids = implode(',', $profileIds);
307 $query = "SELECT g.* from civicrm_uf_group g
308 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
309 WHERE g.id IN ( {$gids} )
310 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
312 $params = array(1 => array($restrict, 'String'));
315 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
319 $query .= " AND g.is_active = 1";
322 $checkPermission = array(
324 'administer CiviCRM',
325 'manage event profiles',
328 if ($eventProfile && CRM_Core_Permission
::check($checkPermission)) {
329 $skipPermission = TRUE;
332 // add permissioning for profiles only if not registration
333 if (!$skipPermission) {
334 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
335 $query .= " AND $permissionClause ";
338 if ($orderProfiles AND count($profileIds) > 1) {
339 $query .= " ORDER BY FIELD( g.id, {$gids} )";
341 $group = CRM_Core_DAO
::executeQuery($query, $params);
345 while ($group->fetch()) {
347 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
348 $field = CRM_Core_DAO
::executeQuery($query);
350 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
351 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
352 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
353 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
355 while ($field->fetch()) {
356 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
357 if ($formattedField !== NULL) {
358 $fields[$name] = $formattedField;
364 if (empty($fields) && !$validGroup) {
365 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.',
366 array(1 => implode(',', $profileIds))
370 self
::reformatProfileFields($fields);
377 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
380 * @param array $groupArr
381 * (mimic CRM_UF_DAO_UFGroup).
382 * @param array $fieldArrs
383 * List of fields (each mimics CRM_UF_DAO_UFField).
384 * @param bool $visibility
385 * Visibility of fields we are interested in.
386 * @param bool $searchable
387 * @param bool $showAll
389 * @param int $permissionType
392 * @see self::getFields
394 public static function formatUFFields(
401 $permissionType = CRM_Core_Permission
::CREATE
403 // $group = new CRM_Core_DAO_UFGroup();
404 // $group->copyValues($groupArr); // no... converts string('') to string('null')
405 $group = (object) $groupArr;
407 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
408 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
409 // they did -- the obvious fix would produce mutual recursion.
410 $ufGroupType = self
::_calculateGroupType($fieldArrs);
411 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',', $ufGroupType));
412 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',', $ufGroupType));
413 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
414 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
416 $formattedFields = array();
417 foreach ($fieldArrs as $fieldArr) {
418 $field = (object) $fieldArr;
419 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
423 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
424 if ($formattedField !== NULL) {
425 $formattedFields[$name] = $formattedField;
428 return $formattedFields;
432 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
434 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
435 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
436 * @param array $customFields
437 * @param array $addressCustomFields
438 * @param array $importableFields
439 * @param int $permissionType
440 * Eg CRM_Core_Permission::CREATE.
443 protected static function formatUFField(
447 $addressCustomFields,
449 $permissionType = CRM_Core_Permission
::CREATE
451 $name = $field->field_name
;
452 $title = $field->label
;
454 $addressCustom = FALSE;
455 if (in_array($permissionType, array(
456 CRM_Core_Permission
::CREATE
,
457 CRM_Core_Permission
::EDIT
,
459 in_array($field->field_name
, array_keys($addressCustomFields))
461 $addressCustom = TRUE;
462 $name = "address_{$name}";
464 if ($field->field_name
== 'url') {
465 $name .= "-{$field->website_type_id}";
467 elseif (!empty($field->location_type_id
)) {
468 $name .= "-{$field->location_type_id}";
471 $locationFields = self
::getLocationFields();
472 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
477 if (isset($field->phone_type_id
)) {
478 $name .= "-{$field->phone_type_id}";
481 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
482 // I guess to make field self sufficient with all the required data and avoid additional calls
483 $formattedField = array(
485 'groupTitle' => $group->title
,
486 'groupName' => $group->name
,
487 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
488 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
490 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
491 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
492 'is_required' => $field->is_required
,
493 'is_view' => $field->is_view
,
494 'help_pre' => $field->help_pre
,
495 'help_post' => $field->help_post
,
496 'visibility' => $field->visibility
,
497 'in_selector' => $field->in_selector
,
498 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
499 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
500 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
501 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
502 'group_id' => $group->id
,
503 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
504 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
505 'field_type' => $field->field_type
,
506 'field_id' => $field->id
,
507 'pseudoconstant' => CRM_Utils_Array
::value(
509 CRM_Utils_Array
::value($field->field_name
, $importableFields)
511 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
512 'dbName' => CRM_Utils_Array
::value(
514 CRM_Utils_Array
::value($field->field_name
, $importableFields)
519 //adding custom field property
520 if (substr($field->field_name
, 0, 6) == 'custom' ||
521 substr($field->field_name
, 0, 14) === 'address_custom'
523 // if field is not present in customFields, that means the user
524 // DOES NOT HAVE permission to access that field
525 if (array_key_exists($field->field_name
, $customFields)) {
526 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
528 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
529 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
530 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
532 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
533 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
534 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
537 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
538 return array($name, $formattedField);
541 $formattedField = NULL;
542 return array($name, $formattedField);
545 return array($name, $formattedField);
549 * Create a query to find all visible UFFields in a UFGroup.
551 * This is the SQL-variant of checkUFFieldDisplayable().
553 * @param int $groupId
554 * @param bool $searchable
555 * @param bool $showAll
556 * @param int $visibility
557 * @param string $orderBy
558 * Comma-delimited list of SQL columns.
561 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
562 $where = " WHERE uf_group_id = {$groupId}";
565 $where .= " AND is_searchable = 1";
569 $where .= " AND is_active = 1";
574 if ($visibility & self
::PUBLIC_VISIBILITY
) {
575 $clause[] = 'visibility = "Public Pages"';
577 if ($visibility & self
::ADMIN_VISIBILITY
) {
578 $clause[] = 'visibility = "User and User Admin Only"';
580 if ($visibility & self
::LISTINGS_VISIBILITY
) {
581 $clause[] = 'visibility = "Public Pages and Listings"';
583 if (!empty($clause)) {
584 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
588 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
590 $query .= ", " . $orderBy;
597 * Create a query to find all visible UFFields in a UFGroup.
599 * This is the PHP in-memory variant of createUFFieldQuery().
601 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
602 * @param bool $searchable
603 * @param bool $showAll
604 * @param int $visibility
606 * TRUE if field is displayable
608 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
609 if ($searchable && $field->is_searchable
!= 1) {
613 if (!$showAll && $field->is_active
!= 1) {
618 $allowedVisibilities = array();
619 if ($visibility & self
::PUBLIC_VISIBILITY
) {
620 $allowedVisibilities[] = 'Public Pages';
622 if ($visibility & self
::ADMIN_VISIBILITY
) {
623 $allowedVisibilities[] = 'User and User Admin Only';
625 if ($visibility & self
::LISTINGS_VISIBILITY
) {
626 $allowedVisibilities[] = 'Public Pages and Listings';
628 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
629 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
639 * @param $profileType
640 * @param $contactActivityProfile
644 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
646 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
649 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
652 if ($profileType == 'Activity' ||
$contactActivityProfile) {
653 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
656 $componentFields = CRM_Core_Component
::getQueryFields();
659 $importableFields = array_merge($importableFields, $componentFields);
661 $importableFields['group']['title'] = ts('Group(s)');
662 $importableFields['group']['where'] = NULL;
663 $importableFields['tag']['title'] = ts('Tag(s)');
664 $importableFields['tag']['where'] = NULL;
665 return $importableFields;
668 public static function getLocationFields() {
669 static $locationFields = array(
671 'supplemental_address_1',
672 'supplemental_address_2',
675 'postal_code_suffix',
688 return $locationFields;
696 protected static function getCustomFields($ctype) {
697 static $customFieldCache = array();
698 if (!isset($customFieldCache[$ctype])) {
699 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
701 // hack to add custom data for components
702 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
703 foreach ($components as $value) {
704 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
706 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
707 $customFields = array_merge($customFields, $addressCustomFields);
708 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
710 return $customFieldCache[$ctype];
714 * Check the data validity.
717 * The user id that we are actually editing.
718 * @param string $title
719 * The title of the group we are interested in.
720 * @param bool $register
722 * The action of the form.
724 * @pram boolean $register is this the registrtion form
726 * true if form is valid
728 public static function isValid($userID, $title, $register = FALSE, $action = NULL) {
730 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
731 ts('Dynamic Form Creator'),
734 $controller->set('id', $userID);
735 $controller->set('register', 1);
736 $controller->process();
737 return $controller->validate();
740 // make sure we have a valid group
741 $group = new CRM_Core_DAO_UFGroup();
743 $group->title
= $title;
745 if ($group->find(TRUE) && $userID) {
746 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
747 $controller->set('gid', $group->id
);
748 $controller->set('id', $userID);
749 $controller->set('register', 0);
750 $controller->process();
751 return $controller->validate();
758 * Get the html for the form that represents this particular group.
761 * The user id that we are actually editing.
762 * @param string $title
763 * The title of the group we are interested in.
765 * The action of the form.
766 * @param bool $register
767 * Is this the registration form.
769 * Should we reset the form?.
770 * @param int $profileID
771 * Do we have the profile ID?.
773 * @param bool $doNotProcess
777 * the html for the form on success, otherwise empty string
779 public static function getEditHTML(
786 $doNotProcess = FALSE,
791 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
792 ts('Dynamic Form Creator'),
795 if ($reset ||
$doNotProcess) {
796 // hack to make sure we do not process this form
797 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
800 unset($_POST['_qf_default']);
801 unset($_REQUEST['_qf_default']);
803 $controller->reset();
807 $controller->set('id', $userID);
808 $controller->set('register', 1);
809 $controller->set('skipPermission', 1);
810 $controller->set('ctype', $ctype);
811 $controller->process();
812 if ($doNotProcess ||
!empty($_POST)) {
813 $controller->validate();
815 $controller->setEmbedded(TRUE);
817 //CRM-5839 - though we want to process form, get the control back.
818 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
822 // we are done processing so restore the POST/REQUEST vars
823 if (($reset ||
$doNotProcess) && $oldQFDefault) {
824 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
827 $template = CRM_Core_Smarty
::singleton();
829 // Hide CRM error messages if they are displayed using drupal form_set_error.
830 if (!empty($_POST)) {
831 $template->assign('suppressForm', TRUE);
834 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
838 // make sure we have a valid group
839 $group = new CRM_Core_DAO_UFGroup();
841 $group->title
= $title;
843 if ($group->find(TRUE)) {
844 $profileID = $group->id
;
849 // make sure profileID and ctype match if ctype exists
851 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
852 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
853 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
856 if (($profileType != 'Contact') && ($profileType != $ctype)) {
861 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
862 ts('Dynamic Form Creator'),
866 $controller->reset();
868 $controller->set('gid', $profileID);
869 $controller->set('id', $userID);
870 $controller->set('register', 0);
871 $controller->set('skipPermission', 1);
873 $controller->set('ctype', $ctype);
875 $controller->process();
876 $controller->setEmbedded(TRUE);
878 //CRM-5846 - give the control back to drupal.
879 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
882 $template = CRM_Core_Smarty
::singleton();
884 // Hide CRM error messages if they are displayed using drupal form_set_error.
885 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
886 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
887 $template->assign('suppressForm', TRUE);
891 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
892 if (!$template->template_exists($templateFile)) {
893 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
895 return trim($template->fetch($templateFile));
898 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
900 // if post not empty then only proceed
901 if (!empty($_POST)) {
903 $config = CRM_Core_Config
::singleton();
904 $email = CRM_Utils_Array
::value('mail', $_POST);
906 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
907 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
916 * Searches for a contact in the db with similar attributes.
918 * @param array $params
919 * The list of values to be used in the where clause.
921 * The current contact id (hence excluded from matching).
922 * @param string $contactType
925 * contact_id if found, null otherwise
927 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
928 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
929 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
930 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
932 return implode(',', $ids);
940 * Given a contact id and a field set, return the values from the db
944 * @param array $fields
945 * The profile fields of interest.
946 * @param array $values
947 * The values for the above fields.
948 * @param bool $searchable
950 * @param array $componentWhere
951 * Component condition.
952 * @param bool $absolute
953 * Return urls in absolute form (useful when sending an email).
954 * @param null $additionalWhereClause
958 public static function getValues(
959 $cid, &$fields, &$values,
960 $searchable = TRUE, $componentWhere = NULL,
961 $absolute = FALSE, $additionalWhereClause = NULL
963 if (empty($cid) && empty($componentWhere)) {
967 // get the contact details (hier)
968 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
969 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
971 // add conditions specified by components. eg partcipant_id etc
972 if (!empty($componentWhere)) {
973 $params = array_merge($params, $componentWhere);
976 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
977 $options = &$query->_options
;
979 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
980 FALSE, FALSE, FALSE, $additionalWhereClause);
981 if (!$details->fetch()) {
984 $query->convertToPseudoNames($details);
985 $config = CRM_Core_Config
::singleton();
987 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
988 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
989 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
991 $multipleFields = array('url');
993 //start of code to set the default values
994 foreach ($fields as $name => $field) {
997 $name = 'contact_id';
1000 // skip fields that should not be displayed separately
1001 if (!empty($field['skipDisplay'])) {
1005 // Create a unique, non-empty index for each field.
1006 $index = $field['title'];
1007 if ($index === '') {
1010 while (array_key_exists($index, $values)) {
1014 $params[$index] = $values[$index] = '';
1015 $customFieldName = NULL;
1017 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
1018 // to handle gender / suffix / prefix
1019 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
1020 $params[$index] = $details->$name;
1021 $values[$index] = $details->$name;
1023 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1024 $dname = $name . '_display';
1025 $values[$index] = $details->$dname;
1026 $name = $name . '_id';
1027 $params[$index] = $details->$name;
1029 elseif (in_array($name, array(
1034 $values[$index] = $details->$name;
1035 $idx = $name . '_id';
1036 $params[$index] = $details->$idx;
1038 elseif ($name === 'preferred_communication_method') {
1039 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1041 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1043 foreach ($pref as $k) {
1045 $compref[] = $communicationFields[$k];
1048 $params[$index] = $details->$name;
1049 $values[$index] = implode(',', $compref);
1051 elseif ($name === 'preferred_language') {
1052 $params[$index] = $details->$name;
1053 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1055 elseif ($name == 'group') {
1056 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1057 $title = $ids = array();
1059 foreach ($groups as $g) {
1060 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1061 // VIEW permission on that group
1062 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1064 if ($g['visibility'] != 'User and User Admin Only' ||
1065 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1067 $title[] = $g['title'];
1068 if ($g['visibility'] == 'Public Pages') {
1069 $ids[] = $g['group_id'];
1073 $values[$index] = implode(', ', $title);
1074 $params[$index] = implode(',', $ids);
1076 elseif ($name == 'tag') {
1077 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1078 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1080 foreach ($entityTags as $tagId) {
1081 $title[] = $allTags[$tagId];
1083 $values[$index] = implode(', ', $title);
1084 $params[$index] = implode(',', $entityTags);
1086 elseif ($name == 'activity_status_id') {
1087 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1088 $values[$index] = $activityStatus[$details->$name];
1089 $params[$index] = $details->$name;
1091 elseif ($name == 'activity_date_time') {
1092 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1093 $params[$index] = $details->$name;
1095 elseif ($name == 'contact_sub_type') {
1096 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1097 if (!empty($contactSubTypeNames)) {
1098 $contactSubTypeLabels = array();
1099 // get all contact subtypes
1100 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1101 // build contact subtype labels array
1102 foreach ($contactSubTypeNames as $cstName) {
1104 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1107 $values[$index] = implode(',', $contactSubTypeLabels);
1110 $params[$index] = $details->$name;
1113 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1114 if ($details->$name) {
1115 $values[$index] = '[ x ]';
1119 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1120 $htmlType = $field['html_type'];
1122 // field_type is only set when we are retrieving profile values
1123 // when sending email, we call the same function to get custom field
1124 // values etc, i.e. emulating a profile
1125 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1127 if ($htmlType == 'File') {
1130 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1132 $entityId = $componentWhere[0][2];
1135 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1139 $additionalWhereClause
1141 $params[$index] = $values[$index] = $fileURL['file_url'];
1145 if (isset($dao) && property_exists($dao, 'data_type') &&
1146 ($dao->data_type
== 'Int' ||
1147 $dao->data_type
== 'Boolean'
1150 $customVal = (int ) ($details->{$name});
1152 elseif (isset($dao) && property_exists($dao, 'data_type')
1153 && $dao->data_type
== 'Float'
1155 $customVal = (float ) ($details->{$name});
1157 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1161 $customVal = $details->{$name};
1165 if (CRM_Utils_System
::isNull($customVal)) {
1169 $params[$index] = $customVal;
1170 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1174 if ($field['data_type'] == 'ContactReference') {
1175 $params[$index] = $values[$index];
1177 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1178 $cfID, 'is_search_range'
1181 $customFieldName = "{$name}_from";
1185 elseif ($name == 'image_URL') {
1186 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1187 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1189 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1190 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1192 elseif (in_array($name, array(
1195 'membership_start_date',
1196 'membership_end_date',
1199 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1200 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1204 if ($index == 'Campaign') {
1205 $dao = 'CRM_Campaign_DAO_Campaign';
1207 elseif ($index == 'Contribution Page') {
1208 $dao = 'CRM_Contribute_DAO_ContributionPage';
1211 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1214 $value = $details->$name;
1216 $values[$index] = $value;
1221 elseif (strpos($name, '-') !== FALSE) {
1222 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1224 if (!in_array($fieldName, $multipleFields)) {
1225 if ($id == 'Primary') {
1227 // not sure why we'd every use Primary location type id
1228 // we need to fix the source if we are using it
1229 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1230 $locationTypeName = 1;
1233 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1236 if (!$locationTypeName) {
1240 $detailName = "{$locationTypeName}-{$fieldName}";
1241 $detailName = str_replace(' ', '_', $detailName);
1243 if (in_array($fieldName, array(
1250 $detailName .= "-{$type}";
1254 if (in_array($fieldName, array(
1259 $values[$index] = $details->$detailName;
1260 $idx = $detailName . '_id';
1261 $params[$index] = $details->$idx;
1263 elseif ($fieldName == 'im') {
1264 $providerId = $detailName . '-provider_id';
1265 if (isset($imProviders[$details->$providerId])) {
1266 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1269 $values[$index] = $details->$detailName;
1271 $params[$index] = $details->$detailName;
1273 elseif ($fieldName == 'phone') {
1274 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1275 if (isset($details->$phoneExtField)) {
1276 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1279 $values[$index] = $details->$detailName;
1281 $params[$index] = $details->$detailName;
1284 $values[$index] = $params[$index] = $details->$detailName;
1288 $detailName = "website-{$id}-{$fieldName}";
1289 $url = CRM_Utils_System
::fixURL($details->$detailName);
1290 if ($details->$detailName) {
1291 $websiteTypeId = "website-{$id}-website_type_id";
1292 $websiteType = $websiteTypes[$details->$websiteTypeId];
1293 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1296 $values[$index] = '';
1301 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1302 CRM_Core_Permission
::check('profile listings and forms')
1305 if (CRM_Utils_System
::isNull($params[$index])) {
1306 $params[$index] = $values[$index];
1308 if (!isset($params[$index])) {
1311 if (!$customFieldName) {
1312 $fieldName = $field['name'];
1315 $fieldName = $customFieldName;
1319 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1320 $htmlType = $field['html_type'];
1321 if ($htmlType == 'Link') {
1322 $url = $params[$index];
1324 elseif (in_array($htmlType, array(
1328 'Multi-Select State/Province',
1329 'Multi-Select Country',
1331 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1332 $selectedOptions = explode($valSeperator, $params[$index]);
1334 foreach ($selectedOptions as $key => $multiOption) {
1336 $url[] = CRM_Utils_System
::url('civicrm/profile',
1337 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1338 urlencode($fieldName) .
1340 urlencode($multiOption)
1346 $url = CRM_Utils_System
::url('civicrm/profile',
1347 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1348 urlencode($fieldName) .
1350 urlencode($params[$index])
1355 $url = CRM_Utils_System
::url('civicrm/profile',
1356 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1357 urlencode($fieldName) .
1359 urlencode($params[$index])
1364 !empty($values[$index]) &&
1368 if (is_array($url) && !empty($url)) {
1370 $eachMultiValue = explode(', ', $values[$index]);
1371 foreach ($eachMultiValue as $key => $valueLabel) {
1372 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1374 $values[$index] = implode(', ', $links);
1377 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1385 * Check if profile Group used by any module.
1393 public static function usedByModule($id) {
1394 //check whether this group is used by any module(check uf join records)
1396 FROM civicrm_uf_join
1397 WHERE civicrm_uf_join.uf_group_id=$id";
1399 $dao = new CRM_Core_DAO();
1401 if ($dao->fetch()) {
1410 * Delete the profile Group.
1418 public static function del($id) {
1419 //check whether this group contains any profile fields
1420 $profileField = new CRM_Core_DAO_UFField();
1421 $profileField->uf_group_id
= $id;
1422 $profileField->find();
1423 while ($profileField->fetch()) {
1424 CRM_Core_BAO_UFField
::del($profileField->id
);
1427 //delete records from uf join table
1428 $ufJoin = new CRM_Core_DAO_UFJoin();
1429 $ufJoin->uf_group_id
= $id;
1432 //delete profile group
1433 $group = new CRM_Core_DAO_UFGroup();
1442 * @param array $params
1443 * Reference array contains the values submitted by the form.
1445 * Reference array contains the id.
1450 public static function add(&$params, $ids = array()) {
1460 foreach ($fields as $field) {
1461 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1464 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1465 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1468 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1469 $params['group_type'] = implode(',', $params['group_type']);
1471 $ufGroup = new CRM_Core_DAO_UFGroup();
1472 $ufGroup->copyValues($params);
1474 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1476 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1478 $ufGroup->id
= $ufGroupID;
1483 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1491 * Make uf join entries for an uf group.
1493 * @param array $params
1494 * (reference) an assoc array of name/value pairs.
1495 * @param int $ufGroupId
1500 public static function createUFJoin(&$params, $ufGroupId) {
1501 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1503 // get ufjoin records for uf group
1504 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1506 // get the list of all ufgroup types
1507 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1509 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1510 if (!is_array($groupTypes)) {
1511 $groupTypes = array();
1514 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1515 if (!is_array($ufGroupRecord)) {
1516 $ufGroupRecord = array();
1519 // check which values has to be inserted/deleted for contact
1520 $menuRebuild = FALSE;
1521 foreach ($allUFGroupType as $key => $value) {
1522 $joinParams = array();
1523 $joinParams['uf_group_id'] = $ufGroupId;
1524 $joinParams['module'] = $key;
1525 if ($key == 'User Account') {
1526 $menuRebuild = TRUE;
1528 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1529 // insert a new record
1530 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1532 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1533 // delete a record for existing ufgroup
1534 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1540 UPDATE civicrm_uf_join
1542 WHERE uf_group_id = %2
1543 AND ( entity_id IS NULL OR entity_id <= 0 )
1546 1 => array($params['weight'], 'Integer'),
1547 2 => array($ufGroupId, 'Integer'),
1549 CRM_Core_DAO
::executeQuery($query, $p);
1551 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1553 $config = CRM_Core_Config
::singleton();
1555 $config->userSystem
->is_drupal
1562 * Get the UF Join records for an ufgroup id.
1564 * @param int $ufGroupId
1566 * @param int $displayName
1567 * If set return display name in array.
1568 * @param int $status
1569 * If set return module other than default modules (User Account/User registration/Profile).
1574 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1576 $UFGroupType = array();
1577 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1581 $dao = new CRM_Core_DAO_UFJoin();
1584 $dao->uf_group_id
= $ufGroupId;
1590 while ($dao->fetch()) {
1591 if (!$displayName) {
1592 $ufJoin[$dao->id
] = $dao->module
;
1595 if (isset($UFGroupType[$dao->module
])) {
1596 // skip the default modules
1598 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1600 // added for CRM-1475
1602 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1603 $ufJoin[$dao->id
] = $dao->module
;
1611 * Function takes an associative array and creates a ufjoin record for ufgroup.
1613 * @param array $params
1614 * (reference) an assoc array of name/value pairs.
1616 * @return CRM_Core_BAO_UFJoin
1618 public static function addUFJoin(&$params) {
1619 $ufJoin = new CRM_Core_DAO_UFJoin();
1620 $ufJoin->copyValues($params);
1626 * Delete the uf join record for an uf group.
1628 * @param array $params
1629 * (reference) an assoc array of name/value pairs.
1633 public static function delUFJoin(&$params) {
1634 $ufJoin = new CRM_Core_DAO_UFJoin();
1635 $ufJoin->copyValues($params);
1640 * Get the weight for ufjoin record.
1642 * @param int $ufGroupId
1643 * If $ufGroupId get update weight or add weight.
1646 * weight of the UFGroup
1648 public static function getWeight($ufGroupId = NULL) {
1649 //calculate the weight
1652 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1653 FROM civicrm_uf_join
1654 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1657 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1658 FROM civicrm_uf_join
1659 WHERE civicrm_uf_join.uf_group_id = %1
1660 AND ( entity_id IS NULL OR entity_id <= 0 )";
1661 $p[1] = array($ufGroupId, 'Integer');
1664 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1666 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1670 * Get the uf group for a module.
1672 * @param string $moduleName
1675 * No to increment the weight.
1676 * @param bool $skipPermission
1678 * Which operation (view, edit, create, etc) to check permission for.
1679 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1682 * array of ufgroups for a module
1684 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1685 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1687 if (!CRM_Core_Config
::isUpgradeMode()) {
1688 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1689 $selectFields[] = 'description';
1692 if (!empty($returnFields)) {
1693 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1696 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1697 FROM civicrm_uf_group
1698 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1701 $queryString .= ' AND civicrm_uf_group.is_active = 1
1702 WHERE civicrm_uf_join.module = %2';
1703 $p[2] = array($moduleName, 'String');
1706 // add permissioning for profiles only if not registration
1707 if (!$skipPermission) {
1708 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1709 if (strpos($queryString, 'WHERE') !== FALSE) {
1710 $queryString .= " AND $permissionClause ";
1713 $queryString .= " $permissionClause ";
1717 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1718 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1720 $ufGroups = array();
1721 while ($dao->fetch()) {
1722 //skip mix profiles in user Registration / User Account
1723 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1724 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1728 foreach ($selectFields as $key => $field) {
1729 if ($field == 'id') {
1732 $ufGroups[$dao->id
][$field] = $dao->$field;
1736 // Allow other modules to alter/override the UFGroups.
1737 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1743 * Filter ufgroups based on logged in user contact type.
1745 * @param int $ufGroupId
1746 * Uf group id (profile id).
1747 * @param int $contactID
1752 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1754 $session = CRM_Core_Session
::singleton();
1755 $contactID = $session->get('userID');
1759 //get the contact type
1760 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1762 //match if exixting contact type is same as profile contact type
1763 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1765 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1766 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1769 //allow special mix profiles for Contribution and Participant
1770 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1772 if (in_array($profileType, $specialProfiles)) {
1776 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1785 * Add profile field to a form.
1787 * @param CRM_Core_Form $form
1788 * @param array $field
1792 * @param int $contactId
1793 * @param bool $online
1794 * @param string $usedFor
1795 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1796 * @param int $rowNumber
1797 * @param string $prefix
1801 public static function buildProfile(
1811 $defaultValues = array();
1812 $fieldName = $field['name'];
1813 $title = $field['title'];
1814 $attributes = $field['attributes'];
1815 $rule = $field['rule'];
1816 $view = $field['is_view'];
1817 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1818 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1819 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1821 // do not display view fields in drupal registration form
1823 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1827 if ($usedFor == 'onbehalf') {
1828 $name = "onbehalf[$fieldName]";
1830 elseif ($usedFor == 'honor') {
1831 $name = "honor[$fieldName]";
1833 elseif ($contactId && !$online) {
1834 $name = "field[$contactId][$fieldName]";
1836 elseif ($rowNumber) {
1837 $name = "field[$rowNumber][$fieldName]";
1839 elseif (!empty($prefix)) {
1840 $name = $prefix . "[$fieldName]";
1846 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1848 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1849 $deleteExtra = json_encode(ts('Are you sure you want to delete contact image.'));
1851 CRM_Core_Action
::DELETE
=> array(
1852 'name' => ts('Delete Contact Image'),
1853 'url' => 'civicrm/contact/image',
1854 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1855 'extra' => 'onclick = "' . htmlspecialchars("if (confirm($deleteExtra)) this.href+='&confirmed=1'; else return false;") . '"',
1858 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1859 CRM_Core_Action
::DELETE
,
1861 'id' => $form->get('id'),
1862 'gid' => $form->get('gid'),
1866 'contact.profileimage.delete',
1870 $form->assign('deleteURL', $deleteURL);
1872 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1873 'address_options', TRUE, NULL, TRUE
1876 if (substr($fieldName, 0, 14) === 'state_province') {
1877 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1878 $config = CRM_Core_Config
::singleton();
1879 if (!in_array($mode, array(
1880 CRM_Profile_Form
::MODE_EDIT
,
1881 CRM_Profile_Form
::MODE_SEARCH
,
1883 $config->defaultContactStateProvince
1885 $defaultValues[$name] = $config->defaultContactStateProvince
;
1886 $form->setDefaults($defaultValues);
1889 elseif (substr($fieldName, 0, 7) === 'country') {
1890 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1891 $config = CRM_Core_Config
::singleton();
1892 if (!in_array($mode, array(
1893 CRM_Profile_Form
::MODE_EDIT
,
1894 CRM_Profile_Form
::MODE_SEARCH
,
1896 $config->defaultContactCountry
1898 $defaultValues[$name] = $config->defaultContactCountry
;
1899 $form->setDefaults($defaultValues);
1902 elseif (substr($fieldName, 0, 6) === 'county') {
1903 if ($addressOptions['county']) {
1904 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1907 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1908 $form->add('file', $name, $title, $attributes, $required);
1909 $form->addUploadElement($name);
1911 elseif (substr($fieldName, 0, 2) === 'im') {
1912 $form->add('text', $name, $title, $attributes, $required);
1915 if (substr($name, -1) == ']') {
1916 $providerName = substr($name, 0, -1) . '-provider_id]';
1918 $form->add('select', $providerName, NULL,
1920 '' => ts('- select -'),
1921 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1925 $form->add('select', $name . '-provider_id', $title,
1927 '' => ts('- select -'),
1928 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1932 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1933 $form->freeze($name . '-provider_id');
1937 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1938 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1940 elseif (in_array($fieldName, array(
1941 'membership_start_date',
1942 'membership_end_date',
1945 $form->addDate($name, $title, $required, array('formatType' => 'activityDate'));
1947 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1948 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1949 $sel = &$form->addElement('hierselect', $name, $title);
1950 $select = array('' => ts('- select -'));
1951 if (count($orgInfo) == 1 && $field['is_required']) {
1952 // we only have one org - so we should default to it. Not sure about defaulting to first type
1953 // as it could be missed - so adding a select
1954 // however, possibly that is more similar to the membership form
1955 if (count($types[1]) > 1) {
1956 $types[1] = $select +
$types[1];
1960 $orgInfo = $select +
$orgInfo;
1962 $sel->setOptions(array($orgInfo, $types));
1964 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1965 $form->add('select', $name, $title,
1967 '' => ts('- select -'),
1968 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1971 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1973 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1974 foreach ($pseudoValues as $key => $var) {
1975 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1977 $group = $form->addGroup($options, $name, $title);
1979 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1982 $group->setAttribute('allowClear', TRUE);
1985 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1986 $form->addSelect($name, array(
1988 'entity' => 'contact',
1989 'field' => $fieldName,
1991 'placeholder' => '',
1994 elseif ($fieldName === 'contact_sub_type') {
1995 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1996 if ($usedFor == 'onbehalf') {
1997 $profileType = 'Organization';
1999 elseif ($usedFor == 'honor') {
2000 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
2003 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
2004 if ($profileType == 'Contact') {
2005 $profileType = 'Individual';
2009 $setSubtype = FALSE;
2010 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2011 $setSubtype = $profileType;
2012 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2015 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2018 $subtypeList = array();
2019 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2022 $subtypeList = $subtypes;
2025 $sel = $form->add('select', $name, $title, $subtypeList, $required);
2026 $sel->setMultiple(TRUE);
2028 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2029 //add email greeting, postal greeting, addressee, CRM-4575
2030 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2031 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2033 if (empty($profileType) ||
in_array($profileType, array(
2040 $profileType = 'Individual';
2042 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2043 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2046 'contact_type' => $profileType,
2047 'greeting_type' => $fieldName,
2049 $form->add('select', $name, $title,
2051 '' => ts('- select -'),
2052 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2054 // add custom greeting element
2055 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2059 elseif ($fieldName === 'preferred_communication_method') {
2060 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2061 foreach ($communicationFields as $key => $var) {
2065 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2067 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2069 elseif ($fieldName === 'preferred_mail_format') {
2070 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2072 elseif ($fieldName === 'preferred_language') {
2073 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2075 elseif ($fieldName == 'external_identifier') {
2076 $form->add('text', $name, $title, $attributes, $required);
2077 $contID = $contactId;
2079 $contID = $form->get('id');
2081 $form->addRule($name,
2082 ts('External ID already exists in Database.'),
2084 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2087 elseif ($fieldName === 'group') {
2088 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2089 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2094 elseif ($fieldName === 'tag') {
2095 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2096 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2101 elseif (substr($fieldName, 0, 4) === 'url-') {
2102 $form->add('text', $name, $title,
2103 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2105 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2106 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2111 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2113 // Note should be rendered as textarea
2114 elseif (substr($fieldName, -4) == 'note') {
2115 $form->add('textarea', $name, $title, $attributes, $required);
2117 elseif (substr($fieldName, 0, 6) === 'custom') {
2118 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2119 if ($customFieldID) {
2120 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2123 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2124 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2125 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2126 if ($customFieldID) {
2127 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2130 elseif (in_array($fieldName, array(
2136 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2138 elseif ($fieldName == 'send_receipt') {
2139 $form->addElement('checkbox', $name, $title);
2141 elseif ($fieldName == 'soft_credit') {
2142 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2143 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2145 elseif ($fieldName == 'product_name') {
2146 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2147 $sel = &$form->addElement('hierselect', $name, $title);
2149 '0' => ts('- select -'),
2151 $sel->setOptions(array($products, $options));
2153 elseif ($fieldName == 'payment_instrument') {
2154 $form->add('select', $name, $title,
2155 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2157 elseif ($fieldName == 'financial_type') {
2158 $form->add('select', $name, $title,
2160 '' => ts('- select -'),
2161 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2164 elseif ($fieldName == 'contribution_status_id') {
2165 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2166 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2172 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2175 $form->add('select', $name, $title,
2177 '' => ts('- select -'),
2178 ) +
$contributionStatuses, $required
2181 elseif ($fieldName == 'soft_credit_type') {
2182 $name = "soft_credit_type[$rowNumber]";
2183 $form->add('select', $name, $title,
2185 '' => ts('- select -'),
2186 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2188 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2189 //else (for contribution), use configured SCT default value
2190 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2191 if ($field['field_type'] == 'Membership') {
2192 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2194 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2196 elseif ($fieldName == 'currency') {
2197 $form->addCurrency($name, $title, $required);
2199 elseif ($fieldName == 'contribution_page_id') {
2200 $form->add('select', $name, $title,
2202 '' => ts('- select -'),
2203 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2206 elseif ($fieldName == 'participant_register_date') {
2207 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2209 elseif ($fieldName == 'activity_status_id') {
2210 $form->add('select', $name, $title,
2212 '' => ts('- select -'),
2213 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2216 elseif ($fieldName == 'activity_engagement_level') {
2217 $form->add('select', $name, $title,
2219 '' => ts('- select -'),
2220 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2223 elseif ($fieldName == 'activity_date_time') {
2224 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2226 elseif ($fieldName == 'participant_status') {
2228 if ($online == TRUE) {
2229 $cond = 'visibility_id = 1';
2231 $form->add('select', $name, $title,
2233 '' => ts('- select -'),
2234 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2237 elseif ($fieldName == 'participant_role') {
2238 if (!empty($field['is_multiple'])) {
2239 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2242 $form->add('select', $name, $title,
2244 '' => ts('- select -'),
2245 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2249 elseif ($fieldName == 'world_region') {
2250 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2252 elseif ($fieldName == 'signature_html') {
2253 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2255 elseif ($fieldName == 'signature_text') {
2256 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2258 elseif (substr($fieldName, -11) == 'campaign_id') {
2259 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2260 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2261 $form->_componentCampaigns
2263 $form->add('select', $name, $title,
2265 '' => ts('- select -'),
2266 ) +
$campaigns, $required, 'class="crm-select2 big"'
2270 elseif ($fieldName == 'activity_details') {
2271 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2273 elseif ($fieldName == 'activity_duration') {
2274 $form->add('text', $name, $title, $attributes, $required);
2275 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2278 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2279 $form->add('advcheckbox', $name, $title, $attributes, $required);
2282 $form->add('text', $name, $title, $attributes, $required);
2286 static $hiddenSubtype = FALSE;
2287 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2288 // In registration mode params are submitted via POST and we don't have any clue
2289 // about profile-id or the profile-type (which could be a subtype)
2290 // To generalize the behavior and simplify the process,
2291 // lets always add the hidden
2292 //subtype value if there is any, and we won't have to
2293 // compute it while processing.
2295 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2298 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2300 $hiddenSubtype = TRUE;
2303 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2304 $form->freeze($name);
2308 if (in_array($fieldName, array(
2309 'non_deductible_amount',
2314 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2317 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2318 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2324 * Set profile defaults.
2326 * @param int $contactId
2328 * @param array $fields
2329 * Associative array of fields.
2330 * @param array $defaults
2332 * @param bool $singleProfile
2333 * True for single profile else false(batch update).
2334 * @param int $componentId
2335 * Id for specific components like contribute, event etc.
2336 * @param null $component
2338 public static function setProfileDefaults(
2339 $contactId, &$fields, &$defaults,
2340 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2342 if (!$componentId) {
2343 //get the contact details
2344 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2345 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2346 $multipleFields = array('website' => 'url');
2348 //start of code to set the default values
2349 foreach ($fields as $name => $field) {
2350 // skip pseudo fields
2351 if (substr($name, 0, 9) == 'phone_ext') {
2355 //set the field name depending upon the profile mode(single/batch)
2356 if ($singleProfile) {
2360 $fldName = "field[$contactId][$name]";
2363 if ($name == 'group') {
2364 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2366 if ($name == 'tag') {
2367 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2370 if (!empty($details[$name]) ||
isset($details[$name])) {
2371 //to handle custom data (checkbox) to be written
2372 // to handle birth/deceased date, greeting_type and few other fields
2373 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2374 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2376 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2377 $defaults[$fldName] = $details[$name . '_id'];
2378 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2380 elseif ($name == 'preferred_communication_method') {
2381 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2382 foreach ($v as $item) {
2384 $defaults[$fldName . "[$item]"] = 1;
2388 elseif ($name == 'contact_sub_type') {
2389 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2391 elseif ($name == 'world_region') {
2392 $defaults[$fldName] = $details['worldregion_id'];
2394 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2395 //fix for custom fields
2396 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2398 // hack to add custom data for components
2399 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2400 foreach ($components as $value) {
2401 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2402 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2406 switch ($customFields[$customFieldId]['html_type']) {
2407 case 'Multi-Select State/Province':
2408 case 'Multi-Select Country':
2409 case 'AdvMulti-Select':
2410 case 'Multi-Select':
2411 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2412 foreach ($v as $item) {
2414 $defaults[$fldName][$item] = $item;
2420 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2421 foreach ($v as $item) {
2423 $defaults[$fldName][$item] = 1;
2424 // seems like we need this for QF style checkboxes in profile where its multiindexed
2426 $defaults["{$fldName}[{$item}]"] = 1;
2432 // CRM-6681, set defult values according to date and time format (if any).
2434 if (!empty($customFields[$customFieldId]['date_format'])) {
2435 $dateFormat = $customFields[$customFieldId]['date_format'];
2438 if (empty($customFields[$customFieldId]['time_format'])) {
2439 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2444 $timeElement = $fldName . '_time';
2445 if (substr($fldName, -1) == ']') {
2446 $timeElement = substr($fldName, 0, -1) . '_time]';
2448 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2449 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2454 $defaults[$fldName] = $details[$name];
2459 $defaults[$fldName] = $details[$name];
2463 $blocks = array('email', 'phone', 'im', 'openid');
2464 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2465 if (!in_array($fieldName, $multipleFields)) {
2466 if (is_array($details)) {
2467 foreach ($details as $key => $value) {
2468 // when we fixed CRM-5319 - get primary loc
2469 // type as per loc field and removed below code.
2470 $primaryLocationType = FALSE;
2471 if ($locTypeId == 'Primary') {
2472 if (is_array($value) && array_key_exists($fieldName, $value)) {
2473 $primaryLocationType = TRUE;
2474 if (in_array($fieldName, $blocks)) {
2475 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2478 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2483 // fixed for CRM-665
2484 if (is_numeric($locTypeId)) {
2485 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2486 if (!empty($value[$fieldName])) {
2487 //to handle stateprovince and country
2488 if ($fieldName == 'state_province') {
2489 $defaults[$fldName] = $value['state_province_id'];
2491 elseif ($fieldName == 'county') {
2492 $defaults[$fldName] = $value['county_id'];
2494 elseif ($fieldName == 'country') {
2495 if (!isset($value['country_id']) ||
!$value['country_id']) {
2496 $config = CRM_Core_Config
::singleton();
2497 if ($config->defaultContactCountry
) {
2498 $defaults[$fldName] = $config->defaultContactCountry
;
2502 $defaults[$fldName] = $value['country_id'];
2505 elseif ($fieldName == 'phone') {
2507 if (isset($value['phone'][$phoneTypeId])) {
2508 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2510 if (isset($value['phone_ext'][$phoneTypeId])) {
2511 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2515 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2517 if (!is_array($phoneDefault)) {
2518 $defaults[$fldName] = $phoneDefault;
2522 elseif ($fieldName == 'email') {
2523 //adding the first email (currently we don't support multiple emails of same location type)
2524 $defaults[$fldName] = $value['email'];
2526 elseif ($fieldName == 'im') {
2527 //adding the first im (currently we don't support multiple ims of same location type)
2528 $defaults[$fldName] = $value['im'];
2529 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2532 $defaults[$fldName] = $value[$fieldName];
2535 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2536 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2538 $defaults[$fldName] = $value[substr($fieldName, 8)];
2546 if (is_array($details)) {
2547 if ($fieldName === 'url'
2548 && !empty($details['website'])
2549 && !empty($details['website'][$locTypeId])
2551 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2559 //Handling Contribution Part of the batch profile
2560 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2561 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2564 //Handling Event Participation Part of the batch profile
2565 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2566 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2569 //Handling membership Part of the batch profile
2570 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2571 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2574 //Handling Activity Part of the batch profile
2575 if ($component == 'Activity') {
2576 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2581 * Get profiles by type eg: pure Individual etc
2583 * @param array $types
2584 * Associative array of types eg: types('Individual').
2585 * @param bool $onlyPure
2586 * True if only pure profiles are required.
2589 * associative array of profiles
2591 public static function getProfiles($types, $onlyPure = FALSE) {
2592 $profiles = array();
2593 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2595 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2597 // Exclude Batch Data Entry profiles - CRM-10901
2598 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2600 foreach ($ufGroups as $id => $title) {
2601 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2602 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2603 $profiles[$id] = $title;
2610 * Check whether a profile is valid combination of
2611 * required and/or optional profile types
2613 * @param array $required
2614 * Array of types those are required.
2615 * @param array $optional
2616 * Array of types those are optional.
2619 * associative array of profiles
2621 public static function getValidProfiles($required, $optional = NULL) {
2622 if (!is_array($required) ||
empty($required)) {
2626 $profiles = array();
2627 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2629 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2631 foreach ($ufGroups as $id => $title) {
2632 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2634 $profiles[$id] = $title;
2642 * Check whether a profile is valid combination of
2643 * required profile fields
2645 * @param array $ufId
2646 * Integer id of the profile.
2647 * @param array $required
2648 * Array of fields those are required in the profile.
2651 * associative array of profiles
2653 public static function checkValidProfile($ufId, $required = NULL) {
2654 $validProfile = FALSE;
2656 return $validProfile;
2659 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2660 return $validProfile;
2663 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2664 NULL, FALSE, NULL, FALSE, NULL,
2665 CRM_Core_Permission
::CREATE
, NULL
2668 $validProfile = array();
2669 if (!empty($profileFields)) {
2670 $fields = array_keys($profileFields);
2671 foreach ($fields as $val) {
2672 foreach ($required as $key => $field) {
2673 if (strpos($val, $field) === 0) {
2674 unset($required[$key]);
2679 $validProfile = (empty($required)) ?
TRUE : FALSE;
2682 return $validProfile;
2686 * Get default value for Register.
2688 * @param array $fields
2689 * @param array $defaults
2693 public static function setRegisterDefaults(&$fields, &$defaults) {
2694 $config = CRM_Core_Config
::singleton();
2695 foreach ($fields as $name => $field) {
2696 if (substr($name, 0, 8) == 'country-') {
2697 if (!empty($config->defaultContactCountry
)) {
2698 $defaults[$name] = $config->defaultContactCountry
;
2701 elseif (substr($name, 0, 15) == 'state_province-') {
2702 if (!empty($config->defaultContactStateProvince
)) {
2703 $defaults[$name] = $config->defaultContactStateProvince
;
2711 * make a copy of a profile, including
2712 * all the fields in the profile
2715 * The profile id to copy.
2719 public static function copy($id) {
2720 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2721 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2727 if ($pos = strrpos($copy->name
, "_{$id}")) {
2728 $copy->name
= substr_replace($copy->name
, '', $pos);
2730 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2733 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2734 array('uf_group_id' => $id),
2735 array('uf_group_id' => $copy->id
),
2740 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2741 array('uf_group_id' => $id),
2742 array('uf_group_id' => $copy->id
)
2745 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2749 UPDATE civicrm_uf_join
2751 WHERE uf_group_id = %2
2752 AND ( entity_id IS NULL OR entity_id <= 0 )
2755 1 => array($maxWeight +
1, 'Integer'),
2756 2 => array($copy->id
, 'Integer'),
2758 CRM_Core_DAO
::executeQuery($query, $p);
2759 if ($copy->is_reserved
) {
2760 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2761 $params = array(1 => array($copy->id
, 'Integer'));
2762 CRM_Core_DAO
::executeQuery($query, $params);
2764 CRM_Utils_Hook
::copy('UFGroup', $copy);
2770 * Process that send notification e-mails
2772 * @param int $contactID
2774 * @param array $values
2775 * Associative array of name/value pair.
2779 public static function commonSendMail($contactID, &$values) {
2780 if (!$contactID ||
!$values) {
2784 $template = CRM_Core_Smarty
::singleton();
2786 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2791 self
::profileDisplay($values['id'], $values['values'], $template);
2792 $emailList = explode(',', $values['email']);
2794 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2795 "reset=1&cid=$contactID",
2796 TRUE, NULL, FALSE, FALSE, TRUE
2799 //get the default domain email address.
2800 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2802 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2803 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2804 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)));
2807 foreach ($emailList as $emailTo) {
2808 // FIXME: take the below out of the foreach loop
2809 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2811 'groupName' => 'msg_tpl_workflow_uf',
2812 'valueName' => 'uf_notify',
2813 'contactId' => $contactID,
2814 'tplParams' => array(
2815 'displayName' => $displayName,
2816 'currentDate' => date('r'),
2817 'contactLink' => $contactLink,
2819 'from' => "$domainEmailName <$domainEmailAddress>",
2820 'toEmail' => $emailTo,
2827 * Given a contact id and a group id, returns the field values from the db
2828 * for this group and notify email only if group's notify field is
2829 * set and field values are not empty
2835 * @param array $params
2836 * @param bool $skipCheck
2840 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2842 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2844 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2845 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2847 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2849 if (!empty($values) &&
2854 'values' => $values,
2865 * Assign uf fields to template.
2869 * @param array $values
2870 * @param CRM_Core_Smarty $template
2874 public function profileDisplay($gid, $values, $template) {
2875 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2876 $template->assign('grouptitle', $groupTitle);
2877 if (count($values)) {
2878 $template->assign('values', $values);
2883 * Format fields for dupe Contact Matching.
2885 * @param array $params
2887 * @param int $contactId
2890 * assoicated formatted array
2892 public static function formatFields($params, $contactId = NULL) {
2894 // get the primary location type id and email
2895 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2898 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2899 $primaryLocationType = $defaultLocationType->id
;
2903 $locationType = array();
2905 $primaryLocation = 0;
2906 foreach ($params as $key => $value) {
2907 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2909 if ($locTypeId == 'Primary') {
2910 $locTypeId = $primaryLocationType;
2913 if (is_numeric($locTypeId)) {
2914 if (!in_array($locTypeId, $locationType)) {
2915 $locationType[$count] = $locTypeId;
2918 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2920 $data['location'][$loc]['location_type_id'] = $locTypeId;
2922 // if we are getting in a new primary email, dont overwrite the new one
2923 if ($locTypeId == $primaryLocationType) {
2924 if (!empty($params['email-' . $primaryLocationType])) {
2925 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2927 elseif (isset($primaryEmail)) {
2928 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2934 $data['location'][$loc]['is_primary'] = 1;
2936 if ($fieldName == 'phone') {
2938 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2941 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2943 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2945 elseif ($fieldName == 'email') {
2946 $data['location'][$loc]['email'][$loc]['email'] = $value;
2948 elseif ($fieldName == 'im') {
2949 $data['location'][$loc]['im'][$loc]['name'] = $value;
2952 if ($fieldName === 'state_province') {
2953 $data['location'][$loc]['address']['state_province_id'] = $value;
2955 elseif ($fieldName === 'country') {
2956 $data['location'][$loc]['address']['country_id'] = $value;
2959 $data['location'][$loc]['address'][$fieldName] = $value;
2964 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2965 if ($key === 'individual_suffix') {
2966 $data['suffix_id'] = $value;
2968 elseif ($key === 'individual_prefix') {
2969 $data['prefix_id'] = $value;
2971 elseif ($key === 'gender') {
2972 $data['gender_id'] = $value;
2974 elseif (substr($key, 0, 6) === 'custom') {
2975 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2977 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2978 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2980 // fix the date field
2981 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2982 $date = CRM_Utils_Date
::format($value);
2989 $data['custom'][$customFieldID] = array(
2992 'extends' => $customFields[$customFieldID]['extends'],
2993 'type' => $customFields[$customFieldID]['data_type'],
2994 'custom_field_id' => $customFieldID,
2998 elseif ($key == 'edit') {
3002 $data[$key] = $value;
3007 if (!$primaryLocation) {
3009 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
3016 * Calculate the profile type 'group_type' as per profile fields.
3020 * @param bool $includeTypeValues
3021 * @param int $ignoreFieldId
3022 * Ignore particular profile field.
3025 * list of calculated group type
3027 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3028 //get the profile fields.
3029 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3030 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3034 * Calculate the profile type 'group_type' as per profile fields.
3037 * @param bool $includeTypeValues
3038 * @param int $ignoreFieldId
3039 * Ignore perticular profile field.
3042 * list of calculated group type
3044 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3045 $groupType = $groupTypeValues = $customFieldIds = array();
3046 if (!empty($ufFields)) {
3047 foreach ($ufFields as $fieldName => $fieldValue) {
3048 //ignore field from group type when provided.
3049 //in case of update profile field.
3050 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3053 if (!in_array($fieldValue['field_type'], $groupType)) {
3054 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3057 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3058 $customFieldIds[$fldId] = $fldId;
3063 if (!empty($customFieldIds)) {
3064 $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) . ')';
3066 $customGroups = CRM_Core_DAO
::executeQuery($query);
3067 while ($customGroups->fetch()) {
3068 if (!$customGroups->extends_entity_column_value
) {
3072 $groupTypeName = "{$customGroups->extends}Type";
3073 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3074 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3077 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3079 $groupTypeValues[$groupTypeName][$val] = $val;
3084 if (!empty($groupTypeValues)) {
3085 $groupType = array_merge($groupType, $groupTypeValues);
3093 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3094 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3097 * BirthDate + Email Individual,Contact
3098 * BirthDate + Subject Individual,Activity
3099 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3100 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3101 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3102 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3103 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3104 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3105 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3108 * @param array $groupTypes
3109 * With key having group type names.
3113 public static function updateGroupTypes($gId, $groupTypes = array()) {
3114 if (!is_array($groupTypes) ||
!$gId) {
3118 // If empty group types set group_type as 'null'
3119 if (empty($groupTypes)) {
3120 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3123 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3124 $validGroupTypes = array_merge(array(
3129 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3131 $gTypes = $gTypeValues = array();
3133 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3134 // Get valid group type and group subtypes
3135 foreach ($groupTypes as $groupType => $value) {
3136 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3137 $gTypes[] = $groupType;
3142 if (in_array($groupType, $participantExtends)) {
3143 $subTypesOf = $groupType;
3145 elseif (strpos($groupType, 'Type') > 0) {
3146 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3152 if (!empty($value) &&
3153 (in_array($subTypesOf, $componentGroupTypes) ||
3154 in_array($subTypesOf, $participantExtends)
3157 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3161 if (empty($gTypes)) {
3165 // Build String to store group types and group subtypes
3166 $groupTypeString = implode(',', $gTypes);
3167 if (!empty($gTypeValues)) {
3168 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3171 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3175 * Create a "group_type" string.
3177 * @param array $coreTypes
3178 * E.g. array('Individual','Contact','Student').
3179 * @param array $subTypes
3180 * E.g. array('ActivityType' => array(7, 11)).
3181 * @param string $delim
3184 * @throws CRM_Core_Exception
3186 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3187 $groupTypeExpr = '';
3189 $groupTypeExpr .= implode(',', $coreTypes);
3192 //CRM-15427 Allow Multiple subtype filtering
3193 //if (count($subTypes) > 1) {
3194 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3196 foreach ($subTypes as $subType => $subTypeIds) {
3197 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3200 return $groupTypeExpr;
3204 * setDefault componet specific profile fields.
3206 * @param array $fields
3208 * @param int $componentId
3210 * @param string $component
3212 * @param array $defaults
3213 * An array of default values.
3215 * @param bool $isStandalone
3219 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3220 if (!$componentId ||
3221 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3226 $componentBAO = $componentSubType = NULL;
3227 switch ($component) {
3229 $componentBAO = 'CRM_Member_BAO_Membership';
3230 $componentBAOName = 'Membership';
3231 $componentSubType = array('membership_type_id');
3235 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3236 $componentBAOName = 'Contribution';
3237 $componentSubType = array('financial_type_id');
3241 $componentBAO = 'CRM_Event_BAO_Participant';
3242 $componentBAOName = 'Participant';
3243 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3247 $componentBAO = 'CRM_Activity_BAO_Activity';
3248 $componentBAOName = 'Activity';
3249 $componentSubType = array('activity_type_id');
3254 $params = array('id' => $componentId);
3256 //get the component values.
3257 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3258 if ($componentBAOName == 'Participant') {
3259 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3262 $formattedGroupTree = array();
3263 $dateTimeFields = array(
3264 'participant_register_date',
3265 'activity_date_time',
3270 'membership_start_date',
3271 'membership_end_date',
3274 foreach ($fields as $name => $field) {
3275 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3276 if (in_array($name, $dateTimeFields)) {
3277 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3278 if (!empty($values[$name])) {
3279 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3282 elseif (array_key_exists($name, $values)) {
3283 $defaults[$fldName] = $values[$name];
3285 elseif ($name == 'participant_note') {
3286 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3287 $defaults[$fldName] = array_pop($noteDetails);
3289 elseif (in_array($name, array(
3291 'payment_instrument',
3292 'participant_status',
3295 $defaults[$fldName] = $values["{$name}_id"];
3297 elseif ($name == 'membership_type') {
3298 // since membership_type field is a hierselect -
3299 $defaults[$fldName][0]
3300 = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3301 $defaults[$fldName][1] = $values['membership_type_id'];
3303 elseif ($name == 'membership_status') {
3304 $defaults[$fldName] = $values['status_id'];
3306 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3307 if (empty($formattedGroupTree)) {
3308 //get the groupTree as per subTypes.
3309 $groupTree = array();
3310 foreach ($componentSubType as $subType) {
3311 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3312 $componentId, 0, $values[$subType]
3314 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3316 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3317 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3320 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3321 foreach ($defaults as $customKey => $customValue) {
3322 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3323 if ($name == 'custom_' . $customFieldDetails[0]) {
3325 //hack to set default for checkbox
3326 //basically this is for weired field name like field[33][custom_19]
3327 //we are converting this field name to array structure and assign value.
3330 foreach ($formattedGroupTree as $tree) {
3331 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3332 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3334 $defaults['field'][$componentId][$name] = $customValue;
3337 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3340 // CRM-6681, $default contains formatted date, time values.
3341 $defaults[$fldName] = $customValue;
3342 if (!empty($defaults[$customKey . '_time'])) {
3343 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3349 if (!$skipValue ||
$isStandalone) {
3350 $defaults[$fldName] = $customValue;
3352 unset($defaults[$customKey]);
3362 * @param array|string $profiles - name of profile(s) to create links for
3363 * @param array $appendProfiles
3364 * Name of profile(s) to append to each link.
3368 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3369 // Default to contact profiles
3371 $profiles = array('new_individual', 'new_organization', 'new_household');
3373 $profiles = (array) $profiles;
3374 $toGet = array_merge($profiles, (array) $appendProfiles);
3375 $retrieved = civicrm_api3('uf_group', 'get', array(
3376 'name' => array('IN' => $toGet),
3379 $links = $append = array();
3380 if (!empty($retrieved['values'])) {
3381 foreach ($retrieved['values'] as $id => $profile) {
3382 if (in_array($profile['name'], $profiles)) {
3384 'label' => $profile['title'],
3385 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3386 NULL, NULL, FALSE, FALSE, TRUE),
3387 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3394 foreach ($append as $id) {
3395 foreach ($links as &$link) {
3396 $link['url'] .= ",$id";
3404 * Retrieve groups of profiles.
3406 * @param int $profileID
3407 * Id of the profile.
3412 public static function profileGroups($profileID) {
3413 $groupTypes = array();
3414 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3415 if ($profileTypes) {
3416 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3417 $groupTypes = explode(',', $groupTypeParts[0]);
3423 * Alter contact params by filtering existing subscribed groups and returns
3424 * unsubscribed groups array for subscription.
3426 * @param array $params
3428 * @param int $contactId
3432 * This contains array of groups for subscription
3434 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3435 $config = CRM_Core_Config
::singleton();
3436 $subscribeGroupIds = array();
3438 // process further only if profileDoubleOptIn enabled and if groups exist
3439 if (!array_key_exists('group', $params) ||
3440 !self
::isProfileDoubleOptin() ||
3441 CRM_Utils_System
::isNull($params['group'])
3443 return $subscribeGroupIds;
3446 //check if contact email exist.
3448 foreach ($params as $name => $value) {
3449 if (strpos($name, 'email-') !== FALSE) {
3455 //Proceed furthur only if email present
3457 return $subscribeGroupIds;
3460 //do check for already subscriptions.
3461 $contactGroups = array();
3465 FROM civicrm_group_contact
3466 WHERE status = 'Added'
3467 AND contact_id = %1";
3469 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3470 while ($dao->fetch()) {
3471 $contactGroups[$dao->group_id
] = $dao->group_id
;
3475 //since we don't have names, compare w/ label.
3476 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3478 //actual processing start.
3479 foreach ($params['group'] as $groupId => $isSelected) {
3480 //unset group those are not selected.
3482 unset($params['group'][$groupId]);
3486 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3487 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3489 //get only mailing type group and unset it from params
3490 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3491 $subscribeGroupIds[$groupId] = $groupId;
3492 unset($params['group'][$groupId]);
3496 return $subscribeGroupIds;
3500 * Check if we are rendering mixed profiles.
3502 * @param array $profileIds
3503 * Associated array of profile ids.
3506 * true if profile is mixed
3508 public static function checkForMixProfiles($profileIds) {
3509 $mixProfile = FALSE;
3511 $contactTypes = array('Individual', 'Household', 'Organization');
3512 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3514 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3516 $typeCount = array('ctype' => array(), 'subtype' => array());
3517 foreach ($profileIds as $gid) {
3518 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3519 // ignore profile of type Contact
3520 if ($profileType == 'Contact') {
3523 if (in_array($profileType, $contactTypes)) {
3524 if (!isset($typeCount['ctype'][$profileType])) {
3525 $typeCount['ctype'][$profileType] = 1;
3528 // check if we are rendering profile of different contact types
3529 if (count($typeCount['ctype']) == 2) {
3534 elseif (in_array($profileType, $components)) {
3539 if (!isset($typeCount['subtype'][$profileType])) {
3540 $typeCount['subtype'][$profileType] = 1;
3542 // check if we are rendering profile of different contact sub types
3543 if (count($typeCount['subtype']) == 2) {
3553 * Determine of we show overlay profile or not.
3556 * true if profile should be shown else false
3558 public static function showOverlayProfile() {
3559 $showOverlay = TRUE;
3561 // get the id of overlay profile
3562 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3563 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3565 $count = CRM_Core_DAO
::singleValueQuery($query);
3567 //check if there are no public fields and use is anonymous
3568 $session = CRM_Core_Session
::singleton();
3569 if (!$count && !$session->get('userID')) {
3570 $showOverlay = FALSE;
3573 return $showOverlay;
3577 * Get group type values of the profile.
3579 * @param int $profileId
3580 * @param string $groupType
3585 public static function groupTypeValues($profileId, $groupType = NULL) {
3586 $groupTypeValue = array();
3587 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3589 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3590 if (empty($groupTypeParts[1])) {
3591 return $groupTypeValue;
3593 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3595 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3597 $valueParts = explode(':', $groupTypeValues);
3599 ($valueParts[0] != "{$groupType}Type" ||
3600 ($groupType == 'Participant' &&
3601 !in_array($valueParts[0], $participantExtends)
3607 foreach ($valueParts as $val) {
3608 if (CRM_Utils_Rule
::integer($val)) {
3609 $values[$val] = $val;
3612 if (!empty($values)) {
3613 $typeName = substr($valueParts[0], 0, -4);
3614 if (in_array($valueParts[0], $participantExtends)) {
3615 $typeName = $valueParts[0];
3617 $groupTypeValue[$typeName] = $values;
3621 return $groupTypeValue;
3625 * @return bool|object
3627 public static function isProfileDoubleOptin() {
3628 // check for double optin
3629 $config = CRM_Core_Config
::singleton();
3630 if (in_array('CiviMail', $config->enableComponents
)) {
3631 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3632 'profile_double_optin', NULL, FALSE
3639 * @return bool|object
3641 public static function isProfileAddToGroupDoubleOptin() {
3642 // check for add to group double optin
3643 $config = CRM_Core_Config
::singleton();
3644 if (in_array('CiviMail', $config->enableComponents
)) {
3645 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3646 'profile_add_to_group_double_optin', NULL, FALSE
3653 * Get profiles used for batch entry.
3656 * profileIds profile ids
3658 public static function getBatchProfiles() {
3660 FROM civicrm_uf_group
3661 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3662 $dao = CRM_Core_DAO
::executeQuery($query);
3663 $profileIds = array();
3664 while ($dao->fetch()) {
3665 $profileIds[$dao->id
] = $dao->id
;
3671 * @todo what do I do?
3673 * @param $destination
3674 * @param bool $returnMultiSummaryFields
3676 * @return array|null
3678 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3679 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3680 foreach ($source as $field => $properties) {
3681 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3684 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3685 $destination[$field] = $properties;
3686 if ($returnMultiSummaryFields) {
3687 if ($properties['is_multi_summary']) {
3688 $multiSummaryFields[$field] = $properties;
3691 unset($source[$field]);
3694 return $multiSummaryFields;
3698 * This is function is used to format pseudo fields.
3700 * @param array $fields
3701 * Associated array of profile fields.
3704 public static function reformatProfileFields(&$fields) {
3705 //reformat fields array
3706 foreach ($fields as $name => $field) {
3707 //reformat phone and extension field
3708 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3709 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3711 // retain existing element properties and just update and replace key
3712 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3713 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3714 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3716 // add additional phone extension field
3717 $fields["phone_ext-{$fieldSuffix}"] = $field;
3718 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3719 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3720 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3721 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3722 //ignore required for extension field
3723 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;