3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2015
37 class CRM_Core_BAO_UFGroup
extends CRM_Core_DAO_UFGroup
{
38 const PUBLIC_VISIBILITY
= 1,
40 LISTINGS_VISIBILITY
= 4;
43 * Cache the match clause used in this transaction.
47 static $_matchFields = NULL;
50 * Fetch object based on array of properties.
52 * @param array $params
53 * (reference) an assoc array of name/value pairs.
54 * @param array $defaults
55 * (reference) an assoc array to hold the flattened values.
58 * CRM_Core_DAO_UFGroup object
60 public static function retrieve(&$params, &$defaults) {
61 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
65 * Retrieve the first non-generic contact type
73 public static function getContactType($id) {
75 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
76 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
78 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
79 $types = explode(',', $typesParts[0]);
82 foreach ($types as $type) {
83 if (in_array($type, $validTypes)) {
86 elseif (array_key_exists($type, $validSubTypes)) {
87 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
107 public static function getTitle($id) {
108 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
112 * Update the is_active flag in the db.
115 * Id of the database record.
116 * @param bool $is_active
117 * Value we want to set the is_active field.
120 * CRM_Core_DAO_UFGroup object on success, null otherwise
122 public static function setIsActive($id, $is_active) {
123 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
127 * Get all the registration fields.
130 * What action are we doing.
137 * the fields that are needed for registration
139 public static function getRegistrationFields($action, $mode, $ctype = NULL) {
140 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
141 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
144 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
147 if (!is_array($ufGroups)) {
153 foreach ($ufGroups as $id => $title) {
155 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
156 if (($fieldType != 'Contact') &&
157 ($fieldType != $ctype) &&
158 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
162 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
163 $profileSubType = $fieldType;
167 $subset = self
::getFields($id, TRUE, $action,
168 NULL, NULL, FALSE, NULL, TRUE, $ctype
171 // we do not allow duplicates. the first field is the winner
172 foreach ($subset as $name => $field) {
173 if (empty($fields[$name])) {
174 $fields[$name] = $field;
183 * Get all the listing fields.
186 * What action are we doing.
187 * @param int $visibility
188 * Visibility of fields we are interested in.
189 * @param bool $considerSelector
190 * Whether to consider the in_selector parameter.
191 * @param array $ufGroupIds
192 * @param bool $searchable
194 * @param null $restrict
195 * @param bool $skipPermission
196 * @param int $permissionType
198 * the fields that are listings related
200 public static function getListingFields(
203 $considerSelector = FALSE,
207 $skipPermission = FALSE,
208 $permissionType = CRM_Core_Permission
::SEARCH
211 $subset = self
::getFields($ufGroupIds, FALSE, $action,
212 $visibility, $searchable,
218 if ($considerSelector) {
219 // drop the fields not meant for the selector
220 foreach ($subset as $name => $field) {
221 if (!$field['in_selector']) {
222 unset($subset[$name]);
229 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
232 foreach ($ufGroups as $id => $title) {
233 $subset = self
::getFields($id, FALSE, $action,
234 $visibility, $searchable,
240 if ($considerSelector) {
241 // drop the fields not meant for the selector
242 foreach ($subset as $name => $field) {
243 if (!$field['in_selector']) {
244 unset($subset[$name]);
248 $fields = array_merge($fields, $subset);
255 * Get all the fields that belong to the group with the name title,
256 * and format for use with buildProfile. This is the SQL analog of
260 * The id of the UF group or ids of ufgroup.
261 * @param bool|int $register are we interested in registration fields
263 * What action are we doing.
264 * @param int $visibility
265 * Visibility of fields we are interested in.
267 * @param bool $showAll
268 * @param string $restrict
269 * Should we restrict based on a specified profile type.
270 * @param bool $skipPermission
272 * @param int $permissionType
273 * @param string $orderBy
274 * @param null $orderProfiles
277 * the fields that belong to this ufgroup(s)
279 public static function getFields(
287 $skipPermission = FALSE,
289 $permissionType = CRM_Core_Permission
::CREATE
,
290 $orderBy = 'field_name',
291 $orderProfiles = NULL,
292 $eventProfile = FALSE
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 $checkPermission = array(
322 'administer CiviCRM',
323 'manage event profiles',
326 if ($eventProfile && CRM_Core_Permission
::check($checkPermission)) {
327 $skipPermission = TRUE;
330 // add permissioning for profiles only if not registration
331 if (!$skipPermission) {
332 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
333 $query .= " AND $permissionClause ";
336 if ($orderProfiles AND count($profileIds) > 1) {
337 $query .= " ORDER BY FIELD( g.id, {$gids} )";
339 $group = CRM_Core_DAO
::executeQuery($query, $params);
343 while ($group->fetch()) {
345 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
346 $field = CRM_Core_DAO
::executeQuery($query);
348 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
349 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
350 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
351 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
353 while ($field->fetch()) {
354 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
355 if ($formattedField !== NULL) {
356 $fields[$name] = $formattedField;
362 if (empty($fields) && !$validGroup) {
363 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.',
364 array(1 => implode(',', $profileIds))
368 self
::reformatProfileFields($fields);
375 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
378 * @param array $groupArr
379 * (mimic CRM_UF_DAO_UFGroup).
380 * @param array $fieldArrs
381 * List of fields (each mimics CRM_UF_DAO_UFField).
382 * @param bool $visibility
383 * Visibility of fields we are interested in.
384 * @param bool $searchable
385 * @param bool $showAll
387 * @param int $permissionType
390 * @see self::getFields
392 public static function formatUFFields(
399 $permissionType = CRM_Core_Permission
::CREATE
401 // $group = new CRM_Core_DAO_UFGroup();
402 // $group->copyValues($groupArr); // no... converts string('') to string('null')
403 $group = (object) $groupArr;
405 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
406 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
407 // they did -- the obvious fix would produce mutual recursion.
408 $ufGroupType = self
::_calculateGroupType($fieldArrs);
409 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',', $ufGroupType));
410 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',', $ufGroupType));
411 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
412 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
414 $formattedFields = array();
415 foreach ($fieldArrs as $fieldArr) {
416 $field = (object) $fieldArr;
417 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
421 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
422 if ($formattedField !== NULL) {
423 $formattedFields[$name] = $formattedField;
426 return $formattedFields;
430 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
432 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
433 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
434 * @param array $customFields
435 * @param array $addressCustomFields
436 * @param array $importableFields
437 * @param int $permissionType
438 * Eg CRM_Core_Permission::CREATE.
441 protected static function formatUFField(
445 $addressCustomFields,
447 $permissionType = CRM_Core_Permission
::CREATE
449 $name = $field->field_name
;
450 $title = $field->label
;
452 $addressCustom = FALSE;
453 if (in_array($permissionType, array(
454 CRM_Core_Permission
::CREATE
,
455 CRM_Core_Permission
::EDIT
,
457 in_array($field->field_name
, array_keys($addressCustomFields))
459 $addressCustom = TRUE;
460 $name = "address_{$name}";
462 if ($field->field_name
== 'url') {
463 $name .= "-{$field->website_type_id}";
465 elseif (!empty($field->location_type_id
)) {
466 $name .= "-{$field->location_type_id}";
469 $locationFields = self
::getLocationFields();
470 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
475 if (isset($field->phone_type_id
)) {
476 $name .= "-{$field->phone_type_id}";
479 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
480 // I guess to make field self sufficient with all the required data and avoid additional calls
481 $formattedField = array(
483 'groupTitle' => $group->title
,
484 'groupName' => $group->name
,
485 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
486 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
488 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
489 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
490 'is_required' => $field->is_required
,
491 'is_view' => $field->is_view
,
492 'help_pre' => $field->help_pre
,
493 'help_post' => $field->help_post
,
494 'visibility' => $field->visibility
,
495 'in_selector' => $field->in_selector
,
496 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
497 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
498 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
499 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
500 'group_id' => $group->id
,
501 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
502 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
503 'field_type' => $field->field_type
,
504 'field_id' => $field->id
,
505 'pseudoconstant' => CRM_Utils_Array
::value(
507 CRM_Utils_Array
::value($field->field_name
, $importableFields)
509 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
510 'dbName' => CRM_Utils_Array
::value(
512 CRM_Utils_Array
::value($field->field_name
, $importableFields)
517 //adding custom field property
518 if (substr($field->field_name
, 0, 6) == 'custom' ||
519 substr($field->field_name
, 0, 14) === 'address_custom'
521 // if field is not present in customFields, that means the user
522 // DOES NOT HAVE permission to access that field
523 if (array_key_exists($field->field_name
, $customFields)) {
524 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
526 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
527 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
528 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
530 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
531 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
532 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
535 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
536 return array($name, $formattedField);
539 $formattedField = NULL;
540 return array($name, $formattedField);
543 return array($name, $formattedField);
547 * Create a query to find all visible UFFields in a UFGroup.
549 * This is the SQL-variant of checkUFFieldDisplayable().
551 * @param int $groupId
552 * @param bool $searchable
553 * @param bool $showAll
554 * @param int $visibility
555 * @param string $orderBy
556 * Comma-delimited list of SQL columns.
559 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
560 $where = " WHERE uf_group_id = {$groupId}";
563 $where .= " AND is_searchable = 1";
567 $where .= " AND is_active = 1";
572 if ($visibility & self
::PUBLIC_VISIBILITY
) {
573 $clause[] = 'visibility = "Public Pages"';
575 if ($visibility & self
::ADMIN_VISIBILITY
) {
576 $clause[] = 'visibility = "User and User Admin Only"';
578 if ($visibility & self
::LISTINGS_VISIBILITY
) {
579 $clause[] = 'visibility = "Public Pages and Listings"';
581 if (!empty($clause)) {
582 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
586 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
588 $query .= ", " . $orderBy;
595 * Create a query to find all visible UFFields in a UFGroup.
597 * This is the PHP in-memory variant of createUFFieldQuery().
599 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
600 * @param bool $searchable
601 * @param bool $showAll
602 * @param int $visibility
604 * TRUE if field is displayable
606 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
607 if ($searchable && $field->is_searchable
!= 1) {
611 if (!$showAll && $field->is_active
!= 1) {
616 $allowedVisibilities = array();
617 if ($visibility & self
::PUBLIC_VISIBILITY
) {
618 $allowedVisibilities[] = 'Public Pages';
620 if ($visibility & self
::ADMIN_VISIBILITY
) {
621 $allowedVisibilities[] = 'User and User Admin Only';
623 if ($visibility & self
::LISTINGS_VISIBILITY
) {
624 $allowedVisibilities[] = 'Public Pages and Listings';
626 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
627 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
637 * @param $profileType
638 * @param $contactActivityProfile
642 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
644 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
647 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
650 if ($profileType == 'Activity' ||
$contactActivityProfile) {
651 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
654 $componentFields = CRM_Core_Component
::getQueryFields();
657 $importableFields = array_merge($importableFields, $componentFields);
659 $importableFields['group']['title'] = ts('Group(s)');
660 $importableFields['group']['where'] = NULL;
661 $importableFields['tag']['title'] = ts('Tag(s)');
662 $importableFields['tag']['where'] = NULL;
663 return $importableFields;
666 public static function getLocationFields() {
667 static $locationFields = array(
669 'supplemental_address_1',
670 'supplemental_address_2',
673 'postal_code_suffix',
686 return $locationFields;
694 protected static function getCustomFields($ctype) {
695 static $customFieldCache = array();
696 if (!isset($customFieldCache[$ctype])) {
697 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
699 // hack to add custom data for components
700 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
701 foreach ($components as $value) {
702 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
704 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
705 $customFields = array_merge($customFields, $addressCustomFields);
706 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
708 return $customFieldCache[$ctype];
712 * Check the data validity.
715 * The user id that we are actually editing.
716 * @param string $name
717 * The machine-name of the group we are interested in.
718 * @param bool $register
720 * The action of the form.
722 * @pram boolean $register is this the registrtion form
724 * true if form is valid
726 public static function isValid($userID, $name, $register = FALSE, $action = NULL) {
728 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
729 ts('Dynamic Form Creator'),
732 $controller->set('id', $userID);
733 $controller->set('register', 1);
734 $controller->process();
735 return $controller->validate();
738 // make sure we have a valid group
739 $group = new CRM_Core_DAO_UFGroup();
741 $group->name
= $name;
743 if ($group->find(TRUE) && $userID) {
744 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
745 $controller->set('gid', $group->id
);
746 $controller->set('id', $userID);
747 $controller->set('register', 0);
748 $controller->process();
749 return $controller->validate();
756 * Get the html for the form that represents this particular group.
759 * The user id that we are actually editing.
760 * @param string $title
761 * The title of the group we are interested in.
763 * The action of the form.
764 * @param bool $register
765 * Is this the registration form.
767 * Should we reset the form?.
768 * @param int $profileID
769 * Do we have the profile ID?.
771 * @param bool $doNotProcess
775 * the html for the form on success, otherwise empty string
777 public static function getEditHTML(
784 $doNotProcess = FALSE,
789 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
790 ts('Dynamic Form Creator'),
793 if ($reset ||
$doNotProcess) {
794 // hack to make sure we do not process this form
795 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
798 unset($_POST['_qf_default']);
799 unset($_REQUEST['_qf_default']);
801 $controller->reset();
805 $controller->set('id', $userID);
806 $controller->set('register', 1);
807 $controller->set('skipPermission', 1);
808 $controller->set('ctype', $ctype);
809 $controller->process();
810 if ($doNotProcess ||
!empty($_POST)) {
811 $controller->validate();
813 $controller->setEmbedded(TRUE);
815 //CRM-5839 - though we want to process form, get the control back.
816 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
820 // we are done processing so restore the POST/REQUEST vars
821 if (($reset ||
$doNotProcess) && $oldQFDefault) {
822 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
825 $template = CRM_Core_Smarty
::singleton();
827 // Hide CRM error messages if they are displayed using drupal form_set_error.
828 if (!empty($_POST)) {
829 $template->assign('suppressForm', TRUE);
832 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
836 // make sure we have a valid group
837 $group = new CRM_Core_DAO_UFGroup();
839 $group->title
= $title;
841 if ($group->find(TRUE)) {
842 $profileID = $group->id
;
847 // make sure profileID and ctype match if ctype exists
849 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
850 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
851 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
854 if (($profileType != 'Contact') && ($profileType != $ctype)) {
859 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
860 ts('Dynamic Form Creator'),
864 $controller->reset();
866 $controller->set('gid', $profileID);
867 $controller->set('id', $userID);
868 $controller->set('register', 0);
869 $controller->set('skipPermission', 1);
871 $controller->set('ctype', $ctype);
873 $controller->process();
874 $controller->setEmbedded(TRUE);
876 //CRM-5846 - give the control back to drupal.
877 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
880 $template = CRM_Core_Smarty
::singleton();
882 // Hide CRM error messages if they are displayed using drupal form_set_error.
883 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
884 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
885 $template->assign('suppressForm', TRUE);
889 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
890 if (!$template->template_exists($templateFile)) {
891 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
893 return trim($template->fetch($templateFile));
896 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
898 // if post not empty then only proceed
899 if (!empty($_POST)) {
901 $config = CRM_Core_Config
::singleton();
902 $email = CRM_Utils_Array
::value('mail', $_POST);
904 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
905 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
914 * Searches for a contact in the db with similar attributes.
916 * @param array $params
917 * The list of values to be used in the where clause.
919 * The current contact id (hence excluded from matching).
920 * @param string $contactType
923 * contact_id if found, null otherwise
925 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
926 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
927 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
928 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
930 return implode(',', $ids);
938 * Given a contact id and a field set, return the values from the db
942 * @param array $fields
943 * The profile fields of interest.
944 * @param array $values
945 * The values for the above fields.
946 * @param bool $searchable
948 * @param array $componentWhere
949 * Component condition.
950 * @param bool $absolute
951 * Return urls in absolute form (useful when sending an email).
952 * @param null $additionalWhereClause
954 public static function getValues(
955 $cid, &$fields, &$values,
956 $searchable = TRUE, $componentWhere = NULL,
957 $absolute = FALSE, $additionalWhereClause = NULL
959 if (empty($cid) && empty($componentWhere)) {
963 // get the contact details (hier)
964 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
965 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
967 // add conditions specified by components. eg partcipant_id etc
968 if (!empty($componentWhere)) {
969 $params = array_merge($params, $componentWhere);
972 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
973 $options = &$query->_options
;
975 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
976 FALSE, FALSE, FALSE, $additionalWhereClause);
977 if (!$details->fetch()) {
980 $query->convertToPseudoNames($details);
981 $config = CRM_Core_Config
::singleton();
983 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
984 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
985 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
987 $multipleFields = array('url');
989 //start of code to set the default values
990 foreach ($fields as $name => $field) {
993 $name = 'contact_id';
996 // skip fields that should not be displayed separately
997 if (!empty($field['skipDisplay'])) {
1001 // Create a unique, non-empty index for each field.
1002 $index = $field['title'];
1003 if ($index === '') {
1006 while (array_key_exists($index, $values)) {
1010 $params[$index] = $values[$index] = '';
1011 $customFieldName = NULL;
1013 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
1014 // to handle gender / suffix / prefix
1015 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
1016 $params[$index] = $details->$name;
1017 $values[$index] = $details->$name;
1019 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1020 $dname = $name . '_display';
1021 $values[$index] = $details->$dname;
1022 $name = $name . '_id';
1023 $params[$index] = $details->$name;
1025 elseif (in_array($name, array(
1030 $values[$index] = $details->$name;
1031 $idx = $name . '_id';
1032 $params[$index] = $details->$idx;
1034 elseif ($name === 'preferred_communication_method') {
1035 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1037 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1039 foreach ($pref as $k) {
1041 $compref[] = $communicationFields[$k];
1044 $params[$index] = $details->$name;
1045 $values[$index] = implode(',', $compref);
1047 elseif ($name === 'preferred_language') {
1048 $params[$index] = $details->$name;
1049 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1051 elseif ($name == 'group') {
1052 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1053 $title = $ids = array();
1055 foreach ($groups as $g) {
1056 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1057 // VIEW permission on that group
1058 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1060 if ($g['visibility'] != 'User and User Admin Only' ||
1061 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1063 $title[] = $g['title'];
1064 if ($g['visibility'] == 'Public Pages') {
1065 $ids[] = $g['group_id'];
1069 $values[$index] = implode(', ', $title);
1070 $params[$index] = implode(',', $ids);
1072 elseif ($name == 'tag') {
1073 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1074 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1076 foreach ($entityTags as $tagId) {
1077 $title[] = $allTags[$tagId];
1079 $values[$index] = implode(', ', $title);
1080 $params[$index] = implode(',', $entityTags);
1082 elseif ($name == 'activity_status_id') {
1083 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1084 $values[$index] = $activityStatus[$details->$name];
1085 $params[$index] = $details->$name;
1087 elseif ($name == 'activity_date_time') {
1088 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1089 $params[$index] = $details->$name;
1091 elseif ($name == 'contact_sub_type') {
1092 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1093 if (!empty($contactSubTypeNames)) {
1094 $contactSubTypeLabels = array();
1095 // get all contact subtypes
1096 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1097 // build contact subtype labels array
1098 foreach ($contactSubTypeNames as $cstName) {
1100 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1103 $values[$index] = implode(',', $contactSubTypeLabels);
1106 $params[$index] = $details->$name;
1109 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1110 if ($details->$name) {
1111 $values[$index] = '[ x ]';
1115 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1116 $htmlType = $field['html_type'];
1118 // field_type is only set when we are retrieving profile values
1119 // when sending email, we call the same function to get custom field
1120 // values etc, i.e. emulating a profile
1121 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1123 if ($htmlType == 'File') {
1126 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1128 $entityId = $componentWhere[0][2];
1131 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1135 $additionalWhereClause
1137 $params[$index] = $values[$index] = $fileURL['file_url'];
1141 if (isset($dao) && property_exists($dao, 'data_type') &&
1142 ($dao->data_type
== 'Int' ||
1143 $dao->data_type
== 'Boolean'
1146 $customVal = (int ) ($details->{$name});
1148 elseif (isset($dao) && property_exists($dao, 'data_type')
1149 && $dao->data_type
== 'Float'
1151 $customVal = (float ) ($details->{$name});
1153 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1157 $customVal = $details->{$name};
1161 if (CRM_Utils_System
::isNull($customVal)) {
1165 $params[$index] = $customVal;
1166 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1170 if ($field['data_type'] == 'ContactReference') {
1171 $params[$index] = $values[$index];
1173 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1174 $cfID, 'is_search_range'
1177 $customFieldName = "{$name}_from";
1181 elseif ($name == 'image_URL') {
1182 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1183 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1185 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1186 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1188 elseif (in_array($name, array(
1191 'membership_start_date',
1192 'membership_end_date',
1195 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1196 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1200 if ($index == 'Campaign') {
1201 $dao = 'CRM_Campaign_DAO_Campaign';
1203 elseif ($index == 'Contribution Page') {
1204 $dao = 'CRM_Contribute_DAO_ContributionPage';
1207 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1210 $value = $details->$name;
1212 $values[$index] = $value;
1217 elseif (strpos($name, '-') !== FALSE) {
1218 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1220 if (!in_array($fieldName, $multipleFields)) {
1221 if ($id == 'Primary') {
1223 // not sure why we'd every use Primary location type id
1224 // we need to fix the source if we are using it
1225 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1226 $locationTypeName = 1;
1229 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1232 if (!$locationTypeName) {
1236 $detailName = "{$locationTypeName}-{$fieldName}";
1237 $detailName = str_replace(' ', '_', $detailName);
1239 if (in_array($fieldName, array(
1246 $detailName .= "-{$type}";
1250 if (in_array($fieldName, array(
1255 $values[$index] = $details->$detailName;
1256 $idx = $detailName . '_id';
1257 $params[$index] = $details->$idx;
1259 elseif ($fieldName == 'im') {
1260 $providerId = $detailName . '-provider_id';
1261 if (isset($imProviders[$details->$providerId])) {
1262 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1265 $values[$index] = $details->$detailName;
1267 $params[$index] = $details->$detailName;
1269 elseif ($fieldName == 'phone') {
1270 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1271 if (isset($details->$phoneExtField)) {
1272 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1275 $values[$index] = $details->$detailName;
1277 $params[$index] = $details->$detailName;
1280 $values[$index] = $params[$index] = $details->$detailName;
1284 $detailName = "website-{$id}-{$fieldName}";
1285 $url = CRM_Utils_System
::fixURL($details->$detailName);
1286 if ($details->$detailName) {
1287 $websiteTypeId = "website-{$id}-website_type_id";
1288 $websiteType = $websiteTypes[$details->$websiteTypeId];
1289 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1292 $values[$index] = '';
1297 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1298 CRM_Core_Permission
::check('profile listings and forms')
1301 if (CRM_Utils_System
::isNull($params[$index])) {
1302 $params[$index] = $values[$index];
1304 if (!isset($params[$index])) {
1307 if (!$customFieldName) {
1308 $fieldName = $field['name'];
1311 $fieldName = $customFieldName;
1315 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1316 $htmlType = $field['html_type'];
1317 if ($htmlType == 'Link') {
1318 $url = $params[$index];
1320 elseif (in_array($htmlType, array(
1324 'Multi-Select State/Province',
1325 'Multi-Select Country',
1327 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1328 $selectedOptions = explode($valSeperator, $params[$index]);
1330 foreach ($selectedOptions as $key => $multiOption) {
1332 $url[] = CRM_Utils_System
::url('civicrm/profile',
1333 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1334 urlencode($fieldName) .
1336 urlencode($multiOption)
1342 $url = CRM_Utils_System
::url('civicrm/profile',
1343 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1344 urlencode($fieldName) .
1346 urlencode($params[$index])
1351 $url = CRM_Utils_System
::url('civicrm/profile',
1352 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1353 urlencode($fieldName) .
1355 urlencode($params[$index])
1360 !empty($values[$index]) &&
1364 if (is_array($url) && !empty($url)) {
1366 $eachMultiValue = explode(', ', $values[$index]);
1367 foreach ($eachMultiValue as $key => $valueLabel) {
1368 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1370 $values[$index] = implode(', ', $links);
1373 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1381 * Check if profile Group used by any module.
1389 public static function usedByModule($id) {
1390 //check whether this group is used by any module(check uf join records)
1392 FROM civicrm_uf_join
1393 WHERE civicrm_uf_join.uf_group_id=$id";
1395 $dao = new CRM_Core_DAO();
1397 if ($dao->fetch()) {
1406 * Delete the profile Group.
1414 public static function del($id) {
1415 //check whether this group contains any profile fields
1416 $profileField = new CRM_Core_DAO_UFField();
1417 $profileField->uf_group_id
= $id;
1418 $profileField->find();
1419 while ($profileField->fetch()) {
1420 CRM_Core_BAO_UFField
::del($profileField->id
);
1423 //delete records from uf join table
1424 $ufJoin = new CRM_Core_DAO_UFJoin();
1425 $ufJoin->uf_group_id
= $id;
1428 //delete profile group
1429 $group = new CRM_Core_DAO_UFGroup();
1438 * @param array $params
1439 * Reference array contains the values submitted by the form.
1441 * Reference array contains the id.
1446 public static function add(&$params, $ids = array()) {
1456 foreach ($fields as $field) {
1457 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1460 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1461 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1464 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1465 $params['group_type'] = implode(',', $params['group_type']);
1467 $ufGroup = new CRM_Core_DAO_UFGroup();
1468 $ufGroup->copyValues($params);
1470 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1472 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1474 $ufGroup->id
= $ufGroupID;
1479 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1487 * Make uf join entries for an uf group.
1489 * @param array $params
1490 * (reference) an assoc array of name/value pairs.
1491 * @param int $ufGroupId
1494 public static function createUFJoin(&$params, $ufGroupId) {
1495 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1497 // get ufjoin records for uf group
1498 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1500 // get the list of all ufgroup types
1501 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1503 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1504 if (!is_array($groupTypes)) {
1505 $groupTypes = array();
1508 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1509 if (!is_array($ufGroupRecord)) {
1510 $ufGroupRecord = array();
1513 // check which values has to be inserted/deleted for contact
1514 $menuRebuild = FALSE;
1515 foreach ($allUFGroupType as $key => $value) {
1516 $joinParams = array();
1517 $joinParams['uf_group_id'] = $ufGroupId;
1518 $joinParams['module'] = $key;
1519 if ($key == 'User Account') {
1520 $menuRebuild = TRUE;
1522 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1523 // insert a new record
1524 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1526 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1527 // delete a record for existing ufgroup
1528 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1534 UPDATE civicrm_uf_join
1536 WHERE uf_group_id = %2
1537 AND ( entity_id IS NULL OR entity_id <= 0 )
1540 1 => array($params['weight'], 'Integer'),
1541 2 => array($ufGroupId, 'Integer'),
1543 CRM_Core_DAO
::executeQuery($query, $p);
1545 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1547 $config = CRM_Core_Config
::singleton();
1549 $config->userSystem
->is_drupal
1556 * Get the UF Join records for an ufgroup id.
1558 * @param int $ufGroupId
1560 * @param int $displayName
1561 * If set return display name in array.
1562 * @param int $status
1563 * If set return module other than default modules (User Account/User registration/Profile).
1568 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1570 $UFGroupType = array();
1571 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1575 $dao = new CRM_Core_DAO_UFJoin();
1578 $dao->uf_group_id
= $ufGroupId;
1584 while ($dao->fetch()) {
1585 if (!$displayName) {
1586 $ufJoin[$dao->id
] = $dao->module
;
1589 if (isset($UFGroupType[$dao->module
])) {
1590 // skip the default modules
1592 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1594 // added for CRM-1475
1596 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1597 $ufJoin[$dao->id
] = $dao->module
;
1605 * Function takes an associative array and creates a ufjoin record for ufgroup.
1607 * @param array $params
1608 * (reference) an assoc array of name/value pairs.
1610 * @return CRM_Core_BAO_UFJoin
1612 public static function addUFJoin(&$params) {
1613 $ufJoin = new CRM_Core_DAO_UFJoin();
1614 $ufJoin->copyValues($params);
1620 * Delete the uf join record for an uf group.
1622 * @param array $params
1623 * (reference) an assoc array of name/value pairs.
1625 public static function delUFJoin(&$params) {
1626 $ufJoin = new CRM_Core_DAO_UFJoin();
1627 $ufJoin->copyValues($params);
1632 * Get the weight for ufjoin record.
1634 * @param int $ufGroupId
1635 * If $ufGroupId get update weight or add weight.
1638 * weight of the UFGroup
1640 public static function getWeight($ufGroupId = NULL) {
1641 //calculate the weight
1644 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1645 FROM civicrm_uf_join
1646 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1649 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1650 FROM civicrm_uf_join
1651 WHERE civicrm_uf_join.uf_group_id = %1
1652 AND ( entity_id IS NULL OR entity_id <= 0 )";
1653 $p[1] = array($ufGroupId, 'Integer');
1656 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1658 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1662 * Get the uf group for a module.
1664 * @param string $moduleName
1667 * No to increment the weight.
1668 * @param bool $skipPermission
1670 * Which operation (view, edit, create, etc) to check permission for.
1671 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1674 * array of ufgroups for a module
1676 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1677 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1679 if (!CRM_Core_Config
::isUpgradeMode()) {
1680 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1681 $selectFields[] = 'description';
1684 if (!empty($returnFields)) {
1685 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1688 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1689 FROM civicrm_uf_group
1690 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1693 $queryString .= ' AND civicrm_uf_group.is_active = 1
1694 WHERE civicrm_uf_join.module = %2';
1695 $p[2] = array($moduleName, 'String');
1698 // add permissioning for profiles only if not registration
1699 if (!$skipPermission) {
1700 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1701 if (strpos($queryString, 'WHERE') !== FALSE) {
1702 $queryString .= " AND $permissionClause ";
1705 $queryString .= " $permissionClause ";
1709 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1710 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1712 $ufGroups = array();
1713 while ($dao->fetch()) {
1714 //skip mix profiles in user Registration / User Account
1715 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1716 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1720 foreach ($selectFields as $key => $field) {
1721 if ($field == 'id') {
1724 $ufGroups[$dao->id
][$field] = $dao->$field;
1728 // Allow other modules to alter/override the UFGroups.
1729 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1735 * Filter ufgroups based on logged in user contact type.
1737 * @param int $ufGroupId
1738 * Uf group id (profile id).
1739 * @param int $contactID
1744 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1746 $session = CRM_Core_Session
::singleton();
1747 $contactID = $session->get('userID');
1751 //get the contact type
1752 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1754 //match if exixting contact type is same as profile contact type
1755 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1757 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1758 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1761 //allow special mix profiles for Contribution and Participant
1762 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1764 if (in_array($profileType, $specialProfiles)) {
1768 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1777 * Add profile field to a form.
1779 * @param CRM_Core_Form $form
1780 * @param array $field
1784 * @param int $contactId
1785 * @param bool $online
1786 * @param string $usedFor
1787 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1788 * @param int $rowNumber
1789 * @param string $prefix
1793 public static function buildProfile(
1803 $defaultValues = array();
1804 $fieldName = $field['name'];
1805 $title = $field['title'];
1806 $attributes = $field['attributes'];
1807 $rule = $field['rule'];
1808 $view = $field['is_view'];
1809 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1810 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1811 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1813 // do not display view fields in drupal registration form
1815 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1819 if ($usedFor == 'onbehalf') {
1820 $name = "onbehalf[$fieldName]";
1822 elseif ($usedFor == 'honor') {
1823 $name = "honor[$fieldName]";
1825 elseif ($contactId && !$online) {
1826 $name = "field[$contactId][$fieldName]";
1828 elseif ($rowNumber) {
1829 $name = "field[$rowNumber][$fieldName]";
1831 elseif (!empty($prefix)) {
1832 $name = $prefix . "[$fieldName]";
1838 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1840 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1841 $deleteExtra = json_encode(ts('Are you sure you want to delete contact image.'));
1843 CRM_Core_Action
::DELETE
=> array(
1844 'name' => ts('Delete Contact Image'),
1845 'url' => 'civicrm/contact/image',
1846 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1847 'extra' => 'onclick = "' . htmlspecialchars("if (confirm($deleteExtra)) this.href+='&confirmed=1'; else return false;") . '"',
1850 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1851 CRM_Core_Action
::DELETE
,
1853 'id' => $form->get('id'),
1854 'gid' => $form->get('gid'),
1858 'contact.profileimage.delete',
1862 $form->assign('deleteURL', $deleteURL);
1864 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1865 'address_options', TRUE, NULL, TRUE
1868 if (substr($fieldName, 0, 14) === 'state_province') {
1869 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1870 $config = CRM_Core_Config
::singleton();
1871 if (!in_array($mode, array(
1872 CRM_Profile_Form
::MODE_EDIT
,
1873 CRM_Profile_Form
::MODE_SEARCH
,
1875 $config->defaultContactStateProvince
1877 $defaultValues[$name] = $config->defaultContactStateProvince
;
1878 $form->setDefaults($defaultValues);
1881 elseif (substr($fieldName, 0, 7) === 'country') {
1882 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1883 $config = CRM_Core_Config
::singleton();
1884 if (!in_array($mode, array(
1885 CRM_Profile_Form
::MODE_EDIT
,
1886 CRM_Profile_Form
::MODE_SEARCH
,
1888 $config->defaultContactCountry
1890 $defaultValues[$name] = $config->defaultContactCountry
;
1891 $form->setDefaults($defaultValues);
1894 elseif (substr($fieldName, 0, 6) === 'county') {
1895 if ($addressOptions['county']) {
1896 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1899 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1900 $form->add('file', $name, $title, $attributes, $required);
1901 $form->addUploadElement($name);
1903 elseif (substr($fieldName, 0, 2) === 'im') {
1904 $form->add('text', $name, $title, $attributes, $required);
1907 if (substr($name, -1) == ']') {
1908 $providerName = substr($name, 0, -1) . '-provider_id]';
1910 $form->add('select', $providerName, NULL,
1912 '' => ts('- select -'),
1913 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1917 $form->add('select', $name . '-provider_id', $title,
1919 '' => ts('- select -'),
1920 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1924 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1925 $form->freeze($name . '-provider_id');
1929 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1930 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1932 elseif (in_array($fieldName, array(
1933 'membership_start_date',
1934 'membership_end_date',
1937 $form->addDate($name, $title, $required, array('formatType' => 'activityDate'));
1939 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1940 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1941 $sel = &$form->addElement('hierselect', $name, $title);
1942 $select = array('' => ts('- select -'));
1943 if (count($orgInfo) == 1 && $field['is_required']) {
1944 // we only have one org - so we should default to it. Not sure about defaulting to first type
1945 // as it could be missed - so adding a select
1946 // however, possibly that is more similar to the membership form
1947 if (count($types[1]) > 1) {
1948 $types[1] = $select +
$types[1];
1952 $orgInfo = $select +
$orgInfo;
1954 $sel->setOptions(array($orgInfo, $types));
1956 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1957 $form->add('select', $name, $title,
1959 '' => ts('- select -'),
1960 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1963 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1965 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1966 foreach ($pseudoValues as $key => $var) {
1967 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1969 $group = $form->addGroup($options, $name, $title);
1971 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1974 $group->setAttribute('allowClear', TRUE);
1977 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1978 $form->addSelect($name, array(
1980 'entity' => 'contact',
1981 'field' => $fieldName,
1983 'placeholder' => '',
1986 elseif ($fieldName === 'contact_sub_type') {
1987 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1988 if ($usedFor == 'onbehalf') {
1989 $profileType = 'Organization';
1991 elseif ($usedFor == 'honor') {
1992 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1995 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1996 if ($profileType == 'Contact') {
1997 $profileType = 'Individual';
2001 $setSubtype = FALSE;
2002 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2003 $setSubtype = $profileType;
2004 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2007 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2010 $subtypeList = array();
2011 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2014 $subtypeList = $subtypes;
2017 $form->add('select', $name, $title, $subtypeList, $required, array('class' => 'crm-select2', 'multiple' => TRUE));
2019 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2020 //add email greeting, postal greeting, addressee, CRM-4575
2021 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2022 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2024 if (empty($profileType) ||
in_array($profileType, array(
2031 $profileType = 'Individual';
2033 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2034 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2037 'contact_type' => $profileType,
2038 'greeting_type' => $fieldName,
2040 $form->add('select', $name, $title,
2042 '' => ts('- select -'),
2043 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2045 // add custom greeting element
2046 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2050 elseif ($fieldName === 'preferred_communication_method') {
2051 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2052 foreach ($communicationFields as $key => $var) {
2056 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2058 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2060 elseif ($fieldName === 'preferred_mail_format') {
2061 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2063 elseif ($fieldName === 'preferred_language') {
2064 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2066 elseif ($fieldName == 'external_identifier') {
2067 $form->add('text', $name, $title, $attributes, $required);
2068 $contID = $contactId;
2070 $contID = $form->get('id');
2072 $form->addRule($name,
2073 ts('External ID already exists in Database.'),
2075 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2078 elseif ($fieldName === 'group') {
2079 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2080 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2085 elseif ($fieldName === 'tag') {
2086 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2087 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2092 elseif (substr($fieldName, 0, 4) === 'url-') {
2093 $form->add('text', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'), $required);
2094 $form->addRule($name, ts('Enter a valid web address beginning with \'http://\' or \'https://\'.'), 'url');
2096 // Note should be rendered as textarea
2097 elseif (substr($fieldName, -4) == 'note') {
2098 $form->add('textarea', $name, $title, $attributes, $required);
2100 elseif (substr($fieldName, 0, 6) === 'custom') {
2101 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2102 if ($customFieldID) {
2103 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2106 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2107 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2108 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2109 if ($customFieldID) {
2110 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2113 elseif (in_array($fieldName, array(
2119 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2121 elseif ($fieldName == 'send_receipt') {
2122 $form->addElement('checkbox', $name, $title);
2124 elseif ($fieldName == 'soft_credit') {
2125 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2126 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2128 elseif ($fieldName == 'product_name') {
2129 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2130 $sel = &$form->addElement('hierselect', $name, $title);
2132 '0' => ts('- select -'),
2134 $sel->setOptions(array($products, $options));
2136 elseif ($fieldName == 'payment_instrument') {
2137 $form->add('select', $name, $title,
2138 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2140 elseif ($fieldName == 'financial_type') {
2141 $form->add('select', $name, $title,
2143 '' => ts('- select -'),
2144 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2147 elseif ($fieldName == 'contribution_status_id') {
2148 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2149 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2155 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2158 $form->add('select', $name, $title,
2160 '' => ts('- select -'),
2161 ) +
$contributionStatuses, $required
2164 elseif ($fieldName == 'soft_credit_type') {
2165 $name = "soft_credit_type[$rowNumber]";
2166 $form->add('select', $name, $title,
2168 '' => ts('- select -'),
2169 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2171 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2172 //else (for contribution), use configured SCT default value
2173 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2174 if ($field['field_type'] == 'Membership') {
2175 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2177 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2179 elseif ($fieldName == 'contribution_soft_credit_pcp_id') {
2180 CRM_Contribute_Form_SoftCredit
::addPCPFields($form, "[$rowNumber]");
2182 elseif ($fieldName == 'currency') {
2183 $form->addCurrency($name, $title, $required);
2185 elseif ($fieldName == 'contribution_page_id') {
2186 $form->add('select', $name, $title,
2188 '' => ts('- select -'),
2189 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2192 elseif ($fieldName == 'participant_register_date') {
2193 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2195 elseif ($fieldName == 'activity_status_id') {
2196 $form->add('select', $name, $title,
2198 '' => ts('- select -'),
2199 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2202 elseif ($fieldName == 'activity_engagement_level') {
2203 $form->add('select', $name, $title,
2205 '' => ts('- select -'),
2206 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2209 elseif ($fieldName == 'activity_date_time') {
2210 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2212 elseif ($fieldName == 'participant_status') {
2214 if ($online == TRUE) {
2215 $cond = 'visibility_id = 1';
2217 $form->add('select', $name, $title,
2219 '' => ts('- select -'),
2220 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2223 elseif ($fieldName == 'participant_role') {
2224 if (!empty($field['is_multiple'])) {
2225 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2228 $form->add('select', $name, $title,
2230 '' => ts('- select -'),
2231 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2235 elseif ($fieldName == 'world_region') {
2236 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2238 elseif ($fieldName == 'signature_html') {
2239 $form->add('wysiwyg', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2241 elseif ($fieldName == 'signature_text') {
2242 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2244 elseif (substr($fieldName, -11) == 'campaign_id') {
2245 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2246 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2247 $form->_componentCampaigns
2249 $form->add('select', $name, $title,
2251 '' => ts('- select -'),
2252 ) +
$campaigns, $required, 'class="crm-select2 big"'
2256 elseif ($fieldName == 'activity_details') {
2257 $form->add('wysiwyg', $fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2259 elseif ($fieldName == 'activity_duration') {
2260 $form->add('text', $name, $title, $attributes, $required);
2261 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2264 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2265 $form->add('advcheckbox', $name, $title, $attributes, $required);
2268 $form->add('text', $name, $title, $attributes, $required);
2272 static $hiddenSubtype = FALSE;
2273 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2274 // In registration mode params are submitted via POST and we don't have any clue
2275 // about profile-id or the profile-type (which could be a subtype)
2276 // To generalize the behavior and simplify the process,
2277 // lets always add the hidden
2278 //subtype value if there is any, and we won't have to
2279 // compute it while processing.
2281 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2284 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2286 $hiddenSubtype = TRUE;
2289 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2290 $form->freeze($name);
2294 if (in_array($fieldName, array(
2295 'non_deductible_amount',
2300 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2303 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2304 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2310 * Set profile defaults.
2312 * @param int $contactId
2314 * @param array $fields
2315 * Associative array of fields.
2316 * @param array $defaults
2318 * @param bool $singleProfile
2319 * True for single profile else false(Update multiple items).
2320 * @param int $componentId
2321 * Id for specific components like contribute, event etc.
2322 * @param null $component
2324 public static function setProfileDefaults(
2325 $contactId, &$fields, &$defaults,
2326 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2328 if (!$componentId) {
2329 //get the contact details
2330 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2331 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2332 $multipleFields = array('website' => 'url');
2334 //start of code to set the default values
2335 foreach ($fields as $name => $field) {
2336 // skip pseudo fields
2337 if (substr($name, 0, 9) == 'phone_ext') {
2341 //set the field name depending upon the profile mode(single/multiple)
2342 if ($singleProfile) {
2346 $fldName = "field[$contactId][$name]";
2349 if ($name == 'group') {
2350 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2352 if ($name == 'tag') {
2353 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2356 if (!empty($details[$name]) ||
isset($details[$name])) {
2357 //to handle custom data (checkbox) to be written
2358 // to handle birth/deceased date, greeting_type and few other fields
2359 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2360 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2362 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2363 $defaults[$fldName] = $details[$name . '_id'];
2364 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2366 elseif ($name == 'preferred_communication_method') {
2367 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2368 foreach ($v as $item) {
2370 $defaults[$fldName . "[$item]"] = 1;
2374 elseif ($name == 'contact_sub_type') {
2375 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2377 elseif ($name == 'world_region') {
2378 $defaults[$fldName] = $details['worldregion_id'];
2380 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2381 //fix for custom fields
2382 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2384 // hack to add custom data for components
2385 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2386 foreach ($components as $value) {
2387 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2388 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2392 switch ($customFields[$customFieldId]['html_type']) {
2393 case 'Multi-Select State/Province':
2394 case 'Multi-Select Country':
2395 case 'AdvMulti-Select':
2396 case 'Multi-Select':
2397 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2398 foreach ($v as $item) {
2400 $defaults[$fldName][$item] = $item;
2406 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2407 foreach ($v as $item) {
2409 $defaults[$fldName][$item] = 1;
2410 // seems like we need this for QF style checkboxes in profile where its multiindexed
2412 $defaults["{$fldName}[{$item}]"] = 1;
2418 // CRM-6681, set defult values according to date and time format (if any).
2420 if (!empty($customFields[$customFieldId]['date_format'])) {
2421 $dateFormat = $customFields[$customFieldId]['date_format'];
2424 if (empty($customFields[$customFieldId]['time_format'])) {
2425 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2430 $timeElement = $fldName . '_time';
2431 if (substr($fldName, -1) == ']') {
2432 $timeElement = substr($fldName, 0, -1) . '_time]';
2434 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2435 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2440 $defaults[$fldName] = $details[$name];
2445 $defaults[$fldName] = $details[$name];
2449 $blocks = array('email', 'phone', 'im', 'openid');
2450 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2451 if (!in_array($fieldName, $multipleFields)) {
2452 if (is_array($details)) {
2453 foreach ($details as $key => $value) {
2454 // when we fixed CRM-5319 - get primary loc
2455 // type as per loc field and removed below code.
2456 $primaryLocationType = FALSE;
2457 if ($locTypeId == 'Primary') {
2458 if (is_array($value) && array_key_exists($fieldName, $value)) {
2459 $primaryLocationType = TRUE;
2460 if (in_array($fieldName, $blocks)) {
2461 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2464 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2469 // fixed for CRM-665
2470 if (is_numeric($locTypeId)) {
2471 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2472 if (!empty($value[$fieldName])) {
2473 //to handle stateprovince and country
2474 if ($fieldName == 'state_province') {
2475 $defaults[$fldName] = $value['state_province_id'];
2477 elseif ($fieldName == 'county') {
2478 $defaults[$fldName] = $value['county_id'];
2480 elseif ($fieldName == 'country') {
2481 if (!isset($value['country_id']) ||
!$value['country_id']) {
2482 $config = CRM_Core_Config
::singleton();
2483 if ($config->defaultContactCountry
) {
2484 $defaults[$fldName] = $config->defaultContactCountry
;
2488 $defaults[$fldName] = $value['country_id'];
2491 elseif ($fieldName == 'phone') {
2493 if (isset($value['phone'][$phoneTypeId])) {
2494 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2496 if (isset($value['phone_ext'][$phoneTypeId])) {
2497 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2501 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2503 if (!is_array($phoneDefault)) {
2504 $defaults[$fldName] = $phoneDefault;
2508 elseif ($fieldName == 'email') {
2509 //adding the first email (currently we don't support multiple emails of same location type)
2510 $defaults[$fldName] = $value['email'];
2512 elseif ($fieldName == 'im') {
2513 //adding the first im (currently we don't support multiple ims of same location type)
2514 $defaults[$fldName] = $value['im'];
2515 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2518 $defaults[$fldName] = $value[$fieldName];
2521 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2522 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2524 $defaults[$fldName] = $value[substr($fieldName, 8)];
2532 if (is_array($details)) {
2533 if ($fieldName === 'url'
2534 && !empty($details['website'])
2535 && !empty($details['website'][$locTypeId])
2537 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2545 //Handling Contribution Part of the batch profile
2546 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2547 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2550 //Handling Event Participation Part of the batch profile
2551 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2552 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2555 //Handling membership Part of the batch profile
2556 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2557 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2560 //Handling Activity Part of the batch profile
2561 if ($component == 'Activity') {
2562 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2567 * Get profiles by type eg: pure Individual etc
2569 * @param array $types
2570 * Associative array of types eg: types('Individual').
2571 * @param bool $onlyPure
2572 * True if only pure profiles are required.
2575 * associative array of profiles
2577 public static function getProfiles($types, $onlyPure = FALSE) {
2578 $profiles = array();
2579 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2581 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2583 // Exclude Batch Data Entry profiles - CRM-10901
2584 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2586 foreach ($ufGroups as $id => $title) {
2587 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2588 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2589 $profiles[$id] = $title;
2596 * Check whether a profile is valid combination of
2597 * required and/or optional profile types
2599 * @param array $required
2600 * Array of types those are required.
2601 * @param array $optional
2602 * Array of types those are optional.
2605 * associative array of profiles
2607 public static function getValidProfiles($required, $optional = NULL) {
2608 if (!is_array($required) ||
empty($required)) {
2612 $profiles = array();
2613 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2615 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2617 foreach ($ufGroups as $id => $title) {
2618 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2620 $profiles[$id] = $title;
2628 * Check whether a profile is valid combination of
2629 * required profile fields
2631 * @param array $ufId
2632 * Integer id of the profile.
2633 * @param array $required
2634 * Array of fields those are required in the profile.
2637 * associative array of profiles
2639 public static function checkValidProfile($ufId, $required = NULL) {
2640 $validProfile = FALSE;
2642 return $validProfile;
2645 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2646 return $validProfile;
2649 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2650 NULL, FALSE, NULL, FALSE, NULL,
2651 CRM_Core_Permission
::CREATE
, NULL
2654 $validProfile = array();
2655 if (!empty($profileFields)) {
2656 $fields = array_keys($profileFields);
2657 foreach ($fields as $val) {
2658 foreach ($required as $key => $field) {
2659 if (strpos($val, $field) === 0) {
2660 unset($required[$key]);
2665 $validProfile = (empty($required)) ?
TRUE : FALSE;
2668 return $validProfile;
2672 * Get default value for Register.
2674 * @param array $fields
2675 * @param array $defaults
2679 public static function setRegisterDefaults(&$fields, &$defaults) {
2680 $config = CRM_Core_Config
::singleton();
2681 foreach ($fields as $name => $field) {
2682 if (substr($name, 0, 8) == 'country-') {
2683 if (!empty($config->defaultContactCountry
)) {
2684 $defaults[$name] = $config->defaultContactCountry
;
2687 elseif (substr($name, 0, 15) == 'state_province-') {
2688 if (!empty($config->defaultContactStateProvince
)) {
2689 $defaults[$name] = $config->defaultContactStateProvince
;
2697 * make a copy of a profile, including
2698 * all the fields in the profile
2701 * The profile id to copy.
2703 * @return \CRM_Core_DAO
2705 public static function copy($id) {
2706 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2707 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2713 if ($pos = strrpos($copy->name
, "_{$id}")) {
2714 $copy->name
= substr_replace($copy->name
, '', $pos);
2716 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2719 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2720 array('uf_group_id' => $id),
2721 array('uf_group_id' => $copy->id
),
2726 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2727 array('uf_group_id' => $id),
2728 array('uf_group_id' => $copy->id
)
2731 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2735 UPDATE civicrm_uf_join
2737 WHERE uf_group_id = %2
2738 AND ( entity_id IS NULL OR entity_id <= 0 )
2741 1 => array($maxWeight +
1, 'Integer'),
2742 2 => array($copy->id
, 'Integer'),
2744 CRM_Core_DAO
::executeQuery($query, $p);
2745 if ($copy->is_reserved
) {
2746 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2747 $params = array(1 => array($copy->id
, 'Integer'));
2748 CRM_Core_DAO
::executeQuery($query, $params);
2750 CRM_Utils_Hook
::copy('UFGroup', $copy);
2756 * Process that send notification e-mails
2758 * @param int $contactID
2760 * @param array $values
2761 * Associative array of name/value pair.
2763 public static function commonSendMail($contactID, &$values) {
2764 if (!$contactID ||
!$values) {
2768 $template = CRM_Core_Smarty
::singleton();
2770 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2775 self
::profileDisplay($values['id'], $values['values'], $template);
2776 $emailList = explode(',', $values['email']);
2778 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2779 "reset=1&cid=$contactID",
2780 TRUE, NULL, FALSE, FALSE, TRUE
2783 //get the default domain email address.
2784 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2786 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2787 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2788 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)));
2791 foreach ($emailList as $emailTo) {
2792 // FIXME: take the below out of the foreach loop
2793 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2795 'groupName' => 'msg_tpl_workflow_uf',
2796 'valueName' => 'uf_notify',
2797 'contactId' => $contactID,
2798 'tplParams' => array(
2799 'displayName' => $displayName,
2800 'currentDate' => date('r'),
2801 'contactLink' => $contactLink,
2803 'from' => "$domainEmailName <$domainEmailAddress>",
2804 'toEmail' => $emailTo,
2811 * Given a contact id and a group id, returns the field values from the db
2812 * for this group and notify email only if group's notify field is
2813 * set and field values are not empty
2819 * @param array $params
2820 * @param bool $skipCheck
2824 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2826 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2828 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2829 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2831 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2833 if (!empty($values) &&
2838 'values' => $values,
2849 * Assign uf fields to template.
2853 * @param array $values
2854 * @param CRM_Core_Smarty $template
2856 public function profileDisplay($gid, $values, $template) {
2857 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2858 $template->assign('grouptitle', $groupTitle);
2859 if (count($values)) {
2860 $template->assign('values', $values);
2865 * Format fields for dupe Contact Matching.
2867 * @param array $params
2869 * @param int $contactId
2872 * associated formatted array
2874 public static function formatFields($params, $contactId = NULL) {
2876 // get the primary location type id and email
2877 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2880 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2881 $primaryLocationType = $defaultLocationType->id
;
2885 $locationType = array();
2887 $primaryLocation = 0;
2888 foreach ($params as $key => $value) {
2889 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2891 if ($locTypeId == 'Primary') {
2892 $locTypeId = $primaryLocationType;
2895 if (is_numeric($locTypeId)) {
2896 if (!in_array($locTypeId, $locationType)) {
2897 $locationType[$count] = $locTypeId;
2900 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2902 $data['location'][$loc]['location_type_id'] = $locTypeId;
2904 // if we are getting in a new primary email, dont overwrite the new one
2905 if ($locTypeId == $primaryLocationType) {
2906 if (!empty($params['email-' . $primaryLocationType])) {
2907 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2909 elseif (isset($primaryEmail)) {
2910 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2916 $data['location'][$loc]['is_primary'] = 1;
2918 if ($fieldName == 'phone') {
2920 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2923 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2925 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2927 elseif ($fieldName == 'email') {
2928 $data['location'][$loc]['email'][$loc]['email'] = $value;
2930 elseif ($fieldName == 'im') {
2931 $data['location'][$loc]['im'][$loc]['name'] = $value;
2934 if ($fieldName === 'state_province') {
2935 $data['location'][$loc]['address']['state_province_id'] = $value;
2937 elseif ($fieldName === 'country') {
2938 $data['location'][$loc]['address']['country_id'] = $value;
2941 $data['location'][$loc]['address'][$fieldName] = $value;
2946 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2947 if ($key === 'individual_suffix') {
2948 $data['suffix_id'] = $value;
2950 elseif ($key === 'individual_prefix') {
2951 $data['prefix_id'] = $value;
2953 elseif ($key === 'gender') {
2954 $data['gender_id'] = $value;
2956 elseif (substr($key, 0, 6) === 'custom') {
2957 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2959 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2960 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2962 // fix the date field
2963 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2964 $date = CRM_Utils_Date
::format($value);
2971 $data['custom'][$customFieldID] = array(
2974 'extends' => $customFields[$customFieldID]['extends'],
2975 'type' => $customFields[$customFieldID]['data_type'],
2976 'custom_field_id' => $customFieldID,
2980 elseif ($key == 'edit') {
2984 $data[$key] = $value;
2989 if (!$primaryLocation) {
2991 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2998 * Calculate the profile type 'group_type' as per profile fields.
3002 * @param bool $includeTypeValues
3003 * @param int $ignoreFieldId
3004 * Ignore particular profile field.
3007 * list of calculated group type
3009 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3010 //get the profile fields.
3011 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3012 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3016 * Calculate the profile type 'group_type' as per profile fields.
3019 * @param bool $includeTypeValues
3020 * @param int $ignoreFieldId
3021 * Ignore perticular profile field.
3024 * list of calculated group type
3026 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3027 $groupType = $groupTypeValues = $customFieldIds = array();
3028 if (!empty($ufFields)) {
3029 foreach ($ufFields as $fieldName => $fieldValue) {
3030 //ignore field from group type when provided.
3031 //in case of update profile field.
3032 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3035 if (!in_array($fieldValue['field_type'], $groupType)) {
3036 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3039 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3040 $customFieldIds[$fldId] = $fldId;
3045 if (!empty($customFieldIds)) {
3046 $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) . ')';
3048 $customGroups = CRM_Core_DAO
::executeQuery($query);
3049 while ($customGroups->fetch()) {
3050 if (!$customGroups->extends_entity_column_value
) {
3054 $groupTypeName = "{$customGroups->extends}Type";
3055 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3056 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3059 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3061 $groupTypeValues[$groupTypeName][$val] = $val;
3066 if (!empty($groupTypeValues)) {
3067 $groupType = array_merge($groupType, $groupTypeValues);
3075 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3076 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3079 * BirthDate + Email Individual,Contact
3080 * BirthDate + Subject Individual,Activity
3081 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3082 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3083 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3084 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3085 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3086 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3087 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3090 * @param array $groupTypes
3091 * With key having group type names.
3095 public static function updateGroupTypes($gId, $groupTypes = array()) {
3096 if (!is_array($groupTypes) ||
!$gId) {
3100 // If empty group types set group_type as 'null'
3101 if (empty($groupTypes)) {
3102 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3105 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3106 $validGroupTypes = array_merge(array(
3111 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3113 $gTypes = $gTypeValues = array();
3115 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3116 // Get valid group type and group subtypes
3117 foreach ($groupTypes as $groupType => $value) {
3118 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3119 $gTypes[] = $groupType;
3124 if (in_array($groupType, $participantExtends)) {
3125 $subTypesOf = $groupType;
3127 elseif (strpos($groupType, 'Type') > 0) {
3128 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3134 if (!empty($value) &&
3135 (in_array($subTypesOf, $componentGroupTypes) ||
3136 in_array($subTypesOf, $participantExtends)
3139 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3143 if (empty($gTypes)) {
3147 // Build String to store group types and group subtypes
3148 $groupTypeString = implode(',', $gTypes);
3149 if (!empty($gTypeValues)) {
3150 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3153 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3157 * Create a "group_type" string.
3159 * @param array $coreTypes
3160 * E.g. array('Individual','Contact','Student').
3161 * @param array $subTypes
3162 * E.g. array('ActivityType' => array(7, 11)).
3163 * @param string $delim
3166 * @throws CRM_Core_Exception
3168 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3169 $groupTypeExpr = '';
3171 $groupTypeExpr .= implode(',', $coreTypes);
3174 //CRM-15427 Allow Multiple subtype filtering
3175 //if (count($subTypes) > 1) {
3176 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3178 foreach ($subTypes as $subType => $subTypeIds) {
3179 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3182 return $groupTypeExpr;
3186 * setDefault componet specific profile fields.
3188 * @param array $fields
3190 * @param int $componentId
3192 * @param string $component
3194 * @param array $defaults
3195 * An array of default values.
3197 * @param bool $isStandalone
3199 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3200 if (!$componentId ||
3201 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3206 $componentBAO = $componentSubType = NULL;
3207 switch ($component) {
3209 $componentBAO = 'CRM_Member_BAO_Membership';
3210 $componentBAOName = 'Membership';
3211 $componentSubType = array('membership_type_id');
3215 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3216 $componentBAOName = 'Contribution';
3217 $componentSubType = array('financial_type_id');
3221 $componentBAO = 'CRM_Event_BAO_Participant';
3222 $componentBAOName = 'Participant';
3223 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3227 $componentBAO = 'CRM_Activity_BAO_Activity';
3228 $componentBAOName = 'Activity';
3229 $componentSubType = array('activity_type_id');
3234 $params = array('id' => $componentId);
3236 //get the component values.
3237 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3238 if ($componentBAOName == 'Participant') {
3239 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3242 $formattedGroupTree = array();
3243 $dateTimeFields = array(
3244 'participant_register_date',
3245 'activity_date_time',
3250 'membership_start_date',
3251 'membership_end_date',
3254 foreach ($fields as $name => $field) {
3255 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3256 if (in_array($name, $dateTimeFields)) {
3257 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3258 if (!empty($values[$name])) {
3259 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3262 elseif (array_key_exists($name, $values)) {
3263 $defaults[$fldName] = $values[$name];
3265 elseif ($name == 'participant_note') {
3266 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3267 $defaults[$fldName] = array_pop($noteDetails);
3269 elseif (in_array($name, array(
3271 'payment_instrument',
3272 'participant_status',
3275 $defaults[$fldName] = $values["{$name}_id"];
3277 elseif ($name == 'membership_type') {
3278 // since membership_type field is a hierselect -
3279 $defaults[$fldName][0]
3280 = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3281 $defaults[$fldName][1] = $values['membership_type_id'];
3283 elseif ($name == 'membership_status') {
3284 $defaults[$fldName] = $values['status_id'];
3286 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3287 if (empty($formattedGroupTree)) {
3288 //get the groupTree as per subTypes.
3289 $groupTree = array();
3290 foreach ($componentSubType as $subType) {
3291 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3292 $componentId, 0, $values[$subType]
3294 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3296 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3297 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3300 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3301 foreach ($defaults as $customKey => $customValue) {
3302 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3303 if ($name == 'custom_' . $customFieldDetails[0]) {
3305 //hack to set default for checkbox
3306 //basically this is for weired field name like field[33][custom_19]
3307 //we are converting this field name to array structure and assign value.
3310 foreach ($formattedGroupTree as $tree) {
3311 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3312 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3314 $defaults['field'][$componentId][$name] = $customValue;
3317 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3320 // CRM-6681, $default contains formatted date, time values.
3321 $defaults[$fldName] = $customValue;
3322 if (!empty($defaults[$customKey . '_time'])) {
3323 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3329 if (!$skipValue ||
$isStandalone) {
3330 $defaults[$fldName] = $customValue;
3332 unset($defaults[$customKey]);
3342 * @param array|string $profiles - name of profile(s) to create links for
3343 * @param array $appendProfiles
3344 * Name of profile(s) to append to each link.
3348 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3349 // Default to contact profiles
3351 $profiles = array('new_individual', 'new_organization', 'new_household');
3353 $profiles = (array) $profiles;
3354 $toGet = array_merge($profiles, (array) $appendProfiles);
3355 $retrieved = civicrm_api3('uf_group', 'get', array(
3356 'name' => array('IN' => $toGet),
3359 $links = $append = array();
3360 if (!empty($retrieved['values'])) {
3361 foreach ($retrieved['values'] as $id => $profile) {
3362 if (in_array($profile['name'], $profiles)) {
3364 'label' => $profile['title'],
3365 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3366 NULL, NULL, FALSE, FALSE, TRUE),
3367 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3374 foreach ($append as $id) {
3375 foreach ($links as &$link) {
3376 $link['url'] .= ",$id";
3384 * Retrieve groups of profiles.
3386 * @param int $profileID
3387 * Id of the profile.
3392 public static function profileGroups($profileID) {
3393 $groupTypes = array();
3394 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3395 if ($profileTypes) {
3396 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3397 $groupTypes = explode(',', $groupTypeParts[0]);
3403 * Alter contact params by filtering existing subscribed groups and returns
3404 * unsubscribed groups array for subscription.
3406 * @param array $params
3408 * @param int $contactId
3412 * This contains array of groups for subscription
3414 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3415 $config = CRM_Core_Config
::singleton();
3416 $subscribeGroupIds = array();
3418 // process further only if profileDoubleOptIn enabled and if groups exist
3419 if (!array_key_exists('group', $params) ||
3420 !self
::isProfileDoubleOptin() ||
3421 CRM_Utils_System
::isNull($params['group'])
3423 return $subscribeGroupIds;
3426 //check if contact email exist.
3428 foreach ($params as $name => $value) {
3429 if (strpos($name, 'email-') !== FALSE) {
3435 //Proceed furthur only if email present
3437 return $subscribeGroupIds;
3440 //do check for already subscriptions.
3441 $contactGroups = array();
3445 FROM civicrm_group_contact
3446 WHERE status = 'Added'
3447 AND contact_id = %1";
3449 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3450 while ($dao->fetch()) {
3451 $contactGroups[$dao->group_id
] = $dao->group_id
;
3455 //since we don't have names, compare w/ label.
3456 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3458 //actual processing start.
3459 foreach ($params['group'] as $groupId => $isSelected) {
3460 //unset group those are not selected.
3462 unset($params['group'][$groupId]);
3466 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3467 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3469 //get only mailing type group and unset it from params
3470 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3471 $subscribeGroupIds[$groupId] = $groupId;
3472 unset($params['group'][$groupId]);
3476 return $subscribeGroupIds;
3480 * Check if we are rendering mixed profiles.
3482 * @param array $profileIds
3483 * Associated array of profile ids.
3486 * true if profile is mixed
3488 public static function checkForMixProfiles($profileIds) {
3489 $mixProfile = FALSE;
3491 $contactTypes = array('Individual', 'Household', 'Organization');
3492 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3494 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3496 $typeCount = array('ctype' => array(), 'subtype' => array());
3497 foreach ($profileIds as $gid) {
3498 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3499 // ignore profile of type Contact
3500 if ($profileType == 'Contact') {
3503 if (in_array($profileType, $contactTypes)) {
3504 if (!isset($typeCount['ctype'][$profileType])) {
3505 $typeCount['ctype'][$profileType] = 1;
3508 // check if we are rendering profile of different contact types
3509 if (count($typeCount['ctype']) == 2) {
3514 elseif (in_array($profileType, $components)) {
3519 if (!isset($typeCount['subtype'][$profileType])) {
3520 $typeCount['subtype'][$profileType] = 1;
3522 // check if we are rendering profile of different contact sub types
3523 if (count($typeCount['subtype']) == 2) {
3533 * Determine of we show overlay profile or not.
3536 * true if profile should be shown else false
3538 public static function showOverlayProfile() {
3539 $showOverlay = TRUE;
3541 // get the id of overlay profile
3542 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3543 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3545 $count = CRM_Core_DAO
::singleValueQuery($query);
3547 //check if there are no public fields and use is anonymous
3548 $session = CRM_Core_Session
::singleton();
3549 if (!$count && !$session->get('userID')) {
3550 $showOverlay = FALSE;
3553 return $showOverlay;
3557 * Get group type values of the profile.
3559 * @param int $profileId
3560 * @param string $groupType
3565 public static function groupTypeValues($profileId, $groupType = NULL) {
3566 $groupTypeValue = array();
3567 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3569 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3570 if (empty($groupTypeParts[1])) {
3571 return $groupTypeValue;
3573 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3575 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3577 $valueParts = explode(':', $groupTypeValues);
3579 ($valueParts[0] != "{$groupType}Type" ||
3580 ($groupType == 'Participant' &&
3581 !in_array($valueParts[0], $participantExtends)
3587 foreach ($valueParts as $val) {
3588 if (CRM_Utils_Rule
::integer($val)) {
3589 $values[$val] = $val;
3592 if (!empty($values)) {
3593 $typeName = substr($valueParts[0], 0, -4);
3594 if (in_array($valueParts[0], $participantExtends)) {
3595 $typeName = $valueParts[0];
3597 $groupTypeValue[$typeName] = $values;
3601 return $groupTypeValue;
3605 * @return bool|object
3607 public static function isProfileDoubleOptin() {
3608 // check for double optin
3609 $config = CRM_Core_Config
::singleton();
3610 if (in_array('CiviMail', $config->enableComponents
)) {
3611 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3612 'profile_double_optin', NULL, FALSE
3619 * @return bool|object
3621 public static function isProfileAddToGroupDoubleOptin() {
3622 // check for add to group double optin
3623 $config = CRM_Core_Config
::singleton();
3624 if (in_array('CiviMail', $config->enableComponents
)) {
3625 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3626 'profile_add_to_group_double_optin', NULL, FALSE
3633 * Get profiles used for batch entry.
3636 * profileIds profile ids
3638 public static function getBatchProfiles() {
3640 FROM civicrm_uf_group
3641 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3642 $dao = CRM_Core_DAO
::executeQuery($query);
3643 $profileIds = array();
3644 while ($dao->fetch()) {
3645 $profileIds[$dao->id
] = $dao->id
;
3651 * @todo what do I do?
3653 * @param $destination
3654 * @param bool $returnMultiSummaryFields
3656 * @return array|null
3658 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3659 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3660 foreach ($source as $field => $properties) {
3661 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3664 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3665 $destination[$field] = $properties;
3666 if ($returnMultiSummaryFields) {
3667 if ($properties['is_multi_summary']) {
3668 $multiSummaryFields[$field] = $properties;
3671 unset($source[$field]);
3674 return $multiSummaryFields;
3678 * This is function is used to format pseudo fields.
3680 * @param array $fields
3681 * Associated array of profile fields.
3684 public static function reformatProfileFields(&$fields) {
3685 //reformat fields array
3686 foreach ($fields as $name => $field) {
3687 //reformat phone and extension field
3688 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3689 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3691 // retain existing element properties and just update and replace key
3692 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3693 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3694 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3696 // add additional phone extension field
3697 $fields["phone_ext-{$fieldSuffix}"] = $field;
3698 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3699 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3700 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3701 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3702 //ignore required for extension field
3703 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;