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
134 * @return array the fields that are needed for registration
138 static function getRegistrationFields($action, $mode, $ctype = NULL) {
139 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
140 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
143 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
146 if (!is_array($ufGroups)) {
152 foreach ($ufGroups as $id => $title) {
154 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
155 if (($fieldType != 'Contact') &&
156 ($fieldType != $ctype) &&
157 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
161 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
162 $profileSubType = $fieldType;
166 $subset = self
::getFields($id, TRUE, $action,
167 NULL, NULL, FALSE, NULL, TRUE, $ctype
170 // we do not allow duplicates. the first field is the winner
171 foreach ($subset as $name => $field) {
172 if (empty($fields[$name])) {
173 $fields[$name] = $field;
182 * get all the listing fields
184 * @param int $action what action are we doing
185 * @param int $visibility visibility of fields we are interested in
186 * @param bool $considerSelector whether to consider the in_selector parameter
187 * @param array $ufGroupIds
188 * @param boolean $searchable
190 * @return array the fields that are listings related
194 static function getListingFields(
197 $considerSelector = FALSE,
201 $skipPermission = FALSE,
202 $permissionType = CRM_Core_Permission
::SEARCH
205 $subset = self
::getFields($ufGroupIds, FALSE, $action,
206 $visibility, $searchable,
212 if ($considerSelector) {
213 // drop the fields not meant for the selector
214 foreach ($subset as $name => $field) {
215 if (!$field['in_selector']) {
216 unset($subset[$name]);
223 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
226 foreach ($ufGroups as $id => $title) {
227 $subset = self
::getFields($id, FALSE, $action,
228 $visibility, $searchable,
234 if ($considerSelector) {
235 // drop the fields not meant for the selector
236 foreach ($subset as $name => $field) {
237 if (!$field['in_selector'])unset($subset[$name]);
240 $fields = array_merge($fields, $subset);
247 * Get all the fields that belong to the group with the name title,
248 * and format for use with buildProfile. This is the SQL analog of
251 * @param mix $id the id of the UF group or ids of ufgroup
252 * @param int $register are we interested in registration fields
253 * @param int $action what action are we doing
254 * @param int $visibility visibility of fields we are interested in
256 * @param boolean $showall
257 * @param string $restrict should we restrict based on a specified profile type
259 * @return array the fields that belong to this ufgroup(s)
263 static function getFields(
271 $skipPermission = FALSE,
273 $permissionType = CRM_Core_Permission
::CREATE
,
274 $orderBy = 'field_name',
275 $orderProfiles = NULL
277 if (!is_array($id)) {
278 $id = CRM_Utils_Type
::escape($id, 'Positive');
279 $profileIds = array($id);
285 $gids = implode(',', $profileIds);
288 $query = "SELECT g.* from civicrm_uf_group g, civicrm_uf_join j
289 WHERE g.id IN ( {$gids} )
290 AND j.uf_group_id IN ( {$gids} )
293 $params = array(1 => array($restrict, 'String'));
296 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
300 $query .= " AND g.is_active = 1";
303 // add permissioning for profiles only if not registration
304 if (!$skipPermission) {
305 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
306 $query .= " AND $permissionClause ";
309 if ($orderProfiles AND count($profileIds) > 1) {
310 $query .= " ORDER BY FIELD( g.id, {$gids} )";
312 $group = CRM_Core_DAO
::executeQuery($query, $params);
316 while ($group->fetch()) {
318 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
319 $field = CRM_Core_DAO
::executeQuery($query);
321 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
322 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
323 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
324 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
326 while ($field->fetch()) {
327 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
328 if ($formattedField !== NULL) {
329 $fields[$name] = $formattedField;
335 if (empty($fields) && !$validGroup) {
336 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.',
337 array(1 => implode(',', $profileIds))
341 self
::reformatProfileFields($fields);
348 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
351 * @param array $groupArr (mimic CRM_UF_DAO_UFGroup)
352 * @param array $fieldArrs list of fields (each mimics CRM_UF_DAO_UFField)
353 * @param bool $visibility visibility of fields we are interested in
354 * @param bool $searchable
355 * @param bool $showAll
357 * @param int $permissionType
359 * @internal param bool $showall
363 public static function formatUFFields(
370 $permissionType = CRM_Core_Permission
::CREATE
372 // $group = new CRM_Core_DAO_UFGroup();
373 // $group->copyValues($groupArr); // no... converts string('') to string('null')
374 $group = (object) $groupArr;
376 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
377 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
378 // they did -- the obvious fix would produce mutual recursion.
379 $ufGroupType = self
::_calculateGroupType($fieldArrs);
380 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',',$ufGroupType));
381 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',',$ufGroupType));
382 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
383 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
385 $formattedFields = array();
386 foreach ($fieldArrs as $fieldArr) {
387 $field = (object) $fieldArr;
388 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
392 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
393 if ($formattedField !== NULL) {
394 $formattedFields[$name] = $formattedField;
397 return $formattedFields;
401 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
403 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
404 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
405 * @param array $addressCustomFields
406 * @param array $importableFields
407 * @param array $customFields
408 * @param int $permissionType eg CRM_Core_Permission::CREATE
411 protected static function formatUFField(
415 $addressCustomFields,
417 $permissionType = CRM_Core_Permission
::CREATE
419 $name = $field->field_name
;
420 $title = $field->label
;
422 $addressCustom = FALSE;
423 if (in_array($permissionType, array(
424 CRM_Core_Permission
::CREATE
,
425 CRM_Core_Permission
::EDIT
,
427 in_array($field->field_name
, array_keys($addressCustomFields))
429 $addressCustom = TRUE;
430 $name = "address_{$name}";
432 if ($field->field_name
== 'url') {
433 $name .= "-{$field->website_type_id}";
435 elseif (!empty($field->location_type_id
)) {
436 $name .= "-{$field->location_type_id}";
439 $locationFields = self
::getLocationFields();
440 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
445 if (isset($field->phone_type_id
)) {
446 $name .= "-{$field->phone_type_id}";
449 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
450 // I guess to make field self sufficient with all the required data and avoid additional calls
451 $formattedField = array(
453 'groupTitle' => $group->title
,
454 'groupName' => $group->name
,
455 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
456 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
458 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
459 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
460 'is_required' => $field->is_required
,
461 'is_view' => $field->is_view
,
462 'help_pre' => $field->help_pre
,
463 'help_post' => $field->help_post
,
464 'visibility' => $field->visibility
,
465 'in_selector' => $field->in_selector
,
466 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
467 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
468 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
469 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
470 'group_id' => $group->id
,
471 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
472 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
473 'field_type' => $field->field_type
,
474 'field_id' => $field->id
,
475 'pseudoconstant' => CRM_Utils_Array
::value(
477 CRM_Utils_Array
::value($field->field_name
, $importableFields)
479 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
480 'dbName' => CRM_Utils_Array
::value(
482 CRM_Utils_Array
::value($field->field_name
, $importableFields)
487 //adding custom field property
488 if (substr($field->field_name
, 0, 6) == 'custom' ||
489 substr($field->field_name
, 0, 14) === 'address_custom'
491 // if field is not present in customFields, that means the user
492 // DOES NOT HAVE permission to access that field
493 if (array_key_exists($field->field_name
, $customFields)) {
494 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
496 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
497 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
498 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
500 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
501 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
502 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
505 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
506 return array($name, $formattedField);
509 $formattedField = NULL;
510 return array($name, $formattedField);
513 return array($name, $formattedField);
517 * Create a query to find all visible UFFields in a UFGroup
519 * This is the SQL-variant of checkUFFieldDisplayable().
521 * @param int $groupId
522 * @param bool $searchable
523 * @param bool $showAll
524 * @param int $visibility
525 * @param string $orderBy comma-delimited list of SQL columns
528 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
529 $where = " WHERE uf_group_id = {$groupId}";
532 $where .= " AND is_searchable = 1";
536 $where .= " AND is_active = 1";
541 if ($visibility & self
::PUBLIC_VISIBILITY
) {
542 $clause[] = 'visibility = "Public Pages"';
544 if ($visibility & self
::ADMIN_VISIBILITY
) {
545 $clause[] = 'visibility = "User and User Admin Only"';
547 if ($visibility & self
::LISTINGS_VISIBILITY
) {
548 $clause[] = 'visibility = "Public Pages and Listings"';
550 if (!empty($clause)) {
551 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
555 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
557 $query .= ", " . $orderBy;
564 * Create a query to find all visible UFFields in a UFGroup
566 * This is the PHP in-memory variant of createUFFieldQuery().
568 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
569 * @param bool $searchable
570 * @param bool $showAll
571 * @param int $visibility
572 * @return bool TRUE if field is displayable
574 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
575 if ($searchable && $field->is_searchable
!= 1) {
579 if (!$showAll && $field->is_active
!= 1) {
584 $allowedVisibilities = array();
585 if ($visibility & self
::PUBLIC_VISIBILITY
) {
586 $allowedVisibilities[] = 'Public Pages';
588 if ($visibility & self
::ADMIN_VISIBILITY
) {
589 $allowedVisibilities[] = 'User and User Admin Only';
591 if ($visibility & self
::LISTINGS_VISIBILITY
) {
592 $allowedVisibilities[] = 'Public Pages and Listings';
594 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
595 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
603 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
605 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
608 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
611 if ($profileType == 'Activity' ||
$contactActivityProfile) {
612 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
615 $componentFields = CRM_Core_Component
::getQueryFields();
618 $importableFields = array_merge($importableFields, $componentFields);
620 $importableFields['group']['title'] = ts('Group(s)');
621 $importableFields['group']['where'] = NULL;
622 $importableFields['tag']['title'] = ts('Tag(s)');
623 $importableFields['tag']['where'] = NULL;
624 return $importableFields;
627 public static function getLocationFields() {
628 static $locationFields = array(
630 'supplemental_address_1',
631 'supplemental_address_2',
634 'postal_code_suffix',
647 return $locationFields;
650 protected static function getCustomFields($ctype) {
651 static $customFieldCache = array();
652 if (!isset($customFieldCache[$ctype])) {
653 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
655 // hack to add custom data for components
656 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
657 foreach ($components as $value) {
658 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
660 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
661 $customFields = array_merge($customFields, $addressCustomFields);
662 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
664 return $customFieldCache[$ctype];
668 * check the data validity
670 * @param int $userID the user id that we are actually editing
671 * @param string $title the title of the group we are interested in
672 * @pram boolean $register is this the registrtion form
673 * @param int $action the action of the form
675 * @return boolean true if form is valid
679 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
681 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
682 ts('Dynamic Form Creator'),
685 $controller->set('id', $userID);
686 $controller->set('register', 1);
687 $controller->process();
688 return $controller->validate();
691 // make sure we have a valid group
692 $group = new CRM_Core_DAO_UFGroup();
694 $group->title
= $title;
696 if ($group->find(TRUE) && $userID) {
697 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
698 $controller->set('gid', $group->id
);
699 $controller->set('id', $userID);
700 $controller->set('register', 0);
701 $controller->process();
702 return $controller->validate();
709 * get the html for the form that represents this particular group
711 * @param int $userID the user id that we are actually editing
712 * @param string $title the title of the group we are interested in
713 * @param int $action the action of the form
714 * @param boolean $register is this the registration form
715 * @param boolean $reset should we reset the form?
716 * @param int $profileID do we have the profile ID?
718 * @return string the html for the form on success, otherwise empty string
722 static function getEditHTML($userID,
728 $doNotProcess = FALSE,
733 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
734 ts('Dynamic Form Creator'),
737 if ($reset ||
$doNotProcess) {
738 // hack to make sure we do not process this form
739 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
742 unset($_POST['_qf_default']);
743 unset($_REQUEST['_qf_default']);
745 $controller->reset();
749 $controller->set('id', $userID);
750 $controller->set('register', 1);
751 $controller->set('skipPermission', 1);
752 $controller->set('ctype', $ctype);
753 $controller->process();
754 if ($doNotProcess ||
!empty($_POST)) {
755 $controller->validate();
757 $controller->setEmbedded(TRUE);
759 //CRM-5839 - though we want to process form, get the control back.
760 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
764 // we are done processing so restore the POST/REQUEST vars
765 if (($reset ||
$doNotProcess) && $oldQFDefault) {
766 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
769 $template = CRM_Core_Smarty
::singleton();
771 // Hide CRM error messages if they are displayed using drupal form_set_error.
772 if (!empty($_POST)) {
773 $template->assign('suppressForm', TRUE);
776 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
780 // make sure we have a valid group
781 $group = new CRM_Core_DAO_UFGroup();
783 $group->title
= $title;
785 if ($group->find(TRUE)) {
786 $profileID = $group->id
;
791 // make sure profileID and ctype match if ctype exists
793 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
794 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
795 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
798 if (($profileType != 'Contact') && ($profileType != $ctype)) {
803 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
804 ts('Dynamic Form Creator'),
808 $controller->reset();
810 $controller->set('gid', $profileID);
811 $controller->set('id', $userID);
812 $controller->set('register', 0);
813 $controller->set('skipPermission', 1);
815 $controller->set('ctype', $ctype);
817 $controller->process();
818 $controller->setEmbedded(TRUE);
820 //CRM-5846 - give the control back to drupal.
821 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
824 $template = CRM_Core_Smarty
::singleton();
826 // Hide CRM error messages if they are displayed using drupal form_set_error.
827 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
828 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
829 $template->assign('suppressForm', TRUE);
833 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
834 if (!$template->template_exists($templateFile)) {
835 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
837 return trim($template->fetch($templateFile));
840 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
842 // if post not empty then only proceed
843 if (!empty($_POST)) {
845 $config = CRM_Core_Config
::singleton();
846 $email = CRM_Utils_Array
::value('mail', $_POST);
848 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
849 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
858 * searches for a contact in the db with similar attributes
860 * @param array $params the list of values to be used in the where clause
861 * @param int $id the current contact id (hence excluded from matching)
862 * @param boolean $flatten should we flatten the input params
864 * @return contact_id if found, null otherwise
868 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
869 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
870 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
871 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
873 return implode(',', $ids);
881 * Given a contact id and a field set, return the values from the db
884 * @param int $id the contact id
885 * @param array $fields the profile fields of interest
886 * @param array $values the values for the above fields
887 * @param boolean $searchable searchable or not
888 * @param array $componentWhere component condition
889 * @param boolean $absolute return urls in absolute form (useful when sending an email)
895 public static function getValues($cid, &$fields, &$values,
896 $searchable = TRUE, $componentWhere = NULL,
897 $absolute = FALSE, $additionalWhereClause = NULL
899 if (empty($cid) && empty($componentWhere)) {
903 // get the contact details (hier)
904 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
905 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
907 // add conditions specified by components. eg partcipant_id etc
908 if (!empty($componentWhere)) {
909 $params = array_merge($params, $componentWhere);
912 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
913 $options = &$query->_options
;
915 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
916 FALSE, FALSE, FALSE, $additionalWhereClause);
917 if (!$details->fetch()) {
920 $query->convertToPseudoNames($details);
921 $config = CRM_Core_Config
::singleton();
923 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
924 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
925 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
927 $multipleFields = array('url');
928 $nullIndex = $nullValueIndex = ' ';
930 //start of code to set the default values
931 foreach ($fields as $name => $field) {
934 $name = 'contact_id';
937 // skip fields that should not be displayed separately
938 if (!empty($field['skipDisplay'])) {
942 $index = $field['title'];
943 //handle for the label not set for the field
944 if (empty($field['title'])) {
946 $nullIndex .= $nullIndex;
949 //handle the case to avoid re-write where the profile field labels are the same
950 if (array_key_exists($index, $values)) {
951 $index .= $nullValueIndex;
952 $nullValueIndex .= $nullValueIndex;
954 $params[$index] = $values[$index] = '';
955 $customFieldName = NULL;
957 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
958 // to handle gender / suffix / prefix
959 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
960 $params[$index] = $details->$name;
961 $values[$index] = $details->$name;
963 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
964 $dname = $name . '_display';
965 $values[$index] = $details->$dname;
966 $name = $name . '_id';
967 $params[$index] = $details->$name;
969 elseif (in_array($name, array(
970 'state_province', 'country', 'county'))) {
971 $values[$index] = $details->$name;
972 $idx = $name . '_id';
973 $params[$index] = $details->$idx;
975 elseif ($name === 'preferred_communication_method') {
976 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
978 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
980 foreach ($pref as $k) {
982 $compref[] = $communicationFields[$k];
985 $params[$index] = $details->$name;
986 $values[$index] = implode(',', $compref);
988 elseif ($name === 'preferred_language') {
989 $params[$index] = $details->$name;
990 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
992 elseif ($name == 'group') {
993 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
994 $title = $ids = array();
996 foreach ($groups as $g) {
997 // CRM-8362: User and User Admin visibility groups should be included in display if user has
998 // VIEW permission on that group
999 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1001 if ($g['visibility'] != 'User and User Admin Only' ||
1002 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1004 $title[] = $g['title'];
1005 if ($g['visibility'] == 'Public Pages') {
1006 $ids[] = $g['group_id'];
1010 $values[$index] = implode(', ', $title);
1011 $params[$index] = implode(',', $ids);
1013 elseif ($name == 'tag') {
1014 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1015 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1017 foreach ($entityTags as $tagId) {
1018 $title[] = $allTags[$tagId];
1020 $values[$index] = implode(', ', $title);
1021 $params[$index] = implode(',', $entityTags);
1023 elseif ($name == 'activity_status_id') {
1024 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1025 $values[$index] = $activityStatus[$details->$name];
1026 $params[$index] = $details->$name;
1028 elseif ($name == 'activity_date_time') {
1029 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1030 $params[$index] = $details->$name;
1032 elseif ($name == 'contact_sub_type') {
1033 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1034 if (!empty($contactSubTypeNames)) {
1035 $contactSubTypeLabels = array();
1036 // get all contact subtypes
1037 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1038 // build contact subtype labels array
1039 foreach( $contactSubTypeNames as $cstName ) {
1041 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1044 $values[$index] = implode(',', $contactSubTypeLabels);
1047 $params[$index] = $details->$name;
1050 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1051 if ($details->$name) {
1052 $values[$index] = '[ x ]';
1056 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1057 $htmlType = $field['html_type'];
1059 // field_type is only set when we are retrieving profile values
1060 // when sending email, we call the same function to get custom field
1061 // values etc, i.e. emulating a profile
1062 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1064 if ($htmlType == 'File') {
1067 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
1068 $entityId = $componentWhere[0][2];
1071 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1076 $params[$index] = $values[$index] = $fileURL['file_url'];
1080 if (isset($dao) && property_exists($dao, 'data_type') &&
1081 ($dao->data_type
== 'Int' ||
1082 $dao->data_type
== 'Boolean'
1085 $customVal = (int )($details->{$name});
1087 elseif (isset($dao) && property_exists($dao, 'data_type')
1088 && $dao->data_type
== 'Float'
1090 $customVal = (float )($details->{$name});
1092 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1095 $customVal = $details->{$name};
1099 if (CRM_Utils_System
::isNull($customVal)) {
1103 $params[$index] = $customVal;
1104 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1108 if ($field['data_type'] == 'ContactReference') {
1109 $params[$index] = $values[$index];
1111 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1112 $cfID, 'is_search_range'
1114 $customFieldName = "{$name}_from";
1118 elseif ($name == 'image_URL') {
1119 list($width, $height) = getimagesize($details->$name);
1120 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1122 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1123 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1125 elseif (in_array($name, array(
1126 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1127 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1128 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1132 if ($index == 'Campaign') {
1133 $dao = 'CRM_Campaign_DAO_Campaign';
1135 elseif ($index == 'Contribution Page') {
1136 $dao = 'CRM_Contribute_DAO_ContributionPage';
1139 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1142 $value = $details->$name;
1144 $values[$index] = $value;
1149 elseif (strpos($name, '-') !== FALSE) {
1150 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1152 if (!in_array($fieldName, $multipleFields)) {
1153 if ($id == 'Primary') {
1155 // not sure why we'd every use Primary location type id
1156 // we need to fix the source if we are using it
1157 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1158 $locationTypeName = 1;
1161 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1164 if (!$locationTypeName) {
1168 $detailName = "{$locationTypeName}-{$fieldName}";
1169 $detailName = str_replace(' ', '_', $detailName);
1171 if (in_array($fieldName, array(
1172 'phone', 'im', 'email', 'openid'))) {
1174 $detailName .= "-{$type}";
1178 if (in_array($fieldName, array(
1179 'state_province', 'country', 'county'))) {
1180 $values[$index] = $details->$detailName;
1181 $idx = $detailName . '_id';
1182 $params[$index] = $details->$idx;
1184 elseif ($fieldName == 'im') {
1185 $providerId = $detailName . '-provider_id';
1186 if (isset($imProviders[$details->$providerId])) {
1187 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1190 $values[$index] = $details->$detailName;
1192 $params[$index] = $details->$detailName;
1194 elseif ($fieldName == 'phone') {
1195 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1196 if (isset($details->$phoneExtField)) {
1197 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1200 $values[$index] = $details->$detailName;
1202 $params[$index] = $details->$detailName;
1205 $values[$index] = $params[$index] = $details->$detailName;
1209 $detailName = "website-{$id}-{$fieldName}";
1210 $url = CRM_Utils_System
::fixURL($details->$detailName);
1211 if ($details->$detailName) {
1212 $websiteTypeId = "website-{$id}-website_type_id";
1213 $websiteType = $websiteTypes[$details->$websiteTypeId];
1214 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1217 $values[$index] = '';
1222 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1223 CRM_Core_Permission
::check('profile listings and forms')
1226 if (CRM_Utils_System
::isNull($params[$index])) {
1227 $params[$index] = $values[$index];
1229 if (!isset($params[$index])) {
1232 if (!$customFieldName) {
1233 $fieldName = $field['name'];
1236 $fieldName = $customFieldName;
1240 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1241 $htmlType = $field['html_type'];
1242 if ($htmlType == 'Link') {
1243 $url = $params[$index];
1245 elseif (in_array($htmlType, array(
1246 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1247 'Multi-Select State/Province', 'Multi-Select Country',
1249 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1250 $selectedOptions = explode($valSeperator, $params[$index]);
1252 foreach ($selectedOptions as $key => $multiOption) {
1254 $url[] = CRM_Utils_System
::url('civicrm/profile',
1255 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1256 urlencode($fieldName) .
1258 urlencode($multiOption)
1264 $url = CRM_Utils_System
::url('civicrm/profile',
1265 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1266 urlencode($fieldName) .
1268 urlencode($params[$index])
1273 $url = CRM_Utils_System
::url('civicrm/profile',
1274 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1275 urlencode($fieldName) .
1277 urlencode($params[$index])
1282 !empty($values[$index]) &&
1286 if (is_array($url) && !empty($url)) {
1288 $eachMultiValue = explode(', ', $values[$index]);
1289 foreach ($eachMultiValue as $key => $valueLabel) {
1290 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1292 $values[$index] = implode(', ', $links);
1295 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1303 * Check if profile Group used by any module.
1305 * @param int $id profile Id
1313 public static function usedByModule($id) {
1314 //check whether this group is used by any module(check uf join records)
1316 FROM civicrm_uf_join
1317 WHERE civicrm_uf_join.uf_group_id=$id";
1319 $dao = new CRM_Core_DAO();
1321 if ($dao->fetch()) {
1330 * Delete the profile Group.
1332 * @param int $id profile Id
1340 public static function del($id) {
1341 //check whether this group contains any profile fields
1342 $profileField = new CRM_Core_DAO_UFField();
1343 $profileField->uf_group_id
= $id;
1344 $profileField->find();
1345 while ($profileField->fetch()) {
1346 CRM_Core_BAO_UFField
::del($profileField->id
);
1349 //delete records from uf join table
1350 $ufJoin = new CRM_Core_DAO_UFJoin();
1351 $ufJoin->uf_group_id
= $id;
1354 //delete profile group
1355 $group = new CRM_Core_DAO_UFGroup();
1362 * function to add the UF Group
1364 * @param array $params reference array contains the values submitted by the form
1365 * @param array $ids reference array contains the id
1372 static function add(&$params, $ids = array()) {
1373 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1374 foreach ($fields as $field) {
1375 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1378 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1379 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1381 $ufGroup = new CRM_Core_DAO_UFGroup();
1382 $ufGroup->copyValues($params);
1384 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1386 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1388 $ufGroup->id
= $ufGroupID;
1393 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1401 * Function to make uf join entries for an uf group
1403 * @param array $params (reference) an assoc array of name/value pairs
1404 * @param int $ufGroupId ufgroup id
1410 static function createUFJoin(&$params, $ufGroupId) {
1411 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1413 // get ufjoin records for uf group
1414 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1416 // get the list of all ufgroup types
1417 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1419 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1420 if (!is_array($groupTypes)) {
1421 $groupTypes = array();
1424 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1425 if (!is_array($ufGroupRecord)) {
1426 $ufGroupRecord = array();
1429 // check which values has to be inserted/deleted for contact
1430 $menuRebuild = FALSE;
1431 foreach ($allUFGroupType as $key => $value) {
1432 $joinParams = array();
1433 $joinParams['uf_group_id'] = $ufGroupId;
1434 $joinParams['module'] = $key;
1435 if ($key == 'User Account') {
1436 $menuRebuild = TRUE;
1438 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1439 // insert a new record
1440 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1442 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1443 // delete a record for existing ufgroup
1444 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1450 UPDATE civicrm_uf_join
1452 WHERE uf_group_id = %2
1453 AND ( entity_id IS NULL OR entity_id <= 0 )
1455 $p = array(1 => array($params['weight'], 'Integer'),
1456 2 => array($ufGroupId, 'Integer'),
1458 CRM_Core_DAO
::executeQuery($query, $p);
1460 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1462 $config = CRM_Core_Config
::singleton();
1464 $config->userSystem
->is_drupal
1471 * Function to get the UF Join records for an ufgroup id
1473 * @params int $ufGroupId uf group id
1474 * @params int $displayName if set return display name in array
1475 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1477 * @param null $ufGroupId
1478 * @param null $displayName
1479 * @param null $status
1481 * @return array $ufGroupJoinRecords
1486 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1488 $UFGroupType = array();
1489 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1493 $dao = new CRM_Core_DAO_UFJoin();
1496 $dao->uf_group_id
= $ufGroupId;
1502 while ($dao->fetch()) {
1503 if (!$displayName) {
1504 $ufJoin[$dao->id
] = $dao->module
;
1507 if (isset($UFGroupType[$dao->module
])) {
1508 // skip the default modules
1510 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1512 // added for CRM-1475
1514 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1515 $ufJoin[$dao->id
] = $dao->module
;
1523 * Function takes an associative array and creates a ufjoin record for ufgroup
1525 * @param array $params (reference) an assoc array of name/value pairs
1527 * @return object CRM_Core_BAO_UFJoin object
1531 static function addUFJoin(&$params) {
1532 $ufJoin = new CRM_Core_DAO_UFJoin();
1533 $ufJoin->copyValues($params);
1539 * Function to delete the uf join record for an uf group
1541 * @param array $params (reference) an assoc array of name/value pairs
1547 static function delUFJoin(&$params) {
1548 $ufJoin = new CRM_Core_DAO_UFJoin();
1549 $ufJoin->copyValues($params);
1554 * Function to get the weight for ufjoin record
1556 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1558 * @return int weight of the UFGroup
1562 static function getWeight($ufGroupId = NULL) {
1563 //calculate the weight
1566 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1567 FROM civicrm_uf_join
1568 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1571 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1572 FROM civicrm_uf_join
1573 WHERE civicrm_uf_join.uf_group_id = %1
1574 AND ( entity_id IS NULL OR entity_id <= 0 )";
1575 $p[1] = array($ufGroupId, 'Integer');
1578 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1580 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1584 * Function to get the uf group for a module
1586 * @param string $moduleName module name
1587 * @param int $count no to increment the weight
1588 * @param bool $skipPermission
1589 * @param int $op - which operation (view, edit, create, etc) to check permission for
1590 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1592 * @internal param bool $skipPermision - whether to add permission clause
1593 * @return array $ufGroups array of ufgroups for a module
1597 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1598 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1600 if (!CRM_Core_Config
::isUpgradeMode()) {
1601 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1602 $selectFields[] = 'description';
1605 if (!empty($returnFields)) {
1606 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1609 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1610 FROM civicrm_uf_group
1611 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1614 $queryString .= ' AND civicrm_uf_group.is_active = 1
1615 WHERE civicrm_uf_join.module = %2';
1616 $p[2] = array($moduleName, 'String');
1620 // add permissioning for profiles only if not registration
1621 if (!$skipPermission) {
1622 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1623 if (strpos($queryString, 'WHERE') !== FALSE) {
1624 $queryString .= " AND $permissionClause ";
1627 $queryString .= " $permissionClause ";
1631 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1632 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1634 $ufGroups = array();
1635 while ($dao->fetch()) {
1636 //skip mix profiles in user Registration / User Account
1637 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1638 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1642 foreach ($selectFields as $key => $field) {
1643 if($field == 'id') {
1646 elseif ($field == 'name') {
1647 $ufGroups[$dao->id
][$field] = $dao->title
;
1650 $ufGroups[$dao->id
][$field] = $dao->$field;
1654 // Allow other modules to alter/override the UFGroups.
1655 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1661 * Function to filter ufgroups based on logged in user contact type
1663 * @params int $ufGroupId uf group id (profile id)
1666 * @param null $contactID
1668 * @return boolean true or false
1672 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1674 $session = CRM_Core_Session
::singleton();
1675 $contactID = $session->get('userID');
1679 //get the contact type
1680 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1682 //match if exixting contact type is same as profile contact type
1683 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1685 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1686 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1689 //allow special mix profiles for Contribution and Participant
1690 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1692 if (in_array($profileType, $specialProfiles)) {
1696 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1705 * Function to build profile form
1707 * @params object $form form object
1708 * @params array $field array field properties
1709 * @params int $mode profile mode
1710 * @params int $contactID contact id
1711 * @params string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
1716 * @param null $contactId
1717 * @param bool $online
1718 * @param null $usedFor
1719 * @param null $rowNumber
1720 * @param string $prefix
1726 static function buildProfile(
1736 $defaultValues = array();
1737 $fieldName = $field['name'];
1738 $title = $field['title'];
1739 $attributes = $field['attributes'];
1740 $rule = $field['rule'];
1741 $view = $field['is_view'];
1742 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1743 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1744 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1746 // do not display view fields in drupal registration form
1748 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1752 if ($usedFor == 'onbehalf') {
1753 $name = "onbehalf[$fieldName]";
1755 elseif ($usedFor == 'honor') {
1756 $name = "honor[$fieldName]";
1758 elseif ($contactId && !$online) {
1759 $name = "field[$contactId][$fieldName]";
1761 elseif ($rowNumber) {
1762 $name = "field[$rowNumber][$fieldName]";
1764 elseif (!empty($prefix)) {
1765 $name = $prefix ."[$fieldName]";
1771 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1772 $deleteExtra = ts('Are you sure you want to delete contact image.');
1774 CRM_Core_Action
::DELETE
=>
1776 'name' => ts('Delete Contact Image'),
1777 'url' => 'civicrm/contact/image',
1778 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1780 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1783 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1784 CRM_Core_Action
::DELETE
,
1785 array('id' => $form->get('id'),
1786 'gid' => $form->get('gid'),
1790 'contact.profileimage.delete',
1794 $form->assign('deleteURL', $deleteURL);
1796 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1797 'address_options', TRUE, NULL, TRUE
1800 if (substr($fieldName, 0, 14) === 'state_province') {
1801 $form->add('select', $name, $title,
1803 '' => ts('- select -')) + CRM_Core_PseudoConstant
::stateProvince(), $required
1805 $config = CRM_Core_Config
::singleton();
1806 if (!in_array($mode, array(
1807 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1808 $config->defaultContactStateProvince
1810 $defaultValues[$name] = $config->defaultContactStateProvince
;
1811 $form->setDefaults($defaultValues);
1814 elseif (substr($fieldName, 0, 7) === 'country') {
1815 $form->add('select', $name, $title,
1817 '' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required
1819 $config = CRM_Core_Config
::singleton();
1820 if (!in_array($mode, array(
1821 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1822 $config->defaultContactCountry
1824 $defaultValues[$name] = $config->defaultContactCountry
;
1825 $form->setDefaults($defaultValues);
1828 elseif (substr($fieldName, 0, 6) === 'county') {
1829 if ($addressOptions['county']) {
1830 $form->add('select', $name, $title,
1832 '' => ts('(choose state first)')), $required
1836 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1837 $form->add('file', $name, $title, $attributes, $required);
1838 $form->addUploadElement($name);
1840 elseif (substr($fieldName, 0, 2) === 'im') {
1841 $form->add('text', $name, $title, $attributes, $required);
1844 if (substr($name, -1) == ']') {
1845 $providerName = substr($name, 0, -1) . '-provider_id]';
1847 $form->add('select', $providerName, NULL,
1849 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1853 $form->add('select', $name . '-provider_id', $title,
1855 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1859 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1860 $form->freeze($name . '-provider_id');
1864 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1865 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1867 elseif (in_array($fieldName, array(
1868 'membership_start_date', 'membership_end_date', 'join_date'))) {
1869 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1871 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_type') {
1872 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1873 $sel = &$form->addElement('hierselect', $name, $title);
1874 $select = array('' => ts('- select -') );
1875 if(count($orgInfo) == 1 && $field['is_required']) {
1876 // we only have one org - so we should default to it. Not sure about defaulting to first type
1877 // as it could be missed - so adding a select
1878 // however, possibly that is more similar to the membership form
1879 if(count($types[1]) > 1) {
1880 $types[1] = $select +
$types[1];
1884 $orgInfo = $select +
$orgInfo;
1886 $sel->setOptions(array($orgInfo, $types));
1888 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_status') {
1889 $form->add('select', $name, $title,
1891 '' => ts('- select -')) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1894 elseif ($fieldName === 'gender_id') {
1895 $genderOptions = array();
1896 $gender = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'gender_id');
1897 foreach ($gender as $key => $var) {
1898 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1900 $group = $form->addGroup($genderOptions, $name, $title);
1902 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1905 $group->setAttribute('allowClear', TRUE);
1908 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1909 $form->add('select', $name, $title,
1911 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Contact_BAO_Contact', $fieldName), $required
1914 elseif ($fieldName === 'contact_sub_type') {
1915 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1916 if ($usedFor == 'onbehalf') {
1917 $profileType = 'Organization';
1919 elseif ($usedFor == 'honor') {
1920 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1923 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1924 if ($profileType == 'Contact') {
1925 $profileType = 'Individual';
1929 $setSubtype = FALSE;
1930 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1931 $setSubtype = $profileType;
1932 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1935 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
1938 $subtypeList = array();
1939 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1942 $subtypeList = $subtypes;
1945 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1946 $sel->setMultiple(TRUE);
1948 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1949 //add email greeting, postal greeting, addressee, CRM-4575
1950 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1951 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
1953 if (empty($profileType) ||
in_array($profileType, array(
1954 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1955 $profileType = 'Individual';
1957 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1958 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1961 'contact_type' => $profileType,
1962 'greeting_type' => $fieldName,
1964 $form->add('select', $name, $title,
1966 '' => ts('- select -')) + CRM_Core_PseudoConstant
::greeting($greeting), $required
1968 // add custom greeting element
1969 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1973 elseif ($fieldName === 'preferred_communication_method') {
1974 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1975 foreach ($communicationFields as $key => $var) {
1979 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
1981 $form->addGroup($communicationOptions, $name, $title, '<br/>');
1983 elseif ($fieldName === 'preferred_mail_format') {
1984 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
1986 elseif ($fieldName === 'preferred_language') {
1987 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
1989 elseif ($fieldName == 'external_identifier') {
1990 $form->add('text', $name, $title, $attributes, $required);
1991 $contID = $contactId;
1993 $contID = $form->get('id');
1995 $form->addRule($name,
1996 ts('External ID already exists in Database.'),
1998 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2001 elseif ($fieldName === 'group') {
2002 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2003 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2008 elseif ($fieldName === 'tag') {
2009 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2010 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2015 elseif (substr($fieldName, 0, 4) === 'url-') {
2016 $form->add('text', $name, $title,
2017 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2019 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2020 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2025 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2027 // Note should be rendered as textarea
2028 elseif (substr($fieldName, -4) == 'note') {
2029 $form->add('textarea', $name, $title, $attributes, $required);
2031 elseif (substr($fieldName, 0, 6) === 'custom') {
2032 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2033 if ($customFieldID) {
2034 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2037 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2038 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2039 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2040 if ($customFieldID) {
2041 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2044 elseif (in_array($fieldName, array(
2045 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2046 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2048 elseif ($fieldName == 'send_receipt') {
2049 $form->addElement('checkbox', $name, $title);
2051 elseif ($fieldName == 'soft_credit') {
2052 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2053 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2055 elseif ($fieldName == 'product_name') {
2056 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2057 $sel = &$form->addElement('hierselect', $name, $title);
2059 '0' => ts('- select -')) +
$products;
2060 $sel->setOptions(array($products, $options));
2062 elseif ($fieldName == 'payment_instrument') {
2063 $form->add('select', $name, $title,
2064 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant
::paymentInstrument( ), $required );
2066 else if ($fieldName == 'financial_type' ) {
2067 $form->add('select', $name, $title,
2069 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(), $required
2072 elseif ($fieldName == 'contribution_status_id') {
2073 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2074 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2080 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2083 $form->add('select', $name, $title,
2085 '' => ts('- select -')) +
$contributionStatuses, $required
2088 elseif ($fieldName == 'soft_credit_type') {
2089 $form->add('select', $name, $title,
2091 '' => ts('- select -')) + CRM_Core_OptionGroup
::values("soft_credit_type")
2093 $form->addElement('hidden', 'sct_default_id',
2094 CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type"),
2095 array('id' => 'sct_default_id')
2098 elseif ($fieldName == 'currency') {
2099 $form->addCurrency($name, $title, $required);
2101 elseif ($fieldName == 'contribution_page_id') {
2102 $form->add('select', $name, $title,
2104 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2107 elseif ($fieldName == 'participant_register_date') {
2108 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2110 elseif ($fieldName == 'activity_status_id') {
2111 $form->add('select', $name, $title,
2113 '' => ts('- select -')) + CRM_Core_PseudoConstant
::activityStatus(), $required
2116 elseif ($fieldName == 'activity_engagement_level') {
2117 $form->add('select', $name, $title,
2119 '' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2122 elseif ($fieldName == 'activity_date_time') {
2123 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2125 elseif ($fieldName == 'participant_status') {
2127 if ($online == TRUE) {
2128 $cond = 'visibility_id = 1';
2130 $form->add('select', $name, $title,
2132 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2135 elseif ($fieldName == 'participant_role') {
2136 if (!empty($field['is_multiple'])) {
2137 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2140 $form->add('select', $name, $title,
2142 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantRole(), $required
2146 elseif ($fieldName == 'world_region') {
2147 $form->add('select', $name, $title,
2149 '' => ts('- select -')) + CRM_Core_PseudoConstant
::worldRegion(), $required
2152 elseif ($fieldName == 'signature_html') {
2153 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2155 elseif ($fieldName == 'signature_text') {
2156 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2158 elseif (substr($fieldName, -11) == 'campaign_id') {
2159 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2160 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2161 $form->_componentCampaigns
2163 $form->add('select', $name, $title,
2165 '' => ts('- select -')) +
$campaigns, $required, 'class="big"'
2169 elseif ($fieldName == 'activity_details') {
2170 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2172 elseif ($fieldName == 'activity_duration') {
2173 $form->add('text', $name, $title, $attributes, $required);
2174 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2177 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2178 $form->add('advcheckbox', $name, $title, $attributes, $required);
2181 $form->add('text', $name, $title, $attributes, $required);
2185 static $hiddenSubtype = FALSE;
2186 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2187 // In registration mode params are submitted via POST and we don't have any clue
2188 // about profile-id or the profile-type (which could be a subtype)
2189 // To generalize the behavior and simplify the process,
2190 // lets always add the hidden
2191 //subtype value if there is any, and we won't have to
2192 // compute it while processing.
2194 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2197 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2199 $hiddenSubtype = TRUE;
2202 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2203 $form->freeze($name);
2207 if (in_array($fieldName, array(
2208 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2209 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2211 $stateCountryMap = array();
2212 if (!empty($form->_stateCountryMap
['state_province']) && !empty($form->_stateCountryMap
['country'])) {
2213 foreach ($form->_stateCountryMap
['state_province'] as $key => $value) {
2214 $stateCountryMap[$key]['state_province'] = $value;
2215 $stateCountryMap[$key]['country'] = $form->_stateCountryMap
['country'][$key];
2217 CRM_Core_BAO_Address
::addStateCountryMap($stateCountryMap);
2220 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2221 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2227 * Function to set profile defaults
2229 * @params int $contactId contact id
2230 * @params array $fields associative array of fields
2231 * @params array $defaults defaults array
2232 * @params boolean $singleProfile true for single profile else false(batch update)
2233 * @params int $componentId id for specific components like contribute, event etc
2238 * @param bool $singleProfile
2239 * @param null $componentId
2240 * @param null $component
2246 static function setProfileDefaults($contactId, &$fields, &$defaults,
2247 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2249 if (!$componentId) {
2250 //get the contact details
2251 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2252 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2253 $multipleFields = array('website' => 'url');
2255 //start of code to set the default values
2256 foreach ($fields as $name => $field) {
2257 // skip pseudo fields
2258 if (substr($name, 0, 9) == 'phone_ext') {
2262 //set the field name depending upon the profile mode(single/batch)
2263 if ($singleProfile) {
2267 $fldName = "field[$contactId][$name]";
2270 if ($name == 'group') {
2271 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2273 if ($name == 'tag') {
2274 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2277 if (!empty($details[$name]) ||
isset($details[$name])) {
2278 //to handle custom data (checkbox) to be written
2279 // to handle birth/deceased date, greeting_type and few other fields
2280 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2281 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2283 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2284 $defaults[$fldName] = $details[$name . '_id'];
2285 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2287 elseif ($name == 'preferred_communication_method') {
2288 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2289 foreach ($v as $item) {
2291 $defaults[$fldName . "[$item]"] = 1;
2295 elseif ($name == 'world_region') {
2296 $defaults[$fldName] = $details['worldregion_id'];
2298 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2299 //fix for custom fields
2300 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2302 // hack to add custom data for components
2303 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2304 foreach ($components as $value) {
2305 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2306 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2310 switch ($customFields[$customFieldId]['html_type']) {
2311 case 'Multi-Select State/Province':
2312 case 'Multi-Select Country':
2313 case 'AdvMulti-Select':
2314 case 'Multi-Select':
2315 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2316 foreach ($v as $item) {
2318 $defaults[$fldName][$item] = $item;
2324 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2325 foreach ($v as $item) {
2327 $defaults[$fldName][$item] = 1;
2328 // seems like we need this for QF style checkboxes in profile where its multiindexed
2330 $defaults["{$fldName}[{$item}]"] = 1;
2336 // CRM-6681, set defult values according to date and time format (if any).
2338 if (!empty($customFields[$customFieldId]['date_format'])) {
2339 $dateFormat = $customFields[$customFieldId]['date_format'];
2342 if (empty($customFields[$customFieldId]['time_format'])) {
2343 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2348 $timeElement = $fldName . '_time';
2349 if (substr($fldName, -1) == ']') {
2350 $timeElement = substr($fldName, 0, -1) . '_time]';
2352 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2353 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2358 $defaults[$fldName] = $details[$name];
2363 $defaults[$fldName] = $details[$name];
2367 $blocks = array('email', 'phone', 'im', 'openid');
2368 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2369 if (!in_array($fieldName, $multipleFields)) {
2370 if (is_array($details)) {
2371 foreach ($details as $key => $value) {
2372 // when we fixed CRM-5319 - get primary loc
2373 // type as per loc field and removed below code.
2374 $primaryLocationType = FALSE;
2375 if ($locTypeId == 'Primary') {
2376 if (is_array($value) && array_key_exists($fieldName, $value)){
2377 $primaryLocationType = TRUE;
2378 if (in_array($fieldName, $blocks)){
2379 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2382 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2387 // fixed for CRM-665
2388 if (is_numeric($locTypeId)) {
2389 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2390 if (!empty($value[$fieldName])) {
2391 //to handle stateprovince and country
2392 if ($fieldName == 'state_province') {
2393 $defaults[$fldName] = $value['state_province_id'];
2395 elseif ($fieldName == 'county') {
2396 $defaults[$fldName] = $value['county_id'];
2398 elseif ($fieldName == 'country') {
2399 if (!isset($value['country_id']) ||
!$value['country_id']) {
2400 $config = CRM_Core_Config
::singleton();
2401 if ($config->defaultContactCountry
) {
2402 $defaults[$fldName] = $config->defaultContactCountry
;
2406 $defaults[$fldName] = $value['country_id'];
2409 elseif ($fieldName == 'phone') {
2411 if (isset($value['phone'][$phoneTypeId])) {
2412 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2414 if (isset($value['phone_ext'][$phoneTypeId])) {
2415 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2419 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2421 if (!is_array($phoneDefault)) {
2422 $defaults[$fldName] = $phoneDefault;
2426 elseif ($fieldName == 'email') {
2427 //adding the first email (currently we don't support multiple emails of same location type)
2428 $defaults[$fldName] = $value['email'];
2430 elseif ($fieldName == 'im') {
2431 //adding the first im (currently we don't support multiple ims of same location type)
2432 $defaults[$fldName] = $value['im'];
2433 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2436 $defaults[$fldName] = $value[$fieldName];
2439 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2440 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2442 $defaults[$fldName] = $value[substr($fieldName, 8)];
2450 if (is_array($details)) {
2451 if ($fieldName === 'url'
2452 && !empty($details['website'])
2453 && !empty($details['website'][$locTypeId])) {
2454 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2462 //Handling Contribution Part of the batch profile
2463 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2464 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2467 //Handling Event Participation Part of the batch profile
2468 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2469 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2472 //Handling membership Part of the batch profile
2473 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2474 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2477 //Handling Activity Part of the batch profile
2478 if ($component == 'Activity') {
2479 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2484 * Function to get profiles by type eg: pure Individual etc
2486 * @param array $types associative array of types eg: types('Individual')
2487 * @param boolean $onlyPure true if only pure profiles are required
2489 * @return array $profiles associative array of profiles
2493 static function getProfiles($types, $onlyPure = FALSE) {
2494 $profiles = array();
2495 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2497 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2499 // Exclude Batch Data Entry profiles - CRM-10901
2500 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2502 foreach ($ufGroups as $id => $title) {
2503 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2504 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2505 $profiles[$id] = $title;
2512 * Function to check whether a profile is valid combination of
2513 * required and/or optional profile types
2515 * @param array $required array of types those are required
2516 * @param array $optional array of types those are optional
2518 * @return array $profiles associative array of profiles
2522 static function getValidProfiles($required, $optional = NULL) {
2523 if (!is_array($required) ||
empty($required)) {
2527 $profiles = array();
2528 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2530 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2532 foreach ($ufGroups as $id => $title) {
2533 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2535 $profiles[$id] = $title;
2543 * Function to check whether a profile is valid combination of
2544 * required profile fields
2546 * @param array $ufId integer id of the profile
2547 * @param array $required array of fields those are required in the profile
2549 * @return array $profiles associative array of profiles
2553 static function checkValidProfile($ufId, $required = NULL) {
2554 $validProfile = FALSE;
2556 return $validProfile;
2559 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2560 return $validProfile;
2563 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2564 NULL, FALSE, NULL, FALSE, NULL,
2565 CRM_Core_Permission
::CREATE
, NULL
2568 $validProfile = array();
2569 if (!empty($profileFields)) {
2570 $fields = array_keys($profileFields);
2571 foreach ($fields as $val) {
2572 foreach ($required as $key => $field) {
2573 if (strpos($val, $field) === 0) {
2574 unset($required[$key]);
2579 $validProfile = (empty($required)) ?
TRUE : FALSE;
2582 return $validProfile;
2586 * Function to get default value for Register.
2591 * @return mixed $defaults@static
2594 static function setRegisterDefaults(&$fields, &$defaults) {
2595 $config = CRM_Core_Config
::singleton();
2596 foreach ($fields as $name => $field) {
2597 if (substr($name, 0, 8) == 'country-') {
2598 if (!empty($config->defaultContactCountry
)) {
2599 $defaults[$name] = $config->defaultContactCountry
;
2602 elseif (substr($name, 0, 15) == 'state_province-') {
2603 if (!empty($config->defaultContactStateProvince
)) {
2604 $defaults[$name] = $config->defaultContactStateProvince
;
2612 * This function is to make a copy of a profile, including
2613 * all the fields in the profile
2615 * @param int $id the profile id to copy
2620 static function copy($id) {
2621 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2622 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2628 if ($pos = strrpos($copy->name
, "_{$id}")) {
2629 $copy->name
= substr_replace($copy->name
, '', $pos);
2631 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2634 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2635 array('uf_group_id' => $id),
2636 array('uf_group_id' => $copy->id
),
2641 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2642 array('uf_group_id' => $id),
2643 array('uf_group_id' => $copy->id
)
2646 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2650 UPDATE civicrm_uf_join
2652 WHERE uf_group_id = %2
2653 AND ( entity_id IS NULL OR entity_id <= 0 )
2655 $p = array(1 => array($maxWeight +
1, 'Integer'),
2656 2 => array($copy->id
, 'Integer'),
2658 CRM_Core_DAO
::executeQuery($query, $p);
2659 if ($copy->is_reserved
) {
2660 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2661 $params = array(1 => array($copy->id
, 'Integer'));
2662 CRM_Core_DAO
::executeQuery($query, $params);
2664 CRM_Utils_Hook
::copy('UFGroup', $copy);
2670 * Process that send notification e-mails
2672 * @params int $contactId contact id
2673 * @params array $values associative array of name/value pair
2682 static function commonSendMail($contactID, &$values) {
2683 if (!$contactID ||
!$values) {
2687 $template = CRM_Core_Smarty
::singleton();
2689 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2694 self
::profileDisplay($values['id'], $values['values'], $template);
2695 $emailList = explode(',', $values['email']);
2697 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2698 "reset=1&cid=$contactID",
2699 TRUE, NULL, FALSE, FALSE, TRUE
2702 //get the default domain email address.
2703 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2705 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2706 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2707 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)));
2710 foreach ($emailList as $emailTo) {
2711 // FIXME: take the below out of the foreach loop
2712 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2714 'groupName' => 'msg_tpl_workflow_uf',
2715 'valueName' => 'uf_notify',
2716 'contactId' => $contactID,
2717 'tplParams' => array(
2718 'displayName' => $displayName,
2719 'currentDate' => date('r'),
2720 'contactLink' => $contactLink,
2722 'from' => "$domainEmailName <$domainEmailAddress>",
2723 'toEmail' => $emailTo,
2730 * Given a contact id and a group id, returns the field values from the db
2731 * for this group and notify email only if group's notify field is
2732 * set and field values are not empty
2734 * @params $gid group id
2735 * @params $cid contact id
2736 * @params $params associative array
2741 * @param bool $skipCheck
2746 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2748 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2750 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2751 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2753 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2755 if (!empty($values) &&
2760 'values' => $values,
2771 * Function to assign uf fields to template
2773 * @params int $gid group id
2774 * @params array $values associative array of fields
2783 function profileDisplay($gid, $values, $template) {
2784 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2785 $template->assign('grouptitle', $groupTitle);
2786 if (count($values)) {
2787 $template->assign('values', $values);
2792 * Format fields for dupe Contact Matching
2794 * @param array $params associated array
2796 * @param null $contactId
2798 * @return array $data assoicated formatted array
2802 static function formatFields($params, $contactId = NULL) {
2804 // get the primary location type id and email
2805 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2808 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2809 $primaryLocationType = $defaultLocationType->id
;
2813 $locationType = array();
2815 $primaryLocation = 0;
2816 foreach ($params as $key => $value) {
2817 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2819 if ($locTypeId == 'Primary') {
2820 $locTypeId = $primaryLocationType;
2823 if (is_numeric($locTypeId)) {
2824 if (!in_array($locTypeId, $locationType)) {
2825 $locationType[$count] = $locTypeId;
2828 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2830 $data['location'][$loc]['location_type_id'] = $locTypeId;
2832 // if we are getting in a new primary email, dont overwrite the new one
2833 if ($locTypeId == $primaryLocationType) {
2834 if (!empty($params['email-' . $primaryLocationType])) {
2835 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2837 elseif (isset($primaryEmail)) {
2838 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2844 $data['location'][$loc]['is_primary'] = 1;
2846 if ($fieldName == 'phone') {
2848 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2851 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2853 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2855 elseif ($fieldName == 'email') {
2856 $data['location'][$loc]['email'][$loc]['email'] = $value;
2858 elseif ($fieldName == 'im') {
2859 $data['location'][$loc]['im'][$loc]['name'] = $value;
2862 if ($fieldName === 'state_province') {
2863 $data['location'][$loc]['address']['state_province_id'] = $value;
2865 elseif ($fieldName === 'country') {
2866 $data['location'][$loc]['address']['country_id'] = $value;
2869 $data['location'][$loc]['address'][$fieldName] = $value;
2874 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2875 if ($key === 'individual_suffix') {
2876 $data['suffix_id'] = $value;
2878 elseif ($key === 'individual_prefix') {
2879 $data['prefix_id'] = $value;
2881 elseif ($key === 'gender') {
2882 $data['gender_id'] = $value;
2884 elseif (substr($key, 0, 6) === 'custom') {
2885 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2887 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2888 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2890 // fix the date field
2891 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2892 $date = CRM_Utils_Date
::format($value);
2899 $data['custom'][$customFieldID] = array(
2902 'extends' => $customFields[$customFieldID]['extends'],
2903 'type' => $customFields[$customFieldID]['data_type'],
2904 'custom_field_id' => $customFieldID,
2908 elseif ($key == 'edit') {
2912 $data[$key] = $value;
2917 if (!$primaryLocation) {
2919 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2927 * calculate the profile type 'group_type' as per profile fields.
2930 * @param bool $includeTypeValues
2931 * @param int $ignoreFieldId ignore particular profile field
2933 * @internal param int $gid profile id
2934 * @return array list of calculated group type
2936 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2937 //get the profile fields.
2938 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2939 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2943 * calculate the profile type 'group_type' as per profile fields.
2946 * @param bool $includeTypeValues
2947 * @param int $ignoreFieldId ignore perticular profile field
2949 * @internal param int $gid profile id
2950 * @return array list of calculated group type
2952 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2953 $groupType = $groupTypeValues = $customFieldIds = array();
2954 if (!empty($ufFields)) {
2955 foreach ($ufFields as $fieldName => $fieldValue) {
2956 //ignore field from group type when provided.
2957 //in case of update profile field.
2958 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2961 if (!in_array($fieldValue['field_type'], $groupType)) {
2962 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2965 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
2966 $customFieldIds[$fldId] = $fldId;
2971 if (!empty($customFieldIds)) {
2972 $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) . ')';
2974 $customGroups = CRM_Core_DAO
::executeQuery($query);
2975 while ($customGroups->fetch()) {
2976 if (!$customGroups->extends_entity_column_value
) {
2980 $groupTypeName = "{$customGroups->extends}Type";
2981 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
2982 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
2985 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
2987 $groupTypeValues[$groupTypeName][$val] = $val;
2992 if (!empty($groupTypeValues)) {
2993 $groupType = array_merge($groupType, $groupTypeValues);
3001 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3002 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3005 * BirthDate + Email Individual,Contact
3006 * BirthDate + Subject Individual,Activity
3007 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3008 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3009 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3010 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3011 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3012 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3013 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3016 * @param Array $groupTypes With key having group type names
3018 * @internal param int $gid profile id
3021 static function updateGroupTypes($gId, $groupTypes = array(
3023 if (!is_array($groupTypes) ||
!$gId) {
3027 // If empty group types set group_type as 'null'
3028 if (empty($groupTypes)) {
3029 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3032 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3033 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3035 $gTypes = $gTypeValues = array();
3037 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3038 // Get valid group type and group subtypes
3039 foreach ($groupTypes as $groupType => $value) {
3040 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3041 $gTypes[] = $groupType;
3046 if (in_array($groupType, $participantExtends)) {
3047 $subTypesOf = $groupType;
3049 elseif (strpos($groupType, 'Type') > 0) {
3050 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3056 if (!empty($value) &&
3057 (in_array($subTypesOf, $componentGroupTypes) ||
3058 in_array($subTypesOf, $participantExtends)
3061 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3065 if (empty($gTypes)) {
3069 // Build String to store group types and group subtypes
3070 $groupTypeString = implode(',', $gTypes);
3071 if (!empty($gTypeValues)) {
3072 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3075 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3079 * Create a "group_type" string
3081 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3082 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3083 * @param string $delim
3086 * @throws CRM_Core_Exception
3088 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3089 $groupTypeExpr = '';
3091 $groupTypeExpr .= implode(',', $coreTypes);
3094 if (count($subTypes) > 1) {
3095 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3097 foreach ($subTypes as $subType => $subTypeIds) {
3098 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3101 return $groupTypeExpr;
3105 * This function is used to setDefault componet specific profile fields.
3107 * @param array $fields profile fields.
3108 * @param int $componentId componetID
3109 * @param string $component component name
3110 * @param array $defaults an array of default values.
3112 * @param bool $isStandalone
3116 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3117 if (!$componentId ||
3118 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3123 $componentBAO = $componentSubType = NULL;
3124 switch ($component) {
3126 $componentBAO = 'CRM_Member_BAO_Membership';
3127 $componentBAOName = 'Membership';
3128 $componentSubType = array('membership_type_id');
3132 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3133 $componentBAOName = 'Contribution';
3134 $componentSubType = array( 'financial_type_id' );
3138 $componentBAO = 'CRM_Event_BAO_Participant';
3139 $componentBAOName = 'Participant';
3140 $componentSubType = array('role_id', 'event_id');
3144 $componentBAO = 'CRM_Activity_BAO_Activity';
3145 $componentBAOName = 'Activity';
3146 $componentSubType = array('activity_type_id');
3151 $params = array('id' => $componentId);
3153 //get the component values.
3154 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3156 $formattedGroupTree = array();
3157 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3158 foreach ($fields as $name => $field) {
3159 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3160 if (in_array($name, $dateTimeFields)) {
3161 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3162 if (!empty($values[$name])) {
3163 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3166 elseif (array_key_exists($name, $values)) {
3167 $defaults[$fldName] = $values[$name];
3169 elseif ($name == 'participant_note') {
3170 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3171 $defaults[$fldName] = array_pop($noteDetails);
3173 elseif (in_array($name, array(
3174 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3175 $defaults[$fldName] = $values["{$name}_id"];
3177 elseif ($name == 'membership_type') {
3178 // since membership_type field is a hierselect -
3179 $defaults[$fldName][0] =
3180 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3181 $defaults[$fldName][1] = $values['membership_type_id'];
3183 elseif ($name == 'membership_status') {
3184 $defaults[$fldName] = $values['status_id'];
3186 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3187 if (empty($formattedGroupTree)) {
3188 //get the groupTree as per subTypes.
3189 $groupTree = array();
3190 foreach ($componentSubType as $subType) {
3191 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3192 $componentId, 0, $values[$subType]
3194 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3196 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3197 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3200 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3201 foreach ($defaults as $customKey => $customValue) {
3202 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3203 if ($name == 'custom_' . $customFieldDetails[0]) {
3205 //hack to set default for checkbox
3206 //basically this is for weired field name like field[33][custom_19]
3207 //we are converting this field name to array structure and assign value.
3210 foreach ($formattedGroupTree as $tree) {
3211 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3213 $defaults['field'][$componentId][$name] = $customValue;
3216 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3219 // CRM-6681, $default contains formatted date, time values.
3220 $defaults[$fldName] = $customValue;
3221 if (!empty($defaults[$customKey . '_time'])) {
3222 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3227 if (!$skipValue ||
$isStandalone) {
3228 $defaults[$fldName] = $customValue;
3230 unset($defaults[$customKey]);
3240 * @param array|string $profiles - name of profile(s) to create links for
3241 * @param array $appendProfiles - name of profile(s) to append to each link
3245 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3246 // Default to contact profiles
3248 $profiles = array('new_individual', 'new_organization', 'new_household');
3250 $profiles = (array) $profiles;
3251 $toGet = array_merge($profiles, (array) $appendProfiles);
3252 $retrieved = civicrm_api3('uf_group', 'get', array(
3253 'name' => array('IN' => $toGet),
3256 $links = $append = array();
3257 if (!empty($retrieved['values'])) {
3258 foreach($retrieved['values'] as $id => $profile) {
3259 if (in_array($profile['name'], $profiles)) {
3261 'label' => $profile['title'],
3262 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3263 NULL, NULL, FALSE, NULL, FALSE) ,
3264 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3271 foreach ($append as $id) {
3272 foreach ($links as &$link) {
3273 $link['url'] .= ",$id";
3281 * Function to retrieve groups of profiles
3283 * @param integer $profileID id of the profile
3285 * @return array returns array
3288 static function profileGroups($profileID) {
3289 $groupTypes = array();
3290 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3291 if ($profileTypes) {
3292 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3293 $groupTypes = explode(',', $groupTypeParts[0]);
3299 * Function to alter contact params by filtering existing subscribed groups and returns
3300 * unsubscribed groups array for subscription.
3302 * @param array $params contact params
3303 * @param int $contactId user contact id
3305 * @return array $subscribeGroupIds This contains array of groups for subscription
3307 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3308 $config = CRM_Core_Config
::singleton();
3309 $subscribeGroupIds = array();
3311 // process further only if profileDoubleOptIn enabled and if groups exist
3312 if (!array_key_exists('group', $params) ||
3313 !self
::isProfileDoubleOptin() ||
3314 CRM_Utils_System
::isNull($params['group'])
3316 return $subscribeGroupIds;
3319 //check if contact email exist.
3321 foreach ($params as $name => $value) {
3322 if (strpos($name, 'email-') !== FALSE) {
3328 //Proceed furthur only if email present
3330 return $subscribeGroupIds;
3333 //do check for already subscriptions.
3334 $contactGroups = array();
3338 FROM civicrm_group_contact
3339 WHERE status = 'Added'
3340 AND contact_id = %1";
3342 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3343 while ($dao->fetch()) {
3344 $contactGroups[$dao->group_id
] = $dao->group_id
;
3348 //since we don't have names, compare w/ label.
3349 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3351 //actual processing start.
3352 foreach ($params['group'] as $groupId => $isSelected) {
3353 //unset group those are not selected.
3355 unset($params['group'][$groupId]);
3359 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3360 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3362 //get only mailing type group and unset it from params
3363 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3364 $subscribeGroupIds[$groupId] = $groupId;
3365 unset($params['group'][$groupId]);
3369 return $subscribeGroupIds;
3373 * Function to check if we are rendering mixed profiles
3375 * @param array $profileIds associated array of profile ids
3377 * @return boolean $mixProfile true if profile is mixed
3381 static function checkForMixProfiles($profileIds) {
3382 $mixProfile = FALSE;
3384 $contactTypes = array('Individual', 'Household', 'Organization');
3385 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3387 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3389 $typeCount = array('ctype' => array(), 'subtype' => array());
3390 foreach ($profileIds as $gid) {
3391 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3392 // ignore profile of type Contact
3393 if ($profileType == 'Contact') {
3396 if (in_array($profileType, $contactTypes)) {
3397 if (!isset($typeCount['ctype'][$profileType])) {
3398 $typeCount['ctype'][$profileType] = 1;
3401 // check if we are rendering profile of different contact types
3402 if (count($typeCount['ctype']) == 2) {
3407 elseif (in_array($profileType, $components)) {
3412 if (!isset($typeCount['subtype'][$profileType])) {
3413 $typeCount['subtype'][$profileType] = 1;
3415 // check if we are rendering profile of different contact sub types
3416 if (count($typeCount['subtype']) == 2) {
3426 * Funtion to determine of we show overlay profile or not
3428 * @return boolean true if profile should be shown else false
3432 static function showOverlayProfile() {
3433 $showOverlay = TRUE;
3435 // get the id of overlay profile
3436 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3437 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3439 $count = CRM_Core_DAO
::singleValueQuery($query);
3441 //check if there are no public fields and use is anonymous
3442 $session = CRM_Core_Session
::singleton();
3443 if (!$count && !$session->get('userID')) {
3444 $showOverlay = FALSE;
3447 return $showOverlay;
3451 * function to get group type values of the profile
3453 * @params Integer $profileId Profile Id
3454 * @params String $groupType Group Type
3457 * @param null $groupType
3459 * @return Array group type values
3463 static function groupTypeValues($profileId, $groupType = NULL) {
3464 $groupTypeValue = array();
3465 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3467 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3468 if (empty($groupTypeParts[1])) {
3469 return $groupTypeValue;
3471 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3473 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3475 $valueParts = explode(':', $groupTypeValues);
3477 ($valueParts[0] != "{$groupType}Type" ||
3478 ($groupType == 'Participant' &&
3479 !in_array($valueParts[0], $participantExtends)
3485 foreach ($valueParts as $val) {
3486 if (CRM_Utils_Rule
::integer($val)) {
3487 $values[$val] = $val;
3490 if (!empty($values)) {
3491 $typeName = substr($valueParts[0], 0, -4);
3492 if (in_array($valueParts[0], $participantExtends)) {
3493 $typeName = $valueParts[0];
3495 $groupTypeValue[$typeName] = $values;
3499 return $groupTypeValue;
3502 static function isProfileDoubleOptin() {
3503 // check for double optin
3504 $config = CRM_Core_Config
::singleton();
3505 if (in_array('CiviMail', $config->enableComponents
)) {
3506 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3507 'profile_double_optin', NULL, FALSE
3513 static function isProfileAddToGroupDoubleOptin() {
3514 // check for add to group double optin
3515 $config = CRM_Core_Config
::singleton();
3516 if (in_array('CiviMail', $config->enableComponents
)) {
3517 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3518 'profile_add_to_group_double_optin', NULL, FALSE
3525 * get profiles used for batch entry
3527 * @return array profileIds profile ids
3530 static function getBatchProfiles() {
3532 FROM civicrm_uf_group
3533 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3534 $dao = CRM_Core_DAO
::executeQuery( $query );
3535 $profileIds = array();
3536 while( $dao->fetch() ) {
3537 $profileIds[$dao->id
] = $dao->id
;
3543 * @todo what do I do?
3545 * @param $destination
3546 * @param bool $returnMultiSummaryFields
3548 * @return array|null
3550 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3551 $multiSummaryFields = $returnMultiSummaryFields ?
array( ) : NULL;
3552 foreach ($source as $field => $properties) {
3553 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3556 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3557 $destination[$field] = $properties;
3558 if ($returnMultiSummaryFields) {
3559 if ($properties['is_multi_summary']) {
3560 $multiSummaryFields[$field] = $properties;
3563 unset($source[$field]);
3566 return $multiSummaryFields;
3570 * This is function is used to format pseudo fields
3572 * @param array $fields associated array of profile fields
3576 static function reformatProfileFields(&$fields) {
3577 //reformat fields array
3578 foreach ($fields as $name => $field) {
3579 //reformat phone and extension field
3580 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3581 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3583 // retain existing element properties and just update and replace key
3584 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3585 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3586 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3588 // add additional phone extension field
3589 $fields["phone_ext-{$fieldSuffix}"] = $field;
3590 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3591 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3592 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3593 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3594 //ignore required for extension field
3595 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;