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 $title
717 * The title 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, $title, $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->title
= $title;
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 == 'currency') {
2180 $form->addCurrency($name, $title, $required);
2182 elseif ($fieldName == 'contribution_page_id') {
2183 $form->add('select', $name, $title,
2185 '' => ts('- select -'),
2186 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2189 elseif ($fieldName == 'participant_register_date') {
2190 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2192 elseif ($fieldName == 'activity_status_id') {
2193 $form->add('select', $name, $title,
2195 '' => ts('- select -'),
2196 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2199 elseif ($fieldName == 'activity_engagement_level') {
2200 $form->add('select', $name, $title,
2202 '' => ts('- select -'),
2203 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2206 elseif ($fieldName == 'activity_date_time') {
2207 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2209 elseif ($fieldName == 'participant_status') {
2211 if ($online == TRUE) {
2212 $cond = 'visibility_id = 1';
2214 $form->add('select', $name, $title,
2216 '' => ts('- select -'),
2217 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2220 elseif ($fieldName == 'participant_role') {
2221 if (!empty($field['is_multiple'])) {
2222 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2225 $form->add('select', $name, $title,
2227 '' => ts('- select -'),
2228 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2232 elseif ($fieldName == 'world_region') {
2233 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2235 elseif ($fieldName == 'signature_html') {
2236 $form->add('wysiwyg', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2238 elseif ($fieldName == 'signature_text') {
2239 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2241 elseif (substr($fieldName, -11) == 'campaign_id') {
2242 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2243 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2244 $form->_componentCampaigns
2246 $form->add('select', $name, $title,
2248 '' => ts('- select -'),
2249 ) +
$campaigns, $required, 'class="crm-select2 big"'
2253 elseif ($fieldName == 'activity_details') {
2254 $form->add('wysiwyg', $fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2256 elseif ($fieldName == 'activity_duration') {
2257 $form->add('text', $name, $title, $attributes, $required);
2258 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2261 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2262 $form->add('advcheckbox', $name, $title, $attributes, $required);
2265 $form->add('text', $name, $title, $attributes, $required);
2269 static $hiddenSubtype = FALSE;
2270 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2271 // In registration mode params are submitted via POST and we don't have any clue
2272 // about profile-id or the profile-type (which could be a subtype)
2273 // To generalize the behavior and simplify the process,
2274 // lets always add the hidden
2275 //subtype value if there is any, and we won't have to
2276 // compute it while processing.
2278 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2281 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2283 $hiddenSubtype = TRUE;
2286 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2287 $form->freeze($name);
2291 if (in_array($fieldName, array(
2292 'non_deductible_amount',
2297 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2300 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2301 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2307 * Set profile defaults.
2309 * @param int $contactId
2311 * @param array $fields
2312 * Associative array of fields.
2313 * @param array $defaults
2315 * @param bool $singleProfile
2316 * True for single profile else false(batch update).
2317 * @param int $componentId
2318 * Id for specific components like contribute, event etc.
2319 * @param null $component
2321 public static function setProfileDefaults(
2322 $contactId, &$fields, &$defaults,
2323 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2325 if (!$componentId) {
2326 //get the contact details
2327 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2328 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2329 $multipleFields = array('website' => 'url');
2331 //start of code to set the default values
2332 foreach ($fields as $name => $field) {
2333 // skip pseudo fields
2334 if (substr($name, 0, 9) == 'phone_ext') {
2338 //set the field name depending upon the profile mode(single/batch)
2339 if ($singleProfile) {
2343 $fldName = "field[$contactId][$name]";
2346 if ($name == 'group') {
2347 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2349 if ($name == 'tag') {
2350 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2353 if (!empty($details[$name]) ||
isset($details[$name])) {
2354 //to handle custom data (checkbox) to be written
2355 // to handle birth/deceased date, greeting_type and few other fields
2356 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2357 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2359 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2360 $defaults[$fldName] = $details[$name . '_id'];
2361 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2363 elseif ($name == 'preferred_communication_method') {
2364 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2365 foreach ($v as $item) {
2367 $defaults[$fldName . "[$item]"] = 1;
2371 elseif ($name == 'contact_sub_type') {
2372 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2374 elseif ($name == 'world_region') {
2375 $defaults[$fldName] = $details['worldregion_id'];
2377 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2378 //fix for custom fields
2379 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2381 // hack to add custom data for components
2382 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2383 foreach ($components as $value) {
2384 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2385 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2389 switch ($customFields[$customFieldId]['html_type']) {
2390 case 'Multi-Select State/Province':
2391 case 'Multi-Select Country':
2392 case 'AdvMulti-Select':
2393 case 'Multi-Select':
2394 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2395 foreach ($v as $item) {
2397 $defaults[$fldName][$item] = $item;
2403 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2404 foreach ($v as $item) {
2406 $defaults[$fldName][$item] = 1;
2407 // seems like we need this for QF style checkboxes in profile where its multiindexed
2409 $defaults["{$fldName}[{$item}]"] = 1;
2415 // CRM-6681, set defult values according to date and time format (if any).
2417 if (!empty($customFields[$customFieldId]['date_format'])) {
2418 $dateFormat = $customFields[$customFieldId]['date_format'];
2421 if (empty($customFields[$customFieldId]['time_format'])) {
2422 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2427 $timeElement = $fldName . '_time';
2428 if (substr($fldName, -1) == ']') {
2429 $timeElement = substr($fldName, 0, -1) . '_time]';
2431 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2432 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2437 $defaults[$fldName] = $details[$name];
2442 $defaults[$fldName] = $details[$name];
2446 $blocks = array('email', 'phone', 'im', 'openid');
2447 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2448 if (!in_array($fieldName, $multipleFields)) {
2449 if (is_array($details)) {
2450 foreach ($details as $key => $value) {
2451 // when we fixed CRM-5319 - get primary loc
2452 // type as per loc field and removed below code.
2453 $primaryLocationType = FALSE;
2454 if ($locTypeId == 'Primary') {
2455 if (is_array($value) && array_key_exists($fieldName, $value)) {
2456 $primaryLocationType = TRUE;
2457 if (in_array($fieldName, $blocks)) {
2458 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2461 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2466 // fixed for CRM-665
2467 if (is_numeric($locTypeId)) {
2468 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2469 if (!empty($value[$fieldName])) {
2470 //to handle stateprovince and country
2471 if ($fieldName == 'state_province') {
2472 $defaults[$fldName] = $value['state_province_id'];
2474 elseif ($fieldName == 'county') {
2475 $defaults[$fldName] = $value['county_id'];
2477 elseif ($fieldName == 'country') {
2478 if (!isset($value['country_id']) ||
!$value['country_id']) {
2479 $config = CRM_Core_Config
::singleton();
2480 if ($config->defaultContactCountry
) {
2481 $defaults[$fldName] = $config->defaultContactCountry
;
2485 $defaults[$fldName] = $value['country_id'];
2488 elseif ($fieldName == 'phone') {
2490 if (isset($value['phone'][$phoneTypeId])) {
2491 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2493 if (isset($value['phone_ext'][$phoneTypeId])) {
2494 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2498 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2500 if (!is_array($phoneDefault)) {
2501 $defaults[$fldName] = $phoneDefault;
2505 elseif ($fieldName == 'email') {
2506 //adding the first email (currently we don't support multiple emails of same location type)
2507 $defaults[$fldName] = $value['email'];
2509 elseif ($fieldName == 'im') {
2510 //adding the first im (currently we don't support multiple ims of same location type)
2511 $defaults[$fldName] = $value['im'];
2512 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2515 $defaults[$fldName] = $value[$fieldName];
2518 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2519 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2521 $defaults[$fldName] = $value[substr($fieldName, 8)];
2529 if (is_array($details)) {
2530 if ($fieldName === 'url'
2531 && !empty($details['website'])
2532 && !empty($details['website'][$locTypeId])
2534 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2542 //Handling Contribution Part of the batch profile
2543 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2544 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2547 //Handling Event Participation Part of the batch profile
2548 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2549 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2552 //Handling membership Part of the batch profile
2553 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2554 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2557 //Handling Activity Part of the batch profile
2558 if ($component == 'Activity') {
2559 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2564 * Get profiles by type eg: pure Individual etc
2566 * @param array $types
2567 * Associative array of types eg: types('Individual').
2568 * @param bool $onlyPure
2569 * True if only pure profiles are required.
2572 * associative array of profiles
2574 public static function getProfiles($types, $onlyPure = FALSE) {
2575 $profiles = array();
2576 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2578 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2580 // Exclude Batch Data Entry profiles - CRM-10901
2581 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2583 foreach ($ufGroups as $id => $title) {
2584 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2585 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2586 $profiles[$id] = $title;
2593 * Check whether a profile is valid combination of
2594 * required and/or optional profile types
2596 * @param array $required
2597 * Array of types those are required.
2598 * @param array $optional
2599 * Array of types those are optional.
2602 * associative array of profiles
2604 public static function getValidProfiles($required, $optional = NULL) {
2605 if (!is_array($required) ||
empty($required)) {
2609 $profiles = array();
2610 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2612 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2614 foreach ($ufGroups as $id => $title) {
2615 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2617 $profiles[$id] = $title;
2625 * Check whether a profile is valid combination of
2626 * required profile fields
2628 * @param array $ufId
2629 * Integer id of the profile.
2630 * @param array $required
2631 * Array of fields those are required in the profile.
2634 * associative array of profiles
2636 public static function checkValidProfile($ufId, $required = NULL) {
2637 $validProfile = FALSE;
2639 return $validProfile;
2642 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2643 return $validProfile;
2646 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2647 NULL, FALSE, NULL, FALSE, NULL,
2648 CRM_Core_Permission
::CREATE
, NULL
2651 $validProfile = array();
2652 if (!empty($profileFields)) {
2653 $fields = array_keys($profileFields);
2654 foreach ($fields as $val) {
2655 foreach ($required as $key => $field) {
2656 if (strpos($val, $field) === 0) {
2657 unset($required[$key]);
2662 $validProfile = (empty($required)) ?
TRUE : FALSE;
2665 return $validProfile;
2669 * Get default value for Register.
2671 * @param array $fields
2672 * @param array $defaults
2676 public static function setRegisterDefaults(&$fields, &$defaults) {
2677 $config = CRM_Core_Config
::singleton();
2678 foreach ($fields as $name => $field) {
2679 if (substr($name, 0, 8) == 'country-') {
2680 if (!empty($config->defaultContactCountry
)) {
2681 $defaults[$name] = $config->defaultContactCountry
;
2684 elseif (substr($name, 0, 15) == 'state_province-') {
2685 if (!empty($config->defaultContactStateProvince
)) {
2686 $defaults[$name] = $config->defaultContactStateProvince
;
2694 * make a copy of a profile, including
2695 * all the fields in the profile
2698 * The profile id to copy.
2700 * @return \CRM_Core_DAO
2702 public static function copy($id) {
2703 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2704 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2710 if ($pos = strrpos($copy->name
, "_{$id}")) {
2711 $copy->name
= substr_replace($copy->name
, '', $pos);
2713 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2716 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2717 array('uf_group_id' => $id),
2718 array('uf_group_id' => $copy->id
),
2723 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2724 array('uf_group_id' => $id),
2725 array('uf_group_id' => $copy->id
)
2728 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2732 UPDATE civicrm_uf_join
2734 WHERE uf_group_id = %2
2735 AND ( entity_id IS NULL OR entity_id <= 0 )
2738 1 => array($maxWeight +
1, 'Integer'),
2739 2 => array($copy->id
, 'Integer'),
2741 CRM_Core_DAO
::executeQuery($query, $p);
2742 if ($copy->is_reserved
) {
2743 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2744 $params = array(1 => array($copy->id
, 'Integer'));
2745 CRM_Core_DAO
::executeQuery($query, $params);
2747 CRM_Utils_Hook
::copy('UFGroup', $copy);
2753 * Process that send notification e-mails
2755 * @param int $contactID
2757 * @param array $values
2758 * Associative array of name/value pair.
2760 public static function commonSendMail($contactID, &$values) {
2761 if (!$contactID ||
!$values) {
2765 $template = CRM_Core_Smarty
::singleton();
2767 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2772 self
::profileDisplay($values['id'], $values['values'], $template);
2773 $emailList = explode(',', $values['email']);
2775 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2776 "reset=1&cid=$contactID",
2777 TRUE, NULL, FALSE, FALSE, TRUE
2780 //get the default domain email address.
2781 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2783 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2784 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2785 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)));
2788 foreach ($emailList as $emailTo) {
2789 // FIXME: take the below out of the foreach loop
2790 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2792 'groupName' => 'msg_tpl_workflow_uf',
2793 'valueName' => 'uf_notify',
2794 'contactId' => $contactID,
2795 'tplParams' => array(
2796 'displayName' => $displayName,
2797 'currentDate' => date('r'),
2798 'contactLink' => $contactLink,
2800 'from' => "$domainEmailName <$domainEmailAddress>",
2801 'toEmail' => $emailTo,
2808 * Given a contact id and a group id, returns the field values from the db
2809 * for this group and notify email only if group's notify field is
2810 * set and field values are not empty
2816 * @param array $params
2817 * @param bool $skipCheck
2821 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2823 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2825 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2826 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2828 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2830 if (!empty($values) &&
2835 'values' => $values,
2846 * Assign uf fields to template.
2850 * @param array $values
2851 * @param CRM_Core_Smarty $template
2853 public function profileDisplay($gid, $values, $template) {
2854 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2855 $template->assign('grouptitle', $groupTitle);
2856 if (count($values)) {
2857 $template->assign('values', $values);
2862 * Format fields for dupe Contact Matching.
2864 * @param array $params
2866 * @param int $contactId
2869 * associated formatted array
2871 public static function formatFields($params, $contactId = NULL) {
2873 // get the primary location type id and email
2874 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2877 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2878 $primaryLocationType = $defaultLocationType->id
;
2882 $locationType = array();
2884 $primaryLocation = 0;
2885 foreach ($params as $key => $value) {
2886 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2888 if ($locTypeId == 'Primary') {
2889 $locTypeId = $primaryLocationType;
2892 if (is_numeric($locTypeId)) {
2893 if (!in_array($locTypeId, $locationType)) {
2894 $locationType[$count] = $locTypeId;
2897 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2899 $data['location'][$loc]['location_type_id'] = $locTypeId;
2901 // if we are getting in a new primary email, dont overwrite the new one
2902 if ($locTypeId == $primaryLocationType) {
2903 if (!empty($params['email-' . $primaryLocationType])) {
2904 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2906 elseif (isset($primaryEmail)) {
2907 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2913 $data['location'][$loc]['is_primary'] = 1;
2915 if ($fieldName == 'phone') {
2917 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2920 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2922 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2924 elseif ($fieldName == 'email') {
2925 $data['location'][$loc]['email'][$loc]['email'] = $value;
2927 elseif ($fieldName == 'im') {
2928 $data['location'][$loc]['im'][$loc]['name'] = $value;
2931 if ($fieldName === 'state_province') {
2932 $data['location'][$loc]['address']['state_province_id'] = $value;
2934 elseif ($fieldName === 'country') {
2935 $data['location'][$loc]['address']['country_id'] = $value;
2938 $data['location'][$loc]['address'][$fieldName] = $value;
2943 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2944 if ($key === 'individual_suffix') {
2945 $data['suffix_id'] = $value;
2947 elseif ($key === 'individual_prefix') {
2948 $data['prefix_id'] = $value;
2950 elseif ($key === 'gender') {
2951 $data['gender_id'] = $value;
2953 elseif (substr($key, 0, 6) === 'custom') {
2954 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2956 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2957 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2959 // fix the date field
2960 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2961 $date = CRM_Utils_Date
::format($value);
2968 $data['custom'][$customFieldID] = array(
2971 'extends' => $customFields[$customFieldID]['extends'],
2972 'type' => $customFields[$customFieldID]['data_type'],
2973 'custom_field_id' => $customFieldID,
2977 elseif ($key == 'edit') {
2981 $data[$key] = $value;
2986 if (!$primaryLocation) {
2988 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2995 * Calculate the profile type 'group_type' as per profile fields.
2999 * @param bool $includeTypeValues
3000 * @param int $ignoreFieldId
3001 * Ignore particular profile field.
3004 * list of calculated group type
3006 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3007 //get the profile fields.
3008 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3009 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3013 * Calculate the profile type 'group_type' as per profile fields.
3016 * @param bool $includeTypeValues
3017 * @param int $ignoreFieldId
3018 * Ignore perticular profile field.
3021 * list of calculated group type
3023 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3024 $groupType = $groupTypeValues = $customFieldIds = array();
3025 if (!empty($ufFields)) {
3026 foreach ($ufFields as $fieldName => $fieldValue) {
3027 //ignore field from group type when provided.
3028 //in case of update profile field.
3029 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3032 if (!in_array($fieldValue['field_type'], $groupType)) {
3033 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3036 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3037 $customFieldIds[$fldId] = $fldId;
3042 if (!empty($customFieldIds)) {
3043 $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) . ')';
3045 $customGroups = CRM_Core_DAO
::executeQuery($query);
3046 while ($customGroups->fetch()) {
3047 if (!$customGroups->extends_entity_column_value
) {
3051 $groupTypeName = "{$customGroups->extends}Type";
3052 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3053 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3056 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3058 $groupTypeValues[$groupTypeName][$val] = $val;
3063 if (!empty($groupTypeValues)) {
3064 $groupType = array_merge($groupType, $groupTypeValues);
3072 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3073 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3076 * BirthDate + Email Individual,Contact
3077 * BirthDate + Subject Individual,Activity
3078 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3079 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3080 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3081 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3082 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3083 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3084 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3087 * @param array $groupTypes
3088 * With key having group type names.
3092 public static function updateGroupTypes($gId, $groupTypes = array()) {
3093 if (!is_array($groupTypes) ||
!$gId) {
3097 // If empty group types set group_type as 'null'
3098 if (empty($groupTypes)) {
3099 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3102 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3103 $validGroupTypes = array_merge(array(
3108 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3110 $gTypes = $gTypeValues = array();
3112 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3113 // Get valid group type and group subtypes
3114 foreach ($groupTypes as $groupType => $value) {
3115 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3116 $gTypes[] = $groupType;
3121 if (in_array($groupType, $participantExtends)) {
3122 $subTypesOf = $groupType;
3124 elseif (strpos($groupType, 'Type') > 0) {
3125 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3131 if (!empty($value) &&
3132 (in_array($subTypesOf, $componentGroupTypes) ||
3133 in_array($subTypesOf, $participantExtends)
3136 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3140 if (empty($gTypes)) {
3144 // Build String to store group types and group subtypes
3145 $groupTypeString = implode(',', $gTypes);
3146 if (!empty($gTypeValues)) {
3147 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3150 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3154 * Create a "group_type" string.
3156 * @param array $coreTypes
3157 * E.g. array('Individual','Contact','Student').
3158 * @param array $subTypes
3159 * E.g. array('ActivityType' => array(7, 11)).
3160 * @param string $delim
3163 * @throws CRM_Core_Exception
3165 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3166 $groupTypeExpr = '';
3168 $groupTypeExpr .= implode(',', $coreTypes);
3171 //CRM-15427 Allow Multiple subtype filtering
3172 //if (count($subTypes) > 1) {
3173 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3175 foreach ($subTypes as $subType => $subTypeIds) {
3176 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3179 return $groupTypeExpr;
3183 * setDefault componet specific profile fields.
3185 * @param array $fields
3187 * @param int $componentId
3189 * @param string $component
3191 * @param array $defaults
3192 * An array of default values.
3194 * @param bool $isStandalone
3196 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3197 if (!$componentId ||
3198 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3203 $componentBAO = $componentSubType = NULL;
3204 switch ($component) {
3206 $componentBAO = 'CRM_Member_BAO_Membership';
3207 $componentBAOName = 'Membership';
3208 $componentSubType = array('membership_type_id');
3212 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3213 $componentBAOName = 'Contribution';
3214 $componentSubType = array('financial_type_id');
3218 $componentBAO = 'CRM_Event_BAO_Participant';
3219 $componentBAOName = 'Participant';
3220 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3224 $componentBAO = 'CRM_Activity_BAO_Activity';
3225 $componentBAOName = 'Activity';
3226 $componentSubType = array('activity_type_id');
3231 $params = array('id' => $componentId);
3233 //get the component values.
3234 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3235 if ($componentBAOName == 'Participant') {
3236 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3239 $formattedGroupTree = array();
3240 $dateTimeFields = array(
3241 'participant_register_date',
3242 'activity_date_time',
3247 'membership_start_date',
3248 'membership_end_date',
3251 foreach ($fields as $name => $field) {
3252 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3253 if (in_array($name, $dateTimeFields)) {
3254 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3255 if (!empty($values[$name])) {
3256 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3259 elseif (array_key_exists($name, $values)) {
3260 $defaults[$fldName] = $values[$name];
3262 elseif ($name == 'participant_note') {
3263 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3264 $defaults[$fldName] = array_pop($noteDetails);
3266 elseif (in_array($name, array(
3268 'payment_instrument',
3269 'participant_status',
3272 $defaults[$fldName] = $values["{$name}_id"];
3274 elseif ($name == 'membership_type') {
3275 // since membership_type field is a hierselect -
3276 $defaults[$fldName][0]
3277 = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3278 $defaults[$fldName][1] = $values['membership_type_id'];
3280 elseif ($name == 'membership_status') {
3281 $defaults[$fldName] = $values['status_id'];
3283 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3284 if (empty($formattedGroupTree)) {
3285 //get the groupTree as per subTypes.
3286 $groupTree = array();
3287 foreach ($componentSubType as $subType) {
3288 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3289 $componentId, 0, $values[$subType]
3291 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3293 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3294 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3297 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3298 foreach ($defaults as $customKey => $customValue) {
3299 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3300 if ($name == 'custom_' . $customFieldDetails[0]) {
3302 //hack to set default for checkbox
3303 //basically this is for weired field name like field[33][custom_19]
3304 //we are converting this field name to array structure and assign value.
3307 foreach ($formattedGroupTree as $tree) {
3308 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3309 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3311 $defaults['field'][$componentId][$name] = $customValue;
3314 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3317 // CRM-6681, $default contains formatted date, time values.
3318 $defaults[$fldName] = $customValue;
3319 if (!empty($defaults[$customKey . '_time'])) {
3320 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3326 if (!$skipValue ||
$isStandalone) {
3327 $defaults[$fldName] = $customValue;
3329 unset($defaults[$customKey]);
3339 * @param array|string $profiles - name of profile(s) to create links for
3340 * @param array $appendProfiles
3341 * Name of profile(s) to append to each link.
3345 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3346 // Default to contact profiles
3348 $profiles = array('new_individual', 'new_organization', 'new_household');
3350 $profiles = (array) $profiles;
3351 $toGet = array_merge($profiles, (array) $appendProfiles);
3352 $retrieved = civicrm_api3('uf_group', 'get', array(
3353 'name' => array('IN' => $toGet),
3356 $links = $append = array();
3357 if (!empty($retrieved['values'])) {
3358 foreach ($retrieved['values'] as $id => $profile) {
3359 if (in_array($profile['name'], $profiles)) {
3361 'label' => $profile['title'],
3362 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3363 NULL, NULL, FALSE, FALSE, TRUE),
3364 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3371 foreach ($append as $id) {
3372 foreach ($links as &$link) {
3373 $link['url'] .= ",$id";
3381 * Retrieve groups of profiles.
3383 * @param int $profileID
3384 * Id of the profile.
3389 public static function profileGroups($profileID) {
3390 $groupTypes = array();
3391 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3392 if ($profileTypes) {
3393 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3394 $groupTypes = explode(',', $groupTypeParts[0]);
3400 * Alter contact params by filtering existing subscribed groups and returns
3401 * unsubscribed groups array for subscription.
3403 * @param array $params
3405 * @param int $contactId
3409 * This contains array of groups for subscription
3411 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3412 $config = CRM_Core_Config
::singleton();
3413 $subscribeGroupIds = array();
3415 // process further only if profileDoubleOptIn enabled and if groups exist
3416 if (!array_key_exists('group', $params) ||
3417 !self
::isProfileDoubleOptin() ||
3418 CRM_Utils_System
::isNull($params['group'])
3420 return $subscribeGroupIds;
3423 //check if contact email exist.
3425 foreach ($params as $name => $value) {
3426 if (strpos($name, 'email-') !== FALSE) {
3432 //Proceed furthur only if email present
3434 return $subscribeGroupIds;
3437 //do check for already subscriptions.
3438 $contactGroups = array();
3442 FROM civicrm_group_contact
3443 WHERE status = 'Added'
3444 AND contact_id = %1";
3446 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3447 while ($dao->fetch()) {
3448 $contactGroups[$dao->group_id
] = $dao->group_id
;
3452 //since we don't have names, compare w/ label.
3453 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3455 //actual processing start.
3456 foreach ($params['group'] as $groupId => $isSelected) {
3457 //unset group those are not selected.
3459 unset($params['group'][$groupId]);
3463 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3464 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3466 //get only mailing type group and unset it from params
3467 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3468 $subscribeGroupIds[$groupId] = $groupId;
3469 unset($params['group'][$groupId]);
3473 return $subscribeGroupIds;
3477 * Check if we are rendering mixed profiles.
3479 * @param array $profileIds
3480 * Associated array of profile ids.
3483 * true if profile is mixed
3485 public static function checkForMixProfiles($profileIds) {
3486 $mixProfile = FALSE;
3488 $contactTypes = array('Individual', 'Household', 'Organization');
3489 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3491 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3493 $typeCount = array('ctype' => array(), 'subtype' => array());
3494 foreach ($profileIds as $gid) {
3495 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3496 // ignore profile of type Contact
3497 if ($profileType == 'Contact') {
3500 if (in_array($profileType, $contactTypes)) {
3501 if (!isset($typeCount['ctype'][$profileType])) {
3502 $typeCount['ctype'][$profileType] = 1;
3505 // check if we are rendering profile of different contact types
3506 if (count($typeCount['ctype']) == 2) {
3511 elseif (in_array($profileType, $components)) {
3516 if (!isset($typeCount['subtype'][$profileType])) {
3517 $typeCount['subtype'][$profileType] = 1;
3519 // check if we are rendering profile of different contact sub types
3520 if (count($typeCount['subtype']) == 2) {
3530 * Determine of we show overlay profile or not.
3533 * true if profile should be shown else false
3535 public static function showOverlayProfile() {
3536 $showOverlay = TRUE;
3538 // get the id of overlay profile
3539 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3540 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3542 $count = CRM_Core_DAO
::singleValueQuery($query);
3544 //check if there are no public fields and use is anonymous
3545 $session = CRM_Core_Session
::singleton();
3546 if (!$count && !$session->get('userID')) {
3547 $showOverlay = FALSE;
3550 return $showOverlay;
3554 * Get group type values of the profile.
3556 * @param int $profileId
3557 * @param string $groupType
3562 public static function groupTypeValues($profileId, $groupType = NULL) {
3563 $groupTypeValue = array();
3564 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3566 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3567 if (empty($groupTypeParts[1])) {
3568 return $groupTypeValue;
3570 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3572 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3574 $valueParts = explode(':', $groupTypeValues);
3576 ($valueParts[0] != "{$groupType}Type" ||
3577 ($groupType == 'Participant' &&
3578 !in_array($valueParts[0], $participantExtends)
3584 foreach ($valueParts as $val) {
3585 if (CRM_Utils_Rule
::integer($val)) {
3586 $values[$val] = $val;
3589 if (!empty($values)) {
3590 $typeName = substr($valueParts[0], 0, -4);
3591 if (in_array($valueParts[0], $participantExtends)) {
3592 $typeName = $valueParts[0];
3594 $groupTypeValue[$typeName] = $values;
3598 return $groupTypeValue;
3602 * @return bool|object
3604 public static function isProfileDoubleOptin() {
3605 // check for double optin
3606 $config = CRM_Core_Config
::singleton();
3607 if (in_array('CiviMail', $config->enableComponents
)) {
3608 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3609 'profile_double_optin', NULL, FALSE
3616 * @return bool|object
3618 public static function isProfileAddToGroupDoubleOptin() {
3619 // check for add to group double optin
3620 $config = CRM_Core_Config
::singleton();
3621 if (in_array('CiviMail', $config->enableComponents
)) {
3622 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3623 'profile_add_to_group_double_optin', NULL, FALSE
3630 * Get profiles used for batch entry.
3633 * profileIds profile ids
3635 public static function getBatchProfiles() {
3637 FROM civicrm_uf_group
3638 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3639 $dao = CRM_Core_DAO
::executeQuery($query);
3640 $profileIds = array();
3641 while ($dao->fetch()) {
3642 $profileIds[$dao->id
] = $dao->id
;
3648 * @todo what do I do?
3650 * @param $destination
3651 * @param bool $returnMultiSummaryFields
3653 * @return array|null
3655 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3656 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3657 foreach ($source as $field => $properties) {
3658 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3661 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3662 $destination[$field] = $properties;
3663 if ($returnMultiSummaryFields) {
3664 if ($properties['is_multi_summary']) {
3665 $multiSummaryFields[$field] = $properties;
3668 unset($source[$field]);
3671 return $multiSummaryFields;
3675 * This is function is used to format pseudo fields.
3677 * @param array $fields
3678 * Associated array of profile fields.
3681 public static function reformatProfileFields(&$fields) {
3682 //reformat fields array
3683 foreach ($fields as $name => $field) {
3684 //reformat phone and extension field
3685 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3686 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3688 // retain existing element properties and just update and replace key
3689 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3690 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3691 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3693 // add additional phone extension field
3694 $fields["phone_ext-{$fieldSuffix}"] = $field;
3695 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3696 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3697 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3698 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3699 //ignore required for extension field
3700 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;