3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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-2014
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.
59 * @return object 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
72 * @return string contact type
74 public static function getContactType($id) {
76 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
77 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
79 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
80 $types = explode(',', $typesParts[0]);
83 foreach ($types as $type) {
84 if (in_array($type, $validTypes)) {
87 elseif (array_key_exists($type, $validSubTypes)) {
88 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
104 * @return string 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.
121 * @return Object 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.
138 * @return array 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
199 * @return array the fields that are listings related
202 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']) { unset($subset[$name]);
249 $fields = array_merge($fields, $subset);
256 * Get all the fields that belong to the group with the name title,
257 * and format for use with buildProfile. This is the SQL analog of
261 * The id of the UF group or ids of ufgroup.
262 * @param bool|int $register are we interested in registration fields
264 * What action are we doing.
265 * @param int $visibility
266 * Visibility of fields we are interested in.
268 * @param bool $showAll
269 * @param string $restrict
270 * Should we restrict based on a specified profile type.
271 * @param bool $skipPermission
273 * @param int $permissionType
274 * @param string $orderBy
275 * @param null $orderProfiles
277 * @return array the fields that belong to this ufgroup(s)
280 static function getFields(
288 $skipPermission = FALSE,
290 $permissionType = CRM_Core_Permission
::CREATE
,
291 $orderBy = 'field_name',
292 $orderProfiles = NULL
294 if (!is_array($id)) {
295 $id = CRM_Utils_Type
::escape($id, 'Positive');
296 $profileIds = array($id);
302 $gids = implode(',', $profileIds);
305 $query = "SELECT g.* from civicrm_uf_group g
306 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
307 WHERE g.id IN ( {$gids} )
308 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
310 $params = array(1 => array($restrict, 'String'));
313 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
317 $query .= " AND g.is_active = 1";
320 // add permissioning for profiles only if not registration
321 if (!$skipPermission) {
322 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
323 $query .= " AND $permissionClause ";
326 if ($orderProfiles AND count($profileIds) > 1) {
327 $query .= " ORDER BY FIELD( g.id, {$gids} )";
329 $group = CRM_Core_DAO
::executeQuery($query, $params);
333 while ($group->fetch()) {
335 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
336 $field = CRM_Core_DAO
::executeQuery($query);
338 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
339 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
340 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
341 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
343 while ($field->fetch()) {
344 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
345 if ($formattedField !== NULL) {
346 $fields[$name] = $formattedField;
352 if (empty($fields) && !$validGroup) {
353 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.',
354 array(1 => implode(',', $profileIds))
358 self
::reformatProfileFields($fields);
365 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
368 * @param array $groupArr
369 * (mimic CRM_UF_DAO_UFGroup).
370 * @param array $fieldArrs
371 * List of fields (each mimics CRM_UF_DAO_UFField).
372 * @param bool $visibility
373 * Visibility of fields we are interested in.
374 * @param bool $searchable
375 * @param bool $showAll
377 * @param int $permissionType
380 * @see self::getFields
382 public static function formatUFFields(
389 $permissionType = CRM_Core_Permission
::CREATE
391 // $group = new CRM_Core_DAO_UFGroup();
392 // $group->copyValues($groupArr); // no... converts string('') to string('null')
393 $group = (object) $groupArr;
395 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
396 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
397 // they did -- the obvious fix would produce mutual recursion.
398 $ufGroupType = self
::_calculateGroupType($fieldArrs);
399 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',', $ufGroupType));
400 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',', $ufGroupType));
401 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
402 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
404 $formattedFields = array();
405 foreach ($fieldArrs as $fieldArr) {
406 $field = (object) $fieldArr;
407 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
411 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
412 if ($formattedField !== NULL) {
413 $formattedFields[$name] = $formattedField;
416 return $formattedFields;
420 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
422 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
423 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
424 * @param array $addressCustomFields
425 * @param array $importableFields
426 * @param array $customFields
427 * @param int $permissionType
428 * Eg CRM_Core_Permission::CREATE.
431 protected static function formatUFField(
435 $addressCustomFields,
437 $permissionType = CRM_Core_Permission
::CREATE
439 $name = $field->field_name
;
440 $title = $field->label
;
442 $addressCustom = FALSE;
443 if (in_array($permissionType, array(
444 CRM_Core_Permission
::CREATE
,
445 CRM_Core_Permission
::EDIT
,
447 in_array($field->field_name
, array_keys($addressCustomFields))
449 $addressCustom = TRUE;
450 $name = "address_{$name}";
452 if ($field->field_name
== 'url') {
453 $name .= "-{$field->website_type_id}";
455 elseif (!empty($field->location_type_id
)) {
456 $name .= "-{$field->location_type_id}";
459 $locationFields = self
::getLocationFields();
460 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
465 if (isset($field->phone_type_id
)) {
466 $name .= "-{$field->phone_type_id}";
469 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
470 // I guess to make field self sufficient with all the required data and avoid additional calls
471 $formattedField = array(
473 'groupTitle' => $group->title
,
474 'groupName' => $group->name
,
475 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
476 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
478 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
479 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
480 'is_required' => $field->is_required
,
481 'is_view' => $field->is_view
,
482 'help_pre' => $field->help_pre
,
483 'help_post' => $field->help_post
,
484 'visibility' => $field->visibility
,
485 'in_selector' => $field->in_selector
,
486 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
487 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
488 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
489 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
490 'group_id' => $group->id
,
491 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
492 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
493 'field_type' => $field->field_type
,
494 'field_id' => $field->id
,
495 'pseudoconstant' => CRM_Utils_Array
::value(
497 CRM_Utils_Array
::value($field->field_name
, $importableFields)
499 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
500 'dbName' => CRM_Utils_Array
::value(
502 CRM_Utils_Array
::value($field->field_name
, $importableFields)
507 //adding custom field property
508 if (substr($field->field_name
, 0, 6) == 'custom' ||
509 substr($field->field_name
, 0, 14) === 'address_custom'
511 // if field is not present in customFields, that means the user
512 // DOES NOT HAVE permission to access that field
513 if (array_key_exists($field->field_name
, $customFields)) {
514 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
516 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
517 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
518 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
520 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
521 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
522 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
525 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
526 return array($name, $formattedField);
529 $formattedField = NULL;
530 return array($name, $formattedField);
533 return array($name, $formattedField);
537 * Create a query to find all visible UFFields in a UFGroup
539 * This is the SQL-variant of checkUFFieldDisplayable().
541 * @param int $groupId
542 * @param bool $searchable
543 * @param bool $showAll
544 * @param int $visibility
545 * @param string $orderBy
546 * Comma-delimited list of SQL columns.
549 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
550 $where = " WHERE uf_group_id = {$groupId}";
553 $where .= " AND is_searchable = 1";
557 $where .= " AND is_active = 1";
562 if ($visibility & self
::PUBLIC_VISIBILITY
) {
563 $clause[] = 'visibility = "Public Pages"';
565 if ($visibility & self
::ADMIN_VISIBILITY
) {
566 $clause[] = 'visibility = "User and User Admin Only"';
568 if ($visibility & self
::LISTINGS_VISIBILITY
) {
569 $clause[] = 'visibility = "Public Pages and Listings"';
571 if (!empty($clause)) {
572 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
576 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
578 $query .= ", " . $orderBy;
585 * Create a query to find all visible UFFields in a UFGroup
587 * This is the PHP in-memory variant of createUFFieldQuery().
589 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
590 * @param bool $searchable
591 * @param bool $showAll
592 * @param int $visibility
593 * @return bool TRUE if field is displayable
595 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
596 if ($searchable && $field->is_searchable
!= 1) {
600 if (!$showAll && $field->is_active
!= 1) {
605 $allowedVisibilities = array();
606 if ($visibility & self
::PUBLIC_VISIBILITY
) {
607 $allowedVisibilities[] = 'Public Pages';
609 if ($visibility & self
::ADMIN_VISIBILITY
) {
610 $allowedVisibilities[] = 'User and User Admin Only';
612 if ($visibility & self
::LISTINGS_VISIBILITY
) {
613 $allowedVisibilities[] = 'Public Pages and Listings';
615 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
616 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
626 * @param $profileType
627 * @param $contactActivityProfile
631 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
633 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
636 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
639 if ($profileType == 'Activity' ||
$contactActivityProfile) {
640 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
643 $componentFields = CRM_Core_Component
::getQueryFields();
646 $importableFields = array_merge($importableFields, $componentFields);
648 $importableFields['group']['title'] = ts('Group(s)');
649 $importableFields['group']['where'] = NULL;
650 $importableFields['tag']['title'] = ts('Tag(s)');
651 $importableFields['tag']['where'] = NULL;
652 return $importableFields;
655 public static function getLocationFields() {
656 static $locationFields = array(
658 'supplemental_address_1',
659 'supplemental_address_2',
662 'postal_code_suffix',
675 return $locationFields;
683 protected static function getCustomFields($ctype) {
684 static $customFieldCache = array();
685 if (!isset($customFieldCache[$ctype])) {
686 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
688 // hack to add custom data for components
689 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
690 foreach ($components as $value) {
691 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
693 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
694 $customFields = array_merge($customFields, $addressCustomFields);
695 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
697 return $customFieldCache[$ctype];
701 * Check the data validity
704 * The user id that we are actually editing.
705 * @param string $title
706 * The title of the group we are interested in.
707 * @param bool $register
709 * The action of the form.
711 * @pram boolean $register is this the registrtion form
712 * @return boolean true if form is valid
715 public static function isValid($userID, $title, $register = FALSE, $action = NULL) {
717 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
718 ts('Dynamic Form Creator'),
721 $controller->set('id', $userID);
722 $controller->set('register', 1);
723 $controller->process();
724 return $controller->validate();
727 // make sure we have a valid group
728 $group = new CRM_Core_DAO_UFGroup();
730 $group->title
= $title;
732 if ($group->find(TRUE) && $userID) {
733 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
734 $controller->set('gid', $group->id
);
735 $controller->set('id', $userID);
736 $controller->set('register', 0);
737 $controller->process();
738 return $controller->validate();
745 * Get the html for the form that represents this particular group
748 * The user id that we are actually editing.
749 * @param string $title
750 * The title of the group we are interested in.
752 * The action of the form.
753 * @param bool $register
754 * Is this the registration form.
756 * Should we reset the form?.
757 * @param int $profileID
758 * Do we have the profile ID?.
760 * @param bool $doNotProcess
763 * @return string the html for the form on success, otherwise empty string
766 static function getEditHTML(
773 $doNotProcess = FALSE,
778 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
779 ts('Dynamic Form Creator'),
782 if ($reset ||
$doNotProcess) {
783 // hack to make sure we do not process this form
784 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
787 unset($_POST['_qf_default']);
788 unset($_REQUEST['_qf_default']);
790 $controller->reset();
794 $controller->set('id', $userID);
795 $controller->set('register', 1);
796 $controller->set('skipPermission', 1);
797 $controller->set('ctype', $ctype);
798 $controller->process();
799 if ($doNotProcess ||
!empty($_POST)) {
800 $controller->validate();
802 $controller->setEmbedded(TRUE);
804 //CRM-5839 - though we want to process form, get the control back.
805 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
809 // we are done processing so restore the POST/REQUEST vars
810 if (($reset ||
$doNotProcess) && $oldQFDefault) {
811 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
814 $template = CRM_Core_Smarty
::singleton();
816 // Hide CRM error messages if they are displayed using drupal form_set_error.
817 if (!empty($_POST)) {
818 $template->assign('suppressForm', TRUE);
821 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
825 // make sure we have a valid group
826 $group = new CRM_Core_DAO_UFGroup();
828 $group->title
= $title;
830 if ($group->find(TRUE)) {
831 $profileID = $group->id
;
836 // make sure profileID and ctype match if ctype exists
838 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
839 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
840 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
843 if (($profileType != 'Contact') && ($profileType != $ctype)) {
848 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
849 ts('Dynamic Form Creator'),
853 $controller->reset();
855 $controller->set('gid', $profileID);
856 $controller->set('id', $userID);
857 $controller->set('register', 0);
858 $controller->set('skipPermission', 1);
860 $controller->set('ctype', $ctype);
862 $controller->process();
863 $controller->setEmbedded(TRUE);
865 //CRM-5846 - give the control back to drupal.
866 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
869 $template = CRM_Core_Smarty
::singleton();
871 // Hide CRM error messages if they are displayed using drupal form_set_error.
872 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
873 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
874 $template->assign('suppressForm', TRUE);
878 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
879 if (!$template->template_exists($templateFile)) {
880 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
882 return trim($template->fetch($templateFile));
885 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
887 // if post not empty then only proceed
888 if (!empty($_POST)) {
890 $config = CRM_Core_Config
::singleton();
891 $email = CRM_Utils_Array
::value('mail', $_POST);
893 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
894 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
903 * Searches for a contact in the db with similar attributes
905 * @param array $params
906 * The list of values to be used in the where clause.
908 * The current contact id (hence excluded from matching).
909 * @param string $contactType
911 * @return int|null contact_id if found, null otherwise
914 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
915 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
916 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
917 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
919 return implode(',', $ids);
927 * Given a contact id and a field set, return the values from the db
931 * @param array $fields
932 * The profile fields of interest.
933 * @param array $values
934 * The values for the above fields.
935 * @param bool $searchable
937 * @param array $componentWhere
938 * Component condition.
939 * @param bool $absolute
940 * Return urls in absolute form (useful when sending an email).
941 * @param null $additionalWhereClause
946 public static function getValues(
947 $cid, &$fields, &$values,
948 $searchable = TRUE, $componentWhere = NULL,
949 $absolute = FALSE, $additionalWhereClause = NULL
951 if (empty($cid) && empty($componentWhere)) {
955 // get the contact details (hier)
956 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
957 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
959 // add conditions specified by components. eg partcipant_id etc
960 if (!empty($componentWhere)) {
961 $params = array_merge($params, $componentWhere);
964 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
965 $options = &$query->_options
;
967 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
968 FALSE, FALSE, FALSE, $additionalWhereClause);
969 if (!$details->fetch()) {
972 $query->convertToPseudoNames($details);
973 $config = CRM_Core_Config
::singleton();
975 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
976 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
977 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
979 $multipleFields = array('url');
981 //start of code to set the default values
982 foreach ($fields as $name => $field) {
985 $name = 'contact_id';
988 // skip fields that should not be displayed separately
989 if (!empty($field['skipDisplay'])) {
993 // Create a unique, non-empty index for each field.
994 $index = $field['title'];
998 while (array_key_exists($index, $values)) {
1002 $params[$index] = $values[$index] = '';
1003 $customFieldName = NULL;
1005 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
1006 // to handle gender / suffix / prefix
1007 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
1008 $params[$index] = $details->$name;
1009 $values[$index] = $details->$name;
1011 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1012 $dname = $name . '_display';
1013 $values[$index] = $details->$dname;
1014 $name = $name . '_id';
1015 $params[$index] = $details->$name;
1017 elseif (in_array($name, array(
1022 $values[$index] = $details->$name;
1023 $idx = $name . '_id';
1024 $params[$index] = $details->$idx;
1026 elseif ($name === 'preferred_communication_method') {
1027 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1029 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1031 foreach ($pref as $k) {
1033 $compref[] = $communicationFields[$k];
1036 $params[$index] = $details->$name;
1037 $values[$index] = implode(',', $compref);
1039 elseif ($name === 'preferred_language') {
1040 $params[$index] = $details->$name;
1041 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1043 elseif ($name == 'group') {
1044 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1045 $title = $ids = array();
1047 foreach ($groups as $g) {
1048 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1049 // VIEW permission on that group
1050 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1052 if ($g['visibility'] != 'User and User Admin Only' ||
1053 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1055 $title[] = $g['title'];
1056 if ($g['visibility'] == 'Public Pages') {
1057 $ids[] = $g['group_id'];
1061 $values[$index] = implode(', ', $title);
1062 $params[$index] = implode(',', $ids);
1064 elseif ($name == 'tag') {
1065 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1066 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1068 foreach ($entityTags as $tagId) {
1069 $title[] = $allTags[$tagId];
1071 $values[$index] = implode(', ', $title);
1072 $params[$index] = implode(',', $entityTags);
1074 elseif ($name == 'activity_status_id') {
1075 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1076 $values[$index] = $activityStatus[$details->$name];
1077 $params[$index] = $details->$name;
1079 elseif ($name == 'activity_date_time') {
1080 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1081 $params[$index] = $details->$name;
1083 elseif ($name == 'contact_sub_type') {
1084 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1085 if (!empty($contactSubTypeNames)) {
1086 $contactSubTypeLabels = array();
1087 // get all contact subtypes
1088 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1089 // build contact subtype labels array
1090 foreach ($contactSubTypeNames as $cstName) {
1092 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1095 $values[$index] = implode(',', $contactSubTypeLabels);
1098 $params[$index] = $details->$name;
1101 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1102 if ($details->$name) {
1103 $values[$index] = '[ x ]';
1107 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1108 $htmlType = $field['html_type'];
1110 // field_type is only set when we are retrieving profile values
1111 // when sending email, we call the same function to get custom field
1112 // values etc, i.e. emulating a profile
1113 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1115 if ($htmlType == 'File') {
1118 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1120 $entityId = $componentWhere[0][2];
1123 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1127 $additionalWhereClause
1129 $params[$index] = $values[$index] = $fileURL['file_url'];
1133 if (isset($dao) && property_exists($dao, 'data_type') &&
1134 ($dao->data_type
== 'Int' ||
1135 $dao->data_type
== 'Boolean'
1138 $customVal = (int ) ($details->{$name});
1140 elseif (isset($dao) && property_exists($dao, 'data_type')
1141 && $dao->data_type
== 'Float'
1143 $customVal = (float ) ($details->{$name});
1145 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1149 $customVal = $details->{$name};
1153 if (CRM_Utils_System
::isNull($customVal)) {
1157 $params[$index] = $customVal;
1158 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1162 if ($field['data_type'] == 'ContactReference') {
1163 $params[$index] = $values[$index];
1165 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1166 $cfID, 'is_search_range'
1169 $customFieldName = "{$name}_from";
1173 elseif ($name == 'image_URL') {
1174 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1175 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1177 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1178 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1180 elseif (in_array($name, array(
1183 'membership_start_date',
1184 'membership_end_date',
1187 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1188 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1192 if ($index == 'Campaign') {
1193 $dao = 'CRM_Campaign_DAO_Campaign';
1195 elseif ($index == 'Contribution Page') {
1196 $dao = 'CRM_Contribute_DAO_ContributionPage';
1199 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1202 $value = $details->$name;
1204 $values[$index] = $value;
1209 elseif (strpos($name, '-') !== FALSE) {
1210 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1212 if (!in_array($fieldName, $multipleFields)) {
1213 if ($id == 'Primary') {
1215 // not sure why we'd every use Primary location type id
1216 // we need to fix the source if we are using it
1217 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1218 $locationTypeName = 1;
1221 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1224 if (!$locationTypeName) {
1228 $detailName = "{$locationTypeName}-{$fieldName}";
1229 $detailName = str_replace(' ', '_', $detailName);
1231 if (in_array($fieldName, array(
1238 $detailName .= "-{$type}";
1242 if (in_array($fieldName, array(
1247 $values[$index] = $details->$detailName;
1248 $idx = $detailName . '_id';
1249 $params[$index] = $details->$idx;
1251 elseif ($fieldName == 'im') {
1252 $providerId = $detailName . '-provider_id';
1253 if (isset($imProviders[$details->$providerId])) {
1254 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1257 $values[$index] = $details->$detailName;
1259 $params[$index] = $details->$detailName;
1261 elseif ($fieldName == 'phone') {
1262 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1263 if (isset($details->$phoneExtField)) {
1264 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1267 $values[$index] = $details->$detailName;
1269 $params[$index] = $details->$detailName;
1272 $values[$index] = $params[$index] = $details->$detailName;
1276 $detailName = "website-{$id}-{$fieldName}";
1277 $url = CRM_Utils_System
::fixURL($details->$detailName);
1278 if ($details->$detailName) {
1279 $websiteTypeId = "website-{$id}-website_type_id";
1280 $websiteType = $websiteTypes[$details->$websiteTypeId];
1281 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1284 $values[$index] = '';
1289 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1290 CRM_Core_Permission
::check('profile listings and forms')
1293 if (CRM_Utils_System
::isNull($params[$index])) {
1294 $params[$index] = $values[$index];
1296 if (!isset($params[$index])) {
1299 if (!$customFieldName) {
1300 $fieldName = $field['name'];
1303 $fieldName = $customFieldName;
1307 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1308 $htmlType = $field['html_type'];
1309 if ($htmlType == 'Link') {
1310 $url = $params[$index];
1312 elseif (in_array($htmlType, array(
1316 'Multi-Select State/Province',
1317 'Multi-Select Country',
1319 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1320 $selectedOptions = explode($valSeperator, $params[$index]);
1322 foreach ($selectedOptions as $key => $multiOption) {
1324 $url[] = CRM_Utils_System
::url('civicrm/profile',
1325 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1326 urlencode($fieldName) .
1328 urlencode($multiOption)
1334 $url = CRM_Utils_System
::url('civicrm/profile',
1335 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1336 urlencode($fieldName) .
1338 urlencode($params[$index])
1343 $url = CRM_Utils_System
::url('civicrm/profile',
1344 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1345 urlencode($fieldName) .
1347 urlencode($params[$index])
1352 !empty($values[$index]) &&
1356 if (is_array($url) && !empty($url)) {
1358 $eachMultiValue = explode(', ', $values[$index]);
1359 foreach ($eachMultiValue as $key => $valueLabel) {
1360 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1362 $values[$index] = implode(', ', $links);
1365 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1373 * Check if profile Group used by any module.
1383 public static function usedByModule($id) {
1384 //check whether this group is used by any module(check uf join records)
1386 FROM civicrm_uf_join
1387 WHERE civicrm_uf_join.uf_group_id=$id";
1389 $dao = new CRM_Core_DAO();
1391 if ($dao->fetch()) {
1400 * Delete the profile Group.
1410 public static function del($id) {
1411 //check whether this group contains any profile fields
1412 $profileField = new CRM_Core_DAO_UFField();
1413 $profileField->uf_group_id
= $id;
1414 $profileField->find();
1415 while ($profileField->fetch()) {
1416 CRM_Core_BAO_UFField
::del($profileField->id
);
1419 //delete records from uf join table
1420 $ufJoin = new CRM_Core_DAO_UFJoin();
1421 $ufJoin->uf_group_id
= $id;
1424 //delete profile group
1425 $group = new CRM_Core_DAO_UFGroup();
1434 * @param array $params
1435 * Reference array contains the values submitted by the form.
1437 * Reference array contains the id.
1443 public static function add(&$params, $ids = array()) {
1453 foreach ($fields as $field) {
1454 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1457 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1458 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1461 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1462 $params['group_type'] = implode(',', $params['group_type']);
1464 $ufGroup = new CRM_Core_DAO_UFGroup();
1465 $ufGroup->copyValues($params);
1467 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1469 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1471 $ufGroup->id
= $ufGroupID;
1476 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1484 * Make uf join entries for an uf group
1486 * @param array $params
1487 * (reference) an assoc array of name/value pairs.
1488 * @param int $ufGroupId
1494 public static function createUFJoin(&$params, $ufGroupId) {
1495 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1497 // get ufjoin records for uf group
1498 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1500 // get the list of all ufgroup types
1501 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1503 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1504 if (!is_array($groupTypes)) {
1505 $groupTypes = array();
1508 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1509 if (!is_array($ufGroupRecord)) {
1510 $ufGroupRecord = array();
1513 // check which values has to be inserted/deleted for contact
1514 $menuRebuild = FALSE;
1515 foreach ($allUFGroupType as $key => $value) {
1516 $joinParams = array();
1517 $joinParams['uf_group_id'] = $ufGroupId;
1518 $joinParams['module'] = $key;
1519 if ($key == 'User Account') {
1520 $menuRebuild = TRUE;
1522 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1523 // insert a new record
1524 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1526 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1527 // delete a record for existing ufgroup
1528 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1534 UPDATE civicrm_uf_join
1536 WHERE uf_group_id = %2
1537 AND ( entity_id IS NULL OR entity_id <= 0 )
1540 1 => array($params['weight'], 'Integer'),
1541 2 => array($ufGroupId, 'Integer'),
1543 CRM_Core_DAO
::executeQuery($query, $p);
1545 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1547 $config = CRM_Core_Config
::singleton();
1549 $config->userSystem
->is_drupal
1556 * Get the UF Join records for an ufgroup id
1558 * @param int $ufGroupId
1560 * @param int $displayName
1561 * If set return display name in array.
1562 * @param int $status
1563 * If set return module other than default modules (User Account/User registration/Profile).
1565 * @return array $ufGroupJoinRecords
1569 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1571 $UFGroupType = array();
1572 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1576 $dao = new CRM_Core_DAO_UFJoin();
1579 $dao->uf_group_id
= $ufGroupId;
1585 while ($dao->fetch()) {
1586 if (!$displayName) {
1587 $ufJoin[$dao->id
] = $dao->module
;
1590 if (isset($UFGroupType[$dao->module
])) {
1591 // skip the default modules
1593 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1595 // added for CRM-1475
1597 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1598 $ufJoin[$dao->id
] = $dao->module
;
1606 * Function takes an associative array and creates a ufjoin record for ufgroup
1608 * @param array $params
1609 * (reference) an assoc array of name/value pairs.
1611 * @return CRM_Core_BAO_UFJoin object
1614 public static function addUFJoin(&$params) {
1615 $ufJoin = new CRM_Core_DAO_UFJoin();
1616 $ufJoin->copyValues($params);
1622 * Delete the uf join record for an uf group
1624 * @param array $params
1625 * (reference) an assoc array of name/value pairs.
1630 public static function delUFJoin(&$params) {
1631 $ufJoin = new CRM_Core_DAO_UFJoin();
1632 $ufJoin->copyValues($params);
1637 * Get the weight for ufjoin record
1639 * @param int $ufGroupId
1640 * If $ufGroupId get update weight or add weight.
1642 * @return int weight of the UFGroup
1645 public static function getWeight($ufGroupId = NULL) {
1646 //calculate the weight
1649 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1650 FROM civicrm_uf_join
1651 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1654 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1655 FROM civicrm_uf_join
1656 WHERE civicrm_uf_join.uf_group_id = %1
1657 AND ( entity_id IS NULL OR entity_id <= 0 )";
1658 $p[1] = array($ufGroupId, 'Integer');
1661 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1663 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1667 * Get the uf group for a module
1669 * @param string $moduleName
1672 * No to increment the weight.
1673 * @param bool $skipPermission
1675 * Which operation (view, edit, create, etc) to check permission for.
1676 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1678 * @return array $ufGroups array of ufgroups for a module
1681 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1682 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1684 if (!CRM_Core_Config
::isUpgradeMode()) {
1685 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1686 $selectFields[] = 'description';
1689 if (!empty($returnFields)) {
1690 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1693 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1694 FROM civicrm_uf_group
1695 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1698 $queryString .= ' AND civicrm_uf_group.is_active = 1
1699 WHERE civicrm_uf_join.module = %2';
1700 $p[2] = array($moduleName, 'String');
1703 // add permissioning for profiles only if not registration
1704 if (!$skipPermission) {
1705 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1706 if (strpos($queryString, 'WHERE') !== FALSE) {
1707 $queryString .= " AND $permissionClause ";
1710 $queryString .= " $permissionClause ";
1714 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1715 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1717 $ufGroups = array();
1718 while ($dao->fetch()) {
1719 //skip mix profiles in user Registration / User Account
1720 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1721 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1725 foreach ($selectFields as $key => $field) {
1726 if ($field == 'id') {
1729 elseif ($field == 'name') {
1730 $ufGroups[$dao->id
][$field] = $dao->title
;
1733 $ufGroups[$dao->id
][$field] = $dao->$field;
1737 // Allow other modules to alter/override the UFGroups.
1738 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1744 * Filter ufgroups based on logged in user contact type
1746 * @param int $ufGroupId
1747 * Uf group id (profile id).
1748 * @param int $contactID
1750 * @return boolean true or false
1753 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1755 $session = CRM_Core_Session
::singleton();
1756 $contactID = $session->get('userID');
1760 //get the contact type
1761 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1763 //match if exixting contact type is same as profile contact type
1764 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1766 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1767 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1770 //allow special mix profiles for Contribution and Participant
1771 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1773 if (in_array($profileType, $specialProfiles)) {
1777 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1786 * Add profile field to a form
1788 * @param CRM_Core_Form $form
1789 * @param array $field
1793 * @param int $contactId
1794 * @param bool $online
1795 * @param string $usedFor
1796 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1797 * @param int $rowNumber
1798 * @param string $prefix
1803 static function buildProfile(
1813 $defaultValues = array();
1814 $fieldName = $field['name'];
1815 $title = $field['title'];
1816 $attributes = $field['attributes'];
1817 $rule = $field['rule'];
1818 $view = $field['is_view'];
1819 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1820 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1821 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1823 // do not display view fields in drupal registration form
1825 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1829 if ($usedFor == 'onbehalf') {
1830 $name = "onbehalf[$fieldName]";
1832 elseif ($usedFor == 'honor') {
1833 $name = "honor[$fieldName]";
1835 elseif ($contactId && !$online) {
1836 $name = "field[$contactId][$fieldName]";
1838 elseif ($rowNumber) {
1839 $name = "field[$rowNumber][$fieldName]";
1841 elseif (!empty($prefix)) {
1842 $name = $prefix . "[$fieldName]";
1848 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1850 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1851 $deleteExtra = ts('Are you sure you want to delete contact image.');
1853 CRM_Core_Action
::DELETE
=>
1855 'name' => ts('Delete Contact Image'),
1856 'url' => 'civicrm/contact/image',
1857 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1859 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1862 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1863 CRM_Core_Action
::DELETE
,
1865 'id' => $form->get('id'),
1866 'gid' => $form->get('gid'),
1870 'contact.profileimage.delete',
1874 $form->assign('deleteURL', $deleteURL);
1876 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1877 'address_options', TRUE, NULL, TRUE
1880 if (substr($fieldName, 0, 14) === 'state_province') {
1881 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1882 $config = CRM_Core_Config
::singleton();
1883 if (!in_array($mode, array(
1884 CRM_Profile_Form
::MODE_EDIT
,
1885 CRM_Profile_Form
::MODE_SEARCH
1887 $config->defaultContactStateProvince
1889 $defaultValues[$name] = $config->defaultContactStateProvince
;
1890 $form->setDefaults($defaultValues);
1893 elseif (substr($fieldName, 0, 7) === 'country') {
1894 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1895 $config = CRM_Core_Config
::singleton();
1896 if (!in_array($mode, array(
1897 CRM_Profile_Form
::MODE_EDIT
,
1898 CRM_Profile_Form
::MODE_SEARCH
1900 $config->defaultContactCountry
1902 $defaultValues[$name] = $config->defaultContactCountry
;
1903 $form->setDefaults($defaultValues);
1906 elseif (substr($fieldName, 0, 6) === 'county') {
1907 if ($addressOptions['county']) {
1908 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1911 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1912 $form->add('file', $name, $title, $attributes, $required);
1913 $form->addUploadElement($name);
1915 elseif (substr($fieldName, 0, 2) === 'im') {
1916 $form->add('text', $name, $title, $attributes, $required);
1919 if (substr($name, -1) == ']') {
1920 $providerName = substr($name, 0, -1) . '-provider_id]';
1922 $form->add('select', $providerName, NULL,
1924 '' => ts('- select -')
1925 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1929 $form->add('select', $name . '-provider_id', $title,
1931 '' => ts('- select -')
1932 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1936 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1937 $form->freeze($name . '-provider_id');
1941 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1942 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1944 elseif (in_array($fieldName, array(
1945 'membership_start_date',
1946 'membership_end_date',
1949 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1951 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1952 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1953 $sel = &$form->addElement('hierselect', $name, $title);
1954 $select = array('' => ts('- select -'));
1955 if (count($orgInfo) == 1 && $field['is_required']) {
1956 // we only have one org - so we should default to it. Not sure about defaulting to first type
1957 // as it could be missed - so adding a select
1958 // however, possibly that is more similar to the membership form
1959 if (count($types[1]) > 1) {
1960 $types[1] = $select +
$types[1];
1964 $orgInfo = $select +
$orgInfo;
1966 $sel->setOptions(array($orgInfo, $types));
1968 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1969 $form->add('select', $name, $title,
1971 '' => ts('- select -')
1972 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1975 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1977 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1978 foreach ($pseudoValues as $key => $var) {
1979 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1981 $group = $form->addGroup($options, $name, $title);
1983 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1986 $group->setAttribute('allowClear', TRUE);
1989 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1990 $form->addSelect($name, array(
1992 'entity' => 'contact',
1993 'field' => $fieldName,
1995 'placeholder' => '',
1998 elseif ($fieldName === 'contact_sub_type') {
1999 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2000 if ($usedFor == 'onbehalf') {
2001 $profileType = 'Organization';
2003 elseif ($usedFor == 'honor') {
2004 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
2007 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
2008 if ($profileType == 'Contact') {
2009 $profileType = 'Individual';
2013 $setSubtype = FALSE;
2014 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2015 $setSubtype = $profileType;
2016 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2019 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2022 $subtypeList = array();
2023 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2026 $subtypeList = $subtypes;
2029 $sel = $form->add('select', $name, $title, $subtypeList, $required);
2030 $sel->setMultiple(TRUE);
2032 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2033 //add email greeting, postal greeting, addressee, CRM-4575
2034 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2035 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2037 if (empty($profileType) ||
in_array($profileType, array(
2044 $profileType = 'Individual';
2046 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2047 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2050 'contact_type' => $profileType,
2051 'greeting_type' => $fieldName,
2053 $form->add('select', $name, $title,
2055 '' => ts('- select -')
2056 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2058 // add custom greeting element
2059 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2063 elseif ($fieldName === 'preferred_communication_method') {
2064 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2065 foreach ($communicationFields as $key => $var) {
2069 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2071 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2073 elseif ($fieldName === 'preferred_mail_format') {
2074 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2076 elseif ($fieldName === 'preferred_language') {
2077 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2079 elseif ($fieldName == 'external_identifier') {
2080 $form->add('text', $name, $title, $attributes, $required);
2081 $contID = $contactId;
2083 $contID = $form->get('id');
2085 $form->addRule($name,
2086 ts('External ID already exists in Database.'),
2088 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2091 elseif ($fieldName === 'group') {
2092 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2093 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2098 elseif ($fieldName === 'tag') {
2099 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2100 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2105 elseif (substr($fieldName, 0, 4) === 'url-') {
2106 $form->add('text', $name, $title,
2107 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2109 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2110 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2115 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2117 // Note should be rendered as textarea
2118 elseif (substr($fieldName, -4) == 'note') {
2119 $form->add('textarea', $name, $title, $attributes, $required);
2121 elseif (substr($fieldName, 0, 6) === 'custom') {
2122 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2123 if ($customFieldID) {
2124 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2127 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2128 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2129 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2130 if ($customFieldID) {
2131 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2134 elseif (in_array($fieldName, array(
2140 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2142 elseif ($fieldName == 'send_receipt') {
2143 $form->addElement('checkbox', $name, $title);
2145 elseif ($fieldName == 'soft_credit') {
2146 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2147 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2149 elseif ($fieldName == 'product_name') {
2150 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2151 $sel = &$form->addElement('hierselect', $name, $title);
2153 '0' => ts('- select -')
2155 $sel->setOptions(array($products, $options));
2157 elseif ($fieldName == 'payment_instrument') {
2158 $form->add('select', $name, $title,
2159 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2161 else if ($fieldName == 'financial_type') {
2162 $form->add('select', $name, $title,
2164 '' => ts('- select -')
2165 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2168 elseif ($fieldName == 'contribution_status_id') {
2169 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2170 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2176 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2179 $form->add('select', $name, $title,
2181 '' => ts('- select -')
2182 ) +
$contributionStatuses, $required
2185 elseif ($fieldName == 'soft_credit_type') {
2186 $name = "soft_credit_type[$rowNumber]";
2187 $form->add('select', $name, $title,
2189 '' => ts('- select -')
2190 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2192 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2193 //else (for contribution), use configured SCT default value
2194 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2195 if ($field['field_type'] == 'Membership') {
2196 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2198 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2200 elseif ($fieldName == 'currency') {
2201 $form->addCurrency($name, $title, $required);
2203 elseif ($fieldName == 'contribution_page_id') {
2204 $form->add('select', $name, $title,
2206 '' => ts('- select -')
2207 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2210 elseif ($fieldName == 'participant_register_date') {
2211 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2213 elseif ($fieldName == 'activity_status_id') {
2214 $form->add('select', $name, $title,
2216 '' => ts('- select -')
2217 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2220 elseif ($fieldName == 'activity_engagement_level') {
2221 $form->add('select', $name, $title,
2223 '' => ts('- select -')
2224 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2227 elseif ($fieldName == 'activity_date_time') {
2228 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2230 elseif ($fieldName == 'participant_status') {
2232 if ($online == TRUE) {
2233 $cond = 'visibility_id = 1';
2235 $form->add('select', $name, $title,
2237 '' => ts('- select -')
2238 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2241 elseif ($fieldName == 'participant_role') {
2242 if (!empty($field['is_multiple'])) {
2243 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2246 $form->add('select', $name, $title,
2248 '' => ts('- select -')
2249 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2253 elseif ($fieldName == 'world_region') {
2254 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2256 elseif ($fieldName == 'signature_html') {
2257 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2259 elseif ($fieldName == 'signature_text') {
2260 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2262 elseif (substr($fieldName, -11) == 'campaign_id') {
2263 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2264 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2265 $form->_componentCampaigns
2267 $form->add('select', $name, $title,
2269 '' => ts('- select -')
2270 ) +
$campaigns, $required, 'class="crm-select2 big"'
2274 elseif ($fieldName == 'activity_details') {
2275 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2277 elseif ($fieldName == 'activity_duration') {
2278 $form->add('text', $name, $title, $attributes, $required);
2279 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2282 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2283 $form->add('advcheckbox', $name, $title, $attributes, $required);
2286 $form->add('text', $name, $title, $attributes, $required);
2290 static $hiddenSubtype = FALSE;
2291 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2292 // In registration mode params are submitted via POST and we don't have any clue
2293 // about profile-id or the profile-type (which could be a subtype)
2294 // To generalize the behavior and simplify the process,
2295 // lets always add the hidden
2296 //subtype value if there is any, and we won't have to
2297 // compute it while processing.
2299 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2302 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2304 $hiddenSubtype = TRUE;
2307 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2308 $form->freeze($name);
2312 if (in_array($fieldName, array(
2313 'non_deductible_amount',
2318 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2321 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2322 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2328 * Set profile defaults
2330 * @param int $contactId
2332 * @param array $fields
2333 * Associative array of fields.
2334 * @param array $defaults
2336 * @param bool $singleProfile
2337 * True for single profile else false(batch update).
2338 * @param int $componentId
2339 * Id for specific components like contribute, event etc.
2340 * @param null $component
2345 static function setProfileDefaults(
2346 $contactId, &$fields, &$defaults,
2347 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2349 if (!$componentId) {
2350 //get the contact details
2351 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2352 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2353 $multipleFields = array('website' => 'url');
2355 //start of code to set the default values
2356 foreach ($fields as $name => $field) {
2357 // skip pseudo fields
2358 if (substr($name, 0, 9) == 'phone_ext') {
2362 //set the field name depending upon the profile mode(single/batch)
2363 if ($singleProfile) {
2367 $fldName = "field[$contactId][$name]";
2370 if ($name == 'group') {
2371 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2373 if ($name == 'tag') {
2374 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2377 if (!empty($details[$name]) ||
isset($details[$name])) {
2378 //to handle custom data (checkbox) to be written
2379 // to handle birth/deceased date, greeting_type and few other fields
2380 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2381 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2383 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2384 $defaults[$fldName] = $details[$name . '_id'];
2385 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2387 elseif ($name == 'preferred_communication_method') {
2388 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2389 foreach ($v as $item) {
2391 $defaults[$fldName . "[$item]"] = 1;
2395 elseif ($name == 'contact_sub_type') {
2396 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2398 elseif ($name == 'world_region') {
2399 $defaults[$fldName] = $details['worldregion_id'];
2401 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2402 //fix for custom fields
2403 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2405 // hack to add custom data for components
2406 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2407 foreach ($components as $value) {
2408 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2409 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2413 switch ($customFields[$customFieldId]['html_type']) {
2414 case 'Multi-Select State/Province':
2415 case 'Multi-Select Country':
2416 case 'AdvMulti-Select':
2417 case 'Multi-Select':
2418 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2419 foreach ($v as $item) {
2421 $defaults[$fldName][$item] = $item;
2427 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2428 foreach ($v as $item) {
2430 $defaults[$fldName][$item] = 1;
2431 // seems like we need this for QF style checkboxes in profile where its multiindexed
2433 $defaults["{$fldName}[{$item}]"] = 1;
2439 // CRM-6681, set defult values according to date and time format (if any).
2441 if (!empty($customFields[$customFieldId]['date_format'])) {
2442 $dateFormat = $customFields[$customFieldId]['date_format'];
2445 if (empty($customFields[$customFieldId]['time_format'])) {
2446 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2451 $timeElement = $fldName . '_time';
2452 if (substr($fldName, -1) == ']') {
2453 $timeElement = substr($fldName, 0, -1) . '_time]';
2455 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2456 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2461 $defaults[$fldName] = $details[$name];
2466 $defaults[$fldName] = $details[$name];
2470 $blocks = array('email', 'phone', 'im', 'openid');
2471 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2472 if (!in_array($fieldName, $multipleFields)) {
2473 if (is_array($details)) {
2474 foreach ($details as $key => $value) {
2475 // when we fixed CRM-5319 - get primary loc
2476 // type as per loc field and removed below code.
2477 $primaryLocationType = FALSE;
2478 if ($locTypeId == 'Primary') {
2479 if (is_array($value) && array_key_exists($fieldName, $value)) {
2480 $primaryLocationType = TRUE;
2481 if (in_array($fieldName, $blocks)) {
2482 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2485 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2490 // fixed for CRM-665
2491 if (is_numeric($locTypeId)) {
2492 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2493 if (!empty($value[$fieldName])) {
2494 //to handle stateprovince and country
2495 if ($fieldName == 'state_province') {
2496 $defaults[$fldName] = $value['state_province_id'];
2498 elseif ($fieldName == 'county') {
2499 $defaults[$fldName] = $value['county_id'];
2501 elseif ($fieldName == 'country') {
2502 if (!isset($value['country_id']) ||
!$value['country_id']) {
2503 $config = CRM_Core_Config
::singleton();
2504 if ($config->defaultContactCountry
) {
2505 $defaults[$fldName] = $config->defaultContactCountry
;
2509 $defaults[$fldName] = $value['country_id'];
2512 elseif ($fieldName == 'phone') {
2514 if (isset($value['phone'][$phoneTypeId])) {
2515 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2517 if (isset($value['phone_ext'][$phoneTypeId])) {
2518 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2522 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2524 if (!is_array($phoneDefault)) {
2525 $defaults[$fldName] = $phoneDefault;
2529 elseif ($fieldName == 'email') {
2530 //adding the first email (currently we don't support multiple emails of same location type)
2531 $defaults[$fldName] = $value['email'];
2533 elseif ($fieldName == 'im') {
2534 //adding the first im (currently we don't support multiple ims of same location type)
2535 $defaults[$fldName] = $value['im'];
2536 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2539 $defaults[$fldName] = $value[$fieldName];
2542 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2543 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2545 $defaults[$fldName] = $value[substr($fieldName, 8)];
2553 if (is_array($details)) {
2554 if ($fieldName === 'url'
2555 && !empty($details['website'])
2556 && !empty($details['website'][$locTypeId])
2558 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2566 //Handling Contribution Part of the batch profile
2567 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2568 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2571 //Handling Event Participation Part of the batch profile
2572 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2573 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2576 //Handling membership Part of the batch profile
2577 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2578 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2581 //Handling Activity Part of the batch profile
2582 if ($component == 'Activity') {
2583 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2588 * Get profiles by type eg: pure Individual etc
2590 * @param array $types
2591 * Associative array of types eg: types('Individual').
2592 * @param bool $onlyPure
2593 * True if only pure profiles are required.
2595 * @return array $profiles associative array of profiles
2598 public static function getProfiles($types, $onlyPure = FALSE) {
2599 $profiles = array();
2600 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2602 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2604 // Exclude Batch Data Entry profiles - CRM-10901
2605 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2607 foreach ($ufGroups as $id => $title) {
2608 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2609 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2610 $profiles[$id] = $title;
2617 * Check whether a profile is valid combination of
2618 * required and/or optional profile types
2620 * @param array $required
2621 * Array of types those are required.
2622 * @param array $optional
2623 * Array of types those are optional.
2625 * @return array $profiles associative array of profiles
2628 public static function getValidProfiles($required, $optional = NULL) {
2629 if (!is_array($required) ||
empty($required)) {
2633 $profiles = array();
2634 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2636 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2638 foreach ($ufGroups as $id => $title) {
2639 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2641 $profiles[$id] = $title;
2649 * Check whether a profile is valid combination of
2650 * required profile fields
2652 * @param array $ufId
2653 * Integer id of the profile.
2654 * @param array $required
2655 * Array of fields those are required in the profile.
2657 * @return array $profiles associative array of profiles
2660 public static function checkValidProfile($ufId, $required = NULL) {
2661 $validProfile = FALSE;
2663 return $validProfile;
2666 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2667 return $validProfile;
2670 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2671 NULL, FALSE, NULL, FALSE, NULL,
2672 CRM_Core_Permission
::CREATE
, NULL
2675 $validProfile = array();
2676 if (!empty($profileFields)) {
2677 $fields = array_keys($profileFields);
2678 foreach ($fields as $val) {
2679 foreach ($required as $key => $field) {
2680 if (strpos($val, $field) === 0) {
2681 unset($required[$key]);
2686 $validProfile = (empty($required)) ?
TRUE : FALSE;
2689 return $validProfile;
2693 * Get default value for Register.
2698 * @return mixed $defaults@static
2700 public static function setRegisterDefaults(&$fields, &$defaults) {
2701 $config = CRM_Core_Config
::singleton();
2702 foreach ($fields as $name => $field) {
2703 if (substr($name, 0, 8) == 'country-') {
2704 if (!empty($config->defaultContactCountry
)) {
2705 $defaults[$name] = $config->defaultContactCountry
;
2708 elseif (substr($name, 0, 15) == 'state_province-') {
2709 if (!empty($config->defaultContactStateProvince
)) {
2710 $defaults[$name] = $config->defaultContactStateProvince
;
2718 * This function is to make a copy of a profile, including
2719 * all the fields in the profile
2722 * The profile id to copy.
2726 public static function copy($id) {
2727 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2728 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2734 if ($pos = strrpos($copy->name
, "_{$id}")) {
2735 $copy->name
= substr_replace($copy->name
, '', $pos);
2737 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2740 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2741 array('uf_group_id' => $id),
2742 array('uf_group_id' => $copy->id
),
2747 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2748 array('uf_group_id' => $id),
2749 array('uf_group_id' => $copy->id
)
2752 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2756 UPDATE civicrm_uf_join
2758 WHERE uf_group_id = %2
2759 AND ( entity_id IS NULL OR entity_id <= 0 )
2762 1 => array($maxWeight +
1, 'Integer'),
2763 2 => array($copy->id
, 'Integer'),
2765 CRM_Core_DAO
::executeQuery($query, $p);
2766 if ($copy->is_reserved
) {
2767 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2768 $params = array(1 => array($copy->id
, 'Integer'));
2769 CRM_Core_DAO
::executeQuery($query, $params);
2771 CRM_Utils_Hook
::copy('UFGroup', $copy);
2777 * Process that send notification e-mails
2779 * @param int $contactID
2781 * @param array $values
2782 * Associative array of name/value pair.
2787 public static function commonSendMail($contactID, &$values) {
2788 if (!$contactID ||
!$values) {
2792 $template = CRM_Core_Smarty
::singleton();
2794 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2799 self
::profileDisplay($values['id'], $values['values'], $template);
2800 $emailList = explode(',', $values['email']);
2802 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2803 "reset=1&cid=$contactID",
2804 TRUE, NULL, FALSE, FALSE, TRUE
2807 //get the default domain email address.
2808 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2810 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2811 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2812 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)));
2815 foreach ($emailList as $emailTo) {
2816 // FIXME: take the below out of the foreach loop
2817 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2819 'groupName' => 'msg_tpl_workflow_uf',
2820 'valueName' => 'uf_notify',
2821 'contactId' => $contactID,
2822 'tplParams' => array(
2823 'displayName' => $displayName,
2824 'currentDate' => date('r'),
2825 'contactLink' => $contactLink,
2827 'from' => "$domainEmailName <$domainEmailAddress>",
2828 'toEmail' => $emailTo,
2835 * Given a contact id and a group id, returns the field values from the db
2836 * for this group and notify email only if group's notify field is
2837 * set and field values are not empty
2843 * @param array $params
2844 * @param bool $skipCheck
2848 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2850 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2852 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2853 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2855 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2857 if (!empty($values) &&
2862 'values' => $values,
2873 * Assign uf fields to template
2877 * @param array $values
2878 * @param CRM_Core_Smarty $template
2882 public function profileDisplay($gid, $values, $template) {
2883 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2884 $template->assign('grouptitle', $groupTitle);
2885 if (count($values)) {
2886 $template->assign('values', $values);
2891 * Format fields for dupe Contact Matching
2893 * @param array $params
2896 * @param int $contactId
2898 * @return array $data assoicated formatted array
2901 public static function formatFields($params, $contactId = NULL) {
2903 // get the primary location type id and email
2904 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2907 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2908 $primaryLocationType = $defaultLocationType->id
;
2912 $locationType = array();
2914 $primaryLocation = 0;
2915 foreach ($params as $key => $value) {
2916 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2918 if ($locTypeId == 'Primary') {
2919 $locTypeId = $primaryLocationType;
2922 if (is_numeric($locTypeId)) {
2923 if (!in_array($locTypeId, $locationType)) {
2924 $locationType[$count] = $locTypeId;
2927 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2929 $data['location'][$loc]['location_type_id'] = $locTypeId;
2931 // if we are getting in a new primary email, dont overwrite the new one
2932 if ($locTypeId == $primaryLocationType) {
2933 if (!empty($params['email-' . $primaryLocationType])) {
2934 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2936 elseif (isset($primaryEmail)) {
2937 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2943 $data['location'][$loc]['is_primary'] = 1;
2945 if ($fieldName == 'phone') {
2947 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2950 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2952 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2954 elseif ($fieldName == 'email') {
2955 $data['location'][$loc]['email'][$loc]['email'] = $value;
2957 elseif ($fieldName == 'im') {
2958 $data['location'][$loc]['im'][$loc]['name'] = $value;
2961 if ($fieldName === 'state_province') {
2962 $data['location'][$loc]['address']['state_province_id'] = $value;
2964 elseif ($fieldName === 'country') {
2965 $data['location'][$loc]['address']['country_id'] = $value;
2968 $data['location'][$loc]['address'][$fieldName] = $value;
2973 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2974 if ($key === 'individual_suffix') {
2975 $data['suffix_id'] = $value;
2977 elseif ($key === 'individual_prefix') {
2978 $data['prefix_id'] = $value;
2980 elseif ($key === 'gender') {
2981 $data['gender_id'] = $value;
2983 elseif (substr($key, 0, 6) === 'custom') {
2984 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2986 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2987 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2989 // fix the date field
2990 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2991 $date = CRM_Utils_Date
::format($value);
2998 $data['custom'][$customFieldID] = array(
3001 'extends' => $customFields[$customFieldID]['extends'],
3002 'type' => $customFields[$customFieldID]['data_type'],
3003 'custom_field_id' => $customFieldID,
3007 elseif ($key == 'edit') {
3011 $data[$key] = $value;
3016 if (!$primaryLocation) {
3018 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
3025 * Calculate the profile type 'group_type' as per profile fields.
3029 * @param bool $includeTypeValues
3030 * @param int $ignoreFieldId
3031 * Ignore particular profile field.
3033 * @return array list of calculated group type
3035 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3036 //get the profile fields.
3037 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3038 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3042 * Calculate the profile type 'group_type' as per profile fields.
3045 * @param bool $includeTypeValues
3046 * @param int $ignoreFieldId
3047 * Ignore perticular profile field.
3049 * @return array list of calculated group type
3051 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3052 $groupType = $groupTypeValues = $customFieldIds = array();
3053 if (!empty($ufFields)) {
3054 foreach ($ufFields as $fieldName => $fieldValue) {
3055 //ignore field from group type when provided.
3056 //in case of update profile field.
3057 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3060 if (!in_array($fieldValue['field_type'], $groupType)) {
3061 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3064 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3065 $customFieldIds[$fldId] = $fldId;
3070 if (!empty($customFieldIds)) {
3071 $query = 'SELECT DISTINCT(cg.id), cg.extends, cg.extends_entity_column_id, cg.extends_entity_column_value FROM civicrm_custom_group cg LEFT JOIN civicrm_custom_field cf ON cf.custom_group_id = cg.id WHERE cg.extends_entity_column_value IS NOT NULL AND cf.id IN (' . implode(',', $customFieldIds) . ')';
3073 $customGroups = CRM_Core_DAO
::executeQuery($query);
3074 while ($customGroups->fetch()) {
3075 if (!$customGroups->extends_entity_column_value
) {
3079 $groupTypeName = "{$customGroups->extends}Type";
3080 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3081 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3084 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3086 $groupTypeValues[$groupTypeName][$val] = $val;
3091 if (!empty($groupTypeValues)) {
3092 $groupType = array_merge($groupType, $groupTypeValues);
3100 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3101 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3104 * BirthDate + Email Individual,Contact
3105 * BirthDate + Subject Individual,Activity
3106 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3107 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3108 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3109 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3110 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3111 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3112 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3115 * @param array $groupTypes
3116 * With key having group type names.
3120 public static function updateGroupTypes($gId, $groupTypes = array()) {
3121 if (!is_array($groupTypes) ||
!$gId) {
3125 // If empty group types set group_type as 'null'
3126 if (empty($groupTypes)) {
3127 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3130 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3131 $validGroupTypes = array_merge(array(
3136 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3138 $gTypes = $gTypeValues = array();
3140 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3141 // Get valid group type and group subtypes
3142 foreach ($groupTypes as $groupType => $value) {
3143 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3144 $gTypes[] = $groupType;
3149 if (in_array($groupType, $participantExtends)) {
3150 $subTypesOf = $groupType;
3152 elseif (strpos($groupType, 'Type') > 0) {
3153 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3159 if (!empty($value) &&
3160 (in_array($subTypesOf, $componentGroupTypes) ||
3161 in_array($subTypesOf, $participantExtends)
3164 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3168 if (empty($gTypes)) {
3172 // Build String to store group types and group subtypes
3173 $groupTypeString = implode(',', $gTypes);
3174 if (!empty($gTypeValues)) {
3175 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3178 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3182 * Create a "group_type" string
3184 * @param array $coreTypes
3185 * E.g. array('Individual','Contact','Student').
3186 * @param array $subTypes
3187 * E.g. array('ActivityType' => array(7, 11)).
3188 * @param string $delim
3191 * @throws CRM_Core_Exception
3193 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3194 $groupTypeExpr = '';
3196 $groupTypeExpr .= implode(',', $coreTypes);
3199 //CRM-15427 Allow Multiple subtype filtering
3200 //if (count($subTypes) > 1) {
3201 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3203 foreach ($subTypes as $subType => $subTypeIds) {
3204 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3207 return $groupTypeExpr;
3211 * This function is used to setDefault componet specific profile fields.
3213 * @param array $fields
3215 * @param int $componentId
3217 * @param string $component
3219 * @param array $defaults
3220 * An array of default values.
3222 * @param bool $isStandalone
3226 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3227 if (!$componentId ||
3228 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3233 $componentBAO = $componentSubType = NULL;
3234 switch ($component) {
3236 $componentBAO = 'CRM_Member_BAO_Membership';
3237 $componentBAOName = 'Membership';
3238 $componentSubType = array('membership_type_id');
3242 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3243 $componentBAOName = 'Contribution';
3244 $componentSubType = array('financial_type_id');
3248 $componentBAO = 'CRM_Event_BAO_Participant';
3249 $componentBAOName = 'Participant';
3250 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3254 $componentBAO = 'CRM_Activity_BAO_Activity';
3255 $componentBAOName = 'Activity';
3256 $componentSubType = array('activity_type_id');
3261 $params = array('id' => $componentId);
3263 //get the component values.
3264 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3265 if ($componentBAOName == 'Participant') {
3266 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3269 $formattedGroupTree = array();
3270 $dateTimeFields = array(
3271 'participant_register_date',
3272 'activity_date_time',
3277 'membership_start_date',
3278 'membership_end_date',
3281 foreach ($fields as $name => $field) {
3282 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3283 if (in_array($name, $dateTimeFields)) {
3284 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3285 if (!empty($values[$name])) {
3286 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3289 elseif (array_key_exists($name, $values)) {
3290 $defaults[$fldName] = $values[$name];
3292 elseif ($name == 'participant_note') {
3293 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3294 $defaults[$fldName] = array_pop($noteDetails);
3296 elseif (in_array($name, array(
3298 'payment_instrument',
3299 'participant_status',
3302 $defaults[$fldName] = $values["{$name}_id"];
3304 elseif ($name == 'membership_type') {
3305 // since membership_type field is a hierselect -
3306 $defaults[$fldName][0] =
3307 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3308 $defaults[$fldName][1] = $values['membership_type_id'];
3310 elseif ($name == 'membership_status') {
3311 $defaults[$fldName] = $values['status_id'];
3313 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3314 if (empty($formattedGroupTree)) {
3315 //get the groupTree as per subTypes.
3316 $groupTree = array();
3317 foreach ($componentSubType as $subType) {
3318 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3319 $componentId, 0, $values[$subType]
3321 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3323 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3324 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3327 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3328 foreach ($defaults as $customKey => $customValue) {
3329 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3330 if ($name == 'custom_' . $customFieldDetails[0]) {
3332 //hack to set default for checkbox
3333 //basically this is for weired field name like field[33][custom_19]
3334 //we are converting this field name to array structure and assign value.
3337 foreach ($formattedGroupTree as $tree) {
3338 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3339 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3341 $defaults['field'][$componentId][$name] = $customValue;
3344 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3347 // CRM-6681, $default contains formatted date, time values.
3348 $defaults[$fldName] = $customValue;
3349 if (!empty($defaults[$customKey . '_time'])) {
3350 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3356 if (!$skipValue ||
$isStandalone) {
3357 $defaults[$fldName] = $customValue;
3359 unset($defaults[$customKey]);
3369 * @param array|string $profiles - name of profile(s) to create links for
3370 * @param array $appendProfiles
3371 * Name of profile(s) to append to each link.
3375 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3376 // Default to contact profiles
3378 $profiles = array('new_individual', 'new_organization', 'new_household');
3380 $profiles = (array) $profiles;
3381 $toGet = array_merge($profiles, (array) $appendProfiles);
3382 $retrieved = civicrm_api3('uf_group', 'get', array(
3383 'name' => array('IN' => $toGet),
3386 $links = $append = array();
3387 if (!empty($retrieved['values'])) {
3388 foreach ($retrieved['values'] as $id => $profile) {
3389 if (in_array($profile['name'], $profiles)) {
3391 'label' => $profile['title'],
3392 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3393 NULL, NULL, FALSE, FALSE, TRUE),
3394 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3401 foreach ($append as $id) {
3402 foreach ($links as &$link) {
3403 $link['url'] .= ",$id";
3411 * Retrieve groups of profiles
3413 * @param int $profileID
3414 * Id of the profile.
3416 * @return array returns array
3419 public static function profileGroups($profileID) {
3420 $groupTypes = array();
3421 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3422 if ($profileTypes) {
3423 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3424 $groupTypes = explode(',', $groupTypeParts[0]);
3430 * Alter contact params by filtering existing subscribed groups and returns
3431 * unsubscribed groups array for subscription.
3433 * @param array $params
3435 * @param int $contactId
3438 * @return array $subscribeGroupIds This contains array of groups for subscription
3440 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3441 $config = CRM_Core_Config
::singleton();
3442 $subscribeGroupIds = array();
3444 // process further only if profileDoubleOptIn enabled and if groups exist
3445 if (!array_key_exists('group', $params) ||
3446 !self
::isProfileDoubleOptin() ||
3447 CRM_Utils_System
::isNull($params['group'])
3449 return $subscribeGroupIds;
3452 //check if contact email exist.
3454 foreach ($params as $name => $value) {
3455 if (strpos($name, 'email-') !== FALSE) {
3461 //Proceed furthur only if email present
3463 return $subscribeGroupIds;
3466 //do check for already subscriptions.
3467 $contactGroups = array();
3471 FROM civicrm_group_contact
3472 WHERE status = 'Added'
3473 AND contact_id = %1";
3475 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3476 while ($dao->fetch()) {
3477 $contactGroups[$dao->group_id
] = $dao->group_id
;
3481 //since we don't have names, compare w/ label.
3482 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3484 //actual processing start.
3485 foreach ($params['group'] as $groupId => $isSelected) {
3486 //unset group those are not selected.
3488 unset($params['group'][$groupId]);
3492 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3493 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3495 //get only mailing type group and unset it from params
3496 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3497 $subscribeGroupIds[$groupId] = $groupId;
3498 unset($params['group'][$groupId]);
3502 return $subscribeGroupIds;
3506 * Check if we are rendering mixed profiles
3508 * @param array $profileIds
3509 * Associated array of profile ids.
3511 * @return boolean $mixProfile true if profile is mixed
3514 public static function checkForMixProfiles($profileIds) {
3515 $mixProfile = FALSE;
3517 $contactTypes = array('Individual', 'Household', 'Organization');
3518 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3520 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3522 $typeCount = array('ctype' => array(), 'subtype' => array());
3523 foreach ($profileIds as $gid) {
3524 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3525 // ignore profile of type Contact
3526 if ($profileType == 'Contact') {
3529 if (in_array($profileType, $contactTypes)) {
3530 if (!isset($typeCount['ctype'][$profileType])) {
3531 $typeCount['ctype'][$profileType] = 1;
3534 // check if we are rendering profile of different contact types
3535 if (count($typeCount['ctype']) == 2) {
3540 elseif (in_array($profileType, $components)) {
3545 if (!isset($typeCount['subtype'][$profileType])) {
3546 $typeCount['subtype'][$profileType] = 1;
3548 // check if we are rendering profile of different contact sub types
3549 if (count($typeCount['subtype']) == 2) {
3559 * Determine of we show overlay profile or not
3561 * @return boolean true if profile should be shown else false
3564 public static function showOverlayProfile() {
3565 $showOverlay = TRUE;
3567 // get the id of overlay profile
3568 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3569 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3571 $count = CRM_Core_DAO
::singleValueQuery($query);
3573 //check if there are no public fields and use is anonymous
3574 $session = CRM_Core_Session
::singleton();
3575 if (!$count && !$session->get('userID')) {
3576 $showOverlay = FALSE;
3579 return $showOverlay;
3583 * Get group type values of the profile
3585 * @param int $profileId
3586 * @param string $groupType
3588 * @return Array group type values
3591 public static function groupTypeValues($profileId, $groupType = NULL) {
3592 $groupTypeValue = array();
3593 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3595 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3596 if (empty($groupTypeParts[1])) {
3597 return $groupTypeValue;
3599 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3601 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3603 $valueParts = explode(':', $groupTypeValues);
3605 ($valueParts[0] != "{$groupType}Type" ||
3606 ($groupType == 'Participant' &&
3607 !in_array($valueParts[0], $participantExtends)
3613 foreach ($valueParts as $val) {
3614 if (CRM_Utils_Rule
::integer($val)) {
3615 $values[$val] = $val;
3618 if (!empty($values)) {
3619 $typeName = substr($valueParts[0], 0, -4);
3620 if (in_array($valueParts[0], $participantExtends)) {
3621 $typeName = $valueParts[0];
3623 $groupTypeValue[$typeName] = $values;
3627 return $groupTypeValue;
3631 * @return bool|object
3633 public static function isProfileDoubleOptin() {
3634 // check for double optin
3635 $config = CRM_Core_Config
::singleton();
3636 if (in_array('CiviMail', $config->enableComponents
)) {
3637 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3638 'profile_double_optin', NULL, FALSE
3645 * @return bool|object
3647 public static function isProfileAddToGroupDoubleOptin() {
3648 // check for add to group double optin
3649 $config = CRM_Core_Config
::singleton();
3650 if (in_array('CiviMail', $config->enableComponents
)) {
3651 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3652 'profile_add_to_group_double_optin', NULL, FALSE
3659 * Get profiles used for batch entry
3661 * @return array profileIds profile ids
3664 public static function getBatchProfiles() {
3666 FROM civicrm_uf_group
3667 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3668 $dao = CRM_Core_DAO
::executeQuery($query);
3669 $profileIds = array();
3670 while ($dao->fetch()) {
3671 $profileIds[$dao->id
] = $dao->id
;
3677 * @todo what do I do?
3679 * @param $destination
3680 * @param bool $returnMultiSummaryFields
3682 * @return array|null
3684 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3685 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3686 foreach ($source as $field => $properties) {
3687 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3690 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3691 $destination[$field] = $properties;
3692 if ($returnMultiSummaryFields) {
3693 if ($properties['is_multi_summary']) {
3694 $multiSummaryFields[$field] = $properties;
3697 unset($source[$field]);
3700 return $multiSummaryFields;
3704 * This is function is used to format pseudo fields
3706 * @param array $fields
3707 * Associated array of profile fields.
3711 public static function reformatProfileFields(&$fields) {
3712 //reformat fields array
3713 foreach ($fields as $name => $field) {
3714 //reformat phone and extension field
3715 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3716 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3718 // retain existing element properties and just update and replace key
3719 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3720 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3721 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3723 // add additional phone extension field
3724 $fields["phone_ext-{$fieldSuffix}"] = $field;
3725 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3726 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3727 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3728 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3729 //ignore required for extension field
3730 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;