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)) {
615 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
617 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
620 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
623 if ($profileType == 'Activity' ||
$contactActivityProfile) {
624 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
627 $componentFields = CRM_Core_Component
::getQueryFields();
630 $importableFields = array_merge($importableFields, $componentFields);
632 $importableFields['group']['title'] = ts('Group(s)');
633 $importableFields['group']['where'] = NULL;
634 $importableFields['tag']['title'] = ts('Tag(s)');
635 $importableFields['tag']['where'] = NULL;
636 return $importableFields;
639 public static function getLocationFields() {
640 static $locationFields = array(
642 'supplemental_address_1',
643 'supplemental_address_2',
646 'postal_code_suffix',
659 return $locationFields;
662 protected static function getCustomFields($ctype) {
663 static $customFieldCache = array();
664 if (!isset($customFieldCache[$ctype])) {
665 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
667 // hack to add custom data for components
668 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
669 foreach ($components as $value) {
670 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
672 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
673 $customFields = array_merge($customFields, $addressCustomFields);
674 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
676 return $customFieldCache[$ctype];
680 * check the data validity
682 * @param int $userID the user id that we are actually editing
683 * @param string $title the title of the group we are interested in
684 * @param bool $register
685 * @param int $action the action of the form
687 * @pram boolean $register is this the registrtion form
688 * @return boolean true if form is valid
692 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
694 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
695 ts('Dynamic Form Creator'),
698 $controller->set('id', $userID);
699 $controller->set('register', 1);
700 $controller->process();
701 return $controller->validate();
704 // make sure we have a valid group
705 $group = new CRM_Core_DAO_UFGroup();
707 $group->title
= $title;
709 if ($group->find(TRUE) && $userID) {
710 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
711 $controller->set('gid', $group->id
);
712 $controller->set('id', $userID);
713 $controller->set('register', 0);
714 $controller->process();
715 return $controller->validate();
722 * get the html for the form that represents this particular group
724 * @param int $userID the user id that we are actually editing
725 * @param string $title the title of the group we are interested in
726 * @param int $action the action of the form
727 * @param boolean $register is this the registration form
728 * @param boolean $reset should we reset the form?
729 * @param int $profileID do we have the profile ID?
731 * @param bool $doNotProcess
734 * @return string the html for the form on success, otherwise empty string
738 static function getEditHTML($userID,
744 $doNotProcess = FALSE,
749 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
750 ts('Dynamic Form Creator'),
753 if ($reset ||
$doNotProcess) {
754 // hack to make sure we do not process this form
755 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
758 unset($_POST['_qf_default']);
759 unset($_REQUEST['_qf_default']);
761 $controller->reset();
765 $controller->set('id', $userID);
766 $controller->set('register', 1);
767 $controller->set('skipPermission', 1);
768 $controller->set('ctype', $ctype);
769 $controller->process();
770 if ($doNotProcess ||
!empty($_POST)) {
771 $controller->validate();
773 $controller->setEmbedded(TRUE);
775 //CRM-5839 - though we want to process form, get the control back.
776 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
780 // we are done processing so restore the POST/REQUEST vars
781 if (($reset ||
$doNotProcess) && $oldQFDefault) {
782 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
785 $template = CRM_Core_Smarty
::singleton();
787 // Hide CRM error messages if they are displayed using drupal form_set_error.
788 if (!empty($_POST)) {
789 $template->assign('suppressForm', TRUE);
792 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
796 // make sure we have a valid group
797 $group = new CRM_Core_DAO_UFGroup();
799 $group->title
= $title;
801 if ($group->find(TRUE)) {
802 $profileID = $group->id
;
807 // make sure profileID and ctype match if ctype exists
809 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
810 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
811 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
814 if (($profileType != 'Contact') && ($profileType != $ctype)) {
819 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
820 ts('Dynamic Form Creator'),
824 $controller->reset();
826 $controller->set('gid', $profileID);
827 $controller->set('id', $userID);
828 $controller->set('register', 0);
829 $controller->set('skipPermission', 1);
831 $controller->set('ctype', $ctype);
833 $controller->process();
834 $controller->setEmbedded(TRUE);
836 //CRM-5846 - give the control back to drupal.
837 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
840 $template = CRM_Core_Smarty
::singleton();
842 // Hide CRM error messages if they are displayed using drupal form_set_error.
843 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
844 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
845 $template->assign('suppressForm', TRUE);
849 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
850 if (!$template->template_exists($templateFile)) {
851 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
853 return trim($template->fetch($templateFile));
856 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
858 // if post not empty then only proceed
859 if (!empty($_POST)) {
861 $config = CRM_Core_Config
::singleton();
862 $email = CRM_Utils_Array
::value('mail', $_POST);
864 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
865 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
874 * searches for a contact in the db with similar attributes
876 * @param array $params the list of values to be used in the where clause
877 * @param int $id the current contact id (hence excluded from matching)
878 * @param string $contactType
880 * @internal param bool $flatten should we flatten the input params
882 * @return contact_id if found, null otherwise
886 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
887 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
888 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
889 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
891 return implode(',', $ids);
899 * Given a contact id and a field set, return the values from the db
903 * @param array $fields the profile fields of interest
904 * @param array $values the values for the above fields
905 * @param boolean $searchable searchable or not
906 * @param array $componentWhere component condition
907 * @param boolean $absolute return urls in absolute form (useful when sending an email)
909 * @param null $additionalWhereClause
911 * @internal param int $id the contact id
916 public static function getValues($cid, &$fields, &$values,
917 $searchable = TRUE, $componentWhere = NULL,
918 $absolute = FALSE, $additionalWhereClause = NULL
920 if (empty($cid) && empty($componentWhere)) {
924 // get the contact details (hier)
925 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
926 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
928 // add conditions specified by components. eg partcipant_id etc
929 if (!empty($componentWhere)) {
930 $params = array_merge($params, $componentWhere);
933 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
934 $options = &$query->_options
;
936 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
937 FALSE, FALSE, FALSE, $additionalWhereClause);
938 if (!$details->fetch()) {
941 $query->convertToPseudoNames($details);
942 $config = CRM_Core_Config
::singleton();
944 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
945 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
946 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
948 $multipleFields = array('url');
949 $nullIndex = $nullValueIndex = ' ';
951 //start of code to set the default values
952 foreach ($fields as $name => $field) {
955 $name = 'contact_id';
958 // skip fields that should not be displayed separately
959 if (!empty($field['skipDisplay'])) {
963 $index = $field['title'];
964 //handle for the label not set for the field
965 if (empty($field['title'])) {
967 $nullIndex .= $nullIndex;
970 //handle the case to avoid re-write where the profile field labels are the same
971 if (array_key_exists($index, $values)) {
972 $index .= $nullValueIndex;
973 $nullValueIndex .= $nullValueIndex;
975 $params[$index] = $values[$index] = '';
976 $customFieldName = NULL;
978 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
979 // to handle gender / suffix / prefix
980 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
981 $params[$index] = $details->$name;
982 $values[$index] = $details->$name;
984 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
985 $dname = $name . '_display';
986 $values[$index] = $details->$dname;
987 $name = $name . '_id';
988 $params[$index] = $details->$name;
990 elseif (in_array($name, array(
991 'state_province', 'country', 'county'))) {
992 $values[$index] = $details->$name;
993 $idx = $name . '_id';
994 $params[$index] = $details->$idx;
996 elseif ($name === 'preferred_communication_method') {
997 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
999 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1001 foreach ($pref as $k) {
1003 $compref[] = $communicationFields[$k];
1006 $params[$index] = $details->$name;
1007 $values[$index] = implode(',', $compref);
1009 elseif ($name === 'preferred_language') {
1010 $params[$index] = $details->$name;
1011 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1013 elseif ($name == 'group') {
1014 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1015 $title = $ids = array();
1017 foreach ($groups as $g) {
1018 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1019 // VIEW permission on that group
1020 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1022 if ($g['visibility'] != 'User and User Admin Only' ||
1023 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1025 $title[] = $g['title'];
1026 if ($g['visibility'] == 'Public Pages') {
1027 $ids[] = $g['group_id'];
1031 $values[$index] = implode(', ', $title);
1032 $params[$index] = implode(',', $ids);
1034 elseif ($name == 'tag') {
1035 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1036 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1038 foreach ($entityTags as $tagId) {
1039 $title[] = $allTags[$tagId];
1041 $values[$index] = implode(', ', $title);
1042 $params[$index] = implode(',', $entityTags);
1044 elseif ($name == 'activity_status_id') {
1045 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1046 $values[$index] = $activityStatus[$details->$name];
1047 $params[$index] = $details->$name;
1049 elseif ($name == 'activity_date_time') {
1050 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1051 $params[$index] = $details->$name;
1053 elseif ($name == 'contact_sub_type') {
1054 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1055 if (!empty($contactSubTypeNames)) {
1056 $contactSubTypeLabels = array();
1057 // get all contact subtypes
1058 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1059 // build contact subtype labels array
1060 foreach( $contactSubTypeNames as $cstName ) {
1062 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1065 $values[$index] = implode(',', $contactSubTypeLabels);
1068 $params[$index] = $details->$name;
1071 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1072 if ($details->$name) {
1073 $values[$index] = '[ x ]';
1077 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1078 $htmlType = $field['html_type'];
1080 // field_type is only set when we are retrieving profile values
1081 // when sending email, we call the same function to get custom field
1082 // values etc, i.e. emulating a profile
1083 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1085 if ($htmlType == 'File') {
1088 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
1089 $entityId = $componentWhere[0][2];
1092 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1097 $params[$index] = $values[$index] = $fileURL['file_url'];
1101 if (isset($dao) && property_exists($dao, 'data_type') &&
1102 ($dao->data_type
== 'Int' ||
1103 $dao->data_type
== 'Boolean'
1106 $customVal = (int )($details->{$name});
1108 elseif (isset($dao) && property_exists($dao, 'data_type')
1109 && $dao->data_type
== 'Float'
1111 $customVal = (float )($details->{$name});
1113 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1116 $customVal = $details->{$name};
1120 if (CRM_Utils_System
::isNull($customVal)) {
1124 $params[$index] = $customVal;
1125 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1129 if ($field['data_type'] == 'ContactReference') {
1130 $params[$index] = $values[$index];
1132 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1133 $cfID, 'is_search_range'
1135 $customFieldName = "{$name}_from";
1139 elseif ($name == 'image_URL') {
1140 list($width, $height) = getimagesize($details->$name);
1141 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1143 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1144 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1146 elseif (in_array($name, array(
1147 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1148 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1149 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1153 if ($index == 'Campaign') {
1154 $dao = 'CRM_Campaign_DAO_Campaign';
1156 elseif ($index == 'Contribution Page') {
1157 $dao = 'CRM_Contribute_DAO_ContributionPage';
1160 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1163 $value = $details->$name;
1165 $values[$index] = $value;
1170 elseif (strpos($name, '-') !== FALSE) {
1171 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1173 if (!in_array($fieldName, $multipleFields)) {
1174 if ($id == 'Primary') {
1176 // not sure why we'd every use Primary location type id
1177 // we need to fix the source if we are using it
1178 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1179 $locationTypeName = 1;
1182 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1185 if (!$locationTypeName) {
1189 $detailName = "{$locationTypeName}-{$fieldName}";
1190 $detailName = str_replace(' ', '_', $detailName);
1192 if (in_array($fieldName, array(
1193 'phone', 'im', 'email', 'openid'))) {
1195 $detailName .= "-{$type}";
1199 if (in_array($fieldName, array(
1200 'state_province', 'country', 'county'))) {
1201 $values[$index] = $details->$detailName;
1202 $idx = $detailName . '_id';
1203 $params[$index] = $details->$idx;
1205 elseif ($fieldName == 'im') {
1206 $providerId = $detailName . '-provider_id';
1207 if (isset($imProviders[$details->$providerId])) {
1208 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1211 $values[$index] = $details->$detailName;
1213 $params[$index] = $details->$detailName;
1215 elseif ($fieldName == 'phone') {
1216 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1217 if (isset($details->$phoneExtField)) {
1218 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1221 $values[$index] = $details->$detailName;
1223 $params[$index] = $details->$detailName;
1226 $values[$index] = $params[$index] = $details->$detailName;
1230 $detailName = "website-{$id}-{$fieldName}";
1231 $url = CRM_Utils_System
::fixURL($details->$detailName);
1232 if ($details->$detailName) {
1233 $websiteTypeId = "website-{$id}-website_type_id";
1234 $websiteType = $websiteTypes[$details->$websiteTypeId];
1235 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1238 $values[$index] = '';
1243 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1244 CRM_Core_Permission
::check('profile listings and forms')
1247 if (CRM_Utils_System
::isNull($params[$index])) {
1248 $params[$index] = $values[$index];
1250 if (!isset($params[$index])) {
1253 if (!$customFieldName) {
1254 $fieldName = $field['name'];
1257 $fieldName = $customFieldName;
1261 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1262 $htmlType = $field['html_type'];
1263 if ($htmlType == 'Link') {
1264 $url = $params[$index];
1266 elseif (in_array($htmlType, array(
1267 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1268 'Multi-Select State/Province', 'Multi-Select Country',
1270 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1271 $selectedOptions = explode($valSeperator, $params[$index]);
1273 foreach ($selectedOptions as $key => $multiOption) {
1275 $url[] = CRM_Utils_System
::url('civicrm/profile',
1276 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1277 urlencode($fieldName) .
1279 urlencode($multiOption)
1285 $url = CRM_Utils_System
::url('civicrm/profile',
1286 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1287 urlencode($fieldName) .
1289 urlencode($params[$index])
1294 $url = CRM_Utils_System
::url('civicrm/profile',
1295 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1296 urlencode($fieldName) .
1298 urlencode($params[$index])
1303 !empty($values[$index]) &&
1307 if (is_array($url) && !empty($url)) {
1309 $eachMultiValue = explode(', ', $values[$index]);
1310 foreach ($eachMultiValue as $key => $valueLabel) {
1311 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1313 $values[$index] = implode(', ', $links);
1316 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1324 * Check if profile Group used by any module.
1326 * @param int $id profile Id
1334 public static function usedByModule($id) {
1335 //check whether this group is used by any module(check uf join records)
1337 FROM civicrm_uf_join
1338 WHERE civicrm_uf_join.uf_group_id=$id";
1340 $dao = new CRM_Core_DAO();
1342 if ($dao->fetch()) {
1351 * Delete the profile Group.
1353 * @param int $id profile Id
1361 public static function del($id) {
1362 //check whether this group contains any profile fields
1363 $profileField = new CRM_Core_DAO_UFField();
1364 $profileField->uf_group_id
= $id;
1365 $profileField->find();
1366 while ($profileField->fetch()) {
1367 CRM_Core_BAO_UFField
::del($profileField->id
);
1370 //delete records from uf join table
1371 $ufJoin = new CRM_Core_DAO_UFJoin();
1372 $ufJoin->uf_group_id
= $id;
1375 //delete profile group
1376 $group = new CRM_Core_DAO_UFGroup();
1383 * function to add the UF Group
1385 * @param array $params reference array contains the values submitted by the form
1386 * @param array $ids reference array contains the id
1393 static function add(&$params, $ids = array()) {
1394 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1395 foreach ($fields as $field) {
1396 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1399 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1400 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1402 $ufGroup = new CRM_Core_DAO_UFGroup();
1403 $ufGroup->copyValues($params);
1405 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1407 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1409 $ufGroup->id
= $ufGroupID;
1414 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1422 * Function to make uf join entries for an uf group
1424 * @param array $params (reference) an assoc array of name/value pairs
1425 * @param int $ufGroupId ufgroup id
1431 static function createUFJoin(&$params, $ufGroupId) {
1432 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1434 // get ufjoin records for uf group
1435 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1437 // get the list of all ufgroup types
1438 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1440 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1441 if (!is_array($groupTypes)) {
1442 $groupTypes = array();
1445 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1446 if (!is_array($ufGroupRecord)) {
1447 $ufGroupRecord = array();
1450 // check which values has to be inserted/deleted for contact
1451 $menuRebuild = FALSE;
1452 foreach ($allUFGroupType as $key => $value) {
1453 $joinParams = array();
1454 $joinParams['uf_group_id'] = $ufGroupId;
1455 $joinParams['module'] = $key;
1456 if ($key == 'User Account') {
1457 $menuRebuild = TRUE;
1459 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1460 // insert a new record
1461 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1463 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1464 // delete a record for existing ufgroup
1465 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1471 UPDATE civicrm_uf_join
1473 WHERE uf_group_id = %2
1474 AND ( entity_id IS NULL OR entity_id <= 0 )
1476 $p = array(1 => array($params['weight'], 'Integer'),
1477 2 => array($ufGroupId, 'Integer'),
1479 CRM_Core_DAO
::executeQuery($query, $p);
1481 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1483 $config = CRM_Core_Config
::singleton();
1485 $config->userSystem
->is_drupal
1492 * Function to get the UF Join records for an ufgroup id
1494 * @params int $ufGroupId uf group id
1495 * @params int $displayName if set return display name in array
1496 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1498 * @param null $ufGroupId
1499 * @param null $displayName
1500 * @param null $status
1502 * @return array $ufGroupJoinRecords
1507 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1509 $UFGroupType = array();
1510 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1514 $dao = new CRM_Core_DAO_UFJoin();
1517 $dao->uf_group_id
= $ufGroupId;
1523 while ($dao->fetch()) {
1524 if (!$displayName) {
1525 $ufJoin[$dao->id
] = $dao->module
;
1528 if (isset($UFGroupType[$dao->module
])) {
1529 // skip the default modules
1531 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1533 // added for CRM-1475
1535 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1536 $ufJoin[$dao->id
] = $dao->module
;
1544 * Function takes an associative array and creates a ufjoin record for ufgroup
1546 * @param array $params (reference) an assoc array of name/value pairs
1548 * @return object CRM_Core_BAO_UFJoin object
1552 static function addUFJoin(&$params) {
1553 $ufJoin = new CRM_Core_DAO_UFJoin();
1554 $ufJoin->copyValues($params);
1560 * Function to delete the uf join record for an uf group
1562 * @param array $params (reference) an assoc array of name/value pairs
1568 static function delUFJoin(&$params) {
1569 $ufJoin = new CRM_Core_DAO_UFJoin();
1570 $ufJoin->copyValues($params);
1575 * Function to get the weight for ufjoin record
1577 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1579 * @return int weight of the UFGroup
1583 static function getWeight($ufGroupId = NULL) {
1584 //calculate the weight
1587 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1588 FROM civicrm_uf_join
1589 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1592 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1593 FROM civicrm_uf_join
1594 WHERE civicrm_uf_join.uf_group_id = %1
1595 AND ( entity_id IS NULL OR entity_id <= 0 )";
1596 $p[1] = array($ufGroupId, 'Integer');
1599 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1601 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1605 * Function to get the uf group for a module
1607 * @param string $moduleName module name
1608 * @param int $count no to increment the weight
1609 * @param bool $skipPermission
1610 * @param int $op - which operation (view, edit, create, etc) to check permission for
1611 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1613 * @internal param bool $skipPermision - whether to add permission clause
1614 * @return array $ufGroups array of ufgroups for a module
1618 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1619 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1621 if (!CRM_Core_Config
::isUpgradeMode()) {
1622 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1623 $selectFields[] = 'description';
1626 if (!empty($returnFields)) {
1627 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1630 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1631 FROM civicrm_uf_group
1632 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1635 $queryString .= ' AND civicrm_uf_group.is_active = 1
1636 WHERE civicrm_uf_join.module = %2';
1637 $p[2] = array($moduleName, 'String');
1641 // add permissioning for profiles only if not registration
1642 if (!$skipPermission) {
1643 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1644 if (strpos($queryString, 'WHERE') !== FALSE) {
1645 $queryString .= " AND $permissionClause ";
1648 $queryString .= " $permissionClause ";
1652 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1653 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1655 $ufGroups = array();
1656 while ($dao->fetch()) {
1657 //skip mix profiles in user Registration / User Account
1658 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1659 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1663 foreach ($selectFields as $key => $field) {
1664 if($field == 'id') {
1667 elseif ($field == 'name') {
1668 $ufGroups[$dao->id
][$field] = $dao->title
;
1671 $ufGroups[$dao->id
][$field] = $dao->$field;
1675 // Allow other modules to alter/override the UFGroups.
1676 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1682 * Function to filter ufgroups based on logged in user contact type
1684 * @params int $ufGroupId uf group id (profile id)
1687 * @param null $contactID
1689 * @return boolean true or false
1693 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1695 $session = CRM_Core_Session
::singleton();
1696 $contactID = $session->get('userID');
1700 //get the contact type
1701 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1703 //match if exixting contact type is same as profile contact type
1704 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1706 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1707 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1710 //allow special mix profiles for Contribution and Participant
1711 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1713 if (in_array($profileType, $specialProfiles)) {
1717 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1726 * Function to build profile form
1728 * @params object $form form object
1729 * @params array $field array field properties
1730 * @params int $mode profile mode
1731 * @params int $contactID contact id
1732 * @params string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
1737 * @param null $contactId
1738 * @param bool $online
1739 * @param null $usedFor
1740 * @param null $rowNumber
1741 * @param string $prefix
1747 static function buildProfile(
1757 $defaultValues = array();
1758 $fieldName = $field['name'];
1759 $title = $field['title'];
1760 $attributes = $field['attributes'];
1761 $rule = $field['rule'];
1762 $view = $field['is_view'];
1763 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1764 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1765 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1767 // do not display view fields in drupal registration form
1769 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1773 if ($usedFor == 'onbehalf') {
1774 $name = "onbehalf[$fieldName]";
1776 elseif ($usedFor == 'honor') {
1777 $name = "honor[$fieldName]";
1779 elseif ($contactId && !$online) {
1780 $name = "field[$contactId][$fieldName]";
1782 elseif ($rowNumber) {
1783 $name = "field[$rowNumber][$fieldName]";
1785 elseif (!empty($prefix)) {
1786 $name = $prefix ."[$fieldName]";
1792 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1793 $deleteExtra = ts('Are you sure you want to delete contact image.');
1795 CRM_Core_Action
::DELETE
=>
1797 'name' => ts('Delete Contact Image'),
1798 'url' => 'civicrm/contact/image',
1799 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1801 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1804 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1805 CRM_Core_Action
::DELETE
,
1806 array('id' => $form->get('id'),
1807 'gid' => $form->get('gid'),
1811 'contact.profileimage.delete',
1815 $form->assign('deleteURL', $deleteURL);
1817 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1818 'address_options', TRUE, NULL, TRUE
1821 if (substr($fieldName, 0, 14) === 'state_province') {
1822 $form->add('select', $name, $title,
1824 '' => ts('- select -')) + CRM_Core_PseudoConstant
::stateProvince(), $required
1826 $config = CRM_Core_Config
::singleton();
1827 if (!in_array($mode, array(
1828 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1829 $config->defaultContactStateProvince
1831 $defaultValues[$name] = $config->defaultContactStateProvince
;
1832 $form->setDefaults($defaultValues);
1835 elseif (substr($fieldName, 0, 7) === 'country') {
1836 $form->add('select', $name, $title,
1838 '' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required
1840 $config = CRM_Core_Config
::singleton();
1841 if (!in_array($mode, array(
1842 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1843 $config->defaultContactCountry
1845 $defaultValues[$name] = $config->defaultContactCountry
;
1846 $form->setDefaults($defaultValues);
1849 elseif (substr($fieldName, 0, 6) === 'county') {
1850 if ($addressOptions['county']) {
1851 $form->add('select', $name, $title,
1853 '' => ts('(choose state first)')), $required
1857 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1858 $form->add('file', $name, $title, $attributes, $required);
1859 $form->addUploadElement($name);
1861 elseif (substr($fieldName, 0, 2) === 'im') {
1862 $form->add('text', $name, $title, $attributes, $required);
1865 if (substr($name, -1) == ']') {
1866 $providerName = substr($name, 0, -1) . '-provider_id]';
1868 $form->add('select', $providerName, NULL,
1870 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1874 $form->add('select', $name . '-provider_id', $title,
1876 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1880 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1881 $form->freeze($name . '-provider_id');
1885 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1886 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1888 elseif (in_array($fieldName, array(
1889 'membership_start_date', 'membership_end_date', 'join_date'))) {
1890 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1892 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_type') {
1893 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1894 $sel = &$form->addElement('hierselect', $name, $title);
1895 $select = array('' => ts('- select -') );
1896 if(count($orgInfo) == 1 && $field['is_required']) {
1897 // we only have one org - so we should default to it. Not sure about defaulting to first type
1898 // as it could be missed - so adding a select
1899 // however, possibly that is more similar to the membership form
1900 if(count($types[1]) > 1) {
1901 $types[1] = $select +
$types[1];
1905 $orgInfo = $select +
$orgInfo;
1907 $sel->setOptions(array($orgInfo, $types));
1909 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_status') {
1910 $form->add('select', $name, $title,
1912 '' => ts('- select -')) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1915 elseif ($fieldName === 'gender_id') {
1916 $genderOptions = array();
1917 $gender = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'gender_id');
1918 foreach ($gender as $key => $var) {
1919 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1921 $group = $form->addGroup($genderOptions, $name, $title);
1923 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1926 $group->setAttribute('allowClear', TRUE);
1929 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1930 $form->add('select', $name, $title,
1932 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Contact_BAO_Contact', $fieldName), $required
1935 elseif ($fieldName === 'contact_sub_type') {
1936 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1937 if ($usedFor == 'onbehalf') {
1938 $profileType = 'Organization';
1940 elseif ($usedFor == 'honor') {
1941 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1944 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1945 if ($profileType == 'Contact') {
1946 $profileType = 'Individual';
1950 $setSubtype = FALSE;
1951 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1952 $setSubtype = $profileType;
1953 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1956 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
1959 $subtypeList = array();
1960 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1963 $subtypeList = $subtypes;
1966 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1967 $sel->setMultiple(TRUE);
1969 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1970 //add email greeting, postal greeting, addressee, CRM-4575
1971 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1972 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
1974 if (empty($profileType) ||
in_array($profileType, array(
1975 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1976 $profileType = 'Individual';
1978 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1979 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1982 'contact_type' => $profileType,
1983 'greeting_type' => $fieldName,
1985 $form->add('select', $name, $title,
1987 '' => ts('- select -')) + CRM_Core_PseudoConstant
::greeting($greeting), $required
1989 // add custom greeting element
1990 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1994 elseif ($fieldName === 'preferred_communication_method') {
1995 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1996 foreach ($communicationFields as $key => $var) {
2000 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2002 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2004 elseif ($fieldName === 'preferred_mail_format') {
2005 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2007 elseif ($fieldName === 'preferred_language') {
2008 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2010 elseif ($fieldName == 'external_identifier') {
2011 $form->add('text', $name, $title, $attributes, $required);
2012 $contID = $contactId;
2014 $contID = $form->get('id');
2016 $form->addRule($name,
2017 ts('External ID already exists in Database.'),
2019 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2022 elseif ($fieldName === 'group') {
2023 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2024 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2029 elseif ($fieldName === 'tag') {
2030 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2031 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2036 elseif (substr($fieldName, 0, 4) === 'url-') {
2037 $form->add('text', $name, $title,
2038 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2040 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2041 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2046 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2048 // Note should be rendered as textarea
2049 elseif (substr($fieldName, -4) == 'note') {
2050 $form->add('textarea', $name, $title, $attributes, $required);
2052 elseif (substr($fieldName, 0, 6) === 'custom') {
2053 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2054 if ($customFieldID) {
2055 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2058 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2059 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2060 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2061 if ($customFieldID) {
2062 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2065 elseif (in_array($fieldName, array(
2066 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2067 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2069 elseif ($fieldName == 'send_receipt') {
2070 $form->addElement('checkbox', $name, $title);
2072 elseif ($fieldName == 'soft_credit') {
2073 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2074 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2076 elseif ($fieldName == 'product_name') {
2077 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2078 $sel = &$form->addElement('hierselect', $name, $title);
2080 '0' => ts('- select -')) +
$products;
2081 $sel->setOptions(array($products, $options));
2083 elseif ($fieldName == 'payment_instrument') {
2084 $form->add('select', $name, $title,
2085 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant
::paymentInstrument( ), $required );
2087 else if ($fieldName == 'financial_type' ) {
2088 $form->add('select', $name, $title,
2090 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(), $required
2093 elseif ($fieldName == 'contribution_status_id') {
2094 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2095 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2101 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2104 $form->add('select', $name, $title,
2106 '' => ts('- select -')) +
$contributionStatuses, $required
2109 elseif ($fieldName == 'soft_credit_type') {
2110 $form->add('select', $name, $title,
2112 '' => ts('- select -')) + CRM_Core_OptionGroup
::values("soft_credit_type")
2114 $form->addElement('hidden', 'sct_default_id',
2115 CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type"),
2116 array('id' => 'sct_default_id')
2119 elseif ($fieldName == 'currency') {
2120 $form->addCurrency($name, $title, $required);
2122 elseif ($fieldName == 'contribution_page_id') {
2123 $form->add('select', $name, $title,
2125 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2128 elseif ($fieldName == 'participant_register_date') {
2129 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2131 elseif ($fieldName == 'activity_status_id') {
2132 $form->add('select', $name, $title,
2134 '' => ts('- select -')) + CRM_Core_PseudoConstant
::activityStatus(), $required
2137 elseif ($fieldName == 'activity_engagement_level') {
2138 $form->add('select', $name, $title,
2140 '' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2143 elseif ($fieldName == 'activity_date_time') {
2144 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2146 elseif ($fieldName == 'participant_status') {
2148 if ($online == TRUE) {
2149 $cond = 'visibility_id = 1';
2151 $form->add('select', $name, $title,
2153 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2156 elseif ($fieldName == 'participant_role') {
2157 if (!empty($field['is_multiple'])) {
2158 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2161 $form->add('select', $name, $title,
2163 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantRole(), $required
2167 elseif ($fieldName == 'world_region') {
2168 $form->add('select', $name, $title,
2170 '' => ts('- select -')) + CRM_Core_PseudoConstant
::worldRegion(), $required
2173 elseif ($fieldName == 'signature_html') {
2174 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2176 elseif ($fieldName == 'signature_text') {
2177 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2179 elseif (substr($fieldName, -11) == 'campaign_id') {
2180 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2181 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2182 $form->_componentCampaigns
2184 $form->add('select', $name, $title,
2186 '' => ts('- select -')) +
$campaigns, $required, 'class="big"'
2190 elseif ($fieldName == 'activity_details') {
2191 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2193 elseif ($fieldName == 'activity_duration') {
2194 $form->add('text', $name, $title, $attributes, $required);
2195 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2198 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2199 $form->add('advcheckbox', $name, $title, $attributes, $required);
2202 $form->add('text', $name, $title, $attributes, $required);
2206 static $hiddenSubtype = FALSE;
2207 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2208 // In registration mode params are submitted via POST and we don't have any clue
2209 // about profile-id or the profile-type (which could be a subtype)
2210 // To generalize the behavior and simplify the process,
2211 // lets always add the hidden
2212 //subtype value if there is any, and we won't have to
2213 // compute it while processing.
2215 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2218 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2220 $hiddenSubtype = TRUE;
2223 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2224 $form->freeze($name);
2228 if (in_array($fieldName, array(
2229 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2230 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2232 $stateCountryMap = array();
2233 if (!empty($form->_stateCountryMap
['state_province']) && !empty($form->_stateCountryMap
['country'])) {
2234 foreach ($form->_stateCountryMap
['state_province'] as $key => $value) {
2235 $stateCountryMap[$key]['state_province'] = $value;
2236 $stateCountryMap[$key]['country'] = $form->_stateCountryMap
['country'][$key];
2238 CRM_Core_BAO_Address
::addStateCountryMap($stateCountryMap);
2241 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2242 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2248 * Function to set profile defaults
2250 * @params int $contactId contact id
2251 * @params array $fields associative array of fields
2252 * @params array $defaults defaults array
2253 * @params boolean $singleProfile true for single profile else false(batch update)
2254 * @params int $componentId id for specific components like contribute, event etc
2259 * @param bool $singleProfile
2260 * @param null $componentId
2261 * @param null $component
2267 static function setProfileDefaults($contactId, &$fields, &$defaults,
2268 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2270 if (!$componentId) {
2271 //get the contact details
2272 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2273 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2274 $multipleFields = array('website' => 'url');
2276 //start of code to set the default values
2277 foreach ($fields as $name => $field) {
2278 // skip pseudo fields
2279 if (substr($name, 0, 9) == 'phone_ext') {
2283 //set the field name depending upon the profile mode(single/batch)
2284 if ($singleProfile) {
2288 $fldName = "field[$contactId][$name]";
2291 if ($name == 'group') {
2292 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2294 if ($name == 'tag') {
2295 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2298 if (!empty($details[$name]) ||
isset($details[$name])) {
2299 //to handle custom data (checkbox) to be written
2300 // to handle birth/deceased date, greeting_type and few other fields
2301 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2302 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2304 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2305 $defaults[$fldName] = $details[$name . '_id'];
2306 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2308 elseif ($name == 'preferred_communication_method') {
2309 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2310 foreach ($v as $item) {
2312 $defaults[$fldName . "[$item]"] = 1;
2316 elseif ($name == 'world_region') {
2317 $defaults[$fldName] = $details['worldregion_id'];
2319 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2320 //fix for custom fields
2321 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2323 // hack to add custom data for components
2324 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2325 foreach ($components as $value) {
2326 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2327 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2331 switch ($customFields[$customFieldId]['html_type']) {
2332 case 'Multi-Select State/Province':
2333 case 'Multi-Select Country':
2334 case 'AdvMulti-Select':
2335 case 'Multi-Select':
2336 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2337 foreach ($v as $item) {
2339 $defaults[$fldName][$item] = $item;
2345 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2346 foreach ($v as $item) {
2348 $defaults[$fldName][$item] = 1;
2349 // seems like we need this for QF style checkboxes in profile where its multiindexed
2351 $defaults["{$fldName}[{$item}]"] = 1;
2357 // CRM-6681, set defult values according to date and time format (if any).
2359 if (!empty($customFields[$customFieldId]['date_format'])) {
2360 $dateFormat = $customFields[$customFieldId]['date_format'];
2363 if (empty($customFields[$customFieldId]['time_format'])) {
2364 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2369 $timeElement = $fldName . '_time';
2370 if (substr($fldName, -1) == ']') {
2371 $timeElement = substr($fldName, 0, -1) . '_time]';
2373 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2374 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2379 $defaults[$fldName] = $details[$name];
2384 $defaults[$fldName] = $details[$name];
2388 $blocks = array('email', 'phone', 'im', 'openid');
2389 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2390 if (!in_array($fieldName, $multipleFields)) {
2391 if (is_array($details)) {
2392 foreach ($details as $key => $value) {
2393 // when we fixed CRM-5319 - get primary loc
2394 // type as per loc field and removed below code.
2395 $primaryLocationType = FALSE;
2396 if ($locTypeId == 'Primary') {
2397 if (is_array($value) && array_key_exists($fieldName, $value)){
2398 $primaryLocationType = TRUE;
2399 if (in_array($fieldName, $blocks)){
2400 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2403 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2408 // fixed for CRM-665
2409 if (is_numeric($locTypeId)) {
2410 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2411 if (!empty($value[$fieldName])) {
2412 //to handle stateprovince and country
2413 if ($fieldName == 'state_province') {
2414 $defaults[$fldName] = $value['state_province_id'];
2416 elseif ($fieldName == 'county') {
2417 $defaults[$fldName] = $value['county_id'];
2419 elseif ($fieldName == 'country') {
2420 if (!isset($value['country_id']) ||
!$value['country_id']) {
2421 $config = CRM_Core_Config
::singleton();
2422 if ($config->defaultContactCountry
) {
2423 $defaults[$fldName] = $config->defaultContactCountry
;
2427 $defaults[$fldName] = $value['country_id'];
2430 elseif ($fieldName == 'phone') {
2432 if (isset($value['phone'][$phoneTypeId])) {
2433 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2435 if (isset($value['phone_ext'][$phoneTypeId])) {
2436 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2440 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2442 if (!is_array($phoneDefault)) {
2443 $defaults[$fldName] = $phoneDefault;
2447 elseif ($fieldName == 'email') {
2448 //adding the first email (currently we don't support multiple emails of same location type)
2449 $defaults[$fldName] = $value['email'];
2451 elseif ($fieldName == 'im') {
2452 //adding the first im (currently we don't support multiple ims of same location type)
2453 $defaults[$fldName] = $value['im'];
2454 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2457 $defaults[$fldName] = $value[$fieldName];
2460 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2461 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2463 $defaults[$fldName] = $value[substr($fieldName, 8)];
2471 if (is_array($details)) {
2472 if ($fieldName === 'url'
2473 && !empty($details['website'])
2474 && !empty($details['website'][$locTypeId])) {
2475 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2483 //Handling Contribution Part of the batch profile
2484 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2485 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2488 //Handling Event Participation Part of the batch profile
2489 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2490 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2493 //Handling membership Part of the batch profile
2494 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2495 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2498 //Handling Activity Part of the batch profile
2499 if ($component == 'Activity') {
2500 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2505 * Function to get profiles by type eg: pure Individual etc
2507 * @param array $types associative array of types eg: types('Individual')
2508 * @param boolean $onlyPure true if only pure profiles are required
2510 * @return array $profiles associative array of profiles
2514 static function getProfiles($types, $onlyPure = FALSE) {
2515 $profiles = array();
2516 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2518 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2520 // Exclude Batch Data Entry profiles - CRM-10901
2521 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2523 foreach ($ufGroups as $id => $title) {
2524 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2525 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2526 $profiles[$id] = $title;
2533 * Function to check whether a profile is valid combination of
2534 * required and/or optional profile types
2536 * @param array $required array of types those are required
2537 * @param array $optional array of types those are optional
2539 * @return array $profiles associative array of profiles
2543 static function getValidProfiles($required, $optional = NULL) {
2544 if (!is_array($required) ||
empty($required)) {
2548 $profiles = array();
2549 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2551 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2553 foreach ($ufGroups as $id => $title) {
2554 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2556 $profiles[$id] = $title;
2564 * Function to check whether a profile is valid combination of
2565 * required profile fields
2567 * @param array $ufId integer id of the profile
2568 * @param array $required array of fields those are required in the profile
2570 * @return array $profiles associative array of profiles
2574 static function checkValidProfile($ufId, $required = NULL) {
2575 $validProfile = FALSE;
2577 return $validProfile;
2580 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2581 return $validProfile;
2584 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2585 NULL, FALSE, NULL, FALSE, NULL,
2586 CRM_Core_Permission
::CREATE
, NULL
2589 $validProfile = array();
2590 if (!empty($profileFields)) {
2591 $fields = array_keys($profileFields);
2592 foreach ($fields as $val) {
2593 foreach ($required as $key => $field) {
2594 if (strpos($val, $field) === 0) {
2595 unset($required[$key]);
2600 $validProfile = (empty($required)) ?
TRUE : FALSE;
2603 return $validProfile;
2607 * Function to get default value for Register.
2612 * @return mixed $defaults@static
2615 static function setRegisterDefaults(&$fields, &$defaults) {
2616 $config = CRM_Core_Config
::singleton();
2617 foreach ($fields as $name => $field) {
2618 if (substr($name, 0, 8) == 'country-') {
2619 if (!empty($config->defaultContactCountry
)) {
2620 $defaults[$name] = $config->defaultContactCountry
;
2623 elseif (substr($name, 0, 15) == 'state_province-') {
2624 if (!empty($config->defaultContactStateProvince
)) {
2625 $defaults[$name] = $config->defaultContactStateProvince
;
2633 * This function is to make a copy of a profile, including
2634 * all the fields in the profile
2636 * @param int $id the profile id to copy
2641 static function copy($id) {
2642 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2643 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2649 if ($pos = strrpos($copy->name
, "_{$id}")) {
2650 $copy->name
= substr_replace($copy->name
, '', $pos);
2652 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2655 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2656 array('uf_group_id' => $id),
2657 array('uf_group_id' => $copy->id
),
2662 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2663 array('uf_group_id' => $id),
2664 array('uf_group_id' => $copy->id
)
2667 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2671 UPDATE civicrm_uf_join
2673 WHERE uf_group_id = %2
2674 AND ( entity_id IS NULL OR entity_id <= 0 )
2676 $p = array(1 => array($maxWeight +
1, 'Integer'),
2677 2 => array($copy->id
, 'Integer'),
2679 CRM_Core_DAO
::executeQuery($query, $p);
2680 if ($copy->is_reserved
) {
2681 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2682 $params = array(1 => array($copy->id
, 'Integer'));
2683 CRM_Core_DAO
::executeQuery($query, $params);
2685 CRM_Utils_Hook
::copy('UFGroup', $copy);
2691 * Process that send notification e-mails
2693 * @params int $contactId contact id
2694 * @params array $values associative array of name/value pair
2703 static function commonSendMail($contactID, &$values) {
2704 if (!$contactID ||
!$values) {
2708 $template = CRM_Core_Smarty
::singleton();
2710 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2715 self
::profileDisplay($values['id'], $values['values'], $template);
2716 $emailList = explode(',', $values['email']);
2718 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2719 "reset=1&cid=$contactID",
2720 TRUE, NULL, FALSE, FALSE, TRUE
2723 //get the default domain email address.
2724 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2726 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2727 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2728 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)));
2731 foreach ($emailList as $emailTo) {
2732 // FIXME: take the below out of the foreach loop
2733 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2735 'groupName' => 'msg_tpl_workflow_uf',
2736 'valueName' => 'uf_notify',
2737 'contactId' => $contactID,
2738 'tplParams' => array(
2739 'displayName' => $displayName,
2740 'currentDate' => date('r'),
2741 'contactLink' => $contactLink,
2743 'from' => "$domainEmailName <$domainEmailAddress>",
2744 'toEmail' => $emailTo,
2751 * Given a contact id and a group id, returns the field values from the db
2752 * for this group and notify email only if group's notify field is
2753 * set and field values are not empty
2755 * @params $gid group id
2756 * @params $cid contact id
2757 * @params $params associative array
2762 * @param bool $skipCheck
2767 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2769 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2771 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2772 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2774 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2776 if (!empty($values) &&
2781 'values' => $values,
2792 * Function to assign uf fields to template
2794 * @params int $gid group id
2795 * @params array $values associative array of fields
2804 function profileDisplay($gid, $values, $template) {
2805 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2806 $template->assign('grouptitle', $groupTitle);
2807 if (count($values)) {
2808 $template->assign('values', $values);
2813 * Format fields for dupe Contact Matching
2815 * @param array $params associated array
2817 * @param null $contactId
2819 * @return array $data assoicated formatted array
2823 static function formatFields($params, $contactId = NULL) {
2825 // get the primary location type id and email
2826 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2829 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2830 $primaryLocationType = $defaultLocationType->id
;
2834 $locationType = array();
2836 $primaryLocation = 0;
2837 foreach ($params as $key => $value) {
2838 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2840 if ($locTypeId == 'Primary') {
2841 $locTypeId = $primaryLocationType;
2844 if (is_numeric($locTypeId)) {
2845 if (!in_array($locTypeId, $locationType)) {
2846 $locationType[$count] = $locTypeId;
2849 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2851 $data['location'][$loc]['location_type_id'] = $locTypeId;
2853 // if we are getting in a new primary email, dont overwrite the new one
2854 if ($locTypeId == $primaryLocationType) {
2855 if (!empty($params['email-' . $primaryLocationType])) {
2856 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2858 elseif (isset($primaryEmail)) {
2859 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2865 $data['location'][$loc]['is_primary'] = 1;
2867 if ($fieldName == 'phone') {
2869 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2872 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2874 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2876 elseif ($fieldName == 'email') {
2877 $data['location'][$loc]['email'][$loc]['email'] = $value;
2879 elseif ($fieldName == 'im') {
2880 $data['location'][$loc]['im'][$loc]['name'] = $value;
2883 if ($fieldName === 'state_province') {
2884 $data['location'][$loc]['address']['state_province_id'] = $value;
2886 elseif ($fieldName === 'country') {
2887 $data['location'][$loc]['address']['country_id'] = $value;
2890 $data['location'][$loc]['address'][$fieldName] = $value;
2895 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2896 if ($key === 'individual_suffix') {
2897 $data['suffix_id'] = $value;
2899 elseif ($key === 'individual_prefix') {
2900 $data['prefix_id'] = $value;
2902 elseif ($key === 'gender') {
2903 $data['gender_id'] = $value;
2905 elseif (substr($key, 0, 6) === 'custom') {
2906 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2908 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2909 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2911 // fix the date field
2912 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2913 $date = CRM_Utils_Date
::format($value);
2920 $data['custom'][$customFieldID] = array(
2923 'extends' => $customFields[$customFieldID]['extends'],
2924 'type' => $customFields[$customFieldID]['data_type'],
2925 'custom_field_id' => $customFieldID,
2929 elseif ($key == 'edit') {
2933 $data[$key] = $value;
2938 if (!$primaryLocation) {
2940 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2948 * calculate the profile type 'group_type' as per profile fields.
2951 * @param bool $includeTypeValues
2952 * @param int $ignoreFieldId ignore particular profile field
2954 * @internal param int $gid profile id
2955 * @return array list of calculated group type
2957 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2958 //get the profile fields.
2959 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2960 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2964 * calculate the profile type 'group_type' as per profile fields.
2967 * @param bool $includeTypeValues
2968 * @param int $ignoreFieldId ignore perticular profile field
2970 * @internal param int $gid profile id
2971 * @return array list of calculated group type
2973 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2974 $groupType = $groupTypeValues = $customFieldIds = array();
2975 if (!empty($ufFields)) {
2976 foreach ($ufFields as $fieldName => $fieldValue) {
2977 //ignore field from group type when provided.
2978 //in case of update profile field.
2979 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2982 if (!in_array($fieldValue['field_type'], $groupType)) {
2983 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2986 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
2987 $customFieldIds[$fldId] = $fldId;
2992 if (!empty($customFieldIds)) {
2993 $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) . ')';
2995 $customGroups = CRM_Core_DAO
::executeQuery($query);
2996 while ($customGroups->fetch()) {
2997 if (!$customGroups->extends_entity_column_value
) {
3001 $groupTypeName = "{$customGroups->extends}Type";
3002 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3003 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3006 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3008 $groupTypeValues[$groupTypeName][$val] = $val;
3013 if (!empty($groupTypeValues)) {
3014 $groupType = array_merge($groupType, $groupTypeValues);
3022 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3023 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3026 * BirthDate + Email Individual,Contact
3027 * BirthDate + Subject Individual,Activity
3028 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3029 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3030 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3031 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3032 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3033 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3034 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3037 * @param Array $groupTypes With key having group type names
3039 * @internal param int $gid profile id
3042 static function updateGroupTypes($gId, $groupTypes = array(
3044 if (!is_array($groupTypes) ||
!$gId) {
3048 // If empty group types set group_type as 'null'
3049 if (empty($groupTypes)) {
3050 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3053 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3054 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3056 $gTypes = $gTypeValues = array();
3058 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3059 // Get valid group type and group subtypes
3060 foreach ($groupTypes as $groupType => $value) {
3061 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3062 $gTypes[] = $groupType;
3067 if (in_array($groupType, $participantExtends)) {
3068 $subTypesOf = $groupType;
3070 elseif (strpos($groupType, 'Type') > 0) {
3071 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3077 if (!empty($value) &&
3078 (in_array($subTypesOf, $componentGroupTypes) ||
3079 in_array($subTypesOf, $participantExtends)
3082 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3086 if (empty($gTypes)) {
3090 // Build String to store group types and group subtypes
3091 $groupTypeString = implode(',', $gTypes);
3092 if (!empty($gTypeValues)) {
3093 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3096 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3100 * Create a "group_type" string
3102 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3103 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3104 * @param string $delim
3107 * @throws CRM_Core_Exception
3109 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3110 $groupTypeExpr = '';
3112 $groupTypeExpr .= implode(',', $coreTypes);
3115 if (count($subTypes) > 1) {
3116 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3118 foreach ($subTypes as $subType => $subTypeIds) {
3119 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3122 return $groupTypeExpr;
3126 * This function is used to setDefault componet specific profile fields.
3128 * @param array $fields profile fields.
3129 * @param int $componentId componetID
3130 * @param string $component component name
3131 * @param array $defaults an array of default values.
3133 * @param bool $isStandalone
3137 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3138 if (!$componentId ||
3139 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3144 $componentBAO = $componentSubType = NULL;
3145 switch ($component) {
3147 $componentBAO = 'CRM_Member_BAO_Membership';
3148 $componentBAOName = 'Membership';
3149 $componentSubType = array('membership_type_id');
3153 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3154 $componentBAOName = 'Contribution';
3155 $componentSubType = array( 'financial_type_id' );
3159 $componentBAO = 'CRM_Event_BAO_Participant';
3160 $componentBAOName = 'Participant';
3161 $componentSubType = array('role_id', 'event_id');
3165 $componentBAO = 'CRM_Activity_BAO_Activity';
3166 $componentBAOName = 'Activity';
3167 $componentSubType = array('activity_type_id');
3172 $params = array('id' => $componentId);
3174 //get the component values.
3175 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3177 $formattedGroupTree = array();
3178 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3179 foreach ($fields as $name => $field) {
3180 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3181 if (in_array($name, $dateTimeFields)) {
3182 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3183 if (!empty($values[$name])) {
3184 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3187 elseif (array_key_exists($name, $values)) {
3188 $defaults[$fldName] = $values[$name];
3190 elseif ($name == 'participant_note') {
3191 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3192 $defaults[$fldName] = array_pop($noteDetails);
3194 elseif (in_array($name, array(
3195 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3196 $defaults[$fldName] = $values["{$name}_id"];
3198 elseif ($name == 'membership_type') {
3199 // since membership_type field is a hierselect -
3200 $defaults[$fldName][0] =
3201 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3202 $defaults[$fldName][1] = $values['membership_type_id'];
3204 elseif ($name == 'membership_status') {
3205 $defaults[$fldName] = $values['status_id'];
3207 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3208 if (empty($formattedGroupTree)) {
3209 //get the groupTree as per subTypes.
3210 $groupTree = array();
3211 foreach ($componentSubType as $subType) {
3212 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3213 $componentId, 0, $values[$subType]
3215 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3217 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3218 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3221 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3222 foreach ($defaults as $customKey => $customValue) {
3223 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3224 if ($name == 'custom_' . $customFieldDetails[0]) {
3226 //hack to set default for checkbox
3227 //basically this is for weired field name like field[33][custom_19]
3228 //we are converting this field name to array structure and assign value.
3231 foreach ($formattedGroupTree as $tree) {
3232 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3234 $defaults['field'][$componentId][$name] = $customValue;
3237 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3240 // CRM-6681, $default contains formatted date, time values.
3241 $defaults[$fldName] = $customValue;
3242 if (!empty($defaults[$customKey . '_time'])) {
3243 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3248 if (!$skipValue ||
$isStandalone) {
3249 $defaults[$fldName] = $customValue;
3251 unset($defaults[$customKey]);
3261 * @param array|string $profiles - name of profile(s) to create links for
3262 * @param array $appendProfiles - name of profile(s) to append to each link
3266 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3267 // Default to contact profiles
3269 $profiles = array('new_individual', 'new_organization', 'new_household');
3271 $profiles = (array) $profiles;
3272 $toGet = array_merge($profiles, (array) $appendProfiles);
3273 $retrieved = civicrm_api3('uf_group', 'get', array(
3274 'name' => array('IN' => $toGet),
3277 $links = $append = array();
3278 if (!empty($retrieved['values'])) {
3279 foreach($retrieved['values'] as $id => $profile) {
3280 if (in_array($profile['name'], $profiles)) {
3282 'label' => $profile['title'],
3283 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3284 NULL, NULL, FALSE, NULL, FALSE) ,
3285 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3292 foreach ($append as $id) {
3293 foreach ($links as &$link) {
3294 $link['url'] .= ",$id";
3302 * Function to retrieve groups of profiles
3304 * @param integer $profileID id of the profile
3306 * @return array returns array
3309 static function profileGroups($profileID) {
3310 $groupTypes = array();
3311 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3312 if ($profileTypes) {
3313 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3314 $groupTypes = explode(',', $groupTypeParts[0]);
3320 * Function to alter contact params by filtering existing subscribed groups and returns
3321 * unsubscribed groups array for subscription.
3323 * @param array $params contact params
3324 * @param int $contactId user contact id
3326 * @return array $subscribeGroupIds This contains array of groups for subscription
3328 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3329 $config = CRM_Core_Config
::singleton();
3330 $subscribeGroupIds = array();
3332 // process further only if profileDoubleOptIn enabled and if groups exist
3333 if (!array_key_exists('group', $params) ||
3334 !self
::isProfileDoubleOptin() ||
3335 CRM_Utils_System
::isNull($params['group'])
3337 return $subscribeGroupIds;
3340 //check if contact email exist.
3342 foreach ($params as $name => $value) {
3343 if (strpos($name, 'email-') !== FALSE) {
3349 //Proceed furthur only if email present
3351 return $subscribeGroupIds;
3354 //do check for already subscriptions.
3355 $contactGroups = array();
3359 FROM civicrm_group_contact
3360 WHERE status = 'Added'
3361 AND contact_id = %1";
3363 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3364 while ($dao->fetch()) {
3365 $contactGroups[$dao->group_id
] = $dao->group_id
;
3369 //since we don't have names, compare w/ label.
3370 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3372 //actual processing start.
3373 foreach ($params['group'] as $groupId => $isSelected) {
3374 //unset group those are not selected.
3376 unset($params['group'][$groupId]);
3380 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3381 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3383 //get only mailing type group and unset it from params
3384 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3385 $subscribeGroupIds[$groupId] = $groupId;
3386 unset($params['group'][$groupId]);
3390 return $subscribeGroupIds;
3394 * Function to check if we are rendering mixed profiles
3396 * @param array $profileIds associated array of profile ids
3398 * @return boolean $mixProfile true if profile is mixed
3402 static function checkForMixProfiles($profileIds) {
3403 $mixProfile = FALSE;
3405 $contactTypes = array('Individual', 'Household', 'Organization');
3406 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3408 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3410 $typeCount = array('ctype' => array(), 'subtype' => array());
3411 foreach ($profileIds as $gid) {
3412 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3413 // ignore profile of type Contact
3414 if ($profileType == 'Contact') {
3417 if (in_array($profileType, $contactTypes)) {
3418 if (!isset($typeCount['ctype'][$profileType])) {
3419 $typeCount['ctype'][$profileType] = 1;
3422 // check if we are rendering profile of different contact types
3423 if (count($typeCount['ctype']) == 2) {
3428 elseif (in_array($profileType, $components)) {
3433 if (!isset($typeCount['subtype'][$profileType])) {
3434 $typeCount['subtype'][$profileType] = 1;
3436 // check if we are rendering profile of different contact sub types
3437 if (count($typeCount['subtype']) == 2) {
3447 * Funtion to determine of we show overlay profile or not
3449 * @return boolean true if profile should be shown else false
3453 static function showOverlayProfile() {
3454 $showOverlay = TRUE;
3456 // get the id of overlay profile
3457 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3458 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3460 $count = CRM_Core_DAO
::singleValueQuery($query);
3462 //check if there are no public fields and use is anonymous
3463 $session = CRM_Core_Session
::singleton();
3464 if (!$count && !$session->get('userID')) {
3465 $showOverlay = FALSE;
3468 return $showOverlay;
3472 * function to get group type values of the profile
3474 * @params Integer $profileId Profile Id
3475 * @params String $groupType Group Type
3478 * @param null $groupType
3480 * @return Array group type values
3484 static function groupTypeValues($profileId, $groupType = NULL) {
3485 $groupTypeValue = array();
3486 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3488 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3489 if (empty($groupTypeParts[1])) {
3490 return $groupTypeValue;
3492 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3494 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3496 $valueParts = explode(':', $groupTypeValues);
3498 ($valueParts[0] != "{$groupType}Type" ||
3499 ($groupType == 'Participant' &&
3500 !in_array($valueParts[0], $participantExtends)
3506 foreach ($valueParts as $val) {
3507 if (CRM_Utils_Rule
::integer($val)) {
3508 $values[$val] = $val;
3511 if (!empty($values)) {
3512 $typeName = substr($valueParts[0], 0, -4);
3513 if (in_array($valueParts[0], $participantExtends)) {
3514 $typeName = $valueParts[0];
3516 $groupTypeValue[$typeName] = $values;
3520 return $groupTypeValue;
3523 static function isProfileDoubleOptin() {
3524 // check for double optin
3525 $config = CRM_Core_Config
::singleton();
3526 if (in_array('CiviMail', $config->enableComponents
)) {
3527 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3528 'profile_double_optin', NULL, FALSE
3534 static function isProfileAddToGroupDoubleOptin() {
3535 // check for add to group double optin
3536 $config = CRM_Core_Config
::singleton();
3537 if (in_array('CiviMail', $config->enableComponents
)) {
3538 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3539 'profile_add_to_group_double_optin', NULL, FALSE
3546 * get profiles used for batch entry
3548 * @return array profileIds profile ids
3551 static function getBatchProfiles() {
3553 FROM civicrm_uf_group
3554 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3555 $dao = CRM_Core_DAO
::executeQuery( $query );
3556 $profileIds = array();
3557 while( $dao->fetch() ) {
3558 $profileIds[$dao->id
] = $dao->id
;
3564 * @todo what do I do?
3566 * @param $destination
3567 * @param bool $returnMultiSummaryFields
3569 * @return array|null
3571 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3572 $multiSummaryFields = $returnMultiSummaryFields ?
array( ) : NULL;
3573 foreach ($source as $field => $properties) {
3574 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3577 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3578 $destination[$field] = $properties;
3579 if ($returnMultiSummaryFields) {
3580 if ($properties['is_multi_summary']) {
3581 $multiSummaryFields[$field] = $properties;
3584 unset($source[$field]);
3587 return $multiSummaryFields;
3591 * This is function is used to format pseudo fields
3593 * @param array $fields associated array of profile fields
3597 static function reformatProfileFields(&$fields) {
3598 //reformat fields array
3599 foreach ($fields as $name => $field) {
3600 //reformat phone and extension field
3601 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3602 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3604 // retain existing element properties and just update and replace key
3605 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3606 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3607 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3609 // add additional phone extension field
3610 $fields["phone_ext-{$fieldSuffix}"] = $field;
3611 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3612 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3613 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3614 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3615 //ignore required for extension field
3616 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;