3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
39 class CRM_Core_BAO_UFGroup
extends CRM_Core_DAO_UFGroup
{
40 CONST PUBLIC_VISIBILITY
= 1,
42 LISTINGS_VISIBILITY
= 4;
45 * cache the match clause used in this transaction
49 static $_matchFields = NULL;
52 * Takes a bunch of params that are needed to match certain criteria and
53 * retrieves the relevant objects. Typically the valid params are only
54 * contact_id. We'll tweak this function to be more full featured over a period
55 * of time. This is the inverse function of create. It also stores all the retrieved
56 * values in the default array
58 * @param array $params (reference) an assoc array of name/value pairs
59 * @param array $defaults (reference) an assoc array to hold the flattened values
61 * @return object CRM_Core_DAO_UFGroup object
65 static function retrieve(&$params, &$defaults) {
66 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
70 * Retrieve the first non-generic contact type
72 * @param int $id id of uf_group
74 * @return string contact type
76 static function getContactType($id) {
78 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
79 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
81 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
82 $types = explode(',', $typesParts[0]);
85 foreach ($types as $type) {
86 if (in_array($type, $validTypes)) {
89 elseif (array_key_exists($type, $validSubTypes)) {
90 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
100 * Get the form title.
102 * @param int $id id of uf_form
104 * @return string title
110 public static function getTitle($id) {
111 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
115 * update the is_active flag in the db
117 * @param int $id id of the database record
118 * @param boolean $is_active value we want to set the is_active field
120 * @return Object CRM_Core_DAO_UFGroup object on success, null otherwise
124 static function setIsActive($id, $is_active) {
125 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
129 * get all the registration fields
131 * @param int $action what action are we doing
132 * @param int $mode mode
136 * @return array the fields that are needed for registration
140 static function getRegistrationFields($action, $mode, $ctype = NULL) {
141 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
142 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
145 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
148 if (!is_array($ufGroups)) {
154 foreach ($ufGroups as $id => $title) {
156 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
157 if (($fieldType != 'Contact') &&
158 ($fieldType != $ctype) &&
159 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
163 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
164 $profileSubType = $fieldType;
168 $subset = self
::getFields($id, TRUE, $action,
169 NULL, NULL, FALSE, NULL, TRUE, $ctype
172 // we do not allow duplicates. the first field is the winner
173 foreach ($subset as $name => $field) {
174 if (empty($fields[$name])) {
175 $fields[$name] = $field;
184 * get all the listing fields
186 * @param int $action what action are we doing
187 * @param int $visibility visibility of fields we are interested in
188 * @param bool $considerSelector whether to consider the in_selector parameter
189 * @param array $ufGroupIds
190 * @param boolean $searchable
192 * @param null $restrict
193 * @param bool $skipPermission
194 * @param int $permissionType
195 * @return array the fields that are listings related
199 static function getListingFields(
202 $considerSelector = FALSE,
206 $skipPermission = FALSE,
207 $permissionType = CRM_Core_Permission
::SEARCH
210 $subset = self
::getFields($ufGroupIds, FALSE, $action,
211 $visibility, $searchable,
217 if ($considerSelector) {
218 // drop the fields not meant for the selector
219 foreach ($subset as $name => $field) {
220 if (!$field['in_selector']) {
221 unset($subset[$name]);
228 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
231 foreach ($ufGroups as $id => $title) {
232 $subset = self
::getFields($id, FALSE, $action,
233 $visibility, $searchable,
239 if ($considerSelector) {
240 // drop the fields not meant for the selector
241 foreach ($subset as $name => $field) {
242 if (!$field['in_selector'])unset($subset[$name]);
245 $fields = array_merge($fields, $subset);
252 * Get all the fields that belong to the group with the name title,
253 * and format for use with buildProfile. This is the SQL analog of
256 * @param mix $id the id of the UF group or ids of ufgroup
257 * @param bool|int $register are we interested in registration fields
258 * @param int $action what action are we doing
259 * @param int $visibility visibility of fields we are interested in
261 * @param bool $showAll
262 * @param string $restrict should we restrict based on a specified profile type
264 * @param bool $skipPermission
266 * @param int $permissionType
267 * @param string $orderBy
268 * @param null $orderProfiles
270 * @internal param bool $showall
271 * @return array the fields that belong to this ufgroup(s)
275 static function getFields(
283 $skipPermission = FALSE,
285 $permissionType = CRM_Core_Permission
::CREATE
,
286 $orderBy = 'field_name',
287 $orderProfiles = NULL
289 if (!is_array($id)) {
290 $id = CRM_Utils_Type
::escape($id, 'Positive');
291 $profileIds = array($id);
297 $gids = implode(',', $profileIds);
300 $query = "SELECT g.* from civicrm_uf_group g
301 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
302 WHERE g.id IN ( {$gids} )
303 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
305 $params = array(1 => array($restrict, 'String'));
308 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
312 $query .= " AND g.is_active = 1";
315 // add permissioning for profiles only if not registration
316 if (!$skipPermission) {
317 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
318 $query .= " AND $permissionClause ";
321 if ($orderProfiles AND count($profileIds) > 1) {
322 $query .= " ORDER BY FIELD( g.id, {$gids} )";
324 $group = CRM_Core_DAO
::executeQuery($query, $params);
328 while ($group->fetch()) {
330 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
331 $field = CRM_Core_DAO
::executeQuery($query);
333 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
334 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
335 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
336 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
338 while ($field->fetch()) {
339 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
340 if ($formattedField !== NULL) {
341 $fields[$name] = $formattedField;
347 if (empty($fields) && !$validGroup) {
348 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.',
349 array(1 => implode(',', $profileIds))
353 self
::reformatProfileFields($fields);
360 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
363 * @param array $groupArr (mimic CRM_UF_DAO_UFGroup)
364 * @param array $fieldArrs list of fields (each mimics CRM_UF_DAO_UFField)
365 * @param bool $visibility visibility of fields we are interested in
366 * @param bool $searchable
367 * @param bool $showAll
369 * @param int $permissionType
371 * @internal param bool $showall
375 public static function formatUFFields(
382 $permissionType = CRM_Core_Permission
::CREATE
384 // $group = new CRM_Core_DAO_UFGroup();
385 // $group->copyValues($groupArr); // no... converts string('') to string('null')
386 $group = (object) $groupArr;
388 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
389 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
390 // they did -- the obvious fix would produce mutual recursion.
391 $ufGroupType = self
::_calculateGroupType($fieldArrs);
392 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',',$ufGroupType));
393 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',',$ufGroupType));
394 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
395 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
397 $formattedFields = array();
398 foreach ($fieldArrs as $fieldArr) {
399 $field = (object) $fieldArr;
400 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
404 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
405 if ($formattedField !== NULL) {
406 $formattedFields[$name] = $formattedField;
409 return $formattedFields;
413 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
415 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
416 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
417 * @param array $addressCustomFields
418 * @param array $importableFields
419 * @param array $customFields
420 * @param int $permissionType eg CRM_Core_Permission::CREATE
423 protected static function formatUFField(
427 $addressCustomFields,
429 $permissionType = CRM_Core_Permission
::CREATE
431 $name = $field->field_name
;
432 $title = $field->label
;
434 $addressCustom = FALSE;
435 if (in_array($permissionType, array(
436 CRM_Core_Permission
::CREATE
,
437 CRM_Core_Permission
::EDIT
,
439 in_array($field->field_name
, array_keys($addressCustomFields))
441 $addressCustom = TRUE;
442 $name = "address_{$name}";
444 if ($field->field_name
== 'url') {
445 $name .= "-{$field->website_type_id}";
447 elseif (!empty($field->location_type_id
)) {
448 $name .= "-{$field->location_type_id}";
451 $locationFields = self
::getLocationFields();
452 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
457 if (isset($field->phone_type_id
)) {
458 $name .= "-{$field->phone_type_id}";
461 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
462 // I guess to make field self sufficient with all the required data and avoid additional calls
463 $formattedField = array(
465 'groupTitle' => $group->title
,
466 'groupName' => $group->name
,
467 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
468 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
470 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
471 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
472 'is_required' => $field->is_required
,
473 'is_view' => $field->is_view
,
474 'help_pre' => $field->help_pre
,
475 'help_post' => $field->help_post
,
476 'visibility' => $field->visibility
,
477 'in_selector' => $field->in_selector
,
478 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
479 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
480 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
481 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
482 'group_id' => $group->id
,
483 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
484 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
485 'field_type' => $field->field_type
,
486 'field_id' => $field->id
,
487 'pseudoconstant' => CRM_Utils_Array
::value(
489 CRM_Utils_Array
::value($field->field_name
, $importableFields)
491 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
492 'dbName' => CRM_Utils_Array
::value(
494 CRM_Utils_Array
::value($field->field_name
, $importableFields)
499 //adding custom field property
500 if (substr($field->field_name
, 0, 6) == 'custom' ||
501 substr($field->field_name
, 0, 14) === 'address_custom'
503 // if field is not present in customFields, that means the user
504 // DOES NOT HAVE permission to access that field
505 if (array_key_exists($field->field_name
, $customFields)) {
506 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
508 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
509 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
510 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
512 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
513 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
514 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
517 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
518 return array($name, $formattedField);
521 $formattedField = NULL;
522 return array($name, $formattedField);
525 return array($name, $formattedField);
529 * Create a query to find all visible UFFields in a UFGroup
531 * This is the SQL-variant of checkUFFieldDisplayable().
533 * @param int $groupId
534 * @param bool $searchable
535 * @param bool $showAll
536 * @param int $visibility
537 * @param string $orderBy comma-delimited list of SQL columns
540 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
541 $where = " WHERE uf_group_id = {$groupId}";
544 $where .= " AND is_searchable = 1";
548 $where .= " AND is_active = 1";
553 if ($visibility & self
::PUBLIC_VISIBILITY
) {
554 $clause[] = 'visibility = "Public Pages"';
556 if ($visibility & self
::ADMIN_VISIBILITY
) {
557 $clause[] = 'visibility = "User and User Admin Only"';
559 if ($visibility & self
::LISTINGS_VISIBILITY
) {
560 $clause[] = 'visibility = "Public Pages and Listings"';
562 if (!empty($clause)) {
563 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
567 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
569 $query .= ", " . $orderBy;
576 * Create a query to find all visible UFFields in a UFGroup
578 * This is the PHP in-memory variant of createUFFieldQuery().
580 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
581 * @param bool $searchable
582 * @param bool $showAll
583 * @param int $visibility
584 * @return bool TRUE if field is displayable
586 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
587 if ($searchable && $field->is_searchable
!= 1) {
591 if (!$showAll && $field->is_active
!= 1) {
596 $allowedVisibilities = array();
597 if ($visibility & self
::PUBLIC_VISIBILITY
) {
598 $allowedVisibilities[] = 'Public Pages';
600 if ($visibility & self
::ADMIN_VISIBILITY
) {
601 $allowedVisibilities[] = 'User and User Admin Only';
603 if ($visibility & self
::LISTINGS_VISIBILITY
) {
604 $allowedVisibilities[] = 'Public Pages and Listings';
606 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
607 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
617 * @param $profileType
618 * @param $contactActivityProfile
622 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
624 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
627 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
630 if ($profileType == 'Activity' ||
$contactActivityProfile) {
631 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
634 $componentFields = CRM_Core_Component
::getQueryFields();
637 $importableFields = array_merge($importableFields, $componentFields);
639 $importableFields['group']['title'] = ts('Group(s)');
640 $importableFields['group']['where'] = NULL;
641 $importableFields['tag']['title'] = ts('Tag(s)');
642 $importableFields['tag']['where'] = NULL;
643 return $importableFields;
646 public static function getLocationFields() {
647 static $locationFields = array(
649 'supplemental_address_1',
650 'supplemental_address_2',
653 'postal_code_suffix',
666 return $locationFields;
674 protected static function getCustomFields($ctype) {
675 static $customFieldCache = array();
676 if (!isset($customFieldCache[$ctype])) {
677 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
679 // hack to add custom data for components
680 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
681 foreach ($components as $value) {
682 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
684 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
685 $customFields = array_merge($customFields, $addressCustomFields);
686 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
688 return $customFieldCache[$ctype];
692 * check the data validity
694 * @param int $userID the user id that we are actually editing
695 * @param string $title the title of the group we are interested in
696 * @param bool $register
697 * @param int $action the action of the form
699 * @pram boolean $register is this the registrtion form
700 * @return boolean true if form is valid
704 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
706 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
707 ts('Dynamic Form Creator'),
710 $controller->set('id', $userID);
711 $controller->set('register', 1);
712 $controller->process();
713 return $controller->validate();
716 // make sure we have a valid group
717 $group = new CRM_Core_DAO_UFGroup();
719 $group->title
= $title;
721 if ($group->find(TRUE) && $userID) {
722 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
723 $controller->set('gid', $group->id
);
724 $controller->set('id', $userID);
725 $controller->set('register', 0);
726 $controller->process();
727 return $controller->validate();
734 * get the html for the form that represents this particular group
736 * @param int $userID the user id that we are actually editing
737 * @param string $title the title of the group we are interested in
738 * @param int $action the action of the form
739 * @param boolean $register is this the registration form
740 * @param boolean $reset should we reset the form?
741 * @param int $profileID do we have the profile ID?
743 * @param bool $doNotProcess
746 * @return string the html for the form on success, otherwise empty string
750 static function getEditHTML($userID,
756 $doNotProcess = FALSE,
761 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
762 ts('Dynamic Form Creator'),
765 if ($reset ||
$doNotProcess) {
766 // hack to make sure we do not process this form
767 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
770 unset($_POST['_qf_default']);
771 unset($_REQUEST['_qf_default']);
773 $controller->reset();
777 $controller->set('id', $userID);
778 $controller->set('register', 1);
779 $controller->set('skipPermission', 1);
780 $controller->set('ctype', $ctype);
781 $controller->process();
782 if ($doNotProcess ||
!empty($_POST)) {
783 $controller->validate();
785 $controller->setEmbedded(TRUE);
787 //CRM-5839 - though we want to process form, get the control back.
788 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
792 // we are done processing so restore the POST/REQUEST vars
793 if (($reset ||
$doNotProcess) && $oldQFDefault) {
794 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
797 $template = CRM_Core_Smarty
::singleton();
799 // Hide CRM error messages if they are displayed using drupal form_set_error.
800 if (!empty($_POST)) {
801 $template->assign('suppressForm', TRUE);
804 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
808 // make sure we have a valid group
809 $group = new CRM_Core_DAO_UFGroup();
811 $group->title
= $title;
813 if ($group->find(TRUE)) {
814 $profileID = $group->id
;
819 // make sure profileID and ctype match if ctype exists
821 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
822 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
823 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
826 if (($profileType != 'Contact') && ($profileType != $ctype)) {
831 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
832 ts('Dynamic Form Creator'),
836 $controller->reset();
838 $controller->set('gid', $profileID);
839 $controller->set('id', $userID);
840 $controller->set('register', 0);
841 $controller->set('skipPermission', 1);
843 $controller->set('ctype', $ctype);
845 $controller->process();
846 $controller->setEmbedded(TRUE);
848 //CRM-5846 - give the control back to drupal.
849 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
852 $template = CRM_Core_Smarty
::singleton();
854 // Hide CRM error messages if they are displayed using drupal form_set_error.
855 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
856 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
857 $template->assign('suppressForm', TRUE);
861 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
862 if (!$template->template_exists($templateFile)) {
863 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
865 return trim($template->fetch($templateFile));
868 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
870 // if post not empty then only proceed
871 if (!empty($_POST)) {
873 $config = CRM_Core_Config
::singleton();
874 $email = CRM_Utils_Array
::value('mail', $_POST);
876 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
877 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
886 * searches for a contact in the db with similar attributes
888 * @param array $params the list of values to be used in the where clause
889 * @param int $id the current contact id (hence excluded from matching)
890 * @param string $contactType
892 * @internal param bool $flatten should we flatten the input params
894 * @return contact_id if found, null otherwise
898 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
899 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
900 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
901 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
903 return implode(',', $ids);
911 * Given a contact id and a field set, return the values from the db
915 * @param array $fields the profile fields of interest
916 * @param array $values the values for the above fields
917 * @param boolean $searchable searchable or not
918 * @param array $componentWhere component condition
919 * @param boolean $absolute return urls in absolute form (useful when sending an email)
921 * @param null $additionalWhereClause
923 * @internal param int $id the contact id
928 public static function getValues($cid, &$fields, &$values,
929 $searchable = TRUE, $componentWhere = NULL,
930 $absolute = FALSE, $additionalWhereClause = NULL
932 if (empty($cid) && empty($componentWhere)) {
936 // get the contact details (hier)
937 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
938 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
940 // add conditions specified by components. eg partcipant_id etc
941 if (!empty($componentWhere)) {
942 $params = array_merge($params, $componentWhere);
945 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
946 $options = &$query->_options
;
948 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
949 FALSE, FALSE, FALSE, $additionalWhereClause);
950 if (!$details->fetch()) {
953 $query->convertToPseudoNames($details);
954 $config = CRM_Core_Config
::singleton();
956 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
957 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
958 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
960 $multipleFields = array('url');
961 $nullIndex = $nullValueIndex = ' ';
963 //start of code to set the default values
964 foreach ($fields as $name => $field) {
967 $name = 'contact_id';
970 // skip fields that should not be displayed separately
971 if (!empty($field['skipDisplay'])) {
975 $index = $field['title'];
976 //handle for the label not set for the field
977 if (empty($field['title'])) {
979 $nullIndex .= $nullIndex;
982 //handle the case to avoid re-write where the profile field labels are the same
983 if (array_key_exists($index, $values)) {
984 $index .= $nullValueIndex;
985 $nullValueIndex .= $nullValueIndex;
987 $params[$index] = $values[$index] = '';
988 $customFieldName = NULL;
990 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
991 // to handle gender / suffix / prefix
992 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
993 $params[$index] = $details->$name;
994 $values[$index] = $details->$name;
996 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
997 $dname = $name . '_display';
998 $values[$index] = $details->$dname;
999 $name = $name . '_id';
1000 $params[$index] = $details->$name;
1002 elseif (in_array($name, array(
1003 'state_province', 'country', 'county'))) {
1004 $values[$index] = $details->$name;
1005 $idx = $name . '_id';
1006 $params[$index] = $details->$idx;
1008 elseif ($name === 'preferred_communication_method') {
1009 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1011 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1013 foreach ($pref as $k) {
1015 $compref[] = $communicationFields[$k];
1018 $params[$index] = $details->$name;
1019 $values[$index] = implode(',', $compref);
1021 elseif ($name === 'preferred_language') {
1022 $params[$index] = $details->$name;
1023 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1025 elseif ($name == 'group') {
1026 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1027 $title = $ids = array();
1029 foreach ($groups as $g) {
1030 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1031 // VIEW permission on that group
1032 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1034 if ($g['visibility'] != 'User and User Admin Only' ||
1035 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1037 $title[] = $g['title'];
1038 if ($g['visibility'] == 'Public Pages') {
1039 $ids[] = $g['group_id'];
1043 $values[$index] = implode(', ', $title);
1044 $params[$index] = implode(',', $ids);
1046 elseif ($name == 'tag') {
1047 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1048 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1050 foreach ($entityTags as $tagId) {
1051 $title[] = $allTags[$tagId];
1053 $values[$index] = implode(', ', $title);
1054 $params[$index] = implode(',', $entityTags);
1056 elseif ($name == 'activity_status_id') {
1057 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1058 $values[$index] = $activityStatus[$details->$name];
1059 $params[$index] = $details->$name;
1061 elseif ($name == 'activity_date_time') {
1062 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1063 $params[$index] = $details->$name;
1065 elseif ($name == 'contact_sub_type') {
1066 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1067 if (!empty($contactSubTypeNames)) {
1068 $contactSubTypeLabels = array();
1069 // get all contact subtypes
1070 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1071 // build contact subtype labels array
1072 foreach( $contactSubTypeNames as $cstName ) {
1074 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1077 $values[$index] = implode(',', $contactSubTypeLabels);
1080 $params[$index] = $details->$name;
1083 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1084 if ($details->$name) {
1085 $values[$index] = '[ x ]';
1089 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1090 $htmlType = $field['html_type'];
1092 // field_type is only set when we are retrieving profile values
1093 // when sending email, we call the same function to get custom field
1094 // values etc, i.e. emulating a profile
1095 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1097 if ($htmlType == 'File') {
1100 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
1101 $entityId = $componentWhere[0][2];
1104 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1109 $params[$index] = $values[$index] = $fileURL['file_url'];
1113 if (isset($dao) && property_exists($dao, 'data_type') &&
1114 ($dao->data_type
== 'Int' ||
1115 $dao->data_type
== 'Boolean'
1118 $customVal = (int )($details->{$name});
1120 elseif (isset($dao) && property_exists($dao, 'data_type')
1121 && $dao->data_type
== 'Float'
1123 $customVal = (float )($details->{$name});
1125 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1128 $customVal = $details->{$name};
1132 if (CRM_Utils_System
::isNull($customVal)) {
1136 $params[$index] = $customVal;
1137 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1141 if ($field['data_type'] == 'ContactReference') {
1142 $params[$index] = $values[$index];
1144 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1145 $cfID, 'is_search_range'
1147 $customFieldName = "{$name}_from";
1151 elseif ($name == 'image_URL') {
1152 list($width, $height) = getimagesize($details->$name);
1153 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1155 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1156 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1158 elseif (in_array($name, array(
1159 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1160 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1161 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1165 if ($index == 'Campaign') {
1166 $dao = 'CRM_Campaign_DAO_Campaign';
1168 elseif ($index == 'Contribution Page') {
1169 $dao = 'CRM_Contribute_DAO_ContributionPage';
1172 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1175 $value = $details->$name;
1177 $values[$index] = $value;
1182 elseif (strpos($name, '-') !== FALSE) {
1183 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1185 if (!in_array($fieldName, $multipleFields)) {
1186 if ($id == 'Primary') {
1188 // not sure why we'd every use Primary location type id
1189 // we need to fix the source if we are using it
1190 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1191 $locationTypeName = 1;
1194 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1197 if (!$locationTypeName) {
1201 $detailName = "{$locationTypeName}-{$fieldName}";
1202 $detailName = str_replace(' ', '_', $detailName);
1204 if (in_array($fieldName, array(
1205 'phone', 'im', 'email', 'openid'))) {
1207 $detailName .= "-{$type}";
1211 if (in_array($fieldName, array(
1212 'state_province', 'country', 'county'))) {
1213 $values[$index] = $details->$detailName;
1214 $idx = $detailName . '_id';
1215 $params[$index] = $details->$idx;
1217 elseif ($fieldName == 'im') {
1218 $providerId = $detailName . '-provider_id';
1219 if (isset($imProviders[$details->$providerId])) {
1220 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1223 $values[$index] = $details->$detailName;
1225 $params[$index] = $details->$detailName;
1227 elseif ($fieldName == 'phone') {
1228 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1229 if (isset($details->$phoneExtField)) {
1230 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1233 $values[$index] = $details->$detailName;
1235 $params[$index] = $details->$detailName;
1238 $values[$index] = $params[$index] = $details->$detailName;
1242 $detailName = "website-{$id}-{$fieldName}";
1243 $url = CRM_Utils_System
::fixURL($details->$detailName);
1244 if ($details->$detailName) {
1245 $websiteTypeId = "website-{$id}-website_type_id";
1246 $websiteType = $websiteTypes[$details->$websiteTypeId];
1247 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1250 $values[$index] = '';
1255 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1256 CRM_Core_Permission
::check('profile listings and forms')
1259 if (CRM_Utils_System
::isNull($params[$index])) {
1260 $params[$index] = $values[$index];
1262 if (!isset($params[$index])) {
1265 if (!$customFieldName) {
1266 $fieldName = $field['name'];
1269 $fieldName = $customFieldName;
1273 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1274 $htmlType = $field['html_type'];
1275 if ($htmlType == 'Link') {
1276 $url = $params[$index];
1278 elseif (in_array($htmlType, array(
1279 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1280 'Multi-Select State/Province', 'Multi-Select Country',
1282 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1283 $selectedOptions = explode($valSeperator, $params[$index]);
1285 foreach ($selectedOptions as $key => $multiOption) {
1287 $url[] = CRM_Utils_System
::url('civicrm/profile',
1288 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1289 urlencode($fieldName) .
1291 urlencode($multiOption)
1297 $url = CRM_Utils_System
::url('civicrm/profile',
1298 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1299 urlencode($fieldName) .
1301 urlencode($params[$index])
1306 $url = CRM_Utils_System
::url('civicrm/profile',
1307 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1308 urlencode($fieldName) .
1310 urlencode($params[$index])
1315 !empty($values[$index]) &&
1319 if (is_array($url) && !empty($url)) {
1321 $eachMultiValue = explode(', ', $values[$index]);
1322 foreach ($eachMultiValue as $key => $valueLabel) {
1323 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1325 $values[$index] = implode(', ', $links);
1328 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1336 * Check if profile Group used by any module.
1338 * @param int $id profile Id
1346 public static function usedByModule($id) {
1347 //check whether this group is used by any module(check uf join records)
1349 FROM civicrm_uf_join
1350 WHERE civicrm_uf_join.uf_group_id=$id";
1352 $dao = new CRM_Core_DAO();
1354 if ($dao->fetch()) {
1363 * Delete the profile Group.
1365 * @param int $id profile Id
1373 public static function del($id) {
1374 //check whether this group contains any profile fields
1375 $profileField = new CRM_Core_DAO_UFField();
1376 $profileField->uf_group_id
= $id;
1377 $profileField->find();
1378 while ($profileField->fetch()) {
1379 CRM_Core_BAO_UFField
::del($profileField->id
);
1382 //delete records from uf join table
1383 $ufJoin = new CRM_Core_DAO_UFJoin();
1384 $ufJoin->uf_group_id
= $id;
1387 //delete profile group
1388 $group = new CRM_Core_DAO_UFGroup();
1395 * function to add the UF Group
1397 * @param array $params reference array contains the values submitted by the form
1398 * @param array $ids reference array contains the id
1405 static function add(&$params, $ids = array()) {
1406 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1407 foreach ($fields as $field) {
1408 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1411 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1412 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1414 $ufGroup = new CRM_Core_DAO_UFGroup();
1415 $ufGroup->copyValues($params);
1417 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1419 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1421 $ufGroup->id
= $ufGroupID;
1426 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1434 * Function to make uf join entries for an uf group
1436 * @param array $params (reference) an assoc array of name/value pairs
1437 * @param int $ufGroupId ufgroup id
1443 static function createUFJoin(&$params, $ufGroupId) {
1444 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1446 // get ufjoin records for uf group
1447 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1449 // get the list of all ufgroup types
1450 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1452 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1453 if (!is_array($groupTypes)) {
1454 $groupTypes = array();
1457 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1458 if (!is_array($ufGroupRecord)) {
1459 $ufGroupRecord = array();
1462 // check which values has to be inserted/deleted for contact
1463 $menuRebuild = FALSE;
1464 foreach ($allUFGroupType as $key => $value) {
1465 $joinParams = array();
1466 $joinParams['uf_group_id'] = $ufGroupId;
1467 $joinParams['module'] = $key;
1468 if ($key == 'User Account') {
1469 $menuRebuild = TRUE;
1471 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1472 // insert a new record
1473 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1475 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1476 // delete a record for existing ufgroup
1477 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1483 UPDATE civicrm_uf_join
1485 WHERE uf_group_id = %2
1486 AND ( entity_id IS NULL OR entity_id <= 0 )
1488 $p = array(1 => array($params['weight'], 'Integer'),
1489 2 => array($ufGroupId, 'Integer'),
1491 CRM_Core_DAO
::executeQuery($query, $p);
1493 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1495 $config = CRM_Core_Config
::singleton();
1497 $config->userSystem
->is_drupal
1504 * Function to get the UF Join records for an ufgroup id
1506 * @params int $ufGroupId uf group id
1507 * @params int $displayName if set return display name in array
1508 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1510 * @param null $ufGroupId
1511 * @param null $displayName
1512 * @param null $status
1514 * @return array $ufGroupJoinRecords
1519 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1521 $UFGroupType = array();
1522 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1526 $dao = new CRM_Core_DAO_UFJoin();
1529 $dao->uf_group_id
= $ufGroupId;
1535 while ($dao->fetch()) {
1536 if (!$displayName) {
1537 $ufJoin[$dao->id
] = $dao->module
;
1540 if (isset($UFGroupType[$dao->module
])) {
1541 // skip the default modules
1543 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1545 // added for CRM-1475
1547 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1548 $ufJoin[$dao->id
] = $dao->module
;
1556 * Function takes an associative array and creates a ufjoin record for ufgroup
1558 * @param array $params (reference) an assoc array of name/value pairs
1560 * @return object CRM_Core_BAO_UFJoin object
1564 static function addUFJoin(&$params) {
1565 $ufJoin = new CRM_Core_DAO_UFJoin();
1566 $ufJoin->copyValues($params);
1572 * Function to delete the uf join record for an uf group
1574 * @param array $params (reference) an assoc array of name/value pairs
1580 static function delUFJoin(&$params) {
1581 $ufJoin = new CRM_Core_DAO_UFJoin();
1582 $ufJoin->copyValues($params);
1587 * Function to get the weight for ufjoin record
1589 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1591 * @return int weight of the UFGroup
1595 static function getWeight($ufGroupId = NULL) {
1596 //calculate the weight
1599 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1600 FROM civicrm_uf_join
1601 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1604 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1605 FROM civicrm_uf_join
1606 WHERE civicrm_uf_join.uf_group_id = %1
1607 AND ( entity_id IS NULL OR entity_id <= 0 )";
1608 $p[1] = array($ufGroupId, 'Integer');
1611 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1613 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1617 * Function to get the uf group for a module
1619 * @param string $moduleName module name
1620 * @param int $count no to increment the weight
1621 * @param bool $skipPermission
1622 * @param int $op - which operation (view, edit, create, etc) to check permission for
1623 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1625 * @internal param bool $skipPermision - whether to add permission clause
1626 * @return array $ufGroups array of ufgroups for a module
1630 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1631 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1633 if (!CRM_Core_Config
::isUpgradeMode()) {
1634 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1635 $selectFields[] = 'description';
1638 if (!empty($returnFields)) {
1639 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1642 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1643 FROM civicrm_uf_group
1644 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1647 $queryString .= ' AND civicrm_uf_group.is_active = 1
1648 WHERE civicrm_uf_join.module = %2';
1649 $p[2] = array($moduleName, 'String');
1653 // add permissioning for profiles only if not registration
1654 if (!$skipPermission) {
1655 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1656 if (strpos($queryString, 'WHERE') !== FALSE) {
1657 $queryString .= " AND $permissionClause ";
1660 $queryString .= " $permissionClause ";
1664 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1665 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1667 $ufGroups = array();
1668 while ($dao->fetch()) {
1669 //skip mix profiles in user Registration / User Account
1670 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1671 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1675 foreach ($selectFields as $key => $field) {
1676 if($field == 'id') {
1679 elseif ($field == 'name') {
1680 $ufGroups[$dao->id
][$field] = $dao->title
;
1683 $ufGroups[$dao->id
][$field] = $dao->$field;
1687 // Allow other modules to alter/override the UFGroups.
1688 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1694 * Function to filter ufgroups based on logged in user contact type
1696 * @params int $ufGroupId uf group id (profile id)
1699 * @param null $contactID
1701 * @return boolean true or false
1705 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1707 $session = CRM_Core_Session
::singleton();
1708 $contactID = $session->get('userID');
1712 //get the contact type
1713 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1715 //match if exixting contact type is same as profile contact type
1716 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1718 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1719 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1722 //allow special mix profiles for Contribution and Participant
1723 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1725 if (in_array($profileType, $specialProfiles)) {
1729 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1738 * Function to build profile form
1740 * @params object $form form object
1741 * @params array $field array field properties
1742 * @params int $mode profile mode
1743 * @params int $contactID contact id
1744 * @params string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
1749 * @param null $contactId
1750 * @param bool $online
1751 * @param null $usedFor
1752 * @param null $rowNumber
1753 * @param string $prefix
1759 static function buildProfile(
1769 $defaultValues = array();
1770 $fieldName = $field['name'];
1771 $title = $field['title'];
1772 $attributes = $field['attributes'];
1773 $rule = $field['rule'];
1774 $view = $field['is_view'];
1775 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1776 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1777 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1779 // do not display view fields in drupal registration form
1781 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1785 if ($usedFor == 'onbehalf') {
1786 $name = "onbehalf[$fieldName]";
1788 elseif ($usedFor == 'honor') {
1789 $name = "honor[$fieldName]";
1791 elseif ($contactId && !$online) {
1792 $name = "field[$contactId][$fieldName]";
1794 elseif ($rowNumber) {
1795 $name = "field[$rowNumber][$fieldName]";
1797 elseif (!empty($prefix)) {
1798 $name = $prefix ."[$fieldName]";
1804 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1805 $deleteExtra = ts('Are you sure you want to delete contact image.');
1807 CRM_Core_Action
::DELETE
=>
1809 'name' => ts('Delete Contact Image'),
1810 'url' => 'civicrm/contact/image',
1811 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1813 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1816 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1817 CRM_Core_Action
::DELETE
,
1818 array('id' => $form->get('id'),
1819 'gid' => $form->get('gid'),
1823 'contact.profileimage.delete',
1827 $form->assign('deleteURL', $deleteURL);
1829 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1830 'address_options', TRUE, NULL, TRUE
1833 if (substr($fieldName, 0, 14) === 'state_province') {
1834 $form->add('select', $name, $title,
1836 '' => ts('- select -')) + CRM_Core_PseudoConstant
::stateProvince(), $required
1838 $config = CRM_Core_Config
::singleton();
1839 if (!in_array($mode, array(
1840 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1841 $config->defaultContactStateProvince
1843 $defaultValues[$name] = $config->defaultContactStateProvince
;
1844 $form->setDefaults($defaultValues);
1847 elseif (substr($fieldName, 0, 7) === 'country') {
1848 $form->add('select', $name, $title,
1850 '' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required
1852 $config = CRM_Core_Config
::singleton();
1853 if (!in_array($mode, array(
1854 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1855 $config->defaultContactCountry
1857 $defaultValues[$name] = $config->defaultContactCountry
;
1858 $form->setDefaults($defaultValues);
1861 elseif (substr($fieldName, 0, 6) === 'county') {
1862 if ($addressOptions['county']) {
1863 $form->add('select', $name, $title,
1865 '' => ts('(choose state first)')), $required
1869 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1870 $form->add('file', $name, $title, $attributes, $required);
1871 $form->addUploadElement($name);
1873 elseif (substr($fieldName, 0, 2) === 'im') {
1874 $form->add('text', $name, $title, $attributes, $required);
1877 if (substr($name, -1) == ']') {
1878 $providerName = substr($name, 0, -1) . '-provider_id]';
1880 $form->add('select', $providerName, NULL,
1882 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1886 $form->add('select', $name . '-provider_id', $title,
1888 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1892 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1893 $form->freeze($name . '-provider_id');
1897 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1898 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1900 elseif (in_array($fieldName, array(
1901 'membership_start_date', 'membership_end_date', 'join_date'))) {
1902 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1904 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_type') {
1905 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1906 $sel = &$form->addElement('hierselect', $name, $title);
1907 $select = array('' => ts('- select -') );
1908 if(count($orgInfo) == 1 && $field['is_required']) {
1909 // we only have one org - so we should default to it. Not sure about defaulting to first type
1910 // as it could be missed - so adding a select
1911 // however, possibly that is more similar to the membership form
1912 if(count($types[1]) > 1) {
1913 $types[1] = $select +
$types[1];
1917 $orgInfo = $select +
$orgInfo;
1919 $sel->setOptions(array($orgInfo, $types));
1921 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_status') {
1922 $form->add('select', $name, $title,
1924 '' => ts('- select -')) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1927 elseif ($fieldName === 'gender_id') {
1928 $genderOptions = array();
1929 $gender = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'gender_id');
1930 foreach ($gender as $key => $var) {
1931 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1933 $group = $form->addGroup($genderOptions, $name, $title);
1935 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1938 $group->setAttribute('allowClear', TRUE);
1941 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1942 $form->add('select', $name, $title,
1944 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Contact_BAO_Contact', $fieldName), $required
1947 elseif ($fieldName === 'contact_sub_type') {
1948 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1949 if ($usedFor == 'onbehalf') {
1950 $profileType = 'Organization';
1952 elseif ($usedFor == 'honor') {
1953 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1956 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1957 if ($profileType == 'Contact') {
1958 $profileType = 'Individual';
1962 $setSubtype = FALSE;
1963 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1964 $setSubtype = $profileType;
1965 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1968 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
1971 $subtypeList = array();
1972 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1975 $subtypeList = $subtypes;
1978 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1979 $sel->setMultiple(TRUE);
1981 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1982 //add email greeting, postal greeting, addressee, CRM-4575
1983 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1984 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
1986 if (empty($profileType) ||
in_array($profileType, array(
1987 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1988 $profileType = 'Individual';
1990 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1991 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1994 'contact_type' => $profileType,
1995 'greeting_type' => $fieldName,
1997 $form->add('select', $name, $title,
1999 '' => ts('- select -')) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2001 // add custom greeting element
2002 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2006 elseif ($fieldName === 'preferred_communication_method') {
2007 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2008 foreach ($communicationFields as $key => $var) {
2012 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2014 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2016 elseif ($fieldName === 'preferred_mail_format') {
2017 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2019 elseif ($fieldName === 'preferred_language') {
2020 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2022 elseif ($fieldName == 'external_identifier') {
2023 $form->add('text', $name, $title, $attributes, $required);
2024 $contID = $contactId;
2026 $contID = $form->get('id');
2028 $form->addRule($name,
2029 ts('External ID already exists in Database.'),
2031 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2034 elseif ($fieldName === 'group') {
2035 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2036 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2041 elseif ($fieldName === 'tag') {
2042 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2043 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2048 elseif (substr($fieldName, 0, 4) === 'url-') {
2049 $form->add('text', $name, $title,
2050 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2052 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2053 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2058 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2060 // Note should be rendered as textarea
2061 elseif (substr($fieldName, -4) == 'note') {
2062 $form->add('textarea', $name, $title, $attributes, $required);
2064 elseif (substr($fieldName, 0, 6) === 'custom') {
2065 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2066 if ($customFieldID) {
2067 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2070 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2071 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2072 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2073 if ($customFieldID) {
2074 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2077 elseif (in_array($fieldName, array(
2078 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2079 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2081 elseif ($fieldName == 'send_receipt') {
2082 $form->addElement('checkbox', $name, $title);
2084 elseif ($fieldName == 'soft_credit') {
2085 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2086 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2088 elseif ($fieldName == 'product_name') {
2089 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2090 $sel = &$form->addElement('hierselect', $name, $title);
2092 '0' => ts('- select -')) +
$products;
2093 $sel->setOptions(array($products, $options));
2095 elseif ($fieldName == 'payment_instrument') {
2096 $form->add('select', $name, $title,
2097 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant
::paymentInstrument( ), $required );
2099 else if ($fieldName == 'financial_type' ) {
2100 $form->add('select', $name, $title,
2102 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(), $required
2105 elseif ($fieldName == 'contribution_status_id') {
2106 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2107 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2113 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2116 $form->add('select', $name, $title,
2118 '' => ts('- select -')) +
$contributionStatuses, $required
2121 elseif ($fieldName == 'soft_credit_type') {
2122 $form->add('select', $name, $title,
2124 '' => ts('- select -')) + CRM_Core_OptionGroup
::values("soft_credit_type")
2126 $form->addElement('hidden', 'sct_default_id',
2127 CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type"),
2128 array('id' => 'sct_default_id')
2131 elseif ($fieldName == 'currency') {
2132 $form->addCurrency($name, $title, $required);
2134 elseif ($fieldName == 'contribution_page_id') {
2135 $form->add('select', $name, $title,
2137 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2140 elseif ($fieldName == 'participant_register_date') {
2141 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2143 elseif ($fieldName == 'activity_status_id') {
2144 $form->add('select', $name, $title,
2146 '' => ts('- select -')) + CRM_Core_PseudoConstant
::activityStatus(), $required
2149 elseif ($fieldName == 'activity_engagement_level') {
2150 $form->add('select', $name, $title,
2152 '' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2155 elseif ($fieldName == 'activity_date_time') {
2156 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2158 elseif ($fieldName == 'participant_status') {
2160 if ($online == TRUE) {
2161 $cond = 'visibility_id = 1';
2163 $form->add('select', $name, $title,
2165 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2168 elseif ($fieldName == 'participant_role') {
2169 if (!empty($field['is_multiple'])) {
2170 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2173 $form->add('select', $name, $title,
2175 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantRole(), $required
2179 elseif ($fieldName == 'world_region') {
2180 $form->add('select', $name, $title,
2182 '' => ts('- select -')) + CRM_Core_PseudoConstant
::worldRegion(), $required
2185 elseif ($fieldName == 'signature_html') {
2186 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2188 elseif ($fieldName == 'signature_text') {
2189 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2191 elseif (substr($fieldName, -11) == 'campaign_id') {
2192 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2193 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2194 $form->_componentCampaigns
2196 $form->add('select', $name, $title,
2198 '' => ts('- select -')) +
$campaigns, $required, 'class="big"'
2202 elseif ($fieldName == 'activity_details') {
2203 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2205 elseif ($fieldName == 'activity_duration') {
2206 $form->add('text', $name, $title, $attributes, $required);
2207 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2210 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2211 $form->add('advcheckbox', $name, $title, $attributes, $required);
2214 $form->add('text', $name, $title, $attributes, $required);
2218 static $hiddenSubtype = FALSE;
2219 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2220 // In registration mode params are submitted via POST and we don't have any clue
2221 // about profile-id or the profile-type (which could be a subtype)
2222 // To generalize the behavior and simplify the process,
2223 // lets always add the hidden
2224 //subtype value if there is any, and we won't have to
2225 // compute it while processing.
2227 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2230 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2232 $hiddenSubtype = TRUE;
2235 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2236 $form->freeze($name);
2240 if (in_array($fieldName, array(
2241 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2242 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2244 $stateCountryMap = array();
2245 if (!empty($form->_stateCountryMap
['state_province']) && !empty($form->_stateCountryMap
['country'])) {
2246 foreach ($form->_stateCountryMap
['state_province'] as $key => $value) {
2247 $stateCountryMap[$key]['state_province'] = $value;
2248 $stateCountryMap[$key]['country'] = $form->_stateCountryMap
['country'][$key];
2250 CRM_Core_BAO_Address
::addStateCountryMap($stateCountryMap);
2253 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2254 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2260 * Function to set profile defaults
2262 * @params int $contactId contact id
2263 * @params array $fields associative array of fields
2264 * @params array $defaults defaults array
2265 * @params boolean $singleProfile true for single profile else false(batch update)
2266 * @params int $componentId id for specific components like contribute, event etc
2271 * @param bool $singleProfile
2272 * @param null $componentId
2273 * @param null $component
2279 static function setProfileDefaults($contactId, &$fields, &$defaults,
2280 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2282 if (!$componentId) {
2283 //get the contact details
2284 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2285 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2286 $multipleFields = array('website' => 'url');
2288 //start of code to set the default values
2289 foreach ($fields as $name => $field) {
2290 // skip pseudo fields
2291 if (substr($name, 0, 9) == 'phone_ext') {
2295 //set the field name depending upon the profile mode(single/batch)
2296 if ($singleProfile) {
2300 $fldName = "field[$contactId][$name]";
2303 if ($name == 'group') {
2304 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2306 if ($name == 'tag') {
2307 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2310 if (!empty($details[$name]) ||
isset($details[$name])) {
2311 //to handle custom data (checkbox) to be written
2312 // to handle birth/deceased date, greeting_type and few other fields
2313 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2314 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2316 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2317 $defaults[$fldName] = $details[$name . '_id'];
2318 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2320 elseif ($name == 'preferred_communication_method') {
2321 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2322 foreach ($v as $item) {
2324 $defaults[$fldName . "[$item]"] = 1;
2328 elseif ($name == 'world_region') {
2329 $defaults[$fldName] = $details['worldregion_id'];
2331 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2332 //fix for custom fields
2333 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2335 // hack to add custom data for components
2336 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2337 foreach ($components as $value) {
2338 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2339 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2343 switch ($customFields[$customFieldId]['html_type']) {
2344 case 'Multi-Select State/Province':
2345 case 'Multi-Select Country':
2346 case 'AdvMulti-Select':
2347 case 'Multi-Select':
2348 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2349 foreach ($v as $item) {
2351 $defaults[$fldName][$item] = $item;
2357 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2358 foreach ($v as $item) {
2360 $defaults[$fldName][$item] = 1;
2361 // seems like we need this for QF style checkboxes in profile where its multiindexed
2363 $defaults["{$fldName}[{$item}]"] = 1;
2369 // CRM-6681, set defult values according to date and time format (if any).
2371 if (!empty($customFields[$customFieldId]['date_format'])) {
2372 $dateFormat = $customFields[$customFieldId]['date_format'];
2375 if (empty($customFields[$customFieldId]['time_format'])) {
2376 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2381 $timeElement = $fldName . '_time';
2382 if (substr($fldName, -1) == ']') {
2383 $timeElement = substr($fldName, 0, -1) . '_time]';
2385 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2386 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2391 $defaults[$fldName] = $details[$name];
2396 $defaults[$fldName] = $details[$name];
2400 $blocks = array('email', 'phone', 'im', 'openid');
2401 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2402 if (!in_array($fieldName, $multipleFields)) {
2403 if (is_array($details)) {
2404 foreach ($details as $key => $value) {
2405 // when we fixed CRM-5319 - get primary loc
2406 // type as per loc field and removed below code.
2407 $primaryLocationType = FALSE;
2408 if ($locTypeId == 'Primary') {
2409 if (is_array($value) && array_key_exists($fieldName, $value)){
2410 $primaryLocationType = TRUE;
2411 if (in_array($fieldName, $blocks)){
2412 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2415 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2420 // fixed for CRM-665
2421 if (is_numeric($locTypeId)) {
2422 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2423 if (!empty($value[$fieldName])) {
2424 //to handle stateprovince and country
2425 if ($fieldName == 'state_province') {
2426 $defaults[$fldName] = $value['state_province_id'];
2428 elseif ($fieldName == 'county') {
2429 $defaults[$fldName] = $value['county_id'];
2431 elseif ($fieldName == 'country') {
2432 if (!isset($value['country_id']) ||
!$value['country_id']) {
2433 $config = CRM_Core_Config
::singleton();
2434 if ($config->defaultContactCountry
) {
2435 $defaults[$fldName] = $config->defaultContactCountry
;
2439 $defaults[$fldName] = $value['country_id'];
2442 elseif ($fieldName == 'phone') {
2444 if (isset($value['phone'][$phoneTypeId])) {
2445 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2447 if (isset($value['phone_ext'][$phoneTypeId])) {
2448 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2452 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2454 if (!is_array($phoneDefault)) {
2455 $defaults[$fldName] = $phoneDefault;
2459 elseif ($fieldName == 'email') {
2460 //adding the first email (currently we don't support multiple emails of same location type)
2461 $defaults[$fldName] = $value['email'];
2463 elseif ($fieldName == 'im') {
2464 //adding the first im (currently we don't support multiple ims of same location type)
2465 $defaults[$fldName] = $value['im'];
2466 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2469 $defaults[$fldName] = $value[$fieldName];
2472 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2473 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2475 $defaults[$fldName] = $value[substr($fieldName, 8)];
2483 if (is_array($details)) {
2484 if ($fieldName === 'url'
2485 && !empty($details['website'])
2486 && !empty($details['website'][$locTypeId])) {
2487 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2495 //Handling Contribution Part of the batch profile
2496 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2497 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2500 //Handling Event Participation Part of the batch profile
2501 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2502 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2505 //Handling membership Part of the batch profile
2506 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2507 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2510 //Handling Activity Part of the batch profile
2511 if ($component == 'Activity') {
2512 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2517 * Function to get profiles by type eg: pure Individual etc
2519 * @param array $types associative array of types eg: types('Individual')
2520 * @param boolean $onlyPure true if only pure profiles are required
2522 * @return array $profiles associative array of profiles
2526 static function getProfiles($types, $onlyPure = FALSE) {
2527 $profiles = array();
2528 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2530 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2532 // Exclude Batch Data Entry profiles - CRM-10901
2533 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2535 foreach ($ufGroups as $id => $title) {
2536 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2537 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2538 $profiles[$id] = $title;
2545 * Function to check whether a profile is valid combination of
2546 * required and/or optional profile types
2548 * @param array $required array of types those are required
2549 * @param array $optional array of types those are optional
2551 * @return array $profiles associative array of profiles
2555 static function getValidProfiles($required, $optional = NULL) {
2556 if (!is_array($required) ||
empty($required)) {
2560 $profiles = array();
2561 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2563 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2565 foreach ($ufGroups as $id => $title) {
2566 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2568 $profiles[$id] = $title;
2576 * Function to check whether a profile is valid combination of
2577 * required profile fields
2579 * @param array $ufId integer id of the profile
2580 * @param array $required array of fields those are required in the profile
2582 * @return array $profiles associative array of profiles
2586 static function checkValidProfile($ufId, $required = NULL) {
2587 $validProfile = FALSE;
2589 return $validProfile;
2592 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2593 return $validProfile;
2596 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2597 NULL, FALSE, NULL, FALSE, NULL,
2598 CRM_Core_Permission
::CREATE
, NULL
2601 $validProfile = array();
2602 if (!empty($profileFields)) {
2603 $fields = array_keys($profileFields);
2604 foreach ($fields as $val) {
2605 foreach ($required as $key => $field) {
2606 if (strpos($val, $field) === 0) {
2607 unset($required[$key]);
2612 $validProfile = (empty($required)) ?
TRUE : FALSE;
2615 return $validProfile;
2619 * Function to get default value for Register.
2624 * @return mixed $defaults@static
2627 static function setRegisterDefaults(&$fields, &$defaults) {
2628 $config = CRM_Core_Config
::singleton();
2629 foreach ($fields as $name => $field) {
2630 if (substr($name, 0, 8) == 'country-') {
2631 if (!empty($config->defaultContactCountry
)) {
2632 $defaults[$name] = $config->defaultContactCountry
;
2635 elseif (substr($name, 0, 15) == 'state_province-') {
2636 if (!empty($config->defaultContactStateProvince
)) {
2637 $defaults[$name] = $config->defaultContactStateProvince
;
2645 * This function is to make a copy of a profile, including
2646 * all the fields in the profile
2648 * @param int $id the profile id to copy
2653 static function copy($id) {
2654 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2655 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2661 if ($pos = strrpos($copy->name
, "_{$id}")) {
2662 $copy->name
= substr_replace($copy->name
, '', $pos);
2664 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2667 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2668 array('uf_group_id' => $id),
2669 array('uf_group_id' => $copy->id
),
2674 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2675 array('uf_group_id' => $id),
2676 array('uf_group_id' => $copy->id
)
2679 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2683 UPDATE civicrm_uf_join
2685 WHERE uf_group_id = %2
2686 AND ( entity_id IS NULL OR entity_id <= 0 )
2688 $p = array(1 => array($maxWeight +
1, 'Integer'),
2689 2 => array($copy->id
, 'Integer'),
2691 CRM_Core_DAO
::executeQuery($query, $p);
2692 if ($copy->is_reserved
) {
2693 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2694 $params = array(1 => array($copy->id
, 'Integer'));
2695 CRM_Core_DAO
::executeQuery($query, $params);
2697 CRM_Utils_Hook
::copy('UFGroup', $copy);
2703 * Process that send notification e-mails
2705 * @params int $contactId contact id
2706 * @params array $values associative array of name/value pair
2715 static function commonSendMail($contactID, &$values) {
2716 if (!$contactID ||
!$values) {
2720 $template = CRM_Core_Smarty
::singleton();
2722 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2727 self
::profileDisplay($values['id'], $values['values'], $template);
2728 $emailList = explode(',', $values['email']);
2730 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2731 "reset=1&cid=$contactID",
2732 TRUE, NULL, FALSE, FALSE, TRUE
2735 //get the default domain email address.
2736 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2738 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2739 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2740 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)));
2743 foreach ($emailList as $emailTo) {
2744 // FIXME: take the below out of the foreach loop
2745 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2747 'groupName' => 'msg_tpl_workflow_uf',
2748 'valueName' => 'uf_notify',
2749 'contactId' => $contactID,
2750 'tplParams' => array(
2751 'displayName' => $displayName,
2752 'currentDate' => date('r'),
2753 'contactLink' => $contactLink,
2755 'from' => "$domainEmailName <$domainEmailAddress>",
2756 'toEmail' => $emailTo,
2763 * Given a contact id and a group id, returns the field values from the db
2764 * for this group and notify email only if group's notify field is
2765 * set and field values are not empty
2767 * @params $gid group id
2768 * @params $cid contact id
2769 * @params $params associative array
2774 * @param bool $skipCheck
2779 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2781 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2783 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2784 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2786 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2788 if (!empty($values) &&
2793 'values' => $values,
2804 * Function to assign uf fields to template
2806 * @params int $gid group id
2807 * @params array $values associative array of fields
2816 function profileDisplay($gid, $values, $template) {
2817 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2818 $template->assign('grouptitle', $groupTitle);
2819 if (count($values)) {
2820 $template->assign('values', $values);
2825 * Format fields for dupe Contact Matching
2827 * @param array $params associated array
2829 * @param null $contactId
2831 * @return array $data assoicated formatted array
2835 static function formatFields($params, $contactId = NULL) {
2837 // get the primary location type id and email
2838 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2841 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2842 $primaryLocationType = $defaultLocationType->id
;
2846 $locationType = array();
2848 $primaryLocation = 0;
2849 foreach ($params as $key => $value) {
2850 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2852 if ($locTypeId == 'Primary') {
2853 $locTypeId = $primaryLocationType;
2856 if (is_numeric($locTypeId)) {
2857 if (!in_array($locTypeId, $locationType)) {
2858 $locationType[$count] = $locTypeId;
2861 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2863 $data['location'][$loc]['location_type_id'] = $locTypeId;
2865 // if we are getting in a new primary email, dont overwrite the new one
2866 if ($locTypeId == $primaryLocationType) {
2867 if (!empty($params['email-' . $primaryLocationType])) {
2868 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2870 elseif (isset($primaryEmail)) {
2871 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2877 $data['location'][$loc]['is_primary'] = 1;
2879 if ($fieldName == 'phone') {
2881 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2884 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2886 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2888 elseif ($fieldName == 'email') {
2889 $data['location'][$loc]['email'][$loc]['email'] = $value;
2891 elseif ($fieldName == 'im') {
2892 $data['location'][$loc]['im'][$loc]['name'] = $value;
2895 if ($fieldName === 'state_province') {
2896 $data['location'][$loc]['address']['state_province_id'] = $value;
2898 elseif ($fieldName === 'country') {
2899 $data['location'][$loc]['address']['country_id'] = $value;
2902 $data['location'][$loc]['address'][$fieldName] = $value;
2907 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2908 if ($key === 'individual_suffix') {
2909 $data['suffix_id'] = $value;
2911 elseif ($key === 'individual_prefix') {
2912 $data['prefix_id'] = $value;
2914 elseif ($key === 'gender') {
2915 $data['gender_id'] = $value;
2917 elseif (substr($key, 0, 6) === 'custom') {
2918 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2920 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2921 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2923 // fix the date field
2924 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2925 $date = CRM_Utils_Date
::format($value);
2932 $data['custom'][$customFieldID] = array(
2935 'extends' => $customFields[$customFieldID]['extends'],
2936 'type' => $customFields[$customFieldID]['data_type'],
2937 'custom_field_id' => $customFieldID,
2941 elseif ($key == 'edit') {
2945 $data[$key] = $value;
2950 if (!$primaryLocation) {
2952 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2960 * calculate the profile type 'group_type' as per profile fields.
2963 * @param bool $includeTypeValues
2964 * @param int $ignoreFieldId ignore particular profile field
2966 * @internal param int $gid profile id
2967 * @return array list of calculated group type
2969 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2970 //get the profile fields.
2971 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2972 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2976 * calculate the profile type 'group_type' as per profile fields.
2979 * @param bool $includeTypeValues
2980 * @param int $ignoreFieldId ignore perticular profile field
2982 * @internal param int $gid profile id
2983 * @return array list of calculated group type
2985 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2986 $groupType = $groupTypeValues = $customFieldIds = array();
2987 if (!empty($ufFields)) {
2988 foreach ($ufFields as $fieldName => $fieldValue) {
2989 //ignore field from group type when provided.
2990 //in case of update profile field.
2991 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2994 if (!in_array($fieldValue['field_type'], $groupType)) {
2995 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2998 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
2999 $customFieldIds[$fldId] = $fldId;
3004 if (!empty($customFieldIds)) {
3005 $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) . ')';
3007 $customGroups = CRM_Core_DAO
::executeQuery($query);
3008 while ($customGroups->fetch()) {
3009 if (!$customGroups->extends_entity_column_value
) {
3013 $groupTypeName = "{$customGroups->extends}Type";
3014 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3015 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3018 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3020 $groupTypeValues[$groupTypeName][$val] = $val;
3025 if (!empty($groupTypeValues)) {
3026 $groupType = array_merge($groupType, $groupTypeValues);
3034 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3035 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3038 * BirthDate + Email Individual,Contact
3039 * BirthDate + Subject Individual,Activity
3040 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3041 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3042 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3043 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3044 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3045 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3046 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3049 * @param Array $groupTypes With key having group type names
3051 * @internal param int $gid profile id
3054 static function updateGroupTypes($gId, $groupTypes = array(
3056 if (!is_array($groupTypes) ||
!$gId) {
3060 // If empty group types set group_type as 'null'
3061 if (empty($groupTypes)) {
3062 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3065 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3066 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3068 $gTypes = $gTypeValues = array();
3070 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3071 // Get valid group type and group subtypes
3072 foreach ($groupTypes as $groupType => $value) {
3073 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3074 $gTypes[] = $groupType;
3079 if (in_array($groupType, $participantExtends)) {
3080 $subTypesOf = $groupType;
3082 elseif (strpos($groupType, 'Type') > 0) {
3083 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3089 if (!empty($value) &&
3090 (in_array($subTypesOf, $componentGroupTypes) ||
3091 in_array($subTypesOf, $participantExtends)
3094 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3098 if (empty($gTypes)) {
3102 // Build String to store group types and group subtypes
3103 $groupTypeString = implode(',', $gTypes);
3104 if (!empty($gTypeValues)) {
3105 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3108 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3112 * Create a "group_type" string
3114 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3115 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3116 * @param string $delim
3119 * @throws CRM_Core_Exception
3121 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3122 $groupTypeExpr = '';
3124 $groupTypeExpr .= implode(',', $coreTypes);
3127 if (count($subTypes) > 1) {
3128 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3130 foreach ($subTypes as $subType => $subTypeIds) {
3131 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3134 return $groupTypeExpr;
3138 * This function is used to setDefault componet specific profile fields.
3140 * @param array $fields profile fields.
3141 * @param int $componentId componetID
3142 * @param string $component component name
3143 * @param array $defaults an array of default values.
3145 * @param bool $isStandalone
3149 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3150 if (!$componentId ||
3151 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3156 $componentBAO = $componentSubType = NULL;
3157 switch ($component) {
3159 $componentBAO = 'CRM_Member_BAO_Membership';
3160 $componentBAOName = 'Membership';
3161 $componentSubType = array('membership_type_id');
3165 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3166 $componentBAOName = 'Contribution';
3167 $componentSubType = array( 'financial_type_id' );
3171 $componentBAO = 'CRM_Event_BAO_Participant';
3172 $componentBAOName = 'Participant';
3173 $componentSubType = array('role_id', 'event_id');
3177 $componentBAO = 'CRM_Activity_BAO_Activity';
3178 $componentBAOName = 'Activity';
3179 $componentSubType = array('activity_type_id');
3184 $params = array('id' => $componentId);
3186 //get the component values.
3187 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3189 $formattedGroupTree = array();
3190 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3191 foreach ($fields as $name => $field) {
3192 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3193 if (in_array($name, $dateTimeFields)) {
3194 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3195 if (!empty($values[$name])) {
3196 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3199 elseif (array_key_exists($name, $values)) {
3200 $defaults[$fldName] = $values[$name];
3202 elseif ($name == 'participant_note') {
3203 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3204 $defaults[$fldName] = array_pop($noteDetails);
3206 elseif (in_array($name, array(
3207 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3208 $defaults[$fldName] = $values["{$name}_id"];
3210 elseif ($name == 'membership_type') {
3211 // since membership_type field is a hierselect -
3212 $defaults[$fldName][0] =
3213 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3214 $defaults[$fldName][1] = $values['membership_type_id'];
3216 elseif ($name == 'membership_status') {
3217 $defaults[$fldName] = $values['status_id'];
3219 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3220 if (empty($formattedGroupTree)) {
3221 //get the groupTree as per subTypes.
3222 $groupTree = array();
3223 foreach ($componentSubType as $subType) {
3224 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3225 $componentId, 0, $values[$subType]
3227 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3229 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3230 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3233 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3234 foreach ($defaults as $customKey => $customValue) {
3235 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3236 if ($name == 'custom_' . $customFieldDetails[0]) {
3238 //hack to set default for checkbox
3239 //basically this is for weired field name like field[33][custom_19]
3240 //we are converting this field name to array structure and assign value.
3243 foreach ($formattedGroupTree as $tree) {
3244 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3246 $defaults['field'][$componentId][$name] = $customValue;
3249 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3252 // CRM-6681, $default contains formatted date, time values.
3253 $defaults[$fldName] = $customValue;
3254 if (!empty($defaults[$customKey . '_time'])) {
3255 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3260 if (!$skipValue ||
$isStandalone) {
3261 $defaults[$fldName] = $customValue;
3263 unset($defaults[$customKey]);
3273 * @param array|string $profiles - name of profile(s) to create links for
3274 * @param array $appendProfiles - name of profile(s) to append to each link
3278 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3279 // Default to contact profiles
3281 $profiles = array('new_individual', 'new_organization', 'new_household');
3283 $profiles = (array) $profiles;
3284 $toGet = array_merge($profiles, (array) $appendProfiles);
3285 $retrieved = civicrm_api3('uf_group', 'get', array(
3286 'name' => array('IN' => $toGet),
3289 $links = $append = array();
3290 if (!empty($retrieved['values'])) {
3291 foreach($retrieved['values'] as $id => $profile) {
3292 if (in_array($profile['name'], $profiles)) {
3294 'label' => $profile['title'],
3295 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3296 NULL, NULL, FALSE, NULL, FALSE) ,
3297 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3304 foreach ($append as $id) {
3305 foreach ($links as &$link) {
3306 $link['url'] .= ",$id";
3314 * Function to retrieve groups of profiles
3316 * @param integer $profileID id of the profile
3318 * @return array returns array
3321 static function profileGroups($profileID) {
3322 $groupTypes = array();
3323 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3324 if ($profileTypes) {
3325 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3326 $groupTypes = explode(',', $groupTypeParts[0]);
3332 * Function to alter contact params by filtering existing subscribed groups and returns
3333 * unsubscribed groups array for subscription.
3335 * @param array $params contact params
3336 * @param int $contactId user contact id
3338 * @return array $subscribeGroupIds This contains array of groups for subscription
3340 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3341 $config = CRM_Core_Config
::singleton();
3342 $subscribeGroupIds = array();
3344 // process further only if profileDoubleOptIn enabled and if groups exist
3345 if (!array_key_exists('group', $params) ||
3346 !self
::isProfileDoubleOptin() ||
3347 CRM_Utils_System
::isNull($params['group'])
3349 return $subscribeGroupIds;
3352 //check if contact email exist.
3354 foreach ($params as $name => $value) {
3355 if (strpos($name, 'email-') !== FALSE) {
3361 //Proceed furthur only if email present
3363 return $subscribeGroupIds;
3366 //do check for already subscriptions.
3367 $contactGroups = array();
3371 FROM civicrm_group_contact
3372 WHERE status = 'Added'
3373 AND contact_id = %1";
3375 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3376 while ($dao->fetch()) {
3377 $contactGroups[$dao->group_id
] = $dao->group_id
;
3381 //since we don't have names, compare w/ label.
3382 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3384 //actual processing start.
3385 foreach ($params['group'] as $groupId => $isSelected) {
3386 //unset group those are not selected.
3388 unset($params['group'][$groupId]);
3392 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3393 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3395 //get only mailing type group and unset it from params
3396 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3397 $subscribeGroupIds[$groupId] = $groupId;
3398 unset($params['group'][$groupId]);
3402 return $subscribeGroupIds;
3406 * Function to check if we are rendering mixed profiles
3408 * @param array $profileIds associated array of profile ids
3410 * @return boolean $mixProfile true if profile is mixed
3414 static function checkForMixProfiles($profileIds) {
3415 $mixProfile = FALSE;
3417 $contactTypes = array('Individual', 'Household', 'Organization');
3418 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3420 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3422 $typeCount = array('ctype' => array(), 'subtype' => array());
3423 foreach ($profileIds as $gid) {
3424 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3425 // ignore profile of type Contact
3426 if ($profileType == 'Contact') {
3429 if (in_array($profileType, $contactTypes)) {
3430 if (!isset($typeCount['ctype'][$profileType])) {
3431 $typeCount['ctype'][$profileType] = 1;
3434 // check if we are rendering profile of different contact types
3435 if (count($typeCount['ctype']) == 2) {
3440 elseif (in_array($profileType, $components)) {
3445 if (!isset($typeCount['subtype'][$profileType])) {
3446 $typeCount['subtype'][$profileType] = 1;
3448 // check if we are rendering profile of different contact sub types
3449 if (count($typeCount['subtype']) == 2) {
3459 * Function to determine of we show overlay profile or not
3461 * @return boolean true if profile should be shown else false
3465 static function showOverlayProfile() {
3466 $showOverlay = TRUE;
3468 // get the id of overlay profile
3469 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3470 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3472 $count = CRM_Core_DAO
::singleValueQuery($query);
3474 //check if there are no public fields and use is anonymous
3475 $session = CRM_Core_Session
::singleton();
3476 if (!$count && !$session->get('userID')) {
3477 $showOverlay = FALSE;
3480 return $showOverlay;
3484 * function to get group type values of the profile
3486 * @params Integer $profileId Profile Id
3487 * @params String $groupType Group Type
3490 * @param null $groupType
3492 * @return Array group type values
3496 static function groupTypeValues($profileId, $groupType = NULL) {
3497 $groupTypeValue = array();
3498 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3500 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3501 if (empty($groupTypeParts[1])) {
3502 return $groupTypeValue;
3504 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3506 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3508 $valueParts = explode(':', $groupTypeValues);
3510 ($valueParts[0] != "{$groupType}Type" ||
3511 ($groupType == 'Participant' &&
3512 !in_array($valueParts[0], $participantExtends)
3518 foreach ($valueParts as $val) {
3519 if (CRM_Utils_Rule
::integer($val)) {
3520 $values[$val] = $val;
3523 if (!empty($values)) {
3524 $typeName = substr($valueParts[0], 0, -4);
3525 if (in_array($valueParts[0], $participantExtends)) {
3526 $typeName = $valueParts[0];
3528 $groupTypeValue[$typeName] = $values;
3532 return $groupTypeValue;
3536 * @return bool|object
3538 static function isProfileDoubleOptin() {
3539 // check for double optin
3540 $config = CRM_Core_Config
::singleton();
3541 if (in_array('CiviMail', $config->enableComponents
)) {
3542 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3543 'profile_double_optin', NULL, FALSE
3550 * @return bool|object
3552 static function isProfileAddToGroupDoubleOptin() {
3553 // check for add to group double optin
3554 $config = CRM_Core_Config
::singleton();
3555 if (in_array('CiviMail', $config->enableComponents
)) {
3556 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3557 'profile_add_to_group_double_optin', NULL, FALSE
3564 * get profiles used for batch entry
3566 * @return array profileIds profile ids
3569 static function getBatchProfiles() {
3571 FROM civicrm_uf_group
3572 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3573 $dao = CRM_Core_DAO
::executeQuery( $query );
3574 $profileIds = array();
3575 while( $dao->fetch() ) {
3576 $profileIds[$dao->id
] = $dao->id
;
3582 * @todo what do I do?
3584 * @param $destination
3585 * @param bool $returnMultiSummaryFields
3587 * @return array|null
3589 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3590 $multiSummaryFields = $returnMultiSummaryFields ?
array( ) : NULL;
3591 foreach ($source as $field => $properties) {
3592 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3595 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3596 $destination[$field] = $properties;
3597 if ($returnMultiSummaryFields) {
3598 if ($properties['is_multi_summary']) {
3599 $multiSummaryFields[$field] = $properties;
3602 unset($source[$field]);
3605 return $multiSummaryFields;
3609 * This is function is used to format pseudo fields
3611 * @param array $fields associated array of profile fields
3615 static function reformatProfileFields(&$fields) {
3616 //reformat fields array
3617 foreach ($fields as $name => $field) {
3618 //reformat phone and extension field
3619 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3620 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3622 // retain existing element properties and just update and replace key
3623 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3624 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3625 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3627 // add additional phone extension field
3628 $fields["phone_ext-{$fieldSuffix}"] = $field;
3629 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3630 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3631 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3632 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3633 //ignore required for extension field
3634 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;