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 * Fetch object based on array of properties
54 * @param array $params (reference) an assoc array of name/value pairs
55 * @param array $defaults (reference) an assoc array to hold the flattened values
57 * @return object CRM_Core_DAO_UFGroup object
61 static function retrieve(&$params, &$defaults) {
62 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
66 * Retrieve the first non-generic contact type
68 * @param int $id id of uf_group
70 * @return string contact type
72 static function getContactType($id) {
74 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
75 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
77 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
78 $types = explode(',', $typesParts[0]);
81 foreach ($types as $type) {
82 if (in_array($type, $validTypes)) {
85 elseif (array_key_exists($type, $validSubTypes)) {
86 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
98 * @param int $id id of uf_form
100 * @return string title
106 public static function getTitle($id) {
107 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
111 * Update the is_active flag in the db
113 * @param int $id id of the database record
114 * @param boolean $is_active value we want to set the is_active field
116 * @return Object CRM_Core_DAO_UFGroup object on success, null otherwise
120 static function setIsActive($id, $is_active) {
121 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
125 * Get all the registration fields
127 * @param int $action what action are we doing
128 * @param int $mode mode
132 * @return array the fields that are needed for registration
136 static function getRegistrationFields($action, $mode, $ctype = NULL) {
137 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
138 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
141 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
144 if (!is_array($ufGroups)) {
150 foreach ($ufGroups as $id => $title) {
152 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
153 if (($fieldType != 'Contact') &&
154 ($fieldType != $ctype) &&
155 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
159 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
160 $profileSubType = $fieldType;
164 $subset = self
::getFields($id, TRUE, $action,
165 NULL, NULL, FALSE, NULL, TRUE, $ctype
168 // we do not allow duplicates. the first field is the winner
169 foreach ($subset as $name => $field) {
170 if (empty($fields[$name])) {
171 $fields[$name] = $field;
180 * Get all the listing fields
182 * @param int $action what action are we doing
183 * @param int $visibility visibility of fields we are interested in
184 * @param bool $considerSelector whether to consider the in_selector parameter
185 * @param array $ufGroupIds
186 * @param boolean $searchable
188 * @param null $restrict
189 * @param bool $skipPermission
190 * @param int $permissionType
191 * @return array the fields that are listings related
195 static function getListingFields(
198 $considerSelector = FALSE,
202 $skipPermission = FALSE,
203 $permissionType = CRM_Core_Permission
::SEARCH
206 $subset = self
::getFields($ufGroupIds, FALSE, $action,
207 $visibility, $searchable,
213 if ($considerSelector) {
214 // drop the fields not meant for the selector
215 foreach ($subset as $name => $field) {
216 if (!$field['in_selector']) {
217 unset($subset[$name]);
224 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
227 foreach ($ufGroups as $id => $title) {
228 $subset = self
::getFields($id, FALSE, $action,
229 $visibility, $searchable,
235 if ($considerSelector) {
236 // drop the fields not meant for the selector
237 foreach ($subset as $name => $field) {
238 if (!$field['in_selector'])unset($subset[$name]);
241 $fields = array_merge($fields, $subset);
248 * Get all the fields that belong to the group with the name title,
249 * and format for use with buildProfile. This is the SQL analog of
252 * @param mix $id the id of the UF group or ids of ufgroup
253 * @param bool|int $register are we interested in registration fields
254 * @param int $action what action are we doing
255 * @param int $visibility visibility of fields we are interested in
257 * @param bool $showAll
258 * @param string $restrict should we restrict based on a specified profile type
259 * @param bool $skipPermission
261 * @param int $permissionType
262 * @param string $orderBy
263 * @param null $orderProfiles
265 * @return array the fields that belong to this ufgroup(s)
269 static function getFields(
277 $skipPermission = FALSE,
279 $permissionType = CRM_Core_Permission
::CREATE
,
280 $orderBy = 'field_name',
281 $orderProfiles = NULL
283 if (!is_array($id)) {
284 $id = CRM_Utils_Type
::escape($id, 'Positive');
285 $profileIds = array($id);
291 $gids = implode(',', $profileIds);
294 $query = "SELECT g.* from civicrm_uf_group g
295 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
296 WHERE g.id IN ( {$gids} )
297 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
299 $params = array(1 => array($restrict, 'String'));
302 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
306 $query .= " AND g.is_active = 1";
309 // add permissioning for profiles only if not registration
310 if (!$skipPermission) {
311 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
312 $query .= " AND $permissionClause ";
315 if ($orderProfiles AND count($profileIds) > 1) {
316 $query .= " ORDER BY FIELD( g.id, {$gids} )";
318 $group = CRM_Core_DAO
::executeQuery($query, $params);
322 while ($group->fetch()) {
324 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
325 $field = CRM_Core_DAO
::executeQuery($query);
327 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
328 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
329 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
330 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
332 while ($field->fetch()) {
333 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
334 if ($formattedField !== NULL) {
335 $fields[$name] = $formattedField;
341 if (empty($fields) && !$validGroup) {
342 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.',
343 array(1 => implode(',', $profileIds))
347 self
::reformatProfileFields($fields);
354 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
357 * @param array $groupArr (mimic CRM_UF_DAO_UFGroup)
358 * @param array $fieldArrs list of fields (each mimics CRM_UF_DAO_UFField)
359 * @param bool $visibility visibility of fields we are interested in
360 * @param bool $searchable
361 * @param bool $showAll
363 * @param int $permissionType
366 * @see self::getFields
368 public static function formatUFFields(
375 $permissionType = CRM_Core_Permission
::CREATE
377 // $group = new CRM_Core_DAO_UFGroup();
378 // $group->copyValues($groupArr); // no... converts string('') to string('null')
379 $group = (object) $groupArr;
381 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
382 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
383 // they did -- the obvious fix would produce mutual recursion.
384 $ufGroupType = self
::_calculateGroupType($fieldArrs);
385 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',',$ufGroupType));
386 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',',$ufGroupType));
387 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
388 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
390 $formattedFields = array();
391 foreach ($fieldArrs as $fieldArr) {
392 $field = (object) $fieldArr;
393 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
397 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
398 if ($formattedField !== NULL) {
399 $formattedFields[$name] = $formattedField;
402 return $formattedFields;
406 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
408 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
409 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
410 * @param array $addressCustomFields
411 * @param array $importableFields
412 * @param array $customFields
413 * @param int $permissionType eg CRM_Core_Permission::CREATE
416 protected static function formatUFField(
420 $addressCustomFields,
422 $permissionType = CRM_Core_Permission
::CREATE
424 $name = $field->field_name
;
425 $title = $field->label
;
427 $addressCustom = FALSE;
428 if (in_array($permissionType, array(
429 CRM_Core_Permission
::CREATE
,
430 CRM_Core_Permission
::EDIT
,
432 in_array($field->field_name
, array_keys($addressCustomFields))
434 $addressCustom = TRUE;
435 $name = "address_{$name}";
437 if ($field->field_name
== 'url') {
438 $name .= "-{$field->website_type_id}";
440 elseif (!empty($field->location_type_id
)) {
441 $name .= "-{$field->location_type_id}";
444 $locationFields = self
::getLocationFields();
445 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
450 if (isset($field->phone_type_id
)) {
451 $name .= "-{$field->phone_type_id}";
454 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
455 // I guess to make field self sufficient with all the required data and avoid additional calls
456 $formattedField = array(
458 'groupTitle' => $group->title
,
459 'groupName' => $group->name
,
460 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
461 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
463 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
464 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
465 'is_required' => $field->is_required
,
466 'is_view' => $field->is_view
,
467 'help_pre' => $field->help_pre
,
468 'help_post' => $field->help_post
,
469 'visibility' => $field->visibility
,
470 'in_selector' => $field->in_selector
,
471 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
472 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
473 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
474 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
475 'group_id' => $group->id
,
476 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
477 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
478 'field_type' => $field->field_type
,
479 'field_id' => $field->id
,
480 'pseudoconstant' => CRM_Utils_Array
::value(
482 CRM_Utils_Array
::value($field->field_name
, $importableFields)
484 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
485 'dbName' => CRM_Utils_Array
::value(
487 CRM_Utils_Array
::value($field->field_name
, $importableFields)
492 //adding custom field property
493 if (substr($field->field_name
, 0, 6) == 'custom' ||
494 substr($field->field_name
, 0, 14) === 'address_custom'
496 // if field is not present in customFields, that means the user
497 // DOES NOT HAVE permission to access that field
498 if (array_key_exists($field->field_name
, $customFields)) {
499 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
501 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
502 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
503 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
505 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
506 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
507 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
510 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
511 return array($name, $formattedField);
514 $formattedField = NULL;
515 return array($name, $formattedField);
518 return array($name, $formattedField);
522 * Create a query to find all visible UFFields in a UFGroup
524 * This is the SQL-variant of checkUFFieldDisplayable().
526 * @param int $groupId
527 * @param bool $searchable
528 * @param bool $showAll
529 * @param int $visibility
530 * @param string $orderBy comma-delimited list of SQL columns
533 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
534 $where = " WHERE uf_group_id = {$groupId}";
537 $where .= " AND is_searchable = 1";
541 $where .= " AND is_active = 1";
546 if ($visibility & self
::PUBLIC_VISIBILITY
) {
547 $clause[] = 'visibility = "Public Pages"';
549 if ($visibility & self
::ADMIN_VISIBILITY
) {
550 $clause[] = 'visibility = "User and User Admin Only"';
552 if ($visibility & self
::LISTINGS_VISIBILITY
) {
553 $clause[] = 'visibility = "Public Pages and Listings"';
555 if (!empty($clause)) {
556 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
560 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
562 $query .= ", " . $orderBy;
569 * Create a query to find all visible UFFields in a UFGroup
571 * This is the PHP in-memory variant of createUFFieldQuery().
573 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
574 * @param bool $searchable
575 * @param bool $showAll
576 * @param int $visibility
577 * @return bool TRUE if field is displayable
579 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
580 if ($searchable && $field->is_searchable
!= 1) {
584 if (!$showAll && $field->is_active
!= 1) {
589 $allowedVisibilities = array();
590 if ($visibility & self
::PUBLIC_VISIBILITY
) {
591 $allowedVisibilities[] = 'Public Pages';
593 if ($visibility & self
::ADMIN_VISIBILITY
) {
594 $allowedVisibilities[] = 'User and User Admin Only';
596 if ($visibility & self
::LISTINGS_VISIBILITY
) {
597 $allowedVisibilities[] = 'Public Pages and Listings';
599 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
600 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
610 * @param $profileType
611 * @param $contactActivityProfile
615 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
617 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
620 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
623 if ($profileType == 'Activity' ||
$contactActivityProfile) {
624 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
627 $componentFields = CRM_Core_Component
::getQueryFields();
630 $importableFields = array_merge($importableFields, $componentFields);
632 $importableFields['group']['title'] = ts('Group(s)');
633 $importableFields['group']['where'] = NULL;
634 $importableFields['tag']['title'] = ts('Tag(s)');
635 $importableFields['tag']['where'] = NULL;
636 return $importableFields;
639 public static function getLocationFields() {
640 static $locationFields = array(
642 'supplemental_address_1',
643 'supplemental_address_2',
646 'postal_code_suffix',
659 return $locationFields;
667 protected static function getCustomFields($ctype) {
668 static $customFieldCache = array();
669 if (!isset($customFieldCache[$ctype])) {
670 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
672 // hack to add custom data for components
673 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
674 foreach ($components as $value) {
675 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
677 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
678 $customFields = array_merge($customFields, $addressCustomFields);
679 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
681 return $customFieldCache[$ctype];
685 * Check the data validity
687 * @param int $userID the user id that we are actually editing
688 * @param string $title the title of the group we are interested in
689 * @param bool $register
690 * @param int $action the action of the form
692 * @pram boolean $register is this the registrtion form
693 * @return boolean true if form is valid
697 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
699 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
700 ts('Dynamic Form Creator'),
703 $controller->set('id', $userID);
704 $controller->set('register', 1);
705 $controller->process();
706 return $controller->validate();
709 // make sure we have a valid group
710 $group = new CRM_Core_DAO_UFGroup();
712 $group->title
= $title;
714 if ($group->find(TRUE) && $userID) {
715 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
716 $controller->set('gid', $group->id
);
717 $controller->set('id', $userID);
718 $controller->set('register', 0);
719 $controller->process();
720 return $controller->validate();
727 * Get the html for the form that represents this particular group
729 * @param int $userID the user id that we are actually editing
730 * @param string $title the title of the group we are interested in
731 * @param int $action the action of the form
732 * @param boolean $register is this the registration form
733 * @param boolean $reset should we reset the form?
734 * @param int $profileID do we have the profile ID?
736 * @param bool $doNotProcess
739 * @return string the html for the form on success, otherwise empty string
743 static function getEditHTML($userID,
749 $doNotProcess = FALSE,
754 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
755 ts('Dynamic Form Creator'),
758 if ($reset ||
$doNotProcess) {
759 // hack to make sure we do not process this form
760 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
763 unset($_POST['_qf_default']);
764 unset($_REQUEST['_qf_default']);
766 $controller->reset();
770 $controller->set('id', $userID);
771 $controller->set('register', 1);
772 $controller->set('skipPermission', 1);
773 $controller->set('ctype', $ctype);
774 $controller->process();
775 if ($doNotProcess ||
!empty($_POST)) {
776 $controller->validate();
778 $controller->setEmbedded(TRUE);
780 //CRM-5839 - though we want to process form, get the control back.
781 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
785 // we are done processing so restore the POST/REQUEST vars
786 if (($reset ||
$doNotProcess) && $oldQFDefault) {
787 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
790 $template = CRM_Core_Smarty
::singleton();
792 // Hide CRM error messages if they are displayed using drupal form_set_error.
793 if (!empty($_POST)) {
794 $template->assign('suppressForm', TRUE);
797 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
801 // make sure we have a valid group
802 $group = new CRM_Core_DAO_UFGroup();
804 $group->title
= $title;
806 if ($group->find(TRUE)) {
807 $profileID = $group->id
;
812 // make sure profileID and ctype match if ctype exists
814 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
815 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
816 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
819 if (($profileType != 'Contact') && ($profileType != $ctype)) {
824 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
825 ts('Dynamic Form Creator'),
829 $controller->reset();
831 $controller->set('gid', $profileID);
832 $controller->set('id', $userID);
833 $controller->set('register', 0);
834 $controller->set('skipPermission', 1);
836 $controller->set('ctype', $ctype);
838 $controller->process();
839 $controller->setEmbedded(TRUE);
841 //CRM-5846 - give the control back to drupal.
842 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
845 $template = CRM_Core_Smarty
::singleton();
847 // Hide CRM error messages if they are displayed using drupal form_set_error.
848 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
849 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
850 $template->assign('suppressForm', TRUE);
854 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
855 if (!$template->template_exists($templateFile)) {
856 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
858 return trim($template->fetch($templateFile));
861 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
863 // if post not empty then only proceed
864 if (!empty($_POST)) {
866 $config = CRM_Core_Config
::singleton();
867 $email = CRM_Utils_Array
::value('mail', $_POST);
869 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
870 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
879 * Searches for a contact in the db with similar attributes
881 * @param array $params the list of values to be used in the where clause
882 * @param int $id the current contact id (hence excluded from matching)
883 * @param string $contactType
885 * @return int|null contact_id if found, null otherwise
889 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
890 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
891 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
892 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
894 return implode(',', $ids);
902 * Given a contact id and a field set, return the values from the db
906 * @param array $fields the profile fields of interest
907 * @param array $values the values for the above fields
908 * @param boolean $searchable searchable or not
909 * @param array $componentWhere component condition
910 * @param boolean $absolute return urls in absolute form (useful when sending an email)
911 * @param null $additionalWhereClause
917 public static function getValues($cid, &$fields, &$values,
918 $searchable = TRUE, $componentWhere = NULL,
919 $absolute = FALSE, $additionalWhereClause = NULL
921 if (empty($cid) && empty($componentWhere)) {
925 // get the contact details (hier)
926 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
927 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
929 // add conditions specified by components. eg partcipant_id etc
930 if (!empty($componentWhere)) {
931 $params = array_merge($params, $componentWhere);
934 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
935 $options = &$query->_options
;
937 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
938 FALSE, FALSE, FALSE, $additionalWhereClause);
939 if (!$details->fetch()) {
942 $query->convertToPseudoNames($details);
943 $config = CRM_Core_Config
::singleton();
945 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
946 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
947 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
949 $multipleFields = array('url');
951 //start of code to set the default values
952 foreach ($fields as $name => $field) {
955 $name = 'contact_id';
958 // skip fields that should not be displayed separately
959 if (!empty($field['skipDisplay'])) {
963 // Create a unique, non-empty index for each field.
964 $index = $field['title'];
965 if ($index === '') $index = ' ';
966 while (array_key_exists($index, $values))
969 $params[$index] = $values[$index] = '';
970 $customFieldName = NULL;
972 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
973 // to handle gender / suffix / prefix
974 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
975 $params[$index] = $details->$name;
976 $values[$index] = $details->$name;
978 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
979 $dname = $name . '_display';
980 $values[$index] = $details->$dname;
981 $name = $name . '_id';
982 $params[$index] = $details->$name;
984 elseif (in_array($name, array(
985 'state_province', 'country', 'county'))) {
986 $values[$index] = $details->$name;
987 $idx = $name . '_id';
988 $params[$index] = $details->$idx;
990 elseif ($name === 'preferred_communication_method') {
991 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
993 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
995 foreach ($pref as $k) {
997 $compref[] = $communicationFields[$k];
1000 $params[$index] = $details->$name;
1001 $values[$index] = implode(',', $compref);
1003 elseif ($name === 'preferred_language') {
1004 $params[$index] = $details->$name;
1005 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1007 elseif ($name == 'group') {
1008 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1009 $title = $ids = array();
1011 foreach ($groups as $g) {
1012 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1013 // VIEW permission on that group
1014 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1016 if ($g['visibility'] != 'User and User Admin Only' ||
1017 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1019 $title[] = $g['title'];
1020 if ($g['visibility'] == 'Public Pages') {
1021 $ids[] = $g['group_id'];
1025 $values[$index] = implode(', ', $title);
1026 $params[$index] = implode(',', $ids);
1028 elseif ($name == 'tag') {
1029 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1030 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1032 foreach ($entityTags as $tagId) {
1033 $title[] = $allTags[$tagId];
1035 $values[$index] = implode(', ', $title);
1036 $params[$index] = implode(',', $entityTags);
1038 elseif ($name == 'activity_status_id') {
1039 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1040 $values[$index] = $activityStatus[$details->$name];
1041 $params[$index] = $details->$name;
1043 elseif ($name == 'activity_date_time') {
1044 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1045 $params[$index] = $details->$name;
1047 elseif ($name == 'contact_sub_type') {
1048 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1049 if (!empty($contactSubTypeNames)) {
1050 $contactSubTypeLabels = array();
1051 // get all contact subtypes
1052 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1053 // build contact subtype labels array
1054 foreach( $contactSubTypeNames as $cstName ) {
1056 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1059 $values[$index] = implode(',', $contactSubTypeLabels);
1062 $params[$index] = $details->$name;
1065 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1066 if ($details->$name) {
1067 $values[$index] = '[ x ]';
1071 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1072 $htmlType = $field['html_type'];
1074 // field_type is only set when we are retrieving profile values
1075 // when sending email, we call the same function to get custom field
1076 // values etc, i.e. emulating a profile
1077 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1079 if ($htmlType == 'File') {
1082 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
1083 $entityId = $componentWhere[0][2];
1086 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1090 $additionalWhereClause
1092 $params[$index] = $values[$index] = $fileURL['file_url'];
1096 if (isset($dao) && property_exists($dao, 'data_type') &&
1097 ($dao->data_type
== 'Int' ||
1098 $dao->data_type
== 'Boolean'
1101 $customVal = (int )($details->{$name});
1103 elseif (isset($dao) && property_exists($dao, 'data_type')
1104 && $dao->data_type
== 'Float'
1106 $customVal = (float )($details->{$name});
1108 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1111 $customVal = $details->{$name};
1115 if (CRM_Utils_System
::isNull($customVal)) {
1119 $params[$index] = $customVal;
1120 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1124 if ($field['data_type'] == 'ContactReference') {
1125 $params[$index] = $values[$index];
1127 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1128 $cfID, 'is_search_range'
1130 $customFieldName = "{$name}_from";
1134 elseif ($name == 'image_URL') {
1135 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1136 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1138 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1139 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1141 elseif (in_array($name, array(
1142 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1143 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1144 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1148 if ($index == 'Campaign') {
1149 $dao = 'CRM_Campaign_DAO_Campaign';
1151 elseif ($index == 'Contribution Page') {
1152 $dao = 'CRM_Contribute_DAO_ContributionPage';
1155 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1158 $value = $details->$name;
1160 $values[$index] = $value;
1165 elseif (strpos($name, '-') !== FALSE) {
1166 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1168 if (!in_array($fieldName, $multipleFields)) {
1169 if ($id == 'Primary') {
1171 // not sure why we'd every use Primary location type id
1172 // we need to fix the source if we are using it
1173 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1174 $locationTypeName = 1;
1177 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1180 if (!$locationTypeName) {
1184 $detailName = "{$locationTypeName}-{$fieldName}";
1185 $detailName = str_replace(' ', '_', $detailName);
1187 if (in_array($fieldName, array(
1188 'phone', 'im', 'email', 'openid'))) {
1190 $detailName .= "-{$type}";
1194 if (in_array($fieldName, array(
1195 'state_province', 'country', 'county'))) {
1196 $values[$index] = $details->$detailName;
1197 $idx = $detailName . '_id';
1198 $params[$index] = $details->$idx;
1200 elseif ($fieldName == 'im') {
1201 $providerId = $detailName . '-provider_id';
1202 if (isset($imProviders[$details->$providerId])) {
1203 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1206 $values[$index] = $details->$detailName;
1208 $params[$index] = $details->$detailName;
1210 elseif ($fieldName == 'phone') {
1211 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1212 if (isset($details->$phoneExtField)) {
1213 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1216 $values[$index] = $details->$detailName;
1218 $params[$index] = $details->$detailName;
1221 $values[$index] = $params[$index] = $details->$detailName;
1225 $detailName = "website-{$id}-{$fieldName}";
1226 $url = CRM_Utils_System
::fixURL($details->$detailName);
1227 if ($details->$detailName) {
1228 $websiteTypeId = "website-{$id}-website_type_id";
1229 $websiteType = $websiteTypes[$details->$websiteTypeId];
1230 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1233 $values[$index] = '';
1238 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1239 CRM_Core_Permission
::check('profile listings and forms')
1242 if (CRM_Utils_System
::isNull($params[$index])) {
1243 $params[$index] = $values[$index];
1245 if (!isset($params[$index])) {
1248 if (!$customFieldName) {
1249 $fieldName = $field['name'];
1252 $fieldName = $customFieldName;
1256 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1257 $htmlType = $field['html_type'];
1258 if ($htmlType == 'Link') {
1259 $url = $params[$index];
1261 elseif (in_array($htmlType, array(
1262 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1263 'Multi-Select State/Province', 'Multi-Select Country',
1265 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1266 $selectedOptions = explode($valSeperator, $params[$index]);
1268 foreach ($selectedOptions as $key => $multiOption) {
1270 $url[] = CRM_Utils_System
::url('civicrm/profile',
1271 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1272 urlencode($fieldName) .
1274 urlencode($multiOption)
1280 $url = CRM_Utils_System
::url('civicrm/profile',
1281 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1282 urlencode($fieldName) .
1284 urlencode($params[$index])
1289 $url = CRM_Utils_System
::url('civicrm/profile',
1290 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1291 urlencode($fieldName) .
1293 urlencode($params[$index])
1298 !empty($values[$index]) &&
1302 if (is_array($url) && !empty($url)) {
1304 $eachMultiValue = explode(', ', $values[$index]);
1305 foreach ($eachMultiValue as $key => $valueLabel) {
1306 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1308 $values[$index] = implode(', ', $links);
1311 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1319 * Check if profile Group used by any module.
1321 * @param int $id profile Id
1329 public static function usedByModule($id) {
1330 //check whether this group is used by any module(check uf join records)
1332 FROM civicrm_uf_join
1333 WHERE civicrm_uf_join.uf_group_id=$id";
1335 $dao = new CRM_Core_DAO();
1337 if ($dao->fetch()) {
1346 * Delete the profile Group.
1348 * @param int $id profile Id
1356 public static function del($id) {
1357 //check whether this group contains any profile fields
1358 $profileField = new CRM_Core_DAO_UFField();
1359 $profileField->uf_group_id
= $id;
1360 $profileField->find();
1361 while ($profileField->fetch()) {
1362 CRM_Core_BAO_UFField
::del($profileField->id
);
1365 //delete records from uf join table
1366 $ufJoin = new CRM_Core_DAO_UFJoin();
1367 $ufJoin->uf_group_id
= $id;
1370 //delete profile group
1371 $group = new CRM_Core_DAO_UFGroup();
1380 * @param array $params reference array contains the values submitted by the form
1381 * @param array $ids reference array contains the id
1388 static function add(&$params, $ids = array()) {
1389 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1390 foreach ($fields as $field) {
1391 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1394 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1395 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1398 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1399 $params['group_type'] = implode(',', $params['group_type']);
1401 $ufGroup = new CRM_Core_DAO_UFGroup();
1402 $ufGroup->copyValues($params);
1404 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1406 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1408 $ufGroup->id
= $ufGroupID;
1413 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1421 * Make uf join entries for an uf group
1423 * @param array $params (reference) an assoc array of name/value pairs
1424 * @param int $ufGroupId ufgroup id
1430 static function createUFJoin(&$params, $ufGroupId) {
1431 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1433 // get ufjoin records for uf group
1434 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1436 // get the list of all ufgroup types
1437 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1439 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1440 if (!is_array($groupTypes)) {
1441 $groupTypes = array();
1444 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1445 if (!is_array($ufGroupRecord)) {
1446 $ufGroupRecord = array();
1449 // check which values has to be inserted/deleted for contact
1450 $menuRebuild = FALSE;
1451 foreach ($allUFGroupType as $key => $value) {
1452 $joinParams = array();
1453 $joinParams['uf_group_id'] = $ufGroupId;
1454 $joinParams['module'] = $key;
1455 if ($key == 'User Account') {
1456 $menuRebuild = TRUE;
1458 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1459 // insert a new record
1460 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1462 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1463 // delete a record for existing ufgroup
1464 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1470 UPDATE civicrm_uf_join
1472 WHERE uf_group_id = %2
1473 AND ( entity_id IS NULL OR entity_id <= 0 )
1475 $p = array(1 => array($params['weight'], 'Integer'),
1476 2 => array($ufGroupId, 'Integer'),
1478 CRM_Core_DAO
::executeQuery($query, $p);
1480 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1482 $config = CRM_Core_Config
::singleton();
1484 $config->userSystem
->is_drupal
1491 * Get the UF Join records for an ufgroup id
1493 * @param int $ufGroupId uf group id
1494 * @param int $displayName if set return display name in array
1495 * @param int $status if set return module other than default modules (User Account/User registration/Profile)
1497 * @return array $ufGroupJoinRecords
1502 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1504 $UFGroupType = array();
1505 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1509 $dao = new CRM_Core_DAO_UFJoin();
1512 $dao->uf_group_id
= $ufGroupId;
1518 while ($dao->fetch()) {
1519 if (!$displayName) {
1520 $ufJoin[$dao->id
] = $dao->module
;
1523 if (isset($UFGroupType[$dao->module
])) {
1524 // skip the default modules
1526 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1528 // added for CRM-1475
1530 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1531 $ufJoin[$dao->id
] = $dao->module
;
1539 * Function takes an associative array and creates a ufjoin record for ufgroup
1541 * @param array $params (reference) an assoc array of name/value pairs
1543 * @return CRM_Core_BAO_UFJoin object
1547 static function addUFJoin(&$params) {
1548 $ufJoin = new CRM_Core_DAO_UFJoin();
1549 $ufJoin->copyValues($params);
1555 * Delete the uf join record for an uf group
1557 * @param array $params (reference) an assoc array of name/value pairs
1563 static function delUFJoin(&$params) {
1564 $ufJoin = new CRM_Core_DAO_UFJoin();
1565 $ufJoin->copyValues($params);
1570 * Get the weight for ufjoin record
1572 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1574 * @return int weight of the UFGroup
1578 static function getWeight($ufGroupId = NULL) {
1579 //calculate the weight
1582 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1583 FROM civicrm_uf_join
1584 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1587 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1588 FROM civicrm_uf_join
1589 WHERE civicrm_uf_join.uf_group_id = %1
1590 AND ( entity_id IS NULL OR entity_id <= 0 )";
1591 $p[1] = array($ufGroupId, 'Integer');
1594 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1596 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1600 * Get the uf group for a module
1602 * @param string $moduleName module name
1603 * @param int $count no to increment the weight
1604 * @param bool $skipPermission
1605 * @param int $op - which operation (view, edit, create, etc) to check permission for
1606 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1608 * @return array $ufGroups array of ufgroups for a module
1612 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1613 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1615 if (!CRM_Core_Config
::isUpgradeMode()) {
1616 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1617 $selectFields[] = 'description';
1620 if (!empty($returnFields)) {
1621 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1624 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1625 FROM civicrm_uf_group
1626 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1629 $queryString .= ' AND civicrm_uf_group.is_active = 1
1630 WHERE civicrm_uf_join.module = %2';
1631 $p[2] = array($moduleName, 'String');
1635 // add permissioning for profiles only if not registration
1636 if (!$skipPermission) {
1637 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1638 if (strpos($queryString, 'WHERE') !== FALSE) {
1639 $queryString .= " AND $permissionClause ";
1642 $queryString .= " $permissionClause ";
1646 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1647 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1649 $ufGroups = array();
1650 while ($dao->fetch()) {
1651 //skip mix profiles in user Registration / User Account
1652 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1653 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1657 foreach ($selectFields as $key => $field) {
1658 if($field == 'id') {
1661 elseif ($field == 'name') {
1662 $ufGroups[$dao->id
][$field] = $dao->title
;
1665 $ufGroups[$dao->id
][$field] = $dao->$field;
1669 // Allow other modules to alter/override the UFGroups.
1670 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1676 * Filter ufgroups based on logged in user contact type
1678 * @param int $ufGroupId uf group id (profile id)
1679 * @param int $contactID
1681 * @return boolean true or false
1685 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1687 $session = CRM_Core_Session
::singleton();
1688 $contactID = $session->get('userID');
1692 //get the contact type
1693 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1695 //match if exixting contact type is same as profile contact type
1696 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1698 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1699 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1702 //allow special mix profiles for Contribution and Participant
1703 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1705 if (in_array($profileType, $specialProfiles)) {
1709 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1718 * Add profile field to a form
1720 * @param CRM_Core_Form $form
1721 * @param array $field properties
1722 * @param int $mode profile mode
1723 * @param int $contactId
1724 * @param bool $online
1725 * @param string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
1726 * @param int $rowNumber
1727 * @param string $prefix
1733 static function buildProfile(
1743 $defaultValues = array();
1744 $fieldName = $field['name'];
1745 $title = $field['title'];
1746 $attributes = $field['attributes'];
1747 $rule = $field['rule'];
1748 $view = $field['is_view'];
1749 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1750 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1751 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1753 // do not display view fields in drupal registration form
1755 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1759 if ($usedFor == 'onbehalf') {
1760 $name = "onbehalf[$fieldName]";
1762 elseif ($usedFor == 'honor') {
1763 $name = "honor[$fieldName]";
1765 elseif ($contactId && !$online) {
1766 $name = "field[$contactId][$fieldName]";
1768 elseif ($rowNumber) {
1769 $name = "field[$rowNumber][$fieldName]";
1771 elseif (!empty($prefix)) {
1772 $name = $prefix ."[$fieldName]";
1778 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1780 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1781 $deleteExtra = ts('Are you sure you want to delete contact image.');
1783 CRM_Core_Action
::DELETE
=>
1785 'name' => ts('Delete Contact Image'),
1786 'url' => 'civicrm/contact/image',
1787 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1789 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1792 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1793 CRM_Core_Action
::DELETE
,
1794 array('id' => $form->get('id'),
1795 'gid' => $form->get('gid'),
1799 'contact.profileimage.delete',
1803 $form->assign('deleteURL', $deleteURL);
1805 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1806 'address_options', TRUE, NULL, TRUE
1809 if (substr($fieldName, 0, 14) === 'state_province') {
1810 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1811 $config = CRM_Core_Config
::singleton();
1812 if (!in_array($mode, array(
1813 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1814 $config->defaultContactStateProvince
1816 $defaultValues[$name] = $config->defaultContactStateProvince
;
1817 $form->setDefaults($defaultValues);
1820 elseif (substr($fieldName, 0, 7) === 'country') {
1821 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1822 $config = CRM_Core_Config
::singleton();
1823 if (!in_array($mode, array(
1824 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1825 $config->defaultContactCountry
1827 $defaultValues[$name] = $config->defaultContactCountry
;
1828 $form->setDefaults($defaultValues);
1831 elseif (substr($fieldName, 0, 6) === 'county') {
1832 if ($addressOptions['county']) {
1833 $form->addChainSelect($name, array('label' => $title, 'required' => $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 (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1896 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1897 foreach ($pseudoValues as $key => $var) {
1898 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1900 $group = $form->addGroup($options, $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->addSelect($name, array(
1911 'entity' => 'contact',
1912 'field' => $fieldName,
1914 'placeholder' => '',
1917 elseif ($fieldName === 'contact_sub_type') {
1918 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1919 if ($usedFor == 'onbehalf') {
1920 $profileType = 'Organization';
1922 elseif ($usedFor == 'honor') {
1923 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1926 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1927 if ($profileType == 'Contact') {
1928 $profileType = 'Individual';
1932 $setSubtype = FALSE;
1933 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1934 $setSubtype = $profileType;
1935 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1938 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
1941 $subtypeList = array();
1942 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1945 $subtypeList = $subtypes;
1948 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1949 $sel->setMultiple(TRUE);
1951 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1952 //add email greeting, postal greeting, addressee, CRM-4575
1953 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1954 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
1956 if (empty($profileType) ||
in_array($profileType, array(
1957 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1958 $profileType = 'Individual';
1960 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1961 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1964 'contact_type' => $profileType,
1965 'greeting_type' => $fieldName,
1967 $form->add('select', $name, $title,
1969 '' => ts('- select -')) + CRM_Core_PseudoConstant
::greeting($greeting), $required
1971 // add custom greeting element
1972 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1976 elseif ($fieldName === 'preferred_communication_method') {
1977 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1978 foreach ($communicationFields as $key => $var) {
1982 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
1984 $form->addGroup($communicationOptions, $name, $title, '<br/>');
1986 elseif ($fieldName === 'preferred_mail_format') {
1987 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
1989 elseif ($fieldName === 'preferred_language') {
1990 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
1992 elseif ($fieldName == 'external_identifier') {
1993 $form->add('text', $name, $title, $attributes, $required);
1994 $contID = $contactId;
1996 $contID = $form->get('id');
1998 $form->addRule($name,
1999 ts('External ID already exists in Database.'),
2001 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2004 elseif ($fieldName === 'group') {
2005 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2006 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2011 elseif ($fieldName === 'tag') {
2012 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2013 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2018 elseif (substr($fieldName, 0, 4) === 'url-') {
2019 $form->add('text', $name, $title,
2020 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2022 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2023 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2028 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2030 // Note should be rendered as textarea
2031 elseif (substr($fieldName, -4) == 'note') {
2032 $form->add('textarea', $name, $title, $attributes, $required);
2034 elseif (substr($fieldName, 0, 6) === 'custom') {
2035 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2036 if ($customFieldID) {
2037 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2040 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2041 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2042 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2043 if ($customFieldID) {
2044 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2047 elseif (in_array($fieldName, array(
2048 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2049 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2051 elseif ($fieldName == 'send_receipt') {
2052 $form->addElement('checkbox', $name, $title);
2054 elseif ($fieldName == 'soft_credit') {
2055 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2056 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2058 elseif ($fieldName == 'product_name') {
2059 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2060 $sel = &$form->addElement('hierselect', $name, $title);
2062 '0' => ts('- select -')) +
$products;
2063 $sel->setOptions(array($products, $options));
2065 elseif ($fieldName == 'payment_instrument') {
2066 $form->add('select', $name, $title,
2067 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant
::paymentInstrument( ), $required );
2069 else if ($fieldName == 'financial_type' ) {
2070 $form->add('select', $name, $title,
2072 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(), $required
2075 elseif ($fieldName == 'contribution_status_id') {
2076 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2077 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2083 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2086 $form->add('select', $name, $title,
2088 '' => ts('- select -')) +
$contributionStatuses, $required
2091 elseif ($fieldName == 'soft_credit_type') {
2092 $name = "soft_credit_type[$rowNumber]";
2093 $form->add('select', $name, $title,
2095 '' => ts('- select -')) + CRM_Core_OptionGroup
::values("soft_credit_type")
2097 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2098 //else (for contribution), use configured SCT default value
2099 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2100 if ($field['field_type'] == 'Membership') {
2101 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2103 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2105 elseif ($fieldName == 'currency') {
2106 $form->addCurrency($name, $title, $required);
2108 elseif ($fieldName == 'contribution_page_id') {
2109 $form->add('select', $name, $title,
2111 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2114 elseif ($fieldName == 'participant_register_date') {
2115 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2117 elseif ($fieldName == 'activity_status_id') {
2118 $form->add('select', $name, $title,
2120 '' => ts('- select -')) + CRM_Core_PseudoConstant
::activityStatus(), $required
2123 elseif ($fieldName == 'activity_engagement_level') {
2124 $form->add('select', $name, $title,
2126 '' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2129 elseif ($fieldName == 'activity_date_time') {
2130 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2132 elseif ($fieldName == 'participant_status') {
2134 if ($online == TRUE) {
2135 $cond = 'visibility_id = 1';
2137 $form->add('select', $name, $title,
2139 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2142 elseif ($fieldName == 'participant_role') {
2143 if (!empty($field['is_multiple'])) {
2144 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2147 $form->add('select', $name, $title,
2149 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantRole(), $required
2153 elseif ($fieldName == 'world_region') {
2154 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2156 elseif ($fieldName == 'signature_html') {
2157 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2159 elseif ($fieldName == 'signature_text') {
2160 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2162 elseif (substr($fieldName, -11) == 'campaign_id') {
2163 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2164 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2165 $form->_componentCampaigns
2167 $form->add('select', $name, $title,
2169 '' => ts('- select -')) +
$campaigns, $required, 'class="crm-select2 big"'
2173 elseif ($fieldName == 'activity_details') {
2174 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2176 elseif ($fieldName == 'activity_duration') {
2177 $form->add('text', $name, $title, $attributes, $required);
2178 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2181 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2182 $form->add('advcheckbox', $name, $title, $attributes, $required);
2185 $form->add('text', $name, $title, $attributes, $required);
2189 static $hiddenSubtype = FALSE;
2190 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2191 // In registration mode params are submitted via POST and we don't have any clue
2192 // about profile-id or the profile-type (which could be a subtype)
2193 // To generalize the behavior and simplify the process,
2194 // lets always add the hidden
2195 //subtype value if there is any, and we won't have to
2196 // compute it while processing.
2198 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2201 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2203 $hiddenSubtype = TRUE;
2206 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2207 $form->freeze($name);
2211 if (in_array($fieldName, array(
2212 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2213 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2216 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2217 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2223 * Set profile defaults
2225 * @param int $contactId contact id
2226 * @param array $fields associative array of fields
2227 * @param array $defaults defaults array
2228 * @param boolean $singleProfile true for single profile else false(batch update)
2229 * @param int $componentId id for specific components like contribute, event etc
2230 * @param null $component
2236 static function setProfileDefaults($contactId, &$fields, &$defaults,
2237 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2239 if (!$componentId) {
2240 //get the contact details
2241 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2242 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2243 $multipleFields = array('website' => 'url');
2245 //start of code to set the default values
2246 foreach ($fields as $name => $field) {
2247 // skip pseudo fields
2248 if (substr($name, 0, 9) == 'phone_ext') {
2252 //set the field name depending upon the profile mode(single/batch)
2253 if ($singleProfile) {
2257 $fldName = "field[$contactId][$name]";
2260 if ($name == 'group') {
2261 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2263 if ($name == 'tag') {
2264 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2267 if (!empty($details[$name]) ||
isset($details[$name])) {
2268 //to handle custom data (checkbox) to be written
2269 // to handle birth/deceased date, greeting_type and few other fields
2270 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2271 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2273 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2274 $defaults[$fldName] = $details[$name . '_id'];
2275 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2277 elseif ($name == 'preferred_communication_method') {
2278 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2279 foreach ($v as $item) {
2281 $defaults[$fldName . "[$item]"] = 1;
2285 elseif ($name == 'contact_sub_type') {
2286 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2288 elseif ($name == 'world_region') {
2289 $defaults[$fldName] = $details['worldregion_id'];
2291 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2292 //fix for custom fields
2293 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2295 // hack to add custom data for components
2296 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2297 foreach ($components as $value) {
2298 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2299 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2303 switch ($customFields[$customFieldId]['html_type']) {
2304 case 'Multi-Select State/Province':
2305 case 'Multi-Select Country':
2306 case 'AdvMulti-Select':
2307 case 'Multi-Select':
2308 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2309 foreach ($v as $item) {
2311 $defaults[$fldName][$item] = $item;
2317 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2318 foreach ($v as $item) {
2320 $defaults[$fldName][$item] = 1;
2321 // seems like we need this for QF style checkboxes in profile where its multiindexed
2323 $defaults["{$fldName}[{$item}]"] = 1;
2329 // CRM-6681, set defult values according to date and time format (if any).
2331 if (!empty($customFields[$customFieldId]['date_format'])) {
2332 $dateFormat = $customFields[$customFieldId]['date_format'];
2335 if (empty($customFields[$customFieldId]['time_format'])) {
2336 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2341 $timeElement = $fldName . '_time';
2342 if (substr($fldName, -1) == ']') {
2343 $timeElement = substr($fldName, 0, -1) . '_time]';
2345 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2346 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2351 $defaults[$fldName] = $details[$name];
2356 $defaults[$fldName] = $details[$name];
2360 $blocks = array('email', 'phone', 'im', 'openid');
2361 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2362 if (!in_array($fieldName, $multipleFields)) {
2363 if (is_array($details)) {
2364 foreach ($details as $key => $value) {
2365 // when we fixed CRM-5319 - get primary loc
2366 // type as per loc field and removed below code.
2367 $primaryLocationType = FALSE;
2368 if ($locTypeId == 'Primary') {
2369 if (is_array($value) && array_key_exists($fieldName, $value)){
2370 $primaryLocationType = TRUE;
2371 if (in_array($fieldName, $blocks)){
2372 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2375 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2380 // fixed for CRM-665
2381 if (is_numeric($locTypeId)) {
2382 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2383 if (!empty($value[$fieldName])) {
2384 //to handle stateprovince and country
2385 if ($fieldName == 'state_province') {
2386 $defaults[$fldName] = $value['state_province_id'];
2388 elseif ($fieldName == 'county') {
2389 $defaults[$fldName] = $value['county_id'];
2391 elseif ($fieldName == 'country') {
2392 if (!isset($value['country_id']) ||
!$value['country_id']) {
2393 $config = CRM_Core_Config
::singleton();
2394 if ($config->defaultContactCountry
) {
2395 $defaults[$fldName] = $config->defaultContactCountry
;
2399 $defaults[$fldName] = $value['country_id'];
2402 elseif ($fieldName == 'phone') {
2404 if (isset($value['phone'][$phoneTypeId])) {
2405 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2407 if (isset($value['phone_ext'][$phoneTypeId])) {
2408 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2412 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2414 if (!is_array($phoneDefault)) {
2415 $defaults[$fldName] = $phoneDefault;
2419 elseif ($fieldName == 'email') {
2420 //adding the first email (currently we don't support multiple emails of same location type)
2421 $defaults[$fldName] = $value['email'];
2423 elseif ($fieldName == 'im') {
2424 //adding the first im (currently we don't support multiple ims of same location type)
2425 $defaults[$fldName] = $value['im'];
2426 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2429 $defaults[$fldName] = $value[$fieldName];
2432 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2433 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2435 $defaults[$fldName] = $value[substr($fieldName, 8)];
2443 if (is_array($details)) {
2444 if ($fieldName === 'url'
2445 && !empty($details['website'])
2446 && !empty($details['website'][$locTypeId])) {
2447 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2455 //Handling Contribution Part of the batch profile
2456 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2457 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2460 //Handling Event Participation Part of the batch profile
2461 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2462 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2465 //Handling membership Part of the batch profile
2466 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2467 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2470 //Handling Activity Part of the batch profile
2471 if ($component == 'Activity') {
2472 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2477 * Get profiles by type eg: pure Individual etc
2479 * @param array $types associative array of types eg: types('Individual')
2480 * @param boolean $onlyPure true if only pure profiles are required
2482 * @return array $profiles associative array of profiles
2486 static function getProfiles($types, $onlyPure = FALSE) {
2487 $profiles = array();
2488 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2490 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2492 // Exclude Batch Data Entry profiles - CRM-10901
2493 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2495 foreach ($ufGroups as $id => $title) {
2496 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2497 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2498 $profiles[$id] = $title;
2505 * Check whether a profile is valid combination of
2506 * required and/or optional profile types
2508 * @param array $required array of types those are required
2509 * @param array $optional array of types those are optional
2511 * @return array $profiles associative array of profiles
2515 static function getValidProfiles($required, $optional = NULL) {
2516 if (!is_array($required) ||
empty($required)) {
2520 $profiles = array();
2521 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2523 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2525 foreach ($ufGroups as $id => $title) {
2526 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2528 $profiles[$id] = $title;
2536 * Check whether a profile is valid combination of
2537 * required profile fields
2539 * @param array $ufId integer id of the profile
2540 * @param array $required array of fields those are required in the profile
2542 * @return array $profiles associative array of profiles
2546 static function checkValidProfile($ufId, $required = NULL) {
2547 $validProfile = FALSE;
2549 return $validProfile;
2552 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2553 return $validProfile;
2556 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2557 NULL, FALSE, NULL, FALSE, NULL,
2558 CRM_Core_Permission
::CREATE
, NULL
2561 $validProfile = array();
2562 if (!empty($profileFields)) {
2563 $fields = array_keys($profileFields);
2564 foreach ($fields as $val) {
2565 foreach ($required as $key => $field) {
2566 if (strpos($val, $field) === 0) {
2567 unset($required[$key]);
2572 $validProfile = (empty($required)) ?
TRUE : FALSE;
2575 return $validProfile;
2579 * Get default value for Register.
2584 * @return mixed $defaults@static
2587 static function setRegisterDefaults(&$fields, &$defaults) {
2588 $config = CRM_Core_Config
::singleton();
2589 foreach ($fields as $name => $field) {
2590 if (substr($name, 0, 8) == 'country-') {
2591 if (!empty($config->defaultContactCountry
)) {
2592 $defaults[$name] = $config->defaultContactCountry
;
2595 elseif (substr($name, 0, 15) == 'state_province-') {
2596 if (!empty($config->defaultContactStateProvince
)) {
2597 $defaults[$name] = $config->defaultContactStateProvince
;
2605 * This function is to make a copy of a profile, including
2606 * all the fields in the profile
2608 * @param int $id the profile id to copy
2613 static function copy($id) {
2614 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2615 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2621 if ($pos = strrpos($copy->name
, "_{$id}")) {
2622 $copy->name
= substr_replace($copy->name
, '', $pos);
2624 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2627 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2628 array('uf_group_id' => $id),
2629 array('uf_group_id' => $copy->id
),
2634 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2635 array('uf_group_id' => $id),
2636 array('uf_group_id' => $copy->id
)
2639 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2643 UPDATE civicrm_uf_join
2645 WHERE uf_group_id = %2
2646 AND ( entity_id IS NULL OR entity_id <= 0 )
2648 $p = array(1 => array($maxWeight +
1, 'Integer'),
2649 2 => array($copy->id
, 'Integer'),
2651 CRM_Core_DAO
::executeQuery($query, $p);
2652 if ($copy->is_reserved
) {
2653 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2654 $params = array(1 => array($copy->id
, 'Integer'));
2655 CRM_Core_DAO
::executeQuery($query, $params);
2657 CRM_Utils_Hook
::copy('UFGroup', $copy);
2663 * Process that send notification e-mails
2665 * @param int $contactID contact id
2666 * @param array $values associative array of name/value pair
2672 static function commonSendMail($contactID, &$values) {
2673 if (!$contactID ||
!$values) {
2677 $template = CRM_Core_Smarty
::singleton();
2679 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2684 self
::profileDisplay($values['id'], $values['values'], $template);
2685 $emailList = explode(',', $values['email']);
2687 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2688 "reset=1&cid=$contactID",
2689 TRUE, NULL, FALSE, FALSE, TRUE
2692 //get the default domain email address.
2693 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2695 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2696 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2697 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)));
2700 foreach ($emailList as $emailTo) {
2701 // FIXME: take the below out of the foreach loop
2702 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2704 'groupName' => 'msg_tpl_workflow_uf',
2705 'valueName' => 'uf_notify',
2706 'contactId' => $contactID,
2707 'tplParams' => array(
2708 'displayName' => $displayName,
2709 'currentDate' => date('r'),
2710 'contactLink' => $contactLink,
2712 'from' => "$domainEmailName <$domainEmailAddress>",
2713 'toEmail' => $emailTo,
2720 * Given a contact id and a group id, returns the field values from the db
2721 * for this group and notify email only if group's notify field is
2722 * set and field values are not empty
2724 * @param int $gid group id
2725 * @param int $cid contact id
2726 * @param array $params
2727 * @param bool $skipCheck
2732 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2734 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2736 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2737 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2739 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2741 if (!empty($values) &&
2746 'values' => $values,
2757 * Assign uf fields to template
2759 * @param int $gid group id
2760 * @param array $values
2761 * @param CRM_Core_Smarty $template
2766 function profileDisplay($gid, $values, $template) {
2767 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2768 $template->assign('grouptitle', $groupTitle);
2769 if (count($values)) {
2770 $template->assign('values', $values);
2775 * Format fields for dupe Contact Matching
2777 * @param array $params associated array
2779 * @param int $contactId
2781 * @return array $data assoicated formatted array
2785 static function formatFields($params, $contactId = NULL) {
2787 // get the primary location type id and email
2788 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2791 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2792 $primaryLocationType = $defaultLocationType->id
;
2796 $locationType = array();
2798 $primaryLocation = 0;
2799 foreach ($params as $key => $value) {
2800 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2802 if ($locTypeId == 'Primary') {
2803 $locTypeId = $primaryLocationType;
2806 if (is_numeric($locTypeId)) {
2807 if (!in_array($locTypeId, $locationType)) {
2808 $locationType[$count] = $locTypeId;
2811 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2813 $data['location'][$loc]['location_type_id'] = $locTypeId;
2815 // if we are getting in a new primary email, dont overwrite the new one
2816 if ($locTypeId == $primaryLocationType) {
2817 if (!empty($params['email-' . $primaryLocationType])) {
2818 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2820 elseif (isset($primaryEmail)) {
2821 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2827 $data['location'][$loc]['is_primary'] = 1;
2829 if ($fieldName == 'phone') {
2831 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2834 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2836 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2838 elseif ($fieldName == 'email') {
2839 $data['location'][$loc]['email'][$loc]['email'] = $value;
2841 elseif ($fieldName == 'im') {
2842 $data['location'][$loc]['im'][$loc]['name'] = $value;
2845 if ($fieldName === 'state_province') {
2846 $data['location'][$loc]['address']['state_province_id'] = $value;
2848 elseif ($fieldName === 'country') {
2849 $data['location'][$loc]['address']['country_id'] = $value;
2852 $data['location'][$loc]['address'][$fieldName] = $value;
2857 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2858 if ($key === 'individual_suffix') {
2859 $data['suffix_id'] = $value;
2861 elseif ($key === 'individual_prefix') {
2862 $data['prefix_id'] = $value;
2864 elseif ($key === 'gender') {
2865 $data['gender_id'] = $value;
2867 elseif (substr($key, 0, 6) === 'custom') {
2868 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2870 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2871 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2873 // fix the date field
2874 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2875 $date = CRM_Utils_Date
::format($value);
2882 $data['custom'][$customFieldID] = array(
2885 'extends' => $customFields[$customFieldID]['extends'],
2886 'type' => $customFields[$customFieldID]['data_type'],
2887 'custom_field_id' => $customFieldID,
2891 elseif ($key == 'edit') {
2895 $data[$key] = $value;
2900 if (!$primaryLocation) {
2902 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2910 * Calculate the profile type 'group_type' as per profile fields.
2912 * @param int $gId profile id
2913 * @param bool $includeTypeValues
2914 * @param int $ignoreFieldId ignore particular profile field
2916 * @return array list of calculated group type
2918 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2919 //get the profile fields.
2920 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2921 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2925 * Calculate the profile type 'group_type' as per profile fields.
2928 * @param bool $includeTypeValues
2929 * @param int $ignoreFieldId ignore perticular profile field
2931 * @return array list of calculated group type
2933 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2934 $groupType = $groupTypeValues = $customFieldIds = array();
2935 if (!empty($ufFields)) {
2936 foreach ($ufFields as $fieldName => $fieldValue) {
2937 //ignore field from group type when provided.
2938 //in case of update profile field.
2939 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2942 if (!in_array($fieldValue['field_type'], $groupType)) {
2943 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2946 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
2947 $customFieldIds[$fldId] = $fldId;
2952 if (!empty($customFieldIds)) {
2953 $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) . ')';
2955 $customGroups = CRM_Core_DAO
::executeQuery($query);
2956 while ($customGroups->fetch()) {
2957 if (!$customGroups->extends_entity_column_value
) {
2961 $groupTypeName = "{$customGroups->extends}Type";
2962 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
2963 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
2966 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
2968 $groupTypeValues[$groupTypeName][$val] = $val;
2973 if (!empty($groupTypeValues)) {
2974 $groupType = array_merge($groupType, $groupTypeValues);
2982 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
2983 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
2986 * BirthDate + Email Individual,Contact
2987 * BirthDate + Subject Individual,Activity
2988 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
2989 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
2990 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
2991 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2992 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2993 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
2994 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
2997 * @param array $groupTypes With key having group type names
3001 static function updateGroupTypes($gId, $groupTypes = array()) {
3002 if (!is_array($groupTypes) ||
!$gId) {
3006 // If empty group types set group_type as 'null'
3007 if (empty($groupTypes)) {
3008 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3011 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3012 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3014 $gTypes = $gTypeValues = array();
3016 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3017 // Get valid group type and group subtypes
3018 foreach ($groupTypes as $groupType => $value) {
3019 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3020 $gTypes[] = $groupType;
3025 if (in_array($groupType, $participantExtends)) {
3026 $subTypesOf = $groupType;
3028 elseif (strpos($groupType, 'Type') > 0) {
3029 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3035 if (!empty($value) &&
3036 (in_array($subTypesOf, $componentGroupTypes) ||
3037 in_array($subTypesOf, $participantExtends)
3040 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3044 if (empty($gTypes)) {
3048 // Build String to store group types and group subtypes
3049 $groupTypeString = implode(',', $gTypes);
3050 if (!empty($gTypeValues)) {
3051 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3054 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3058 * Create a "group_type" string
3060 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3061 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3062 * @param string $delim
3065 * @throws CRM_Core_Exception
3067 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3068 $groupTypeExpr = '';
3070 $groupTypeExpr .= implode(',', $coreTypes);
3073 //CRM-15427 Allow Multiple subtype filtering
3074 //if (count($subTypes) > 1) {
3075 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3077 foreach ($subTypes as $subType => $subTypeIds) {
3078 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3081 return $groupTypeExpr;
3085 * This function is used to setDefault componet specific profile fields.
3087 * @param array $fields profile fields.
3088 * @param int $componentId componetID
3089 * @param string $component component name
3090 * @param array $defaults an array of default values.
3092 * @param bool $isStandalone
3096 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3097 if (!$componentId ||
3098 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3103 $componentBAO = $componentSubType = NULL;
3104 switch ($component) {
3106 $componentBAO = 'CRM_Member_BAO_Membership';
3107 $componentBAOName = 'Membership';
3108 $componentSubType = array('membership_type_id');
3112 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3113 $componentBAOName = 'Contribution';
3114 $componentSubType = array( 'financial_type_id' );
3118 $componentBAO = 'CRM_Event_BAO_Participant';
3119 $componentBAOName = 'Participant';
3120 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3124 $componentBAO = 'CRM_Activity_BAO_Activity';
3125 $componentBAOName = 'Activity';
3126 $componentSubType = array('activity_type_id');
3131 $params = array('id' => $componentId);
3133 //get the component values.
3134 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3135 if ($componentBAOName == 'Participant') {
3136 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3139 $formattedGroupTree = array();
3140 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3141 foreach ($fields as $name => $field) {
3142 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3143 if (in_array($name, $dateTimeFields)) {
3144 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3145 if (!empty($values[$name])) {
3146 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3149 elseif (array_key_exists($name, $values)) {
3150 $defaults[$fldName] = $values[$name];
3152 elseif ($name == 'participant_note') {
3153 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3154 $defaults[$fldName] = array_pop($noteDetails);
3156 elseif (in_array($name, array(
3157 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3158 $defaults[$fldName] = $values["{$name}_id"];
3160 elseif ($name == 'membership_type') {
3161 // since membership_type field is a hierselect -
3162 $defaults[$fldName][0] =
3163 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3164 $defaults[$fldName][1] = $values['membership_type_id'];
3166 elseif ($name == 'membership_status') {
3167 $defaults[$fldName] = $values['status_id'];
3169 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3170 if (empty($formattedGroupTree)) {
3171 //get the groupTree as per subTypes.
3172 $groupTree = array();
3173 foreach ($componentSubType as $subType) {
3174 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3175 $componentId, 0, $values[$subType]
3177 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3179 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3180 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3183 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3184 foreach ($defaults as $customKey => $customValue) {
3185 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3186 if ($name == 'custom_' . $customFieldDetails[0]) {
3188 //hack to set default for checkbox
3189 //basically this is for weired field name like field[33][custom_19]
3190 //we are converting this field name to array structure and assign value.
3193 foreach ($formattedGroupTree as $tree) {
3194 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3195 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3197 $defaults['field'][$componentId][$name] = $customValue;
3200 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3203 // CRM-6681, $default contains formatted date, time values.
3204 $defaults[$fldName] = $customValue;
3205 if (!empty($defaults[$customKey . '_time'])) {
3206 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3212 if (!$skipValue ||
$isStandalone) {
3213 $defaults[$fldName] = $customValue;
3215 unset($defaults[$customKey]);
3225 * @param array|string $profiles - name of profile(s) to create links for
3226 * @param array $appendProfiles - name of profile(s) to append to each link
3230 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3231 // Default to contact profiles
3233 $profiles = array('new_individual', 'new_organization', 'new_household');
3235 $profiles = (array) $profiles;
3236 $toGet = array_merge($profiles, (array) $appendProfiles);
3237 $retrieved = civicrm_api3('uf_group', 'get', array(
3238 'name' => array('IN' => $toGet),
3241 $links = $append = array();
3242 if (!empty($retrieved['values'])) {
3243 foreach($retrieved['values'] as $id => $profile) {
3244 if (in_array($profile['name'], $profiles)) {
3246 'label' => $profile['title'],
3247 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3248 NULL, NULL, FALSE, FALSE, TRUE) ,
3249 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3256 foreach ($append as $id) {
3257 foreach ($links as &$link) {
3258 $link['url'] .= ",$id";
3266 * Retrieve groups of profiles
3268 * @param integer $profileID id of the profile
3270 * @return array returns array
3273 static function profileGroups($profileID) {
3274 $groupTypes = array();
3275 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3276 if ($profileTypes) {
3277 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3278 $groupTypes = explode(',', $groupTypeParts[0]);
3284 * Alter contact params by filtering existing subscribed groups and returns
3285 * unsubscribed groups array for subscription.
3287 * @param array $params contact params
3288 * @param int $contactId user contact id
3290 * @return array $subscribeGroupIds This contains array of groups for subscription
3292 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3293 $config = CRM_Core_Config
::singleton();
3294 $subscribeGroupIds = array();
3296 // process further only if profileDoubleOptIn enabled and if groups exist
3297 if (!array_key_exists('group', $params) ||
3298 !self
::isProfileDoubleOptin() ||
3299 CRM_Utils_System
::isNull($params['group'])
3301 return $subscribeGroupIds;
3304 //check if contact email exist.
3306 foreach ($params as $name => $value) {
3307 if (strpos($name, 'email-') !== FALSE) {
3313 //Proceed furthur only if email present
3315 return $subscribeGroupIds;
3318 //do check for already subscriptions.
3319 $contactGroups = array();
3323 FROM civicrm_group_contact
3324 WHERE status = 'Added'
3325 AND contact_id = %1";
3327 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3328 while ($dao->fetch()) {
3329 $contactGroups[$dao->group_id
] = $dao->group_id
;
3333 //since we don't have names, compare w/ label.
3334 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3336 //actual processing start.
3337 foreach ($params['group'] as $groupId => $isSelected) {
3338 //unset group those are not selected.
3340 unset($params['group'][$groupId]);
3344 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3345 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3347 //get only mailing type group and unset it from params
3348 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3349 $subscribeGroupIds[$groupId] = $groupId;
3350 unset($params['group'][$groupId]);
3354 return $subscribeGroupIds;
3358 * Check if we are rendering mixed profiles
3360 * @param array $profileIds associated array of profile ids
3362 * @return boolean $mixProfile true if profile is mixed
3366 static function checkForMixProfiles($profileIds) {
3367 $mixProfile = FALSE;
3369 $contactTypes = array('Individual', 'Household', 'Organization');
3370 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3372 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3374 $typeCount = array('ctype' => array(), 'subtype' => array());
3375 foreach ($profileIds as $gid) {
3376 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3377 // ignore profile of type Contact
3378 if ($profileType == 'Contact') {
3381 if (in_array($profileType, $contactTypes)) {
3382 if (!isset($typeCount['ctype'][$profileType])) {
3383 $typeCount['ctype'][$profileType] = 1;
3386 // check if we are rendering profile of different contact types
3387 if (count($typeCount['ctype']) == 2) {
3392 elseif (in_array($profileType, $components)) {
3397 if (!isset($typeCount['subtype'][$profileType])) {
3398 $typeCount['subtype'][$profileType] = 1;
3400 // check if we are rendering profile of different contact sub types
3401 if (count($typeCount['subtype']) == 2) {
3411 * Determine of we show overlay profile or not
3413 * @return boolean true if profile should be shown else false
3417 static function showOverlayProfile() {
3418 $showOverlay = TRUE;
3420 // get the id of overlay profile
3421 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3422 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3424 $count = CRM_Core_DAO
::singleValueQuery($query);
3426 //check if there are no public fields and use is anonymous
3427 $session = CRM_Core_Session
::singleton();
3428 if (!$count && !$session->get('userID')) {
3429 $showOverlay = FALSE;
3432 return $showOverlay;
3436 * Get group type values of the profile
3438 * @param int $profileId
3439 * @param string $groupType
3441 * @return Array group type values
3445 static function groupTypeValues($profileId, $groupType = NULL) {
3446 $groupTypeValue = array();
3447 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3449 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3450 if (empty($groupTypeParts[1])) {
3451 return $groupTypeValue;
3453 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3455 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3457 $valueParts = explode(':', $groupTypeValues);
3459 ($valueParts[0] != "{$groupType}Type" ||
3460 ($groupType == 'Participant' &&
3461 !in_array($valueParts[0], $participantExtends)
3467 foreach ($valueParts as $val) {
3468 if (CRM_Utils_Rule
::integer($val)) {
3469 $values[$val] = $val;
3472 if (!empty($values)) {
3473 $typeName = substr($valueParts[0], 0, -4);
3474 if (in_array($valueParts[0], $participantExtends)) {
3475 $typeName = $valueParts[0];
3477 $groupTypeValue[$typeName] = $values;
3481 return $groupTypeValue;
3485 * @return bool|object
3487 static function isProfileDoubleOptin() {
3488 // check for double optin
3489 $config = CRM_Core_Config
::singleton();
3490 if (in_array('CiviMail', $config->enableComponents
)) {
3491 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3492 'profile_double_optin', NULL, FALSE
3499 * @return bool|object
3501 static function isProfileAddToGroupDoubleOptin() {
3502 // check for add to group double optin
3503 $config = CRM_Core_Config
::singleton();
3504 if (in_array('CiviMail', $config->enableComponents
)) {
3505 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3506 'profile_add_to_group_double_optin', NULL, FALSE
3513 * Get profiles used for batch entry
3515 * @return array profileIds profile ids
3518 static function getBatchProfiles() {
3520 FROM civicrm_uf_group
3521 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3522 $dao = CRM_Core_DAO
::executeQuery( $query );
3523 $profileIds = array();
3524 while( $dao->fetch() ) {
3525 $profileIds[$dao->id
] = $dao->id
;
3531 * @todo what do I do?
3533 * @param $destination
3534 * @param bool $returnMultiSummaryFields
3536 * @return array|null
3538 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3539 $multiSummaryFields = $returnMultiSummaryFields ?
array( ) : NULL;
3540 foreach ($source as $field => $properties) {
3541 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3544 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3545 $destination[$field] = $properties;
3546 if ($returnMultiSummaryFields) {
3547 if ($properties['is_multi_summary']) {
3548 $multiSummaryFields[$field] = $properties;
3551 unset($source[$field]);
3554 return $multiSummaryFields;
3558 * This is function is used to format pseudo fields
3560 * @param array $fields associated array of profile fields
3564 static function reformatProfileFields(&$fields) {
3565 //reformat fields array
3566 foreach ($fields as $name => $field) {
3567 //reformat phone and extension field
3568 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3569 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3571 // retain existing element properties and just update and replace key
3572 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3573 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3574 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3576 // add additional phone extension field
3577 $fields["phone_ext-{$fieldSuffix}"] = $field;
3578 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3579 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3580 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3581 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3582 //ignore required for extension field
3583 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;