3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
39 class CRM_Core_BAO_UFGroup
extends CRM_Core_DAO_UFGroup
{
40 CONST PUBLIC_VISIBILITY
= 1,
42 LISTINGS_VISIBILITY
= 4;
45 * cache the match clause used in this transaction
49 static $_matchFields = NULL;
52 * Takes a bunch of params that are needed to match certain criteria and
53 * retrieves the relevant objects. Typically the valid params are only
54 * contact_id. We'll tweak this function to be more full featured over a period
55 * of time. This is the inverse function of create. It also stores all the retrieved
56 * values in the default array
58 * @param array $params (reference) an assoc array of name/value pairs
59 * @param array $defaults (reference) an assoc array to hold the flattened values
61 * @return object CRM_Core_DAO_UFGroup object
65 static function retrieve(&$params, &$defaults) {
66 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
70 * Retrieve the first non-generic contact type
72 * @param int $id id of uf_group
74 * @return string contact type
76 static function getContactType($id) {
78 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
79 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
81 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
82 $types = explode(',', $typesParts[0]);
85 foreach ($types as $type) {
86 if (in_array($type, $validTypes)) {
89 elseif (array_key_exists($type, $validSubTypes)) {
90 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
100 * Get the form title.
102 * @param int $id id of uf_form
104 * @return string title
110 public static function getTitle($id) {
111 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
115 * update the is_active flag in the db
117 * @param int $id id of the database record
118 * @param boolean $is_active value we want to set the is_active field
120 * @return Object CRM_Core_DAO_UFGroup object on success, null otherwise
124 static function setIsActive($id, $is_active) {
125 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
129 * get all the registration fields
131 * @param int $action what action are we doing
132 * @param int $mode mode
134 * @return array the fields that are needed for registration
138 static function getRegistrationFields($action, $mode, $ctype = NULL) {
139 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
140 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
143 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
146 if (!is_array($ufGroups)) {
152 foreach ($ufGroups as $id => $title) {
154 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
155 if (($fieldType != 'Contact') &&
156 ($fieldType != $ctype) &&
157 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
161 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
162 $profileSubType = $fieldType;
166 $subset = self
::getFields($id, TRUE, $action,
167 NULL, NULL, FALSE, NULL, TRUE, $ctype
170 // we do not allow duplicates. the first field is the winner
171 foreach ($subset as $name => $field) {
172 if (empty($fields[$name])) {
173 $fields[$name] = $field;
182 * get all the listing fields
184 * @param int $action what action are we doing
185 * @param int $visibility visibility of fields we are interested in
186 * @param bool $considerSelector whether to consider the in_selector parameter
187 * @param array $ufGroupIds
188 * @param boolean $searchable
190 * @return array the fields that are listings related
194 static function getListingFields(
197 $considerSelector = FALSE,
201 $skipPermission = FALSE,
202 $permissionType = CRM_Core_Permission
::SEARCH
205 $subset = self
::getFields($ufGroupIds, FALSE, $action,
206 $visibility, $searchable,
212 if ($considerSelector) {
213 // drop the fields not meant for the selector
214 foreach ($subset as $name => $field) {
215 if (!$field['in_selector']) {
216 unset($subset[$name]);
223 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
226 foreach ($ufGroups as $id => $title) {
227 $subset = self
::getFields($id, FALSE, $action,
228 $visibility, $searchable,
234 if ($considerSelector) {
235 // drop the fields not meant for the selector
236 foreach ($subset as $name => $field) {
237 if (!$field['in_selector'])unset($subset[$name]);
240 $fields = array_merge($fields, $subset);
247 * Get all the fields that belong to the group with the name title,
248 * and format for use with buildProfile. This is the SQL analog of
251 * @param mix $id the id of the UF group or ids of ufgroup
252 * @param int $register are we interested in registration fields
253 * @param int $action what action are we doing
254 * @param int $visibility visibility of fields we are interested in
256 * @param boolean $showall
257 * @param string $restrict should we restrict based on a specified profile type
259 * @return array the fields that belong to this ufgroup(s)
263 static function getFields(
271 $skipPermission = FALSE,
273 $permissionType = CRM_Core_Permission
::CREATE
,
274 $orderBy = 'field_name',
275 $orderProfiles = NULL
277 if (!is_array($id)) {
278 $id = CRM_Utils_Type
::escape($id, 'Positive');
279 $profileIds = array($id);
285 $gids = implode(',', $profileIds);
288 $query = "SELECT g.* from civicrm_uf_group g, civicrm_uf_join j
289 WHERE g.id IN ( {$gids} )
290 AND j.uf_group_id IN ( {$gids} )
293 $params = array(1 => array($restrict, 'String'));
296 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
300 $query .= " AND g.is_active = 1";
303 // add permissioning for profiles only if not registration
304 if (!$skipPermission) {
305 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
306 $query .= " AND $permissionClause ";
309 if ($orderProfiles AND count($profileIds) > 1) {
310 $query .= " ORDER BY FIELD( g.id, {$gids} )";
312 $group = CRM_Core_DAO
::executeQuery($query, $params);
316 while ($group->fetch()) {
318 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
319 $field = CRM_Core_DAO
::executeQuery($query);
321 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
322 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
323 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
324 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
326 while ($field->fetch()) {
327 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
328 if ($formattedField !== NULL) {
329 $fields[$name] = $formattedField;
335 if (empty($fields) && !$validGroup) {
336 CRM_Core_Error
::fatal(ts('The requested Profile (gid=%1) is disabled OR it is not configured to be used for \'Profile\' listings in its Settings OR there is no Profile with that ID OR you do not have permission to access this profile. Please contact the site administrator if you need assistance.',
337 array(1 => implode(',', $profileIds))
341 self
::reformatProfileFields($fields);
348 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
351 * @param array $groupArr (mimic CRM_UF_DAO_UFGroup)
352 * @param array $fieldArrs list of fields (each mimics CRM_UF_DAO_UFField)
353 * @param bool $visibility visibility of fields we are interested in
354 * @param bool $searchable
355 * @param bool $showall
359 public static function formatUFFields(
366 $permissionType = CRM_Core_Permission
::CREATE
368 // $group = new CRM_Core_DAO_UFGroup();
369 // $group->copyValues($groupArr); // no... converts string('') to string('null')
370 $group = (object) $groupArr;
372 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
373 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
374 // they did -- the obvious fix would produce mutual recursion.
375 $ufGroupType = self
::_calculateGroupType($fieldArrs);
376 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',',$ufGroupType));
377 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',',$ufGroupType));
378 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
379 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
381 $formattedFields = array();
382 foreach ($fieldArrs as $fieldArr) {
383 $field = (object) $fieldArr;
384 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
388 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
389 if ($formattedField !== NULL) {
390 $formattedFields[$name] = $formattedField;
393 return $formattedFields;
397 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
399 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
400 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
401 * @param array $addressCustomFields
402 * @param array $importableFields
403 * @param array $customFields
404 * @param int $permissionType eg CRM_Core_Permission::CREATE
407 protected static function formatUFField(
411 $addressCustomFields,
413 $permissionType = CRM_Core_Permission
::CREATE
415 $name = $field->field_name
;
416 $title = $field->label
;
418 $addressCustom = FALSE;
419 if (in_array($permissionType, array(
420 CRM_Core_Permission
::CREATE
,
421 CRM_Core_Permission
::EDIT
,
423 in_array($field->field_name
, array_keys($addressCustomFields))
425 $addressCustom = TRUE;
426 $name = "address_{$name}";
428 if ($field->field_name
== 'url') {
429 $name .= "-{$field->website_type_id}";
431 elseif (!empty($field->location_type_id
)) {
432 $name .= "-{$field->location_type_id}";
435 $locationFields = self
::getLocationFields();
436 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
441 if (isset($field->phone_type_id
)) {
442 $name .= "-{$field->phone_type_id}";
445 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
446 // I guess to make field self sufficient with all the required data and avoid additional calls
447 $formattedField = array(
449 'groupTitle' => $group->title
,
450 'groupName' => $group->name
,
451 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
452 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
454 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
455 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
456 'is_required' => $field->is_required
,
457 'is_view' => $field->is_view
,
458 'help_pre' => $field->help_pre
,
459 'help_post' => $field->help_post
,
460 'visibility' => $field->visibility
,
461 'in_selector' => $field->in_selector
,
462 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
463 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
464 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
465 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
466 'group_id' => $group->id
,
467 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
468 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
469 'field_type' => $field->field_type
,
470 'field_id' => $field->id
,
471 'pseudoconstant' => CRM_Utils_Array
::value(
473 CRM_Utils_Array
::value($field->field_name
, $importableFields)
475 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
476 'dbName' => CRM_Utils_Array
::value(
478 CRM_Utils_Array
::value($field->field_name
, $importableFields)
483 //adding custom field property
484 if (substr($field->field_name
, 0, 6) == 'custom' ||
485 substr($field->field_name
, 0, 14) === 'address_custom'
487 // if field is not present in customFields, that means the user
488 // DOES NOT HAVE permission to access that field
489 if (array_key_exists($field->field_name
, $customFields)) {
490 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
492 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
493 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
494 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
496 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
497 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
498 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
501 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
502 return array($name, $formattedField);
505 $formattedField = NULL;
506 return array($name, $formattedField);
509 return array($name, $formattedField);
513 * Create a query to find all visible UFFields in a UFGroup
515 * This is the SQL-variant of checkUFFieldDisplayable().
517 * @param int $groupId
518 * @param bool $searchable
519 * @param bool $showAll
520 * @param int $visibility
521 * @param string $orderBy comma-delimited list of SQL columns
524 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
525 $where = " WHERE uf_group_id = {$groupId}";
528 $where .= " AND is_searchable = 1";
532 $where .= " AND is_active = 1";
537 if ($visibility & self
::PUBLIC_VISIBILITY
) {
538 $clause[] = 'visibility = "Public Pages"';
540 if ($visibility & self
::ADMIN_VISIBILITY
) {
541 $clause[] = 'visibility = "User and User Admin Only"';
543 if ($visibility & self
::LISTINGS_VISIBILITY
) {
544 $clause[] = 'visibility = "Public Pages and Listings"';
546 if (!empty($clause)) {
547 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
551 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
553 $query .= ", " . $orderBy;
560 * Create a query to find all visible UFFields in a UFGroup
562 * This is the PHP in-memory variant of createUFFieldQuery().
564 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
565 * @param bool $searchable
566 * @param bool $showAll
567 * @param int $visibility
568 * @return bool TRUE if field is displayable
570 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
571 if ($searchable && $field->is_searchable
!= 1) {
575 if (!$showAll && $field->is_active
!= 1) {
580 $allowedVisibilities = array();
581 if ($visibility & self
::PUBLIC_VISIBILITY
) {
582 $allowedVisibilities[] = 'Public Pages';
584 if ($visibility & self
::ADMIN_VISIBILITY
) {
585 $allowedVisibilities[] = 'User and User Admin Only';
587 if ($visibility & self
::LISTINGS_VISIBILITY
) {
588 $allowedVisibilities[] = 'Public Pages and Listings';
590 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
591 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
599 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
601 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
604 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
607 if ($profileType == 'Activity' ||
$contactActivityProfile) {
608 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
611 $componentFields = CRM_Core_Component
::getQueryFields();
614 $importableFields = array_merge($importableFields, $componentFields);
616 $importableFields['group']['title'] = ts('Group(s)');
617 $importableFields['group']['where'] = NULL;
618 $importableFields['tag']['title'] = ts('Tag(s)');
619 $importableFields['tag']['where'] = NULL;
620 return $importableFields;
623 public static function getLocationFields() {
624 static $locationFields = array(
626 'supplemental_address_1',
627 'supplemental_address_2',
630 'postal_code_suffix',
643 return $locationFields;
646 protected static function getCustomFields($ctype) {
647 static $customFieldCache = array();
648 if (!isset($customFieldCache[$ctype])) {
649 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
651 // hack to add custom data for components
652 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
653 foreach ($components as $value) {
654 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
656 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
657 $customFields = array_merge($customFields, $addressCustomFields);
658 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
660 return $customFieldCache[$ctype];
664 * check the data validity
666 * @param int $userID the user id that we are actually editing
667 * @param string $title the title of the group we are interested in
668 * @pram boolean $register is this the registrtion form
669 * @param int $action the action of the form
671 * @return boolean true if form is valid
675 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
677 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
678 ts('Dynamic Form Creator'),
681 $controller->set('id', $userID);
682 $controller->set('register', 1);
683 $controller->process();
684 return $controller->validate();
687 // make sure we have a valid group
688 $group = new CRM_Core_DAO_UFGroup();
690 $group->title
= $title;
692 if ($group->find(TRUE) && $userID) {
693 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
694 $controller->set('gid', $group->id
);
695 $controller->set('id', $userID);
696 $controller->set('register', 0);
697 $controller->process();
698 return $controller->validate();
705 * get the html for the form that represents this particular group
707 * @param int $userID the user id that we are actually editing
708 * @param string $title the title of the group we are interested in
709 * @param int $action the action of the form
710 * @param boolean $register is this the registration form
711 * @param boolean $reset should we reset the form?
712 * @param int $profileID do we have the profile ID?
714 * @return string the html for the form on success, otherwise empty string
718 static function getEditHTML($userID,
724 $doNotProcess = FALSE,
729 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
730 ts('Dynamic Form Creator'),
733 if ($reset ||
$doNotProcess) {
734 // hack to make sure we do not process this form
735 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
738 unset($_POST['_qf_default']);
739 unset($_REQUEST['_qf_default']);
741 $controller->reset();
745 $controller->set('id', $userID);
746 $controller->set('register', 1);
747 $controller->set('skipPermission', 1);
748 $controller->set('ctype', $ctype);
749 $controller->process();
750 if ($doNotProcess ||
!empty($_POST)) {
751 $controller->validate();
753 $controller->setEmbedded(TRUE);
755 //CRM-5839 - though we want to process form, get the control back.
756 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
760 // we are done processing so restore the POST/REQUEST vars
761 if (($reset ||
$doNotProcess) && $oldQFDefault) {
762 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
765 $template = CRM_Core_Smarty
::singleton();
767 // Hide CRM error messages if they are displayed using drupal form_set_error.
768 if (!empty($_POST)) {
769 $template->assign('suppressForm', TRUE);
772 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
776 // make sure we have a valid group
777 $group = new CRM_Core_DAO_UFGroup();
779 $group->title
= $title;
781 if ($group->find(TRUE)) {
782 $profileID = $group->id
;
787 // make sure profileID and ctype match if ctype exists
789 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
790 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
791 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
794 if (($profileType != 'Contact') && ($profileType != $ctype)) {
799 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
800 ts('Dynamic Form Creator'),
804 $controller->reset();
806 $controller->set('gid', $profileID);
807 $controller->set('id', $userID);
808 $controller->set('register', 0);
809 $controller->set('skipPermission', 1);
811 $controller->set('ctype', $ctype);
813 $controller->process();
814 $controller->setEmbedded(TRUE);
816 //CRM-5846 - give the control back to drupal.
817 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
820 $template = CRM_Core_Smarty
::singleton();
822 // Hide CRM error messages if they are displayed using drupal form_set_error.
823 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
824 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
825 $template->assign('suppressForm', TRUE);
829 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
830 if (!$template->template_exists($templateFile)) {
831 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
833 return trim($template->fetch($templateFile));
836 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
838 // if post not empty then only proceed
839 if (!empty($_POST)) {
841 $config = CRM_Core_Config
::singleton();
842 $email = CRM_Utils_Array
::value('mail', $_POST);
844 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
845 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
854 * searches for a contact in the db with similar attributes
856 * @param array $params the list of values to be used in the where clause
857 * @param int $id the current contact id (hence excluded from matching)
858 * @param boolean $flatten should we flatten the input params
860 * @return contact_id if found, null otherwise
864 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
865 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
866 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
867 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
869 return implode(',', $ids);
877 * Given a contact id and a field set, return the values from the db
880 * @param int $id the contact id
881 * @param array $fields the profile fields of interest
882 * @param array $values the values for the above fields
883 * @param boolean $searchable searchable or not
884 * @param array $componentWhere component condition
885 * @param boolean $absolute return urls in absolute form (useful when sending an email)
891 public static function getValues($cid, &$fields, &$values,
892 $searchable = TRUE, $componentWhere = NULL,
893 $absolute = FALSE, $additionalWhereClause = NULL
895 if (empty($cid) && empty($componentWhere)) {
899 // get the contact details (hier)
900 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
901 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
903 // add conditions specified by components. eg partcipant_id etc
904 if (!empty($componentWhere)) {
905 $params = array_merge($params, $componentWhere);
908 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
909 $options = &$query->_options
;
911 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
912 FALSE, FALSE, FALSE, $additionalWhereClause);
913 if (!$details->fetch()) {
916 $query->convertToPseudoNames($details);
917 $config = CRM_Core_Config
::singleton();
919 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
920 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
921 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
923 $multipleFields = array('url');
924 $nullIndex = $nullValueIndex = ' ';
926 //start of code to set the default values
927 foreach ($fields as $name => $field) {
930 $name = 'contact_id';
933 // skip fields that should not be displayed separately
934 if (!empty($field['skipDisplay'])) {
938 $index = $field['title'];
939 //handle for the label not set for the field
940 if (empty($field['title'])) {
942 $nullIndex .= $nullIndex;
945 //handle the case to avoid re-write where the profile field labels are the same
946 if (array_key_exists($index, $values)) {
947 $index .= $nullValueIndex;
948 $nullValueIndex .= $nullValueIndex;
950 $params[$index] = $values[$index] = '';
951 $customFieldName = NULL;
953 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
954 // to handle gender / suffix / prefix
955 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
956 $params[$index] = $details->$name;
957 $values[$index] = $details->$name;
959 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
960 $dname = $name . '_display';
961 $values[$index] = $details->$dname;
962 $name = $name . '_id';
963 $params[$index] = $details->$name;
965 elseif (in_array($name, array(
966 'state_province', 'country', 'county'))) {
967 $values[$index] = $details->$name;
968 $idx = $name . '_id';
969 $params[$index] = $details->$idx;
971 elseif ($name === 'preferred_communication_method') {
972 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
974 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
976 foreach ($pref as $k) {
978 $compref[] = $communicationFields[$k];
981 $params[$index] = $details->$name;
982 $values[$index] = implode(',', $compref);
984 elseif ($name === 'preferred_language') {
985 $params[$index] = $details->$name;
986 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
988 elseif ($name == 'group') {
989 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
990 $title = $ids = array();
992 foreach ($groups as $g) {
993 // CRM-8362: User and User Admin visibility groups should be included in display if user has
994 // VIEW permission on that group
995 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
997 if ($g['visibility'] != 'User and User Admin Only' ||
998 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1000 $title[] = $g['title'];
1001 if ($g['visibility'] == 'Public Pages') {
1002 $ids[] = $g['group_id'];
1006 $values[$index] = implode(', ', $title);
1007 $params[$index] = implode(',', $ids);
1009 elseif ($name == 'tag') {
1010 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1011 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1013 foreach ($entityTags as $tagId) {
1014 $title[] = $allTags[$tagId];
1016 $values[$index] = implode(', ', $title);
1017 $params[$index] = implode(',', $entityTags);
1019 elseif ($name == 'activity_status_id') {
1020 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1021 $values[$index] = $activityStatus[$details->$name];
1022 $params[$index] = $details->$name;
1024 elseif ($name == 'activity_date_time') {
1025 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1026 $params[$index] = $details->$name;
1028 elseif ($name == 'contact_sub_type') {
1029 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1030 if (!empty($contactSubTypeNames)) {
1031 $contactSubTypeLabels = array();
1032 // get all contact subtypes
1033 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1034 // build contact subtype labels array
1035 foreach( $contactSubTypeNames as $cstName ) {
1037 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1040 $values[$index] = implode(',', $contactSubTypeLabels);
1043 $params[$index] = $details->$name;
1046 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1047 if ($details->$name) {
1048 $values[$index] = '[ x ]';
1052 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1053 $htmlType = $field['html_type'];
1055 // field_type is only set when we are retrieving profile values
1056 // when sending email, we call the same function to get custom field
1057 // values etc, i.e. emulating a profile
1058 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1060 if ($htmlType == 'File') {
1063 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
1064 $entityId = $componentWhere[0][2];
1067 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1072 $params[$index] = $values[$index] = $fileURL['file_url'];
1076 if (isset($dao) && property_exists($dao, 'data_type') &&
1077 ($dao->data_type
== 'Int' ||
1078 $dao->data_type
== 'Boolean'
1081 $customVal = (int )($details->{$name});
1083 elseif (isset($dao) && property_exists($dao, 'data_type')
1084 && $dao->data_type
== 'Float'
1086 $customVal = (float )($details->{$name});
1088 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1091 $customVal = $details->{$name};
1095 if (CRM_Utils_System
::isNull($customVal)) {
1099 $params[$index] = $customVal;
1100 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1104 if ($field['data_type'] == 'ContactReference') {
1105 $params[$index] = $values[$index];
1107 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1108 $cfID, 'is_search_range'
1110 $customFieldName = "{$name}_from";
1114 elseif ($name == 'image_URL') {
1115 list($width, $height) = getimagesize($details->$name);
1116 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1118 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1119 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1121 elseif (in_array($name, array(
1122 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1123 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1124 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1128 if ($index == 'Campaign') {
1129 $dao = 'CRM_Campaign_DAO_Campaign';
1131 elseif ($index == 'Contribution Page') {
1132 $dao = 'CRM_Contribute_DAO_ContributionPage';
1135 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1138 $value = $details->$name;
1140 $values[$index] = $value;
1145 elseif (strpos($name, '-') !== FALSE) {
1146 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1148 if (!in_array($fieldName, $multipleFields)) {
1149 if ($id == 'Primary') {
1151 // not sure why we'd every use Primary location type id
1152 // we need to fix the source if we are using it
1153 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1154 $locationTypeName = 1;
1157 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1160 if (!$locationTypeName) {
1164 $detailName = "{$locationTypeName}-{$fieldName}";
1165 $detailName = str_replace(' ', '_', $detailName);
1167 if (in_array($fieldName, array(
1168 'phone', 'im', 'email', 'openid'))) {
1170 $detailName .= "-{$type}";
1174 if (in_array($fieldName, array(
1175 'state_province', 'country', 'county'))) {
1176 $values[$index] = $details->$detailName;
1177 $idx = $detailName . '_id';
1178 $params[$index] = $details->$idx;
1180 elseif ($fieldName == 'im') {
1181 $providerId = $detailName . '-provider_id';
1182 if (isset($imProviders[$details->$providerId])) {
1183 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1186 $values[$index] = $details->$detailName;
1188 $params[$index] = $details->$detailName;
1190 elseif ($fieldName == 'phone') {
1191 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1192 if (isset($details->$phoneExtField)) {
1193 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1196 $values[$index] = $details->$detailName;
1198 $params[$index] = $details->$detailName;
1201 $values[$index] = $params[$index] = $details->$detailName;
1205 $detailName = "website-{$id}-{$fieldName}";
1206 $url = CRM_Utils_System
::fixURL($details->$detailName);
1207 if ($details->$detailName) {
1208 $websiteTypeId = "website-{$id}-website_type_id";
1209 $websiteType = $websiteTypes[$details->$websiteTypeId];
1210 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1213 $values[$index] = '';
1218 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1219 CRM_Core_Permission
::check('profile listings and forms')
1222 if (CRM_Utils_System
::isNull($params[$index])) {
1223 $params[$index] = $values[$index];
1225 if (!isset($params[$index])) {
1228 if (!$customFieldName) {
1229 $fieldName = $field['name'];
1232 $fieldName = $customFieldName;
1236 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1237 $htmlType = $field['html_type'];
1238 if ($htmlType == 'Link') {
1239 $url = $params[$index];
1241 elseif (in_array($htmlType, array(
1242 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1243 'Multi-Select State/Province', 'Multi-Select Country',
1245 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1246 $selectedOptions = explode($valSeperator, $params[$index]);
1248 foreach ($selectedOptions as $key => $multiOption) {
1250 $url[] = CRM_Utils_System
::url('civicrm/profile',
1251 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1252 urlencode($fieldName) .
1254 urlencode($multiOption)
1260 $url = CRM_Utils_System
::url('civicrm/profile',
1261 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1262 urlencode($fieldName) .
1264 urlencode($params[$index])
1269 $url = CRM_Utils_System
::url('civicrm/profile',
1270 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1271 urlencode($fieldName) .
1273 urlencode($params[$index])
1278 !empty($values[$index]) &&
1282 if (is_array($url) && !empty($url)) {
1284 $eachMultiValue = explode(', ', $values[$index]);
1285 foreach ($eachMultiValue as $key => $valueLabel) {
1286 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1288 $values[$index] = implode(', ', $links);
1291 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1299 * Check if profile Group used by any module.
1301 * @param int $id profile Id
1309 public static function usedByModule($id) {
1310 //check whether this group is used by any module(check uf join records)
1312 FROM civicrm_uf_join
1313 WHERE civicrm_uf_join.uf_group_id=$id";
1315 $dao = new CRM_Core_DAO();
1317 if ($dao->fetch()) {
1326 * Delete the profile Group.
1328 * @param int $id profile Id
1336 public static function del($id) {
1337 //check whether this group contains any profile fields
1338 $profileField = new CRM_Core_DAO_UFField();
1339 $profileField->uf_group_id
= $id;
1340 $profileField->find();
1341 while ($profileField->fetch()) {
1342 CRM_Core_BAO_UFField
::del($profileField->id
);
1345 //delete records from uf join table
1346 $ufJoin = new CRM_Core_DAO_UFJoin();
1347 $ufJoin->uf_group_id
= $id;
1350 //delete profile group
1351 $group = new CRM_Core_DAO_UFGroup();
1358 * function to add the UF Group
1360 * @param array $params reference array contains the values submitted by the form
1361 * @param array $ids reference array contains the id
1368 static function add(&$params, $ids = array()) {
1369 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1370 foreach ($fields as $field) {
1371 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1374 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1375 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1377 $ufGroup = new CRM_Core_DAO_UFGroup();
1378 $ufGroup->copyValues($params);
1380 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1382 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1384 $ufGroup->id
= $ufGroupID;
1389 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1397 * Function to make uf join entries for an uf group
1399 * @param array $params (reference) an assoc array of name/value pairs
1400 * @param int $ufGroupId ufgroup id
1406 static function createUFJoin(&$params, $ufGroupId) {
1407 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1409 // get ufjoin records for uf group
1410 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1412 // get the list of all ufgroup types
1413 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1415 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1416 if (!is_array($groupTypes)) {
1417 $groupTypes = array();
1420 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1421 if (!is_array($ufGroupRecord)) {
1422 $ufGroupRecord = array();
1425 // check which values has to be inserted/deleted for contact
1426 $menuRebuild = FALSE;
1427 foreach ($allUFGroupType as $key => $value) {
1428 $joinParams = array();
1429 $joinParams['uf_group_id'] = $ufGroupId;
1430 $joinParams['module'] = $key;
1431 if ($key == 'User Account') {
1432 $menuRebuild = TRUE;
1434 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1435 // insert a new record
1436 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1438 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1439 // delete a record for existing ufgroup
1440 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1446 UPDATE civicrm_uf_join
1448 WHERE uf_group_id = %2
1449 AND ( entity_id IS NULL OR entity_id <= 0 )
1451 $p = array(1 => array($params['weight'], 'Integer'),
1452 2 => array($ufGroupId, 'Integer'),
1454 CRM_Core_DAO
::executeQuery($query, $p);
1456 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1458 $config = CRM_Core_Config
::singleton();
1460 $config->userSystem
->is_drupal
1467 * Function to get the UF Join records for an ufgroup id
1469 * @params int $ufGroupId uf group id
1470 * @params int $displayName if set return display name in array
1471 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1473 * @return array $ufGroupJoinRecords
1478 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1480 $UFGroupType = array();
1481 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1485 $dao = new CRM_Core_DAO_UFJoin();
1488 $dao->uf_group_id
= $ufGroupId;
1494 while ($dao->fetch()) {
1495 if (!$displayName) {
1496 $ufJoin[$dao->id
] = $dao->module
;
1499 if (isset($UFGroupType[$dao->module
])) {
1500 // skip the default modules
1502 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1504 // added for CRM-1475
1506 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1507 $ufJoin[$dao->id
] = $dao->module
;
1515 * Function takes an associative array and creates a ufjoin record for ufgroup
1517 * @param array $params (reference) an assoc array of name/value pairs
1519 * @return object CRM_Core_BAO_UFJoin object
1523 static function addUFJoin(&$params) {
1524 $ufJoin = new CRM_Core_DAO_UFJoin();
1525 $ufJoin->copyValues($params);
1531 * Function to delete the uf join record for an uf group
1533 * @param array $params (reference) an assoc array of name/value pairs
1539 static function delUFJoin(&$params) {
1540 $ufJoin = new CRM_Core_DAO_UFJoin();
1541 $ufJoin->copyValues($params);
1546 * Function to get the weight for ufjoin record
1548 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1550 * @return int weight of the UFGroup
1554 static function getWeight($ufGroupId = NULL) {
1555 //calculate the weight
1558 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1559 FROM civicrm_uf_join
1560 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1563 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1564 FROM civicrm_uf_join
1565 WHERE civicrm_uf_join.uf_group_id = %1
1566 AND ( entity_id IS NULL OR entity_id <= 0 )";
1567 $p[1] = array($ufGroupId, 'Integer');
1570 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1572 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1576 * Function to get the uf group for a module
1578 * @param string $moduleName module name
1579 * @param int $count no to increment the weight
1580 * @param bool $skipPermision - whether to add permission clause
1581 * @param int $op - which operation (view, edit, create, etc) to check permission for
1582 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1584 * @return array $ufGroups array of ufgroups for a module
1588 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1589 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1591 if (!CRM_Core_Config
::isUpgradeMode()) {
1592 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1593 $selectFields[] = 'description';
1596 if (!empty($returnFields)) {
1597 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1600 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1601 FROM civicrm_uf_group
1602 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1605 $queryString .= ' AND civicrm_uf_group.is_active = 1
1606 WHERE civicrm_uf_join.module = %2';
1607 $p[2] = array($moduleName, 'String');
1611 // add permissioning for profiles only if not registration
1612 if (!$skipPermission) {
1613 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1614 if (strpos($queryString, 'WHERE') !== FALSE) {
1615 $queryString .= " AND $permissionClause ";
1618 $queryString .= " $permissionClause ";
1622 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1623 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1625 $ufGroups = array();
1626 while ($dao->fetch()) {
1627 //skip mix profiles in user Registration / User Account
1628 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1629 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1633 foreach ($selectFields as $key => $field) {
1634 if($field == 'id') {
1637 elseif ($field == 'name') {
1638 $ufGroups[$dao->id
][$field] = $dao->title
;
1641 $ufGroups[$dao->id
][$field] = $dao->$field;
1645 // Allow other modules to alter/override the UFGroups.
1646 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1652 * Function to filter ufgroups based on logged in user contact type
1654 * @params int $ufGroupId uf group id (profile id)
1656 * @return boolean true or false
1660 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1662 $session = CRM_Core_Session
::singleton();
1663 $contactID = $session->get('userID');
1667 //get the contact type
1668 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1670 //match if exixting contact type is same as profile contact type
1671 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1673 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1674 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1677 //allow special mix profiles for Contribution and Participant
1678 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1680 if (in_array($profileType, $specialProfiles)) {
1684 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1693 * Function to build profile form
1695 * @params object $form form object
1696 * @params array $field array field properties
1697 * @params int $mode profile mode
1698 * @params int $contactID contact id
1699 * @params string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
1705 static function buildProfile(
1715 $defaultValues = array();
1716 $fieldName = $field['name'];
1717 $title = $field['title'];
1718 $attributes = $field['attributes'];
1719 $rule = $field['rule'];
1720 $view = $field['is_view'];
1721 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1722 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1723 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1725 // do not display view fields in drupal registration form
1727 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1731 if ($usedFor == 'onbehalf') {
1732 $name = "onbehalf[$fieldName]";
1734 elseif ($usedFor == 'honor') {
1735 $name = "honor[$fieldName]";
1737 elseif ($contactId && !$online) {
1738 $name = "field[$contactId][$fieldName]";
1740 elseif ($rowNumber) {
1741 $name = "field[$rowNumber][$fieldName]";
1743 elseif (!empty($prefix)) {
1744 $name = $prefix ."[$fieldName]";
1750 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1751 $deleteExtra = ts('Are you sure you want to delete contact image.');
1753 CRM_Core_Action
::DELETE
=>
1755 'name' => ts('Delete Contact Image'),
1756 'url' => 'civicrm/contact/image',
1757 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1759 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1762 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1763 CRM_Core_Action
::DELETE
,
1764 array('id' => $form->get('id'),
1765 'gid' => $form->get('gid'),
1769 'contact.profileimage.delete',
1773 $form->assign('deleteURL', $deleteURL);
1775 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1776 'address_options', TRUE, NULL, TRUE
1779 if (substr($fieldName, 0, 14) === 'state_province') {
1780 $form->add('select', $name, $title,
1782 '' => ts('- select -')) + CRM_Core_PseudoConstant
::stateProvince(), $required
1784 $config = CRM_Core_Config
::singleton();
1785 if (!in_array($mode, array(
1786 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1787 $config->defaultContactStateProvince
1789 $defaultValues[$name] = $config->defaultContactStateProvince
;
1790 $form->setDefaults($defaultValues);
1793 elseif (substr($fieldName, 0, 7) === 'country') {
1794 $form->add('select', $name, $title,
1796 '' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required
1798 $config = CRM_Core_Config
::singleton();
1799 if (!in_array($mode, array(
1800 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1801 $config->defaultContactCountry
1803 $defaultValues[$name] = $config->defaultContactCountry
;
1804 $form->setDefaults($defaultValues);
1807 elseif (substr($fieldName, 0, 6) === 'county') {
1808 if ($addressOptions['county']) {
1809 $form->add('select', $name, $title,
1811 '' => ts('(choose state first)')), $required
1815 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1816 $form->add('file', $name, $title, $attributes, $required);
1817 $form->addUploadElement($name);
1819 elseif (substr($fieldName, 0, 2) === 'im') {
1820 $form->add('text', $name, $title, $attributes, $required);
1823 if (substr($name, -1) == ']') {
1824 $providerName = substr($name, 0, -1) . '-provider_id]';
1826 $form->add('select', $providerName, NULL,
1828 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1832 $form->add('select', $name . '-provider_id', $title,
1834 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1838 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1839 $form->freeze($name . '-provider_id');
1843 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1844 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1846 elseif (in_array($fieldName, array(
1847 'membership_start_date', 'membership_end_date', 'join_date'))) {
1848 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1850 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_type') {
1851 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1852 $sel = &$form->addElement('hierselect', $name, $title);
1853 $select = array('' => ts('- select -') );
1854 if(count($orgInfo) == 1 && $field['is_required']) {
1855 // we only have one org - so we should default to it. Not sure about defaulting to first type
1856 // as it could be missed - so adding a select
1857 // however, possibly that is more similar to the membership form
1858 if(count($types[1]) > 1) {
1859 $types[1] = $select +
$types[1];
1863 $orgInfo = $select +
$orgInfo;
1865 $sel->setOptions(array($orgInfo, $types));
1867 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_status') {
1868 $form->add('select', $name, $title,
1870 '' => ts('- select -')) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1873 elseif ($fieldName === 'gender_id') {
1874 $genderOptions = array();
1875 $gender = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'gender_id');
1876 foreach ($gender as $key => $var) {
1877 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1879 $group = $form->addGroup($genderOptions, $name, $title);
1881 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1884 $group->setAttribute('allowClear', TRUE);
1887 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1888 $form->add('select', $name, $title,
1890 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Contact_BAO_Contact', $fieldName), $required
1893 elseif ($fieldName === 'contact_sub_type') {
1894 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1895 if ($usedFor == 'onbehalf') {
1896 $profileType = 'Organization';
1898 elseif ($usedFor == 'honor') {
1899 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1902 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1903 if ($profileType == 'Contact') {
1904 $profileType = 'Individual';
1908 $setSubtype = FALSE;
1909 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1910 $setSubtype = $profileType;
1911 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1914 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
1917 $subtypeList = array();
1918 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1921 $subtypeList = $subtypes;
1924 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1925 $sel->setMultiple(TRUE);
1927 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1928 //add email greeting, postal greeting, addressee, CRM-4575
1929 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1930 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
1932 if (empty($profileType) ||
in_array($profileType, array(
1933 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1934 $profileType = 'Individual';
1936 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1937 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1940 'contact_type' => $profileType,
1941 'greeting_type' => $fieldName,
1943 $form->add('select', $name, $title,
1945 '' => ts('- select -')) + CRM_Core_PseudoConstant
::greeting($greeting), $required
1947 // add custom greeting element
1948 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1952 elseif ($fieldName === 'preferred_communication_method') {
1953 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1954 foreach ($communicationFields as $key => $var) {
1958 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
1960 $form->addGroup($communicationOptions, $name, $title, '<br/>');
1962 elseif ($fieldName === 'preferred_mail_format') {
1963 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
1965 elseif ($fieldName === 'preferred_language') {
1966 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
1968 elseif ($fieldName == 'external_identifier') {
1969 $form->add('text', $name, $title, $attributes, $required);
1970 $contID = $contactId;
1972 $contID = $form->get('id');
1974 $form->addRule($name,
1975 ts('External ID already exists in Database.'),
1977 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
1980 elseif ($fieldName === 'group') {
1981 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
1982 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
1987 elseif ($fieldName === 'tag') {
1988 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
1989 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
1994 elseif (substr($fieldName, 0, 4) === 'url-') {
1995 $form->add('text', $name, $title,
1996 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
1998 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
1999 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2004 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2006 // Note should be rendered as textarea
2007 elseif (substr($fieldName, -4) == 'note') {
2008 $form->add('textarea', $name, $title, $attributes, $required);
2010 elseif (substr($fieldName, 0, 6) === 'custom') {
2011 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2012 if ($customFieldID) {
2013 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2016 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2017 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2018 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2019 if ($customFieldID) {
2020 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2023 elseif (in_array($fieldName, array(
2024 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2025 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2027 elseif ($fieldName == 'send_receipt') {
2028 $form->addElement('checkbox', $name, $title);
2030 elseif ($fieldName == 'soft_credit') {
2031 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2032 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2034 elseif ($fieldName == 'product_name') {
2035 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2036 $sel = &$form->addElement('hierselect', $name, $title);
2038 '0' => ts('- select -')) +
$products;
2039 $sel->setOptions(array($products, $options));
2041 elseif ($fieldName == 'payment_instrument') {
2042 $form->add('select', $name, $title,
2043 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant
::paymentInstrument( ), $required );
2045 else if ($fieldName == 'financial_type' ) {
2046 $form->add('select', $name, $title,
2048 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(), $required
2051 elseif ($fieldName == 'contribution_status_id') {
2052 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2053 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2059 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2062 $form->add('select', $name, $title,
2064 '' => ts('- select -')) +
$contributionStatuses, $required
2067 elseif ($fieldName == 'soft_credit_type') {
2068 $form->add('select', $name, $title,
2070 '' => ts('- select -')) + CRM_Core_OptionGroup
::values("soft_credit_type")
2072 $form->addElement('hidden', 'sct_default_id',
2073 CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type"),
2074 array('id' => 'sct_default_id')
2077 elseif ($fieldName == 'currency') {
2078 $form->addCurrency($name, $title, $required);
2080 elseif ($fieldName == 'contribution_page_id') {
2081 $form->add('select', $name, $title,
2083 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2086 elseif ($fieldName == 'participant_register_date') {
2087 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2089 elseif ($fieldName == 'activity_status_id') {
2090 $form->add('select', $name, $title,
2092 '' => ts('- select -')) + CRM_Core_PseudoConstant
::activityStatus(), $required
2095 elseif ($fieldName == 'activity_engagement_level') {
2096 $form->add('select', $name, $title,
2098 '' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2101 elseif ($fieldName == 'activity_date_time') {
2102 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2104 elseif ($fieldName == 'participant_status') {
2106 if ($online == TRUE) {
2107 $cond = 'visibility_id = 1';
2109 $form->add('select', $name, $title,
2111 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2114 elseif ($fieldName == 'participant_role') {
2115 if (!empty($field['is_multiple'])) {
2116 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2119 $form->add('select', $name, $title,
2121 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantRole(), $required
2125 elseif ($fieldName == 'world_region') {
2126 $form->add('select', $name, $title,
2128 '' => ts('- select -')) + CRM_Core_PseudoConstant
::worldRegion(), $required
2131 elseif ($fieldName == 'signature_html') {
2132 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2134 elseif ($fieldName == 'signature_text') {
2135 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2137 elseif (substr($fieldName, -11) == 'campaign_id') {
2138 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2139 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2140 $form->_componentCampaigns
2142 $form->add('select', $name, $title,
2144 '' => ts('- select -')) +
$campaigns, $required, 'class="big"'
2148 elseif ($fieldName == 'activity_details') {
2149 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2151 elseif ($fieldName == 'activity_duration') {
2152 $form->add('text', $name, $title, $attributes, $required);
2153 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2156 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2157 $form->add('advcheckbox', $name, $title, $attributes, $required);
2160 $form->add('text', $name, $title, $attributes, $required);
2164 static $hiddenSubtype = FALSE;
2165 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2166 // In registration mode params are submitted via POST and we don't have any clue
2167 // about profile-id or the profile-type (which could be a subtype)
2168 // To generalize the behavior and simplify the process,
2169 // lets always add the hidden
2170 //subtype value if there is any, and we won't have to
2171 // compute it while processing.
2173 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2176 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2178 $hiddenSubtype = TRUE;
2181 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2182 $form->freeze($name);
2186 if (in_array($fieldName, array(
2187 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2188 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2190 $stateCountryMap = array();
2191 if (!empty($form->_stateCountryMap
['state_province']) && !empty($form->_stateCountryMap
['country'])) {
2192 foreach ($form->_stateCountryMap
['state_province'] as $key => $value) {
2193 $stateCountryMap[$key]['state_province'] = $value;
2194 $stateCountryMap[$key]['country'] = $form->_stateCountryMap
['country'][$key];
2196 CRM_Core_BAO_Address
::addStateCountryMap($stateCountryMap);
2199 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2200 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2206 * Function to set profile defaults
2208 * @params int $contactId contact id
2209 * @params array $fields associative array of fields
2210 * @params array $defaults defaults array
2211 * @params boolean $singleProfile true for single profile else false(batch update)
2212 * @params int $componentId id for specific components like contribute, event etc
2218 static function setProfileDefaults($contactId, &$fields, &$defaults,
2219 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2221 if (!$componentId) {
2222 //get the contact details
2223 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2224 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2225 $multipleFields = array('website' => 'url');
2227 //start of code to set the default values
2228 foreach ($fields as $name => $field) {
2229 // skip pseudo fields
2230 if (substr($name, 0, 9) == 'phone_ext') {
2234 //set the field name depending upon the profile mode(single/batch)
2235 if ($singleProfile) {
2239 $fldName = "field[$contactId][$name]";
2242 if ($name == 'group') {
2243 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2245 if ($name == 'tag') {
2246 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2249 if (!empty($details[$name]) ||
isset($details[$name])) {
2250 //to handle custom data (checkbox) to be written
2251 // to handle birth/deceased date, greeting_type and few other fields
2252 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2253 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2255 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2256 $defaults[$fldName] = $details[$name . '_id'];
2257 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2259 elseif ($name == 'preferred_communication_method') {
2260 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2261 foreach ($v as $item) {
2263 $defaults[$fldName . "[$item]"] = 1;
2267 elseif ($name == 'world_region') {
2268 $defaults[$fldName] = $details['worldregion_id'];
2270 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2271 //fix for custom fields
2272 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2274 // hack to add custom data for components
2275 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2276 foreach ($components as $value) {
2277 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2278 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2282 switch ($customFields[$customFieldId]['html_type']) {
2283 case 'Multi-Select State/Province':
2284 case 'Multi-Select Country':
2285 case 'AdvMulti-Select':
2286 case 'Multi-Select':
2287 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2288 foreach ($v as $item) {
2290 $defaults[$fldName][$item] = $item;
2296 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2297 foreach ($v as $item) {
2299 $defaults[$fldName][$item] = 1;
2300 // seems like we need this for QF style checkboxes in profile where its multiindexed
2302 $defaults["{$fldName}[{$item}]"] = 1;
2307 case 'Autocomplete-Select':
2308 if ($customFields[$customFieldId]['data_type'] == 'ContactReference') {
2309 if (is_numeric($details[$name])) {
2310 $defaults[$fldName . '_id'] = $details[$name];
2311 $defaults[$fldName] = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact', $details[$name], 'sort_name');
2315 $defaults[$fldName] = $details[$name];
2320 // CRM-6681, set defult values according to date and time format (if any).
2322 if (!empty($customFields[$customFieldId]['date_format'])) {
2323 $dateFormat = $customFields[$customFieldId]['date_format'];
2326 if (empty($customFields[$customFieldId]['time_format'])) {
2327 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2332 $timeElement = $fldName . '_time';
2333 if (substr($fldName, -1) == ']') {
2334 $timeElement = substr($fldName, 0, -1) . '_time]';
2336 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2337 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2342 $defaults[$fldName] = $details[$name];
2347 $defaults[$fldName] = $details[$name];
2351 $blocks = array('email', 'phone', 'im', 'openid');
2352 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2353 if (!in_array($fieldName, $multipleFields)) {
2354 if (is_array($details)) {
2355 foreach ($details as $key => $value) {
2356 // when we fixed CRM-5319 - get primary loc
2357 // type as per loc field and removed below code.
2358 $primaryLocationType = FALSE;
2359 if ($locTypeId == 'Primary') {
2360 if (is_array($value) && array_key_exists($fieldName, $value)){
2361 $primaryLocationType = TRUE;
2362 if (in_array($fieldName, $blocks)){
2363 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2366 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2371 // fixed for CRM-665
2372 if (is_numeric($locTypeId)) {
2373 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2374 if (!empty($value[$fieldName])) {
2375 //to handle stateprovince and country
2376 if ($fieldName == 'state_province') {
2377 $defaults[$fldName] = $value['state_province_id'];
2379 elseif ($fieldName == 'county') {
2380 $defaults[$fldName] = $value['county_id'];
2382 elseif ($fieldName == 'country') {
2383 if (!isset($value['country_id']) ||
!$value['country_id']) {
2384 $config = CRM_Core_Config
::singleton();
2385 if ($config->defaultContactCountry
) {
2386 $defaults[$fldName] = $config->defaultContactCountry
;
2390 $defaults[$fldName] = $value['country_id'];
2393 elseif ($fieldName == 'phone') {
2395 if (isset($value['phone'][$phoneTypeId])) {
2396 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2398 if (isset($value['phone_ext'][$phoneTypeId])) {
2399 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2403 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2405 if (!is_array($phoneDefault)) {
2406 $defaults[$fldName] = $phoneDefault;
2410 elseif ($fieldName == 'email') {
2411 //adding the first email (currently we don't support multiple emails of same location type)
2412 $defaults[$fldName] = $value['email'];
2414 elseif ($fieldName == 'im') {
2415 //adding the first im (currently we don't support multiple ims of same location type)
2416 $defaults[$fldName] = $value['im'];
2417 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2420 $defaults[$fldName] = $value[$fieldName];
2423 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2424 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2426 $defaults[$fldName] = $value[substr($fieldName, 8)];
2434 if (is_array($details)) {
2435 if ($fieldName === 'url'
2436 && !empty($details['website'])
2437 && !empty($details['website'][$locTypeId])) {
2438 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2446 //Handling Contribution Part of the batch profile
2447 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2448 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2451 //Handling Event Participation Part of the batch profile
2452 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2453 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2456 //Handling membership Part of the batch profile
2457 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2458 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2461 //Handling Activity Part of the batch profile
2462 if ($component == 'Activity') {
2463 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2468 * Function to get profiles by type eg: pure Individual etc
2470 * @param array $types associative array of types eg: types('Individual')
2471 * @param boolean $onlyPure true if only pure profiles are required
2473 * @return array $profiles associative array of profiles
2477 static function getProfiles($types, $onlyPure = FALSE) {
2478 $profiles = array();
2479 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2481 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2483 // Exclude Batch Data Entry profiles - CRM-10901
2484 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2486 foreach ($ufGroups as $id => $title) {
2487 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2488 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2489 $profiles[$id] = $title;
2496 * Function to check whether a profile is valid combination of
2497 * required and/or optional profile types
2499 * @param array $required array of types those are required
2500 * @param array $optional array of types those are optional
2502 * @return array $profiles associative array of profiles
2506 static function getValidProfiles($required, $optional = NULL) {
2507 if (!is_array($required) ||
empty($required)) {
2511 $profiles = array();
2512 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2514 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2516 foreach ($ufGroups as $id => $title) {
2517 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2519 $profiles[$id] = $title;
2527 * Function to check whether a profile is valid combination of
2528 * required profile fields
2530 * @param array $ufId integer id of the profile
2531 * @param array $required array of fields those are required in the profile
2533 * @return array $profiles associative array of profiles
2537 static function checkValidProfile($ufId, $required = NULL) {
2538 $validProfile = FALSE;
2540 return $validProfile;
2543 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2544 return $validProfile;
2547 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2548 NULL, FALSE, NULL, FALSE, NULL,
2549 CRM_Core_Permission
::CREATE
, NULL
2552 $validProfile = array();
2553 if (!empty($profileFields)) {
2554 $fields = array_keys($profileFields);
2555 foreach ($fields as $val) {
2556 foreach ($required as $key => $field) {
2557 if (strpos($val, $field) === 0) {
2558 unset($required[$key]);
2563 $validProfile = (empty($required)) ?
TRUE : FALSE;
2566 return $validProfile;
2570 * Function to get default value for Register.
2576 static function setRegisterDefaults(&$fields, &$defaults) {
2577 $config = CRM_Core_Config
::singleton();
2578 foreach ($fields as $name => $field) {
2579 if (substr($name, 0, 8) == 'country-') {
2580 if (!empty($config->defaultContactCountry
)) {
2581 $defaults[$name] = $config->defaultContactCountry
;
2584 elseif (substr($name, 0, 15) == 'state_province-') {
2585 if (!empty($config->defaultContactStateProvince
)) {
2586 $defaults[$name] = $config->defaultContactStateProvince
;
2594 * This function is to make a copy of a profile, including
2595 * all the fields in the profile
2597 * @param int $id the profile id to copy
2602 static function copy($id) {
2603 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2604 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2610 if ($pos = strrpos($copy->name
, "_{$id}")) {
2611 $copy->name
= substr_replace($copy->name
, '', $pos);
2613 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2616 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2617 array('uf_group_id' => $id),
2618 array('uf_group_id' => $copy->id
),
2623 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2624 array('uf_group_id' => $id),
2625 array('uf_group_id' => $copy->id
)
2628 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2632 UPDATE civicrm_uf_join
2634 WHERE uf_group_id = %2
2635 AND ( entity_id IS NULL OR entity_id <= 0 )
2637 $p = array(1 => array($maxWeight +
1, 'Integer'),
2638 2 => array($copy->id
, 'Integer'),
2640 CRM_Core_DAO
::executeQuery($query, $p);
2641 if ($copy->is_reserved
) {
2642 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2643 $params = array(1 => array($copy->id
, 'Integer'));
2644 CRM_Core_DAO
::executeQuery($query, $params);
2646 CRM_Utils_Hook
::copy('UFGroup', $copy);
2652 * Process that send notification e-mails
2654 * @params int $contactId contact id
2655 * @params array $values associative array of name/value pair
2661 static function commonSendMail($contactID, &$values) {
2662 if (!$contactID ||
!$values) {
2666 $template = CRM_Core_Smarty
::singleton();
2668 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2673 self
::profileDisplay($values['id'], $values['values'], $template);
2674 $emailList = explode(',', $values['email']);
2676 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2677 "reset=1&cid=$contactID",
2678 TRUE, NULL, FALSE, FALSE, TRUE
2681 //get the default domain email address.
2682 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2684 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2685 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2686 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)));
2689 foreach ($emailList as $emailTo) {
2690 // FIXME: take the below out of the foreach loop
2691 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2693 'groupName' => 'msg_tpl_workflow_uf',
2694 'valueName' => 'uf_notify',
2695 'contactId' => $contactID,
2696 'tplParams' => array(
2697 'displayName' => $displayName,
2698 'currentDate' => date('r'),
2699 'contactLink' => $contactLink,
2701 'from' => "$domainEmailName <$domainEmailAddress>",
2702 'toEmail' => $emailTo,
2709 * Given a contact id and a group id, returns the field values from the db
2710 * for this group and notify email only if group's notify field is
2711 * set and field values are not empty
2713 * @params $gid group id
2714 * @params $cid contact id
2715 * @params $params associative array
2720 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2722 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2724 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2725 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2727 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2729 if (!empty($values) &&
2734 'values' => $values,
2745 * Function to assign uf fields to template
2747 * @params int $gid group id
2748 * @params array $values associative array of fields
2753 function profileDisplay($gid, $values, $template) {
2754 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2755 $template->assign('grouptitle', $groupTitle);
2756 if (count($values)) {
2757 $template->assign('values', $values);
2762 * Format fields for dupe Contact Matching
2764 * @param array $params associated array
2766 * @return array $data assoicated formatted array
2770 static function formatFields($params, $contactId = NULL) {
2772 // get the primary location type id and email
2773 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2776 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2777 $primaryLocationType = $defaultLocationType->id
;
2781 $locationType = array();
2783 $primaryLocation = 0;
2784 foreach ($params as $key => $value) {
2785 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2787 if ($locTypeId == 'Primary') {
2788 $locTypeId = $primaryLocationType;
2791 if (is_numeric($locTypeId)) {
2792 if (!in_array($locTypeId, $locationType)) {
2793 $locationType[$count] = $locTypeId;
2796 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2798 $data['location'][$loc]['location_type_id'] = $locTypeId;
2800 // if we are getting in a new primary email, dont overwrite the new one
2801 if ($locTypeId == $primaryLocationType) {
2802 if (!empty($params['email-' . $primaryLocationType])) {
2803 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2805 elseif (isset($primaryEmail)) {
2806 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2812 $data['location'][$loc]['is_primary'] = 1;
2814 if ($fieldName == 'phone') {
2816 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2819 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2821 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2823 elseif ($fieldName == 'email') {
2824 $data['location'][$loc]['email'][$loc]['email'] = $value;
2826 elseif ($fieldName == 'im') {
2827 $data['location'][$loc]['im'][$loc]['name'] = $value;
2830 if ($fieldName === 'state_province') {
2831 $data['location'][$loc]['address']['state_province_id'] = $value;
2833 elseif ($fieldName === 'country') {
2834 $data['location'][$loc]['address']['country_id'] = $value;
2837 $data['location'][$loc]['address'][$fieldName] = $value;
2842 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2843 if ($key === 'individual_suffix') {
2844 $data['suffix_id'] = $value;
2846 elseif ($key === 'individual_prefix') {
2847 $data['prefix_id'] = $value;
2849 elseif ($key === 'gender') {
2850 $data['gender_id'] = $value;
2852 elseif (substr($key, 0, 6) === 'custom') {
2853 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2855 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2856 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2858 // fix the date field
2859 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2860 $date = CRM_Utils_Date
::format($value);
2867 $data['custom'][$customFieldID] = array(
2870 'extends' => $customFields[$customFieldID]['extends'],
2871 'type' => $customFields[$customFieldID]['data_type'],
2872 'custom_field_id' => $customFieldID,
2876 elseif ($key == 'edit') {
2880 $data[$key] = $value;
2885 if (!$primaryLocation) {
2887 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2895 * calculate the profile type 'group_type' as per profile fields.
2897 * @param int $gid profile id
2898 * @param int $ignoreFieldId ignore particular profile field
2900 * @return array list of calculated group type
2902 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2903 //get the profile fields.
2904 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2905 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2909 * calculate the profile type 'group_type' as per profile fields.
2911 * @param int $gid profile id
2912 * @param int $ignoreFieldId ignore perticular profile field
2914 * @return array list of calculated group type
2916 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2917 $groupType = $groupTypeValues = $customFieldIds = array();
2918 if (!empty($ufFields)) {
2919 foreach ($ufFields as $fieldName => $fieldValue) {
2920 //ignore field from group type when provided.
2921 //in case of update profile field.
2922 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2925 if (!in_array($fieldValue['field_type'], $groupType)) {
2926 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2929 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
2930 $customFieldIds[$fldId] = $fldId;
2935 if (!empty($customFieldIds)) {
2936 $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) . ')';
2938 $customGroups = CRM_Core_DAO
::executeQuery($query);
2939 while ($customGroups->fetch()) {
2940 if (!$customGroups->extends_entity_column_value
) {
2944 $groupTypeName = "{$customGroups->extends}Type";
2945 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
2946 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
2949 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
2951 $groupTypeValues[$groupTypeName][$val] = $val;
2956 if (!empty($groupTypeValues)) {
2957 $groupType = array_merge($groupType, $groupTypeValues);
2965 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
2966 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
2969 * BirthDate + Email Individual,Contact
2970 * BirthDate + Subject Individual,Activity
2971 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
2972 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
2973 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
2974 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2975 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2976 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
2977 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
2979 * @param Integer $gid profile id
2980 * @param Array $groupTypes With key having group type names
2984 static function updateGroupTypes($gId, $groupTypes = array(
2986 if (!is_array($groupTypes) ||
!$gId) {
2990 // If empty group types set group_type as 'null'
2991 if (empty($groupTypes)) {
2992 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
2995 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
2996 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
2998 $gTypes = $gTypeValues = array();
3000 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3001 // Get valid group type and group subtypes
3002 foreach ($groupTypes as $groupType => $value) {
3003 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3004 $gTypes[] = $groupType;
3009 if (in_array($groupType, $participantExtends)) {
3010 $subTypesOf = $groupType;
3012 elseif (strpos($groupType, 'Type') > 0) {
3013 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3019 if (!empty($value) &&
3020 (in_array($subTypesOf, $componentGroupTypes) ||
3021 in_array($subTypesOf, $participantExtends)
3024 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3028 if (empty($gTypes)) {
3032 // Build String to store group types and group subtypes
3033 $groupTypeString = implode(',', $gTypes);
3034 if (!empty($gTypeValues)) {
3035 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3038 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3042 * Create a "group_type" string
3044 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3045 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3046 * @param string $delim
3047 * @throws CRM_Core_Exception
3049 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3050 $groupTypeExpr = '';
3052 $groupTypeExpr .= implode(',', $coreTypes);
3055 if (count($subTypes) > 1) {
3056 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3058 foreach ($subTypes as $subType => $subTypeIds) {
3059 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3062 return $groupTypeExpr;
3066 * This function is used to setDefault componet specific profile fields.
3068 * @param array $fields profile fields.
3069 * @param int $componentId componetID
3070 * @param string $component component name
3071 * @param array $defaults an array of default values.
3075 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3076 if (!$componentId ||
3077 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3082 $componentBAO = $componentSubType = NULL;
3083 switch ($component) {
3085 $componentBAO = 'CRM_Member_BAO_Membership';
3086 $componentBAOName = 'Membership';
3087 $componentSubType = array('membership_type_id');
3091 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3092 $componentBAOName = 'Contribution';
3093 $componentSubType = array( 'financial_type_id' );
3097 $componentBAO = 'CRM_Event_BAO_Participant';
3098 $componentBAOName = 'Participant';
3099 $componentSubType = array('role_id', 'event_id');
3103 $componentBAO = 'CRM_Activity_BAO_Activity';
3104 $componentBAOName = 'Activity';
3105 $componentSubType = array('activity_type_id');
3110 $params = array('id' => $componentId);
3112 //get the component values.
3113 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3115 $formattedGroupTree = array();
3116 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3117 foreach ($fields as $name => $field) {
3118 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3119 if (in_array($name, $dateTimeFields)) {
3120 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3121 if (!empty($values[$name])) {
3122 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3125 elseif (array_key_exists($name, $values)) {
3126 $defaults[$fldName] = $values[$name];
3128 elseif ($name == 'participant_note') {
3129 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3130 $defaults[$fldName] = array_pop($noteDetails);
3132 elseif (in_array($name, array(
3133 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3134 $defaults[$fldName] = $values["{$name}_id"];
3136 elseif ($name == 'membership_type') {
3137 // since membership_type field is a hierselect -
3138 $defaults[$fldName][0] =
3139 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3140 $defaults[$fldName][1] = $values['membership_type_id'];
3142 elseif ($name == 'membership_status') {
3143 $defaults[$fldName] = $values['status_id'];
3145 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3146 if (empty($formattedGroupTree)) {
3147 //get the groupTree as per subTypes.
3148 $groupTree = array();
3149 foreach ($componentSubType as $subType) {
3150 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3151 $componentId, 0, $values[$subType]
3153 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3155 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3156 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3159 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3160 foreach ($defaults as $customKey => $customValue) {
3161 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3162 if ($name == 'custom_' . $customFieldDetails[0]) {
3164 //hack to set default for checkbox
3165 //basically this is for weired field name like field[33][custom_19]
3166 //we are converting this field name to array structure and assign value.
3169 foreach ($formattedGroupTree as $tree) {
3170 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3172 $defaults['field'][$componentId][$name] = $customValue;
3175 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3178 // CRM-6681, $default contains formatted date, time values.
3179 $defaults[$fldName] = $customValue;
3180 if (!empty($defaults[$customKey . '_time'])) {
3181 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3186 if (!$skipValue ||
$isStandalone) {
3187 $defaults[$fldName] = $customValue;
3189 unset($defaults[$customKey]);
3199 * @param array|string $profiles - name of profile(s) to create links for
3200 * @param array $appendProfiles - name of profile(s) to append to each link
3202 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3203 // Default to contact profiles
3205 $profiles = array('new_individual', 'new_organization', 'new_household');
3207 $profiles = (array) $profiles;
3208 $toGet = array_merge($profiles, (array) $appendProfiles);
3209 $retrieved = civicrm_api3('uf_group', 'get', array(
3210 'name' => array('IN' => $toGet),
3213 $links = $append = array();
3214 if (!empty($retrieved['values'])) {
3215 foreach($retrieved['values'] as $id => $profile) {
3216 if (in_array($profile['name'], $profiles)) {
3218 'label' => $profile['title'],
3219 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3220 NULL, NULL, FALSE, NULL, FALSE) ,
3221 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3228 foreach ($append as $id) {
3229 foreach ($links as &$link) {
3230 $link['url'] .= ",$id";
3238 * Function to retrieve groups of profiles
3240 * @param integer $profileID id of the profile
3242 * @return array returns array
3245 static function profileGroups($profileID) {
3246 $groupTypes = array();
3247 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3248 if ($profileTypes) {
3249 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3250 $groupTypes = explode(',', $groupTypeParts[0]);
3256 * Function to alter contact params by filtering existing subscribed groups and returns
3257 * unsubscribed groups array for subscription.
3259 * @param array $params contact params
3260 * @param int $contactId user contact id
3262 * @return array $subscribeGroupIds This contains array of groups for subscription
3264 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3265 $config = CRM_Core_Config
::singleton();
3266 $subscribeGroupIds = array();
3268 // process further only if profileDoubleOptIn enabled and if groups exist
3269 if (!array_key_exists('group', $params) ||
3270 !self
::isProfileDoubleOptin() ||
3271 CRM_Utils_System
::isNull($params['group'])
3273 return $subscribeGroupIds;
3276 //check if contact email exist.
3278 foreach ($params as $name => $value) {
3279 if (strpos($name, 'email-') !== FALSE) {
3285 //Proceed furthur only if email present
3287 return $subscribeGroupIds;
3290 //do check for already subscriptions.
3291 $contactGroups = array();
3295 FROM civicrm_group_contact
3296 WHERE status = 'Added'
3297 AND contact_id = %1";
3299 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3300 while ($dao->fetch()) {
3301 $contactGroups[$dao->group_id
] = $dao->group_id
;
3305 //since we don't have names, compare w/ label.
3306 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3308 //actual processing start.
3309 foreach ($params['group'] as $groupId => $isSelected) {
3310 //unset group those are not selected.
3312 unset($params['group'][$groupId]);
3316 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3317 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3319 //get only mailing type group and unset it from params
3320 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3321 $subscribeGroupIds[$groupId] = $groupId;
3322 unset($params['group'][$groupId]);
3326 return $subscribeGroupIds;
3330 * Function to check if we are rendering mixed profiles
3332 * @param array $profileIds associated array of profile ids
3334 * @return boolean $mixProfile true if profile is mixed
3338 static function checkForMixProfiles($profileIds) {
3339 $mixProfile = FALSE;
3341 $contactTypes = array('Individual', 'Household', 'Organization');
3342 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3344 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3346 $typeCount = array('ctype' => array(), 'subtype' => array());
3347 foreach ($profileIds as $gid) {
3348 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3349 // ignore profile of type Contact
3350 if ($profileType == 'Contact') {
3353 if (in_array($profileType, $contactTypes)) {
3354 if (!isset($typeCount['ctype'][$profileType])) {
3355 $typeCount['ctype'][$profileType] = 1;
3358 // check if we are rendering profile of different contact types
3359 if (count($typeCount['ctype']) == 2) {
3364 elseif (in_array($profileType, $components)) {
3369 if (!isset($typeCount['subtype'][$profileType])) {
3370 $typeCount['subtype'][$profileType] = 1;
3372 // check if we are rendering profile of different contact sub types
3373 if (count($typeCount['subtype']) == 2) {
3383 * Funtion to determine of we show overlay profile or not
3385 * @return boolean true if profile should be shown else false
3389 static function showOverlayProfile() {
3390 $showOverlay = TRUE;
3392 // get the id of overlay profile
3393 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3394 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3396 $count = CRM_Core_DAO
::singleValueQuery($query);
3398 //check if there are no public fields and use is anonymous
3399 $session = CRM_Core_Session
::singleton();
3400 if (!$count && !$session->get('userID')) {
3401 $showOverlay = FALSE;
3404 return $showOverlay;
3408 * function to get group type values of the profile
3410 * @params Integer $profileId Profile Id
3411 * @params String $groupType Group Type
3413 * @return Array group type values
3417 static function groupTypeValues($profileId, $groupType = NULL) {
3418 $groupTypeValue = array();
3419 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3421 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3422 if (empty($groupTypeParts[1])) {
3423 return $groupTypeValue;
3425 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3427 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3429 $valueParts = explode(':', $groupTypeValues);
3431 ($valueParts[0] != "{$groupType}Type" ||
3432 ($groupType == 'Participant' &&
3433 !in_array($valueParts[0], $participantExtends)
3439 foreach ($valueParts as $val) {
3440 if (CRM_Utils_Rule
::integer($val)) {
3441 $values[$val] = $val;
3444 if (!empty($values)) {
3445 $typeName = substr($valueParts[0], 0, -4);
3446 if (in_array($valueParts[0], $participantExtends)) {
3447 $typeName = $valueParts[0];
3449 $groupTypeValue[$typeName] = $values;
3453 return $groupTypeValue;
3456 static function isProfileDoubleOptin() {
3457 // check for double optin
3458 $config = CRM_Core_Config
::singleton();
3459 if (in_array('CiviMail', $config->enableComponents
)) {
3460 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3461 'profile_double_optin', NULL, FALSE
3467 static function isProfileAddToGroupDoubleOptin() {
3468 // check for add to group double optin
3469 $config = CRM_Core_Config
::singleton();
3470 if (in_array('CiviMail', $config->enableComponents
)) {
3471 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3472 'profile_add_to_group_double_optin', NULL, FALSE
3479 * get profiles used for batch entry
3481 * @return array profileIds profile ids
3484 static function getBatchProfiles() {
3486 FROM civicrm_uf_group
3487 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3488 $dao = CRM_Core_DAO
::executeQuery( $query );
3489 $profileIds = array();
3490 while( $dao->fetch() ) {
3491 $profileIds[$dao->id
] = $dao->id
;
3496 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3497 $multiSummaryFields = $returnMultiSummaryFields ?
array( ) : NULL;
3498 foreach ($source as $field => $properties) {
3499 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3502 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3503 $destination[$field] = $properties;
3504 if ($returnMultiSummaryFields) {
3505 if ($properties['is_multi_summary']) {
3506 $multiSummaryFields[$field] = $properties;
3509 unset($source[$field]);
3512 return $multiSummaryFields;
3516 * This is function is used to format pseudo fields
3518 * @param array $fields associated array of profile fields
3522 static function reformatProfileFields(&$fields) {
3523 //reformat fields array
3524 foreach ($fields as $name => $field) {
3525 //reformat phone and extension field
3526 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3527 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3529 // retain existing element properties and just update and replace key
3530 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3531 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3532 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3534 // add additional phone extension field
3535 $fields["phone_ext-{$fieldSuffix}"] = $field;
3536 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3537 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3538 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3539 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3540 //ignore required for extension field
3541 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;