3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
39 class CRM_Core_BAO_UFGroup
extends CRM_Core_DAO_UFGroup
{
40 CONST PUBLIC_VISIBILITY
= 1,
42 LISTINGS_VISIBILITY
= 4;
45 * cache the match clause used in this transaction
49 static $_matchFields = NULL;
52 * Takes a bunch of params that are needed to match certain criteria and
53 * retrieves the relevant objects. Typically the valid params are only
54 * contact_id. We'll tweak this function to be more full featured over a period
55 * of time. This is the inverse function of create. It also stores all the retrieved
56 * values in the default array
58 * @param array $params (reference) an assoc array of name/value pairs
59 * @param array $defaults (reference) an assoc array to hold the flattened values
61 * @return object CRM_Core_DAO_UFGroup object
65 static function retrieve(&$params, &$defaults) {
66 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
70 * Retrieve the first non-generic contact type
72 * @param int $id id of uf_group
74 * @return string contact type
76 static function getContactType($id) {
78 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
79 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
81 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
82 $types = explode(',', $typesParts[0]);
85 foreach ($types as $type) {
86 if (in_array($type, $validTypes)) {
89 elseif (array_key_exists($type, $validSubTypes)) {
90 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
100 * Get the form title.
102 * @param int $id id of uf_form
104 * @return string title
110 public static function getTitle($id) {
111 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
115 * update the is_active flag in the db
117 * @param int $id id of the database record
118 * @param boolean $is_active value we want to set the is_active field
120 * @return Object CRM_Core_DAO_UFGroup object on success, null otherwise
124 static function setIsActive($id, $is_active) {
125 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
129 * get all the registration fields
131 * @param int $action what action are we doing
132 * @param int $mode mode
136 * @return array the fields that are needed for registration
140 static function getRegistrationFields($action, $mode, $ctype = NULL) {
141 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
142 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
145 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
148 if (!is_array($ufGroups)) {
154 foreach ($ufGroups as $id => $title) {
156 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
157 if (($fieldType != 'Contact') &&
158 ($fieldType != $ctype) &&
159 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
163 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
164 $profileSubType = $fieldType;
168 $subset = self
::getFields($id, TRUE, $action,
169 NULL, NULL, FALSE, NULL, TRUE, $ctype
172 // we do not allow duplicates. the first field is the winner
173 foreach ($subset as $name => $field) {
174 if (empty($fields[$name])) {
175 $fields[$name] = $field;
184 * get all the listing fields
186 * @param int $action what action are we doing
187 * @param int $visibility visibility of fields we are interested in
188 * @param bool $considerSelector whether to consider the in_selector parameter
189 * @param array $ufGroupIds
190 * @param boolean $searchable
192 * @param null $restrict
193 * @param bool $skipPermission
194 * @param int $permissionType
195 * @return array the fields that are listings related
199 static function getListingFields(
202 $considerSelector = FALSE,
206 $skipPermission = FALSE,
207 $permissionType = CRM_Core_Permission
::SEARCH
210 $subset = self
::getFields($ufGroupIds, FALSE, $action,
211 $visibility, $searchable,
217 if ($considerSelector) {
218 // drop the fields not meant for the selector
219 foreach ($subset as $name => $field) {
220 if (!$field['in_selector']) {
221 unset($subset[$name]);
228 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
231 foreach ($ufGroups as $id => $title) {
232 $subset = self
::getFields($id, FALSE, $action,
233 $visibility, $searchable,
239 if ($considerSelector) {
240 // drop the fields not meant for the selector
241 foreach ($subset as $name => $field) {
242 if (!$field['in_selector'])unset($subset[$name]);
245 $fields = array_merge($fields, $subset);
252 * Get all the fields that belong to the group with the name title,
253 * and format for use with buildProfile. This is the SQL analog of
256 * @param mix $id the id of the UF group or ids of ufgroup
257 * @param bool|int $register are we interested in registration fields
258 * @param int $action what action are we doing
259 * @param int $visibility visibility of fields we are interested in
261 * @param bool $showAll
262 * @param string $restrict should we restrict based on a specified profile type
264 * @param bool $skipPermission
266 * @param int $permissionType
267 * @param string $orderBy
268 * @param null $orderProfiles
270 * @internal param bool $showall
271 * @return array the fields that belong to this ufgroup(s)
275 static function getFields(
283 $skipPermission = FALSE,
285 $permissionType = CRM_Core_Permission
::CREATE
,
286 $orderBy = 'field_name',
287 $orderProfiles = NULL
289 if (!is_array($id)) {
290 $id = CRM_Utils_Type
::escape($id, 'Positive');
291 $profileIds = array($id);
297 $gids = implode(',', $profileIds);
300 $query = "SELECT g.* from civicrm_uf_group g
301 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
302 WHERE g.id IN ( {$gids} )
303 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
305 $params = array(1 => array($restrict, 'String'));
308 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
312 $query .= " AND g.is_active = 1";
315 // add permissioning for profiles only if not registration
316 if (!$skipPermission) {
317 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
318 $query .= " AND $permissionClause ";
321 if ($orderProfiles AND count($profileIds) > 1) {
322 $query .= " ORDER BY FIELD( g.id, {$gids} )";
324 $group = CRM_Core_DAO
::executeQuery($query, $params);
328 while ($group->fetch()) {
330 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
331 $field = CRM_Core_DAO
::executeQuery($query);
333 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
334 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
335 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
336 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
338 while ($field->fetch()) {
339 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
340 if ($formattedField !== NULL) {
341 $fields[$name] = $formattedField;
347 if (empty($fields) && !$validGroup) {
348 CRM_Core_Error
::fatal(ts('The requested Profile (gid=%1) is disabled OR it is not configured to be used for \'Profile\' listings in its Settings OR there is no Profile with that ID OR you do not have permission to access this profile. Please contact the site administrator if you need assistance.',
349 array(1 => implode(',', $profileIds))
353 self
::reformatProfileFields($fields);
360 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
363 * @param array $groupArr (mimic CRM_UF_DAO_UFGroup)
364 * @param array $fieldArrs list of fields (each mimics CRM_UF_DAO_UFField)
365 * @param bool $visibility visibility of fields we are interested in
366 * @param bool $searchable
367 * @param bool $showAll
369 * @param int $permissionType
371 * @internal param bool $showall
375 public static function formatUFFields(
382 $permissionType = CRM_Core_Permission
::CREATE
384 // $group = new CRM_Core_DAO_UFGroup();
385 // $group->copyValues($groupArr); // no... converts string('') to string('null')
386 $group = (object) $groupArr;
388 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
389 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
390 // they did -- the obvious fix would produce mutual recursion.
391 $ufGroupType = self
::_calculateGroupType($fieldArrs);
392 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',',$ufGroupType));
393 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',',$ufGroupType));
394 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
395 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
397 $formattedFields = array();
398 foreach ($fieldArrs as $fieldArr) {
399 $field = (object) $fieldArr;
400 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
404 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
405 if ($formattedField !== NULL) {
406 $formattedFields[$name] = $formattedField;
409 return $formattedFields;
413 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
415 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
416 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
417 * @param array $addressCustomFields
418 * @param array $importableFields
419 * @param array $customFields
420 * @param int $permissionType eg CRM_Core_Permission::CREATE
423 protected static function formatUFField(
427 $addressCustomFields,
429 $permissionType = CRM_Core_Permission
::CREATE
431 $name = $field->field_name
;
432 $title = $field->label
;
434 $addressCustom = FALSE;
435 if (in_array($permissionType, array(
436 CRM_Core_Permission
::CREATE
,
437 CRM_Core_Permission
::EDIT
,
439 in_array($field->field_name
, array_keys($addressCustomFields))
441 $addressCustom = TRUE;
442 $name = "address_{$name}";
444 if ($field->field_name
== 'url') {
445 $name .= "-{$field->website_type_id}";
447 elseif (!empty($field->location_type_id
)) {
448 $name .= "-{$field->location_type_id}";
451 $locationFields = self
::getLocationFields();
452 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
457 if (isset($field->phone_type_id
)) {
458 $name .= "-{$field->phone_type_id}";
461 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
462 // I guess to make field self sufficient with all the required data and avoid additional calls
463 $formattedField = array(
465 'groupTitle' => $group->title
,
466 'groupName' => $group->name
,
467 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
468 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
470 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
471 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
472 'is_required' => $field->is_required
,
473 'is_view' => $field->is_view
,
474 'help_pre' => $field->help_pre
,
475 'help_post' => $field->help_post
,
476 'visibility' => $field->visibility
,
477 'in_selector' => $field->in_selector
,
478 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
479 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
480 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
481 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
482 'group_id' => $group->id
,
483 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
484 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
485 'field_type' => $field->field_type
,
486 'field_id' => $field->id
,
487 'pseudoconstant' => CRM_Utils_Array
::value(
489 CRM_Utils_Array
::value($field->field_name
, $importableFields)
491 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
492 'dbName' => CRM_Utils_Array
::value(
494 CRM_Utils_Array
::value($field->field_name
, $importableFields)
499 //adding custom field property
500 if (substr($field->field_name
, 0, 6) == 'custom' ||
501 substr($field->field_name
, 0, 14) === 'address_custom'
503 // if field is not present in customFields, that means the user
504 // DOES NOT HAVE permission to access that field
505 if (array_key_exists($field->field_name
, $customFields)) {
506 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
508 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
509 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
510 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
512 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
513 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
514 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
517 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
518 return array($name, $formattedField);
521 $formattedField = NULL;
522 return array($name, $formattedField);
525 return array($name, $formattedField);
529 * Create a query to find all visible UFFields in a UFGroup
531 * This is the SQL-variant of checkUFFieldDisplayable().
533 * @param int $groupId
534 * @param bool $searchable
535 * @param bool $showAll
536 * @param int $visibility
537 * @param string $orderBy comma-delimited list of SQL columns
540 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
541 $where = " WHERE uf_group_id = {$groupId}";
544 $where .= " AND is_searchable = 1";
548 $where .= " AND is_active = 1";
553 if ($visibility & self
::PUBLIC_VISIBILITY
) {
554 $clause[] = 'visibility = "Public Pages"';
556 if ($visibility & self
::ADMIN_VISIBILITY
) {
557 $clause[] = 'visibility = "User and User Admin Only"';
559 if ($visibility & self
::LISTINGS_VISIBILITY
) {
560 $clause[] = 'visibility = "Public Pages and Listings"';
562 if (!empty($clause)) {
563 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
567 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
569 $query .= ", " . $orderBy;
576 * Create a query to find all visible UFFields in a UFGroup
578 * This is the PHP in-memory variant of createUFFieldQuery().
580 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
581 * @param bool $searchable
582 * @param bool $showAll
583 * @param int $visibility
584 * @return bool TRUE if field is displayable
586 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
587 if ($searchable && $field->is_searchable
!= 1) {
591 if (!$showAll && $field->is_active
!= 1) {
596 $allowedVisibilities = array();
597 if ($visibility & self
::PUBLIC_VISIBILITY
) {
598 $allowedVisibilities[] = 'Public Pages';
600 if ($visibility & self
::ADMIN_VISIBILITY
) {
601 $allowedVisibilities[] = 'User and User Admin Only';
603 if ($visibility & self
::LISTINGS_VISIBILITY
) {
604 $allowedVisibilities[] = 'Public Pages and Listings';
606 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
607 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
617 * @param $profileType
618 * @param $contactActivityProfile
622 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
624 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
627 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
630 if ($profileType == 'Activity' ||
$contactActivityProfile) {
631 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
634 $componentFields = CRM_Core_Component
::getQueryFields();
637 $importableFields = array_merge($importableFields, $componentFields);
639 $importableFields['group']['title'] = ts('Group(s)');
640 $importableFields['group']['where'] = NULL;
641 $importableFields['tag']['title'] = ts('Tag(s)');
642 $importableFields['tag']['where'] = NULL;
643 return $importableFields;
646 public static function getLocationFields() {
647 static $locationFields = array(
649 'supplemental_address_1',
650 'supplemental_address_2',
653 'postal_code_suffix',
666 return $locationFields;
674 protected static function getCustomFields($ctype) {
675 static $customFieldCache = array();
676 if (!isset($customFieldCache[$ctype])) {
677 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
679 // hack to add custom data for components
680 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
681 foreach ($components as $value) {
682 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
684 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
685 $customFields = array_merge($customFields, $addressCustomFields);
686 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
688 return $customFieldCache[$ctype];
692 * check the data validity
694 * @param int $userID the user id that we are actually editing
695 * @param string $title the title of the group we are interested in
696 * @param bool $register
697 * @param int $action the action of the form
699 * @pram boolean $register is this the registrtion form
700 * @return boolean true if form is valid
704 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
706 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
707 ts('Dynamic Form Creator'),
710 $controller->set('id', $userID);
711 $controller->set('register', 1);
712 $controller->process();
713 return $controller->validate();
716 // make sure we have a valid group
717 $group = new CRM_Core_DAO_UFGroup();
719 $group->title
= $title;
721 if ($group->find(TRUE) && $userID) {
722 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
723 $controller->set('gid', $group->id
);
724 $controller->set('id', $userID);
725 $controller->set('register', 0);
726 $controller->process();
727 return $controller->validate();
734 * get the html for the form that represents this particular group
736 * @param int $userID the user id that we are actually editing
737 * @param string $title the title of the group we are interested in
738 * @param int $action the action of the form
739 * @param boolean $register is this the registration form
740 * @param boolean $reset should we reset the form?
741 * @param int $profileID do we have the profile ID?
743 * @param bool $doNotProcess
746 * @return string the html for the form on success, otherwise empty string
750 static function getEditHTML($userID,
756 $doNotProcess = FALSE,
761 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
762 ts('Dynamic Form Creator'),
765 if ($reset ||
$doNotProcess) {
766 // hack to make sure we do not process this form
767 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
770 unset($_POST['_qf_default']);
771 unset($_REQUEST['_qf_default']);
773 $controller->reset();
777 $controller->set('id', $userID);
778 $controller->set('register', 1);
779 $controller->set('skipPermission', 1);
780 $controller->set('ctype', $ctype);
781 $controller->process();
782 if ($doNotProcess ||
!empty($_POST)) {
783 $controller->validate();
785 $controller->setEmbedded(TRUE);
787 //CRM-5839 - though we want to process form, get the control back.
788 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
792 // we are done processing so restore the POST/REQUEST vars
793 if (($reset ||
$doNotProcess) && $oldQFDefault) {
794 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
797 $template = CRM_Core_Smarty
::singleton();
799 // Hide CRM error messages if they are displayed using drupal form_set_error.
800 if (!empty($_POST)) {
801 $template->assign('suppressForm', TRUE);
804 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
808 // make sure we have a valid group
809 $group = new CRM_Core_DAO_UFGroup();
811 $group->title
= $title;
813 if ($group->find(TRUE)) {
814 $profileID = $group->id
;
819 // make sure profileID and ctype match if ctype exists
821 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
822 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
823 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
826 if (($profileType != 'Contact') && ($profileType != $ctype)) {
831 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
832 ts('Dynamic Form Creator'),
836 $controller->reset();
838 $controller->set('gid', $profileID);
839 $controller->set('id', $userID);
840 $controller->set('register', 0);
841 $controller->set('skipPermission', 1);
843 $controller->set('ctype', $ctype);
845 $controller->process();
846 $controller->setEmbedded(TRUE);
848 //CRM-5846 - give the control back to drupal.
849 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
852 $template = CRM_Core_Smarty
::singleton();
854 // Hide CRM error messages if they are displayed using drupal form_set_error.
855 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
856 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
857 $template->assign('suppressForm', TRUE);
861 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
862 if (!$template->template_exists($templateFile)) {
863 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
865 return trim($template->fetch($templateFile));
868 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
870 // if post not empty then only proceed
871 if (!empty($_POST)) {
873 $config = CRM_Core_Config
::singleton();
874 $email = CRM_Utils_Array
::value('mail', $_POST);
876 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
877 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
886 * searches for a contact in the db with similar attributes
888 * @param array $params the list of values to be used in the where clause
889 * @param int $id the current contact id (hence excluded from matching)
890 * @param string $contactType
892 * @internal param bool $flatten should we flatten the input params
894 * @return contact_id if found, null otherwise
898 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
899 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
900 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
901 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
903 return implode(',', $ids);
911 * Given a contact id and a field set, return the values from the db
915 * @param array $fields the profile fields of interest
916 * @param array $values the values for the above fields
917 * @param boolean $searchable searchable or not
918 * @param array $componentWhere component condition
919 * @param boolean $absolute return urls in absolute form (useful when sending an email)
921 * @param null $additionalWhereClause
923 * @internal param int $id the contact id
928 public static function getValues($cid, &$fields, &$values,
929 $searchable = TRUE, $componentWhere = NULL,
930 $absolute = FALSE, $additionalWhereClause = NULL
932 if (empty($cid) && empty($componentWhere)) {
936 // get the contact details (hier)
937 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
938 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
940 // add conditions specified by components. eg partcipant_id etc
941 if (!empty($componentWhere)) {
942 $params = array_merge($params, $componentWhere);
945 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
946 $options = &$query->_options
;
948 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
949 FALSE, FALSE, FALSE, $additionalWhereClause);
950 if (!$details->fetch()) {
953 $query->convertToPseudoNames($details);
954 $config = CRM_Core_Config
::singleton();
956 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
957 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
958 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
960 $multipleFields = array('url');
962 //start of code to set the default values
963 foreach ($fields as $name => $field) {
966 $name = 'contact_id';
969 // skip fields that should not be displayed separately
970 if (!empty($field['skipDisplay'])) {
974 // Create a unique, non-empty index for each field.
975 $index = $field['title'];
976 if ($index === '') $index = ' ';
977 while (array_key_exists($index, $values))
980 $params[$index] = $values[$index] = '';
981 $customFieldName = NULL;
983 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
984 // to handle gender / suffix / prefix
985 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
986 $params[$index] = $details->$name;
987 $values[$index] = $details->$name;
989 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
990 $dname = $name . '_display';
991 $values[$index] = $details->$dname;
992 $name = $name . '_id';
993 $params[$index] = $details->$name;
995 elseif (in_array($name, array(
996 'state_province', 'country', 'county'))) {
997 $values[$index] = $details->$name;
998 $idx = $name . '_id';
999 $params[$index] = $details->$idx;
1001 elseif ($name === 'preferred_communication_method') {
1002 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1004 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1006 foreach ($pref as $k) {
1008 $compref[] = $communicationFields[$k];
1011 $params[$index] = $details->$name;
1012 $values[$index] = implode(',', $compref);
1014 elseif ($name === 'preferred_language') {
1015 $params[$index] = $details->$name;
1016 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1018 elseif ($name == 'group') {
1019 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1020 $title = $ids = array();
1022 foreach ($groups as $g) {
1023 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1024 // VIEW permission on that group
1025 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1027 if ($g['visibility'] != 'User and User Admin Only' ||
1028 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1030 $title[] = $g['title'];
1031 if ($g['visibility'] == 'Public Pages') {
1032 $ids[] = $g['group_id'];
1036 $values[$index] = implode(', ', $title);
1037 $params[$index] = implode(',', $ids);
1039 elseif ($name == 'tag') {
1040 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1041 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1043 foreach ($entityTags as $tagId) {
1044 $title[] = $allTags[$tagId];
1046 $values[$index] = implode(', ', $title);
1047 $params[$index] = implode(',', $entityTags);
1049 elseif ($name == 'activity_status_id') {
1050 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1051 $values[$index] = $activityStatus[$details->$name];
1052 $params[$index] = $details->$name;
1054 elseif ($name == 'activity_date_time') {
1055 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1056 $params[$index] = $details->$name;
1058 elseif ($name == 'contact_sub_type') {
1059 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1060 if (!empty($contactSubTypeNames)) {
1061 $contactSubTypeLabels = array();
1062 // get all contact subtypes
1063 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1064 // build contact subtype labels array
1065 foreach( $contactSubTypeNames as $cstName ) {
1067 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1070 $values[$index] = implode(',', $contactSubTypeLabels);
1073 $params[$index] = $details->$name;
1076 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1077 if ($details->$name) {
1078 $values[$index] = '[ x ]';
1082 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1083 $htmlType = $field['html_type'];
1085 // field_type is only set when we are retrieving profile values
1086 // when sending email, we call the same function to get custom field
1087 // values etc, i.e. emulating a profile
1088 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1090 if ($htmlType == 'File') {
1093 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
1094 $entityId = $componentWhere[0][2];
1097 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1102 $params[$index] = $values[$index] = $fileURL['file_url'];
1106 if (isset($dao) && property_exists($dao, 'data_type') &&
1107 ($dao->data_type
== 'Int' ||
1108 $dao->data_type
== 'Boolean'
1111 $customVal = (int )($details->{$name});
1113 elseif (isset($dao) && property_exists($dao, 'data_type')
1114 && $dao->data_type
== 'Float'
1116 $customVal = (float )($details->{$name});
1118 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1121 $customVal = $details->{$name};
1125 if (CRM_Utils_System
::isNull($customVal)) {
1129 $params[$index] = $customVal;
1130 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1134 if ($field['data_type'] == 'ContactReference') {
1135 $params[$index] = $values[$index];
1137 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1138 $cfID, 'is_search_range'
1140 $customFieldName = "{$name}_from";
1144 elseif ($name == 'image_URL') {
1145 list($width, $height) = getimagesize($details->$name);
1146 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1148 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1149 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1151 elseif (in_array($name, array(
1152 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1153 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1154 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1158 if ($index == 'Campaign') {
1159 $dao = 'CRM_Campaign_DAO_Campaign';
1161 elseif ($index == 'Contribution Page') {
1162 $dao = 'CRM_Contribute_DAO_ContributionPage';
1165 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1168 $value = $details->$name;
1170 $values[$index] = $value;
1175 elseif (strpos($name, '-') !== FALSE) {
1176 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1178 if (!in_array($fieldName, $multipleFields)) {
1179 if ($id == 'Primary') {
1181 // not sure why we'd every use Primary location type id
1182 // we need to fix the source if we are using it
1183 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1184 $locationTypeName = 1;
1187 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1190 if (!$locationTypeName) {
1194 $detailName = "{$locationTypeName}-{$fieldName}";
1195 $detailName = str_replace(' ', '_', $detailName);
1197 if (in_array($fieldName, array(
1198 'phone', 'im', 'email', 'openid'))) {
1200 $detailName .= "-{$type}";
1204 if (in_array($fieldName, array(
1205 'state_province', 'country', 'county'))) {
1206 $values[$index] = $details->$detailName;
1207 $idx = $detailName . '_id';
1208 $params[$index] = $details->$idx;
1210 elseif ($fieldName == 'im') {
1211 $providerId = $detailName . '-provider_id';
1212 if (isset($imProviders[$details->$providerId])) {
1213 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1216 $values[$index] = $details->$detailName;
1218 $params[$index] = $details->$detailName;
1220 elseif ($fieldName == 'phone') {
1221 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1222 if (isset($details->$phoneExtField)) {
1223 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1226 $values[$index] = $details->$detailName;
1228 $params[$index] = $details->$detailName;
1231 $values[$index] = $params[$index] = $details->$detailName;
1235 $detailName = "website-{$id}-{$fieldName}";
1236 $url = CRM_Utils_System
::fixURL($details->$detailName);
1237 if ($details->$detailName) {
1238 $websiteTypeId = "website-{$id}-website_type_id";
1239 $websiteType = $websiteTypes[$details->$websiteTypeId];
1240 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1243 $values[$index] = '';
1248 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1249 CRM_Core_Permission
::check('profile listings and forms')
1252 if (CRM_Utils_System
::isNull($params[$index])) {
1253 $params[$index] = $values[$index];
1255 if (!isset($params[$index])) {
1258 if (!$customFieldName) {
1259 $fieldName = $field['name'];
1262 $fieldName = $customFieldName;
1266 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1267 $htmlType = $field['html_type'];
1268 if ($htmlType == 'Link') {
1269 $url = $params[$index];
1271 elseif (in_array($htmlType, array(
1272 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1273 'Multi-Select State/Province', 'Multi-Select Country',
1275 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1276 $selectedOptions = explode($valSeperator, $params[$index]);
1278 foreach ($selectedOptions as $key => $multiOption) {
1280 $url[] = CRM_Utils_System
::url('civicrm/profile',
1281 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1282 urlencode($fieldName) .
1284 urlencode($multiOption)
1290 $url = CRM_Utils_System
::url('civicrm/profile',
1291 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1292 urlencode($fieldName) .
1294 urlencode($params[$index])
1299 $url = CRM_Utils_System
::url('civicrm/profile',
1300 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1301 urlencode($fieldName) .
1303 urlencode($params[$index])
1308 !empty($values[$index]) &&
1312 if (is_array($url) && !empty($url)) {
1314 $eachMultiValue = explode(', ', $values[$index]);
1315 foreach ($eachMultiValue as $key => $valueLabel) {
1316 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1318 $values[$index] = implode(', ', $links);
1321 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1329 * Check if profile Group used by any module.
1331 * @param int $id profile Id
1339 public static function usedByModule($id) {
1340 //check whether this group is used by any module(check uf join records)
1342 FROM civicrm_uf_join
1343 WHERE civicrm_uf_join.uf_group_id=$id";
1345 $dao = new CRM_Core_DAO();
1347 if ($dao->fetch()) {
1356 * Delete the profile Group.
1358 * @param int $id profile Id
1366 public static function del($id) {
1367 //check whether this group contains any profile fields
1368 $profileField = new CRM_Core_DAO_UFField();
1369 $profileField->uf_group_id
= $id;
1370 $profileField->find();
1371 while ($profileField->fetch()) {
1372 CRM_Core_BAO_UFField
::del($profileField->id
);
1375 //delete records from uf join table
1376 $ufJoin = new CRM_Core_DAO_UFJoin();
1377 $ufJoin->uf_group_id
= $id;
1380 //delete profile group
1381 $group = new CRM_Core_DAO_UFGroup();
1388 * function to add the UF Group
1390 * @param array $params reference array contains the values submitted by the form
1391 * @param array $ids reference array contains the id
1398 static function add(&$params, $ids = array()) {
1399 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1400 foreach ($fields as $field) {
1401 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1404 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1405 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1407 $ufGroup = new CRM_Core_DAO_UFGroup();
1408 $ufGroup->copyValues($params);
1410 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1412 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1414 $ufGroup->id
= $ufGroupID;
1419 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1427 * Function to make uf join entries for an uf group
1429 * @param array $params (reference) an assoc array of name/value pairs
1430 * @param int $ufGroupId ufgroup id
1436 static function createUFJoin(&$params, $ufGroupId) {
1437 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1439 // get ufjoin records for uf group
1440 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1442 // get the list of all ufgroup types
1443 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
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($groupTypes)) {
1447 $groupTypes = array();
1450 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1451 if (!is_array($ufGroupRecord)) {
1452 $ufGroupRecord = array();
1455 // check which values has to be inserted/deleted for contact
1456 $menuRebuild = FALSE;
1457 foreach ($allUFGroupType as $key => $value) {
1458 $joinParams = array();
1459 $joinParams['uf_group_id'] = $ufGroupId;
1460 $joinParams['module'] = $key;
1461 if ($key == 'User Account') {
1462 $menuRebuild = TRUE;
1464 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1465 // insert a new record
1466 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1468 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1469 // delete a record for existing ufgroup
1470 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1476 UPDATE civicrm_uf_join
1478 WHERE uf_group_id = %2
1479 AND ( entity_id IS NULL OR entity_id <= 0 )
1481 $p = array(1 => array($params['weight'], 'Integer'),
1482 2 => array($ufGroupId, 'Integer'),
1484 CRM_Core_DAO
::executeQuery($query, $p);
1486 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1488 $config = CRM_Core_Config
::singleton();
1490 $config->userSystem
->is_drupal
1497 * Function to get the UF Join records for an ufgroup id
1499 * @params int $ufGroupId uf group id
1500 * @params int $displayName if set return display name in array
1501 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1503 * @param null $ufGroupId
1504 * @param null $displayName
1505 * @param null $status
1507 * @return array $ufGroupJoinRecords
1512 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1514 $UFGroupType = array();
1515 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1519 $dao = new CRM_Core_DAO_UFJoin();
1522 $dao->uf_group_id
= $ufGroupId;
1528 while ($dao->fetch()) {
1529 if (!$displayName) {
1530 $ufJoin[$dao->id
] = $dao->module
;
1533 if (isset($UFGroupType[$dao->module
])) {
1534 // skip the default modules
1536 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1538 // added for CRM-1475
1540 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1541 $ufJoin[$dao->id
] = $dao->module
;
1549 * Function takes an associative array and creates a ufjoin record for ufgroup
1551 * @param array $params (reference) an assoc array of name/value pairs
1553 * @return object CRM_Core_BAO_UFJoin object
1557 static function addUFJoin(&$params) {
1558 $ufJoin = new CRM_Core_DAO_UFJoin();
1559 $ufJoin->copyValues($params);
1565 * Function to delete the uf join record for an uf group
1567 * @param array $params (reference) an assoc array of name/value pairs
1573 static function delUFJoin(&$params) {
1574 $ufJoin = new CRM_Core_DAO_UFJoin();
1575 $ufJoin->copyValues($params);
1580 * Function to get the weight for ufjoin record
1582 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1584 * @return int weight of the UFGroup
1588 static function getWeight($ufGroupId = NULL) {
1589 //calculate the weight
1592 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1593 FROM civicrm_uf_join
1594 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1597 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1598 FROM civicrm_uf_join
1599 WHERE civicrm_uf_join.uf_group_id = %1
1600 AND ( entity_id IS NULL OR entity_id <= 0 )";
1601 $p[1] = array($ufGroupId, 'Integer');
1604 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1606 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1610 * Function to get the uf group for a module
1612 * @param string $moduleName module name
1613 * @param int $count no to increment the weight
1614 * @param bool $skipPermission
1615 * @param int $op - which operation (view, edit, create, etc) to check permission for
1616 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1618 * @internal param bool $skipPermision - whether to add permission clause
1619 * @return array $ufGroups array of ufgroups for a module
1623 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1624 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1626 if (!CRM_Core_Config
::isUpgradeMode()) {
1627 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1628 $selectFields[] = 'description';
1631 if (!empty($returnFields)) {
1632 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1635 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1636 FROM civicrm_uf_group
1637 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1640 $queryString .= ' AND civicrm_uf_group.is_active = 1
1641 WHERE civicrm_uf_join.module = %2';
1642 $p[2] = array($moduleName, 'String');
1646 // add permissioning for profiles only if not registration
1647 if (!$skipPermission) {
1648 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1649 if (strpos($queryString, 'WHERE') !== FALSE) {
1650 $queryString .= " AND $permissionClause ";
1653 $queryString .= " $permissionClause ";
1657 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1658 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1660 $ufGroups = array();
1661 while ($dao->fetch()) {
1662 //skip mix profiles in user Registration / User Account
1663 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1664 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1668 foreach ($selectFields as $key => $field) {
1669 if($field == 'id') {
1672 elseif ($field == 'name') {
1673 $ufGroups[$dao->id
][$field] = $dao->title
;
1676 $ufGroups[$dao->id
][$field] = $dao->$field;
1680 // Allow other modules to alter/override the UFGroups.
1681 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1687 * Function to filter ufgroups based on logged in user contact type
1689 * @params int $ufGroupId uf group id (profile id)
1692 * @param null $contactID
1694 * @return boolean true or false
1698 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1700 $session = CRM_Core_Session
::singleton();
1701 $contactID = $session->get('userID');
1705 //get the contact type
1706 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1708 //match if exixting contact type is same as profile contact type
1709 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1711 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1712 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1715 //allow special mix profiles for Contribution and Participant
1716 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1718 if (in_array($profileType, $specialProfiles)) {
1722 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1731 * Function to build profile form
1733 * @params object $form form object
1734 * @params array $field array field properties
1735 * @params int $mode profile mode
1736 * @params int $contactID contact id
1737 * @params string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
1742 * @param null $contactId
1743 * @param bool $online
1744 * @param null $usedFor
1745 * @param null $rowNumber
1746 * @param string $prefix
1752 static function buildProfile(
1762 $defaultValues = array();
1763 $fieldName = $field['name'];
1764 $title = $field['title'];
1765 $attributes = $field['attributes'];
1766 $rule = $field['rule'];
1767 $view = $field['is_view'];
1768 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1769 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1770 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1772 // do not display view fields in drupal registration form
1774 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1778 if ($usedFor == 'onbehalf') {
1779 $name = "onbehalf[$fieldName]";
1781 elseif ($usedFor == 'honor') {
1782 $name = "honor[$fieldName]";
1784 elseif ($contactId && !$online) {
1785 $name = "field[$contactId][$fieldName]";
1787 elseif ($rowNumber) {
1788 $name = "field[$rowNumber][$fieldName]";
1790 elseif (!empty($prefix)) {
1791 $name = $prefix ."[$fieldName]";
1797 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1798 $deleteExtra = ts('Are you sure you want to delete contact image.');
1800 CRM_Core_Action
::DELETE
=>
1802 'name' => ts('Delete Contact Image'),
1803 'url' => 'civicrm/contact/image',
1804 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1806 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1809 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1810 CRM_Core_Action
::DELETE
,
1811 array('id' => $form->get('id'),
1812 'gid' => $form->get('gid'),
1816 'contact.profileimage.delete',
1820 $form->assign('deleteURL', $deleteURL);
1822 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1823 'address_options', TRUE, NULL, TRUE
1826 if (substr($fieldName, 0, 14) === 'state_province') {
1827 $form->add('select', $name, $title,
1829 '' => ts('- select -')) + CRM_Core_PseudoConstant
::stateProvince(), $required
1831 $config = CRM_Core_Config
::singleton();
1832 if (!in_array($mode, array(
1833 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1834 $config->defaultContactStateProvince
1836 $defaultValues[$name] = $config->defaultContactStateProvince
;
1837 $form->setDefaults($defaultValues);
1840 elseif (substr($fieldName, 0, 7) === 'country') {
1841 $form->add('select', $name, $title,
1843 '' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required
1845 $config = CRM_Core_Config
::singleton();
1846 if (!in_array($mode, array(
1847 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1848 $config->defaultContactCountry
1850 $defaultValues[$name] = $config->defaultContactCountry
;
1851 $form->setDefaults($defaultValues);
1854 elseif (substr($fieldName, 0, 6) === 'county') {
1855 if ($addressOptions['county']) {
1856 $form->add('select', $name, $title,
1858 '' => ts('(choose state first)')), $required
1862 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1863 $form->add('file', $name, $title, $attributes, $required);
1864 $form->addUploadElement($name);
1866 elseif (substr($fieldName, 0, 2) === 'im') {
1867 $form->add('text', $name, $title, $attributes, $required);
1870 if (substr($name, -1) == ']') {
1871 $providerName = substr($name, 0, -1) . '-provider_id]';
1873 $form->add('select', $providerName, NULL,
1875 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1879 $form->add('select', $name . '-provider_id', $title,
1881 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1885 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1886 $form->freeze($name . '-provider_id');
1890 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1891 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1893 elseif (in_array($fieldName, array(
1894 'membership_start_date', 'membership_end_date', 'join_date'))) {
1895 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1897 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_type') {
1898 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1899 $sel = &$form->addElement('hierselect', $name, $title);
1900 $select = array('' => ts('- select -') );
1901 if(count($orgInfo) == 1 && $field['is_required']) {
1902 // we only have one org - so we should default to it. Not sure about defaulting to first type
1903 // as it could be missed - so adding a select
1904 // however, possibly that is more similar to the membership form
1905 if(count($types[1]) > 1) {
1906 $types[1] = $select +
$types[1];
1910 $orgInfo = $select +
$orgInfo;
1912 $sel->setOptions(array($orgInfo, $types));
1914 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_status') {
1915 $form->add('select', $name, $title,
1917 '' => ts('- select -')) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1920 elseif ($fieldName === 'gender_id') {
1921 $genderOptions = array();
1922 $gender = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'gender_id');
1923 foreach ($gender as $key => $var) {
1924 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1926 $group = $form->addGroup($genderOptions, $name, $title);
1928 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1931 $group->setAttribute('allowClear', TRUE);
1934 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1935 $form->add('select', $name, $title,
1937 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Contact_BAO_Contact', $fieldName), $required
1940 elseif ($fieldName === 'contact_sub_type') {
1941 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1942 if ($usedFor == 'onbehalf') {
1943 $profileType = 'Organization';
1945 elseif ($usedFor == 'honor') {
1946 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1949 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1950 if ($profileType == 'Contact') {
1951 $profileType = 'Individual';
1955 $setSubtype = FALSE;
1956 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1957 $setSubtype = $profileType;
1958 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1961 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
1964 $subtypeList = array();
1965 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1968 $subtypeList = $subtypes;
1971 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1972 $sel->setMultiple(TRUE);
1974 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1975 //add email greeting, postal greeting, addressee, CRM-4575
1976 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1977 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
1979 if (empty($profileType) ||
in_array($profileType, array(
1980 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1981 $profileType = 'Individual';
1983 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1984 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1987 'contact_type' => $profileType,
1988 'greeting_type' => $fieldName,
1990 $form->add('select', $name, $title,
1992 '' => ts('- select -')) + CRM_Core_PseudoConstant
::greeting($greeting), $required
1994 // add custom greeting element
1995 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1999 elseif ($fieldName === 'preferred_communication_method') {
2000 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2001 foreach ($communicationFields as $key => $var) {
2005 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2007 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2009 elseif ($fieldName === 'preferred_mail_format') {
2010 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2012 elseif ($fieldName === 'preferred_language') {
2013 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2015 elseif ($fieldName == 'external_identifier') {
2016 $form->add('text', $name, $title, $attributes, $required);
2017 $contID = $contactId;
2019 $contID = $form->get('id');
2021 $form->addRule($name,
2022 ts('External ID already exists in Database.'),
2024 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2027 elseif ($fieldName === 'group') {
2028 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2029 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2034 elseif ($fieldName === 'tag') {
2035 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2036 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2041 elseif (substr($fieldName, 0, 4) === 'url-') {
2042 $form->add('text', $name, $title,
2043 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2045 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2046 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2051 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2053 // Note should be rendered as textarea
2054 elseif (substr($fieldName, -4) == 'note') {
2055 $form->add('textarea', $name, $title, $attributes, $required);
2057 elseif (substr($fieldName, 0, 6) === 'custom') {
2058 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2059 if ($customFieldID) {
2060 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2063 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2064 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2065 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2066 if ($customFieldID) {
2067 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2070 elseif (in_array($fieldName, array(
2071 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2072 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2074 elseif ($fieldName == 'send_receipt') {
2075 $form->addElement('checkbox', $name, $title);
2077 elseif ($fieldName == 'soft_credit') {
2078 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2079 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2081 elseif ($fieldName == 'product_name') {
2082 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2083 $sel = &$form->addElement('hierselect', $name, $title);
2085 '0' => ts('- select -')) +
$products;
2086 $sel->setOptions(array($products, $options));
2088 elseif ($fieldName == 'payment_instrument') {
2089 $form->add('select', $name, $title,
2090 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant
::paymentInstrument( ), $required );
2092 else if ($fieldName == 'financial_type' ) {
2093 $form->add('select', $name, $title,
2095 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(), $required
2098 elseif ($fieldName == 'contribution_status_id') {
2099 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2100 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2106 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2109 $form->add('select', $name, $title,
2111 '' => ts('- select -')) +
$contributionStatuses, $required
2114 elseif ($fieldName == 'soft_credit_type') {
2115 $form->add('select', $name, $title,
2117 '' => ts('- select -')) + CRM_Core_OptionGroup
::values("soft_credit_type")
2119 $form->addElement('hidden', 'sct_default_id',
2120 CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type"),
2121 array('id' => 'sct_default_id')
2124 elseif ($fieldName == 'currency') {
2125 $form->addCurrency($name, $title, $required);
2127 elseif ($fieldName == 'contribution_page_id') {
2128 $form->add('select', $name, $title,
2130 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2133 elseif ($fieldName == 'participant_register_date') {
2134 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2136 elseif ($fieldName == 'activity_status_id') {
2137 $form->add('select', $name, $title,
2139 '' => ts('- select -')) + CRM_Core_PseudoConstant
::activityStatus(), $required
2142 elseif ($fieldName == 'activity_engagement_level') {
2143 $form->add('select', $name, $title,
2145 '' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2148 elseif ($fieldName == 'activity_date_time') {
2149 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2151 elseif ($fieldName == 'participant_status') {
2153 if ($online == TRUE) {
2154 $cond = 'visibility_id = 1';
2156 $form->add('select', $name, $title,
2158 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2161 elseif ($fieldName == 'participant_role') {
2162 if (!empty($field['is_multiple'])) {
2163 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2166 $form->add('select', $name, $title,
2168 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantRole(), $required
2172 elseif ($fieldName == 'world_region') {
2173 $form->add('select', $name, $title,
2175 '' => ts('- select -')) + CRM_Core_PseudoConstant
::worldRegion(), $required
2178 elseif ($fieldName == 'signature_html') {
2179 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2181 elseif ($fieldName == 'signature_text') {
2182 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2184 elseif (substr($fieldName, -11) == 'campaign_id') {
2185 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2186 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2187 $form->_componentCampaigns
2189 $form->add('select', $name, $title,
2191 '' => ts('- select -')) +
$campaigns, $required, 'class="big"'
2195 elseif ($fieldName == 'activity_details') {
2196 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2198 elseif ($fieldName == 'activity_duration') {
2199 $form->add('text', $name, $title, $attributes, $required);
2200 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2203 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2204 $form->add('advcheckbox', $name, $title, $attributes, $required);
2207 $form->add('text', $name, $title, $attributes, $required);
2211 static $hiddenSubtype = FALSE;
2212 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2213 // In registration mode params are submitted via POST and we don't have any clue
2214 // about profile-id or the profile-type (which could be a subtype)
2215 // To generalize the behavior and simplify the process,
2216 // lets always add the hidden
2217 //subtype value if there is any, and we won't have to
2218 // compute it while processing.
2220 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2223 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2225 $hiddenSubtype = TRUE;
2228 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2229 $form->freeze($name);
2233 if (in_array($fieldName, array(
2234 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2235 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2237 $stateCountryMap = array();
2238 if (!empty($form->_stateCountryMap
['state_province']) && !empty($form->_stateCountryMap
['country'])) {
2239 foreach ($form->_stateCountryMap
['state_province'] as $key => $value) {
2240 $stateCountryMap[$key]['state_province'] = $value;
2241 $stateCountryMap[$key]['country'] = $form->_stateCountryMap
['country'][$key];
2243 CRM_Core_BAO_Address
::addStateCountryMap($stateCountryMap);
2246 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2247 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2253 * Function to set profile defaults
2255 * @params int $contactId contact id
2256 * @params array $fields associative array of fields
2257 * @params array $defaults defaults array
2258 * @params boolean $singleProfile true for single profile else false(batch update)
2259 * @params int $componentId id for specific components like contribute, event etc
2264 * @param bool $singleProfile
2265 * @param null $componentId
2266 * @param null $component
2272 static function setProfileDefaults($contactId, &$fields, &$defaults,
2273 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2275 if (!$componentId) {
2276 //get the contact details
2277 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2278 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2279 $multipleFields = array('website' => 'url');
2281 //start of code to set the default values
2282 foreach ($fields as $name => $field) {
2283 // skip pseudo fields
2284 if (substr($name, 0, 9) == 'phone_ext') {
2288 //set the field name depending upon the profile mode(single/batch)
2289 if ($singleProfile) {
2293 $fldName = "field[$contactId][$name]";
2296 if ($name == 'group') {
2297 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2299 if ($name == 'tag') {
2300 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2303 if (!empty($details[$name]) ||
isset($details[$name])) {
2304 //to handle custom data (checkbox) to be written
2305 // to handle birth/deceased date, greeting_type and few other fields
2306 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2307 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2309 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2310 $defaults[$fldName] = $details[$name . '_id'];
2311 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2313 elseif ($name == 'preferred_communication_method') {
2314 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2315 foreach ($v as $item) {
2317 $defaults[$fldName . "[$item]"] = 1;
2321 elseif ($name == 'world_region') {
2322 $defaults[$fldName] = $details['worldregion_id'];
2324 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2325 //fix for custom fields
2326 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2328 // hack to add custom data for components
2329 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2330 foreach ($components as $value) {
2331 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2332 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2336 switch ($customFields[$customFieldId]['html_type']) {
2337 case 'Multi-Select State/Province':
2338 case 'Multi-Select Country':
2339 case 'AdvMulti-Select':
2340 case 'Multi-Select':
2341 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2342 foreach ($v as $item) {
2344 $defaults[$fldName][$item] = $item;
2350 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2351 foreach ($v as $item) {
2353 $defaults[$fldName][$item] = 1;
2354 // seems like we need this for QF style checkboxes in profile where its multiindexed
2356 $defaults["{$fldName}[{$item}]"] = 1;
2362 // CRM-6681, set defult values according to date and time format (if any).
2364 if (!empty($customFields[$customFieldId]['date_format'])) {
2365 $dateFormat = $customFields[$customFieldId]['date_format'];
2368 if (empty($customFields[$customFieldId]['time_format'])) {
2369 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2374 $timeElement = $fldName . '_time';
2375 if (substr($fldName, -1) == ']') {
2376 $timeElement = substr($fldName, 0, -1) . '_time]';
2378 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2379 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2384 $defaults[$fldName] = $details[$name];
2389 $defaults[$fldName] = $details[$name];
2393 $blocks = array('email', 'phone', 'im', 'openid');
2394 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2395 if (!in_array($fieldName, $multipleFields)) {
2396 if (is_array($details)) {
2397 foreach ($details as $key => $value) {
2398 // when we fixed CRM-5319 - get primary loc
2399 // type as per loc field and removed below code.
2400 $primaryLocationType = FALSE;
2401 if ($locTypeId == 'Primary') {
2402 if (is_array($value) && array_key_exists($fieldName, $value)){
2403 $primaryLocationType = TRUE;
2404 if (in_array($fieldName, $blocks)){
2405 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2408 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2413 // fixed for CRM-665
2414 if (is_numeric($locTypeId)) {
2415 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2416 if (!empty($value[$fieldName])) {
2417 //to handle stateprovince and country
2418 if ($fieldName == 'state_province') {
2419 $defaults[$fldName] = $value['state_province_id'];
2421 elseif ($fieldName == 'county') {
2422 $defaults[$fldName] = $value['county_id'];
2424 elseif ($fieldName == 'country') {
2425 if (!isset($value['country_id']) ||
!$value['country_id']) {
2426 $config = CRM_Core_Config
::singleton();
2427 if ($config->defaultContactCountry
) {
2428 $defaults[$fldName] = $config->defaultContactCountry
;
2432 $defaults[$fldName] = $value['country_id'];
2435 elseif ($fieldName == 'phone') {
2437 if (isset($value['phone'][$phoneTypeId])) {
2438 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2440 if (isset($value['phone_ext'][$phoneTypeId])) {
2441 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2445 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2447 if (!is_array($phoneDefault)) {
2448 $defaults[$fldName] = $phoneDefault;
2452 elseif ($fieldName == 'email') {
2453 //adding the first email (currently we don't support multiple emails of same location type)
2454 $defaults[$fldName] = $value['email'];
2456 elseif ($fieldName == 'im') {
2457 //adding the first im (currently we don't support multiple ims of same location type)
2458 $defaults[$fldName] = $value['im'];
2459 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2462 $defaults[$fldName] = $value[$fieldName];
2465 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2466 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2468 $defaults[$fldName] = $value[substr($fieldName, 8)];
2476 if (is_array($details)) {
2477 if ($fieldName === 'url'
2478 && !empty($details['website'])
2479 && !empty($details['website'][$locTypeId])) {
2480 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2488 //Handling Contribution Part of the batch profile
2489 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2490 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2493 //Handling Event Participation Part of the batch profile
2494 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2495 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2498 //Handling membership Part of the batch profile
2499 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2500 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2503 //Handling Activity Part of the batch profile
2504 if ($component == 'Activity') {
2505 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2510 * Function to get profiles by type eg: pure Individual etc
2512 * @param array $types associative array of types eg: types('Individual')
2513 * @param boolean $onlyPure true if only pure profiles are required
2515 * @return array $profiles associative array of profiles
2519 static function getProfiles($types, $onlyPure = FALSE) {
2520 $profiles = array();
2521 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2523 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2525 // Exclude Batch Data Entry profiles - CRM-10901
2526 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2528 foreach ($ufGroups as $id => $title) {
2529 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2530 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2531 $profiles[$id] = $title;
2538 * Function to check whether a profile is valid combination of
2539 * required and/or optional profile types
2541 * @param array $required array of types those are required
2542 * @param array $optional array of types those are optional
2544 * @return array $profiles associative array of profiles
2548 static function getValidProfiles($required, $optional = NULL) {
2549 if (!is_array($required) ||
empty($required)) {
2553 $profiles = array();
2554 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2556 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2558 foreach ($ufGroups as $id => $title) {
2559 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2561 $profiles[$id] = $title;
2569 * Function to check whether a profile is valid combination of
2570 * required profile fields
2572 * @param array $ufId integer id of the profile
2573 * @param array $required array of fields those are required in the profile
2575 * @return array $profiles associative array of profiles
2579 static function checkValidProfile($ufId, $required = NULL) {
2580 $validProfile = FALSE;
2582 return $validProfile;
2585 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2586 return $validProfile;
2589 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2590 NULL, FALSE, NULL, FALSE, NULL,
2591 CRM_Core_Permission
::CREATE
, NULL
2594 $validProfile = array();
2595 if (!empty($profileFields)) {
2596 $fields = array_keys($profileFields);
2597 foreach ($fields as $val) {
2598 foreach ($required as $key => $field) {
2599 if (strpos($val, $field) === 0) {
2600 unset($required[$key]);
2605 $validProfile = (empty($required)) ?
TRUE : FALSE;
2608 return $validProfile;
2612 * Function to get default value for Register.
2617 * @return mixed $defaults@static
2620 static function setRegisterDefaults(&$fields, &$defaults) {
2621 $config = CRM_Core_Config
::singleton();
2622 foreach ($fields as $name => $field) {
2623 if (substr($name, 0, 8) == 'country-') {
2624 if (!empty($config->defaultContactCountry
)) {
2625 $defaults[$name] = $config->defaultContactCountry
;
2628 elseif (substr($name, 0, 15) == 'state_province-') {
2629 if (!empty($config->defaultContactStateProvince
)) {
2630 $defaults[$name] = $config->defaultContactStateProvince
;
2638 * This function is to make a copy of a profile, including
2639 * all the fields in the profile
2641 * @param int $id the profile id to copy
2646 static function copy($id) {
2647 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2648 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2654 if ($pos = strrpos($copy->name
, "_{$id}")) {
2655 $copy->name
= substr_replace($copy->name
, '', $pos);
2657 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2660 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2661 array('uf_group_id' => $id),
2662 array('uf_group_id' => $copy->id
),
2667 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2668 array('uf_group_id' => $id),
2669 array('uf_group_id' => $copy->id
)
2672 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2676 UPDATE civicrm_uf_join
2678 WHERE uf_group_id = %2
2679 AND ( entity_id IS NULL OR entity_id <= 0 )
2681 $p = array(1 => array($maxWeight +
1, 'Integer'),
2682 2 => array($copy->id
, 'Integer'),
2684 CRM_Core_DAO
::executeQuery($query, $p);
2685 if ($copy->is_reserved
) {
2686 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2687 $params = array(1 => array($copy->id
, 'Integer'));
2688 CRM_Core_DAO
::executeQuery($query, $params);
2690 CRM_Utils_Hook
::copy('UFGroup', $copy);
2696 * Process that send notification e-mails
2698 * @params int $contactId contact id
2699 * @params array $values associative array of name/value pair
2708 static function commonSendMail($contactID, &$values) {
2709 if (!$contactID ||
!$values) {
2713 $template = CRM_Core_Smarty
::singleton();
2715 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2720 self
::profileDisplay($values['id'], $values['values'], $template);
2721 $emailList = explode(',', $values['email']);
2723 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2724 "reset=1&cid=$contactID",
2725 TRUE, NULL, FALSE, FALSE, TRUE
2728 //get the default domain email address.
2729 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2731 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2732 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2733 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)));
2736 foreach ($emailList as $emailTo) {
2737 // FIXME: take the below out of the foreach loop
2738 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2740 'groupName' => 'msg_tpl_workflow_uf',
2741 'valueName' => 'uf_notify',
2742 'contactId' => $contactID,
2743 'tplParams' => array(
2744 'displayName' => $displayName,
2745 'currentDate' => date('r'),
2746 'contactLink' => $contactLink,
2748 'from' => "$domainEmailName <$domainEmailAddress>",
2749 'toEmail' => $emailTo,
2756 * Given a contact id and a group id, returns the field values from the db
2757 * for this group and notify email only if group's notify field is
2758 * set and field values are not empty
2760 * @params $gid group id
2761 * @params $cid contact id
2762 * @params $params associative array
2767 * @param bool $skipCheck
2772 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2774 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2776 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2777 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2779 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2781 if (!empty($values) &&
2786 'values' => $values,
2797 * Function to assign uf fields to template
2799 * @params int $gid group id
2800 * @params array $values associative array of fields
2809 function profileDisplay($gid, $values, $template) {
2810 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2811 $template->assign('grouptitle', $groupTitle);
2812 if (count($values)) {
2813 $template->assign('values', $values);
2818 * Format fields for dupe Contact Matching
2820 * @param array $params associated array
2822 * @param null $contactId
2824 * @return array $data assoicated formatted array
2828 static function formatFields($params, $contactId = NULL) {
2830 // get the primary location type id and email
2831 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2834 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2835 $primaryLocationType = $defaultLocationType->id
;
2839 $locationType = array();
2841 $primaryLocation = 0;
2842 foreach ($params as $key => $value) {
2843 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2845 if ($locTypeId == 'Primary') {
2846 $locTypeId = $primaryLocationType;
2849 if (is_numeric($locTypeId)) {
2850 if (!in_array($locTypeId, $locationType)) {
2851 $locationType[$count] = $locTypeId;
2854 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2856 $data['location'][$loc]['location_type_id'] = $locTypeId;
2858 // if we are getting in a new primary email, dont overwrite the new one
2859 if ($locTypeId == $primaryLocationType) {
2860 if (!empty($params['email-' . $primaryLocationType])) {
2861 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2863 elseif (isset($primaryEmail)) {
2864 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2870 $data['location'][$loc]['is_primary'] = 1;
2872 if ($fieldName == 'phone') {
2874 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2877 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2879 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2881 elseif ($fieldName == 'email') {
2882 $data['location'][$loc]['email'][$loc]['email'] = $value;
2884 elseif ($fieldName == 'im') {
2885 $data['location'][$loc]['im'][$loc]['name'] = $value;
2888 if ($fieldName === 'state_province') {
2889 $data['location'][$loc]['address']['state_province_id'] = $value;
2891 elseif ($fieldName === 'country') {
2892 $data['location'][$loc]['address']['country_id'] = $value;
2895 $data['location'][$loc]['address'][$fieldName] = $value;
2900 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2901 if ($key === 'individual_suffix') {
2902 $data['suffix_id'] = $value;
2904 elseif ($key === 'individual_prefix') {
2905 $data['prefix_id'] = $value;
2907 elseif ($key === 'gender') {
2908 $data['gender_id'] = $value;
2910 elseif (substr($key, 0, 6) === 'custom') {
2911 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2913 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2914 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2916 // fix the date field
2917 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2918 $date = CRM_Utils_Date
::format($value);
2925 $data['custom'][$customFieldID] = array(
2928 'extends' => $customFields[$customFieldID]['extends'],
2929 'type' => $customFields[$customFieldID]['data_type'],
2930 'custom_field_id' => $customFieldID,
2934 elseif ($key == 'edit') {
2938 $data[$key] = $value;
2943 if (!$primaryLocation) {
2945 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2953 * calculate the profile type 'group_type' as per profile fields.
2956 * @param bool $includeTypeValues
2957 * @param int $ignoreFieldId ignore particular profile field
2959 * @internal param int $gid profile id
2960 * @return array list of calculated group type
2962 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2963 //get the profile fields.
2964 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2965 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2969 * calculate the profile type 'group_type' as per profile fields.
2972 * @param bool $includeTypeValues
2973 * @param int $ignoreFieldId ignore perticular profile field
2975 * @internal param int $gid profile id
2976 * @return array list of calculated group type
2978 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2979 $groupType = $groupTypeValues = $customFieldIds = array();
2980 if (!empty($ufFields)) {
2981 foreach ($ufFields as $fieldName => $fieldValue) {
2982 //ignore field from group type when provided.
2983 //in case of update profile field.
2984 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2987 if (!in_array($fieldValue['field_type'], $groupType)) {
2988 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2991 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
2992 $customFieldIds[$fldId] = $fldId;
2997 if (!empty($customFieldIds)) {
2998 $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) . ')';
3000 $customGroups = CRM_Core_DAO
::executeQuery($query);
3001 while ($customGroups->fetch()) {
3002 if (!$customGroups->extends_entity_column_value
) {
3006 $groupTypeName = "{$customGroups->extends}Type";
3007 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3008 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3011 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3013 $groupTypeValues[$groupTypeName][$val] = $val;
3018 if (!empty($groupTypeValues)) {
3019 $groupType = array_merge($groupType, $groupTypeValues);
3027 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3028 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3031 * BirthDate + Email Individual,Contact
3032 * BirthDate + Subject Individual,Activity
3033 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3034 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3035 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3036 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3037 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3038 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3039 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3042 * @param Array $groupTypes With key having group type names
3044 * @internal param int $gid profile id
3047 static function updateGroupTypes($gId, $groupTypes = array(
3049 if (!is_array($groupTypes) ||
!$gId) {
3053 // If empty group types set group_type as 'null'
3054 if (empty($groupTypes)) {
3055 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3058 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3059 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3061 $gTypes = $gTypeValues = array();
3063 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3064 // Get valid group type and group subtypes
3065 foreach ($groupTypes as $groupType => $value) {
3066 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3067 $gTypes[] = $groupType;
3072 if (in_array($groupType, $participantExtends)) {
3073 $subTypesOf = $groupType;
3075 elseif (strpos($groupType, 'Type') > 0) {
3076 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3082 if (!empty($value) &&
3083 (in_array($subTypesOf, $componentGroupTypes) ||
3084 in_array($subTypesOf, $participantExtends)
3087 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3091 if (empty($gTypes)) {
3095 // Build String to store group types and group subtypes
3096 $groupTypeString = implode(',', $gTypes);
3097 if (!empty($gTypeValues)) {
3098 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3101 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3105 * Create a "group_type" string
3107 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3108 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3109 * @param string $delim
3112 * @throws CRM_Core_Exception
3114 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3115 $groupTypeExpr = '';
3117 $groupTypeExpr .= implode(',', $coreTypes);
3120 if (count($subTypes) > 1) {
3121 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3123 foreach ($subTypes as $subType => $subTypeIds) {
3124 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3127 return $groupTypeExpr;
3131 * This function is used to setDefault componet specific profile fields.
3133 * @param array $fields profile fields.
3134 * @param int $componentId componetID
3135 * @param string $component component name
3136 * @param array $defaults an array of default values.
3138 * @param bool $isStandalone
3142 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3143 if (!$componentId ||
3144 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3149 $componentBAO = $componentSubType = NULL;
3150 switch ($component) {
3152 $componentBAO = 'CRM_Member_BAO_Membership';
3153 $componentBAOName = 'Membership';
3154 $componentSubType = array('membership_type_id');
3158 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3159 $componentBAOName = 'Contribution';
3160 $componentSubType = array( 'financial_type_id' );
3164 $componentBAO = 'CRM_Event_BAO_Participant';
3165 $componentBAOName = 'Participant';
3166 $componentSubType = array('role_id', 'event_id');
3170 $componentBAO = 'CRM_Activity_BAO_Activity';
3171 $componentBAOName = 'Activity';
3172 $componentSubType = array('activity_type_id');
3177 $params = array('id' => $componentId);
3179 //get the component values.
3180 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3182 $formattedGroupTree = array();
3183 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3184 foreach ($fields as $name => $field) {
3185 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3186 if (in_array($name, $dateTimeFields)) {
3187 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3188 if (!empty($values[$name])) {
3189 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3192 elseif (array_key_exists($name, $values)) {
3193 $defaults[$fldName] = $values[$name];
3195 elseif ($name == 'participant_note') {
3196 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3197 $defaults[$fldName] = array_pop($noteDetails);
3199 elseif (in_array($name, array(
3200 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3201 $defaults[$fldName] = $values["{$name}_id"];
3203 elseif ($name == 'membership_type') {
3204 // since membership_type field is a hierselect -
3205 $defaults[$fldName][0] =
3206 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3207 $defaults[$fldName][1] = $values['membership_type_id'];
3209 elseif ($name == 'membership_status') {
3210 $defaults[$fldName] = $values['status_id'];
3212 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3213 if (empty($formattedGroupTree)) {
3214 //get the groupTree as per subTypes.
3215 $groupTree = array();
3216 foreach ($componentSubType as $subType) {
3217 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3218 $componentId, 0, $values[$subType]
3220 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3222 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3223 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3226 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3227 foreach ($defaults as $customKey => $customValue) {
3228 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3229 if ($name == 'custom_' . $customFieldDetails[0]) {
3231 //hack to set default for checkbox
3232 //basically this is for weired field name like field[33][custom_19]
3233 //we are converting this field name to array structure and assign value.
3236 foreach ($formattedGroupTree as $tree) {
3237 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3239 $defaults['field'][$componentId][$name] = $customValue;
3242 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3245 // CRM-6681, $default contains formatted date, time values.
3246 $defaults[$fldName] = $customValue;
3247 if (!empty($defaults[$customKey . '_time'])) {
3248 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3253 if (!$skipValue ||
$isStandalone) {
3254 $defaults[$fldName] = $customValue;
3256 unset($defaults[$customKey]);
3266 * @param array|string $profiles - name of profile(s) to create links for
3267 * @param array $appendProfiles - name of profile(s) to append to each link
3271 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3272 // Default to contact profiles
3274 $profiles = array('new_individual', 'new_organization', 'new_household');
3276 $profiles = (array) $profiles;
3277 $toGet = array_merge($profiles, (array) $appendProfiles);
3278 $retrieved = civicrm_api3('uf_group', 'get', array(
3279 'name' => array('IN' => $toGet),
3282 $links = $append = array();
3283 if (!empty($retrieved['values'])) {
3284 foreach($retrieved['values'] as $id => $profile) {
3285 if (in_array($profile['name'], $profiles)) {
3287 'label' => $profile['title'],
3288 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3289 NULL, NULL, FALSE, NULL, FALSE) ,
3290 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3297 foreach ($append as $id) {
3298 foreach ($links as &$link) {
3299 $link['url'] .= ",$id";
3307 * Function to retrieve groups of profiles
3309 * @param integer $profileID id of the profile
3311 * @return array returns array
3314 static function profileGroups($profileID) {
3315 $groupTypes = array();
3316 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3317 if ($profileTypes) {
3318 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3319 $groupTypes = explode(',', $groupTypeParts[0]);
3325 * Function to alter contact params by filtering existing subscribed groups and returns
3326 * unsubscribed groups array for subscription.
3328 * @param array $params contact params
3329 * @param int $contactId user contact id
3331 * @return array $subscribeGroupIds This contains array of groups for subscription
3333 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3334 $config = CRM_Core_Config
::singleton();
3335 $subscribeGroupIds = array();
3337 // process further only if profileDoubleOptIn enabled and if groups exist
3338 if (!array_key_exists('group', $params) ||
3339 !self
::isProfileDoubleOptin() ||
3340 CRM_Utils_System
::isNull($params['group'])
3342 return $subscribeGroupIds;
3345 //check if contact email exist.
3347 foreach ($params as $name => $value) {
3348 if (strpos($name, 'email-') !== FALSE) {
3354 //Proceed furthur only if email present
3356 return $subscribeGroupIds;
3359 //do check for already subscriptions.
3360 $contactGroups = array();
3364 FROM civicrm_group_contact
3365 WHERE status = 'Added'
3366 AND contact_id = %1";
3368 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3369 while ($dao->fetch()) {
3370 $contactGroups[$dao->group_id
] = $dao->group_id
;
3374 //since we don't have names, compare w/ label.
3375 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3377 //actual processing start.
3378 foreach ($params['group'] as $groupId => $isSelected) {
3379 //unset group those are not selected.
3381 unset($params['group'][$groupId]);
3385 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3386 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3388 //get only mailing type group and unset it from params
3389 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3390 $subscribeGroupIds[$groupId] = $groupId;
3391 unset($params['group'][$groupId]);
3395 return $subscribeGroupIds;
3399 * Function to check if we are rendering mixed profiles
3401 * @param array $profileIds associated array of profile ids
3403 * @return boolean $mixProfile true if profile is mixed
3407 static function checkForMixProfiles($profileIds) {
3408 $mixProfile = FALSE;
3410 $contactTypes = array('Individual', 'Household', 'Organization');
3411 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3413 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3415 $typeCount = array('ctype' => array(), 'subtype' => array());
3416 foreach ($profileIds as $gid) {
3417 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3418 // ignore profile of type Contact
3419 if ($profileType == 'Contact') {
3422 if (in_array($profileType, $contactTypes)) {
3423 if (!isset($typeCount['ctype'][$profileType])) {
3424 $typeCount['ctype'][$profileType] = 1;
3427 // check if we are rendering profile of different contact types
3428 if (count($typeCount['ctype']) == 2) {
3433 elseif (in_array($profileType, $components)) {
3438 if (!isset($typeCount['subtype'][$profileType])) {
3439 $typeCount['subtype'][$profileType] = 1;
3441 // check if we are rendering profile of different contact sub types
3442 if (count($typeCount['subtype']) == 2) {
3452 * Function to determine of we show overlay profile or not
3454 * @return boolean true if profile should be shown else false
3458 static function showOverlayProfile() {
3459 $showOverlay = TRUE;
3461 // get the id of overlay profile
3462 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3463 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3465 $count = CRM_Core_DAO
::singleValueQuery($query);
3467 //check if there are no public fields and use is anonymous
3468 $session = CRM_Core_Session
::singleton();
3469 if (!$count && !$session->get('userID')) {
3470 $showOverlay = FALSE;
3473 return $showOverlay;
3477 * function to get group type values of the profile
3479 * @params Integer $profileId Profile Id
3480 * @params String $groupType Group Type
3483 * @param null $groupType
3485 * @return Array group type values
3489 static function groupTypeValues($profileId, $groupType = NULL) {
3490 $groupTypeValue = array();
3491 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3493 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3494 if (empty($groupTypeParts[1])) {
3495 return $groupTypeValue;
3497 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3499 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3501 $valueParts = explode(':', $groupTypeValues);
3503 ($valueParts[0] != "{$groupType}Type" ||
3504 ($groupType == 'Participant' &&
3505 !in_array($valueParts[0], $participantExtends)
3511 foreach ($valueParts as $val) {
3512 if (CRM_Utils_Rule
::integer($val)) {
3513 $values[$val] = $val;
3516 if (!empty($values)) {
3517 $typeName = substr($valueParts[0], 0, -4);
3518 if (in_array($valueParts[0], $participantExtends)) {
3519 $typeName = $valueParts[0];
3521 $groupTypeValue[$typeName] = $values;
3525 return $groupTypeValue;
3529 * @return bool|object
3531 static function isProfileDoubleOptin() {
3532 // check for double optin
3533 $config = CRM_Core_Config
::singleton();
3534 if (in_array('CiviMail', $config->enableComponents
)) {
3535 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3536 'profile_double_optin', NULL, FALSE
3543 * @return bool|object
3545 static function isProfileAddToGroupDoubleOptin() {
3546 // check for add to group double optin
3547 $config = CRM_Core_Config
::singleton();
3548 if (in_array('CiviMail', $config->enableComponents
)) {
3549 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3550 'profile_add_to_group_double_optin', NULL, FALSE
3557 * get profiles used for batch entry
3559 * @return array profileIds profile ids
3562 static function getBatchProfiles() {
3564 FROM civicrm_uf_group
3565 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3566 $dao = CRM_Core_DAO
::executeQuery( $query );
3567 $profileIds = array();
3568 while( $dao->fetch() ) {
3569 $profileIds[$dao->id
] = $dao->id
;
3575 * @todo what do I do?
3577 * @param $destination
3578 * @param bool $returnMultiSummaryFields
3580 * @return array|null
3582 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3583 $multiSummaryFields = $returnMultiSummaryFields ?
array( ) : NULL;
3584 foreach ($source as $field => $properties) {
3585 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3588 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3589 $destination[$field] = $properties;
3590 if ($returnMultiSummaryFields) {
3591 if ($properties['is_multi_summary']) {
3592 $multiSummaryFields[$field] = $properties;
3595 unset($source[$field]);
3598 return $multiSummaryFields;
3602 * This is function is used to format pseudo fields
3604 * @param array $fields associated array of profile fields
3608 static function reformatProfileFields(&$fields) {
3609 //reformat fields array
3610 foreach ($fields as $name => $field) {
3611 //reformat phone and extension field
3612 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3613 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3615 // retain existing element properties and just update and replace key
3616 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3617 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3618 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3620 // add additional phone extension field
3621 $fields["phone_ext-{$fieldSuffix}"] = $field;
3622 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3623 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3624 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3625 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3626 //ignore required for extension field
3627 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;