3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.4 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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-2013
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}";
429 if (!empty($field->location_type_id
)) {
430 $name .= "-{$field->location_type_id}";
433 $locationFields = self
::getLocationFields();
434 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
439 if (isset($field->phone_type_id
)) {
440 $name .= "-{$field->phone_type_id}";
443 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
444 // I guess to make field self sufficient with all the required data and avoid additional calls
445 $formattedField = array(
447 'groupTitle' => $group->title
,
448 'groupName' => $group->name
,
449 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
450 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
452 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
453 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
454 'is_required' => $field->is_required
,
455 'is_view' => $field->is_view
,
456 'help_pre' => $field->help_pre
,
457 'help_post' => $field->help_post
,
458 'visibility' => $field->visibility
,
459 'in_selector' => $field->in_selector
,
460 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
461 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
462 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
463 'group_id' => $group->id
,
464 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
465 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
466 'field_type' => $field->field_type
,
467 'field_id' => $field->id
,
468 'pseudoconstant' => CRM_Utils_Array
::value(
470 CRM_Utils_Array
::value($field->field_name
, $importableFields)
472 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
473 'dbName' => CRM_Utils_Array
::value(
475 CRM_Utils_Array
::value($field->field_name
, $importableFields)
480 //adding custom field property
481 if (substr($field->field_name
, 0, 6) == 'custom' ||
482 substr($field->field_name
, 0, 14) === 'address_custom'
484 // if field is not present in customFields, that means the user
485 // DOES NOT HAVE permission to access that field
486 if (array_key_exists($field->field_name
, $customFields)) {
487 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
489 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
490 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
491 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
493 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
494 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
495 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
498 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
499 return array($name, $formattedField);
502 $formattedField = NULL;
503 return array($name, $formattedField);
506 return array($name, $formattedField);
510 * Create a query to find all visible UFFields in a UFGroup
512 * This is the SQL-variant of checkUFFieldDisplayable().
514 * @param int $groupId
515 * @param bool $searchable
516 * @param bool $showAll
517 * @param int $visibility
518 * @param string $orderBy comma-delimited list of SQL columns
521 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
522 $where = " WHERE uf_group_id = {$groupId}";
525 $where .= " AND is_searchable = 1";
529 $where .= " AND is_active = 1";
534 if ($visibility & self
::PUBLIC_VISIBILITY
) {
535 $clause[] = 'visibility = "Public Pages"';
537 if ($visibility & self
::ADMIN_VISIBILITY
) {
538 $clause[] = 'visibility = "User and User Admin Only"';
540 if ($visibility & self
::LISTINGS_VISIBILITY
) {
541 $clause[] = 'visibility = "Public Pages and Listings"';
543 if (!empty($clause)) {
544 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
548 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
550 $query .= ", " . $orderBy;
557 * Create a query to find all visible UFFields in a UFGroup
559 * This is the PHP in-memory variant of createUFFieldQuery().
561 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
562 * @param bool $searchable
563 * @param bool $showAll
564 * @param int $visibility
565 * @return bool TRUE if field is displayable
567 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
568 if ($searchable && $field->is_searchable
!= 1) {
572 if (!$showAll && $field->is_active
!= 1) {
577 $allowedVisibilities = array();
578 if ($visibility & self
::PUBLIC_VISIBILITY
) {
579 $allowedVisibilities[] = 'Public Pages';
581 if ($visibility & self
::ADMIN_VISIBILITY
) {
582 $allowedVisibilities[] = 'User and User Admin Only';
584 if ($visibility & self
::LISTINGS_VISIBILITY
) {
585 $allowedVisibilities[] = 'Public Pages and Listings';
587 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
588 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
596 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
598 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
601 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
604 if ($profileType == 'Activity' ||
$contactActivityProfile) {
605 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
608 $componentFields = CRM_Core_Component
::getQueryFields();
611 $importableFields = array_merge($importableFields, $componentFields);
613 $importableFields['group']['title'] = ts('Group(s)');
614 $importableFields['group']['where'] = NULL;
615 $importableFields['tag']['title'] = ts('Tag(s)');
616 $importableFields['tag']['where'] = NULL;
617 return $importableFields;
620 public static function getLocationFields() {
621 static $locationFields = array(
623 'supplemental_address_1',
624 'supplemental_address_2',
627 'postal_code_suffix',
640 return $locationFields;
643 protected static function getCustomFields($ctype) {
644 static $customFieldCache = array();
645 if (!isset($customFieldCache[$ctype])) {
646 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
648 // hack to add custom data for components
649 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
650 foreach ($components as $value) {
651 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
653 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
654 $customFields = array_merge($customFields, $addressCustomFields);
655 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
657 return $customFieldCache[$ctype];
661 * check the data validity
663 * @param int $userID the user id that we are actually editing
664 * @param string $title the title of the group we are interested in
665 * @pram boolean $register is this the registrtion form
666 * @param int $action the action of the form
668 * @return boolean true if form is valid
672 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
674 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
675 ts('Dynamic Form Creator'),
678 $controller->set('id', $userID);
679 $controller->set('register', 1);
680 $controller->process();
681 return $controller->validate();
684 // make sure we have a valid group
685 $group = new CRM_Core_DAO_UFGroup();
687 $group->title
= $title;
689 if ($group->find(TRUE) && $userID) {
690 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
691 $controller->set('gid', $group->id
);
692 $controller->set('id', $userID);
693 $controller->set('register', 0);
694 $controller->process();
695 return $controller->validate();
702 * get the html for the form that represents this particular group
704 * @param int $userID the user id that we are actually editing
705 * @param string $title the title of the group we are interested in
706 * @param int $action the action of the form
707 * @param boolean $register is this the registration form
708 * @param boolean $reset should we reset the form?
709 * @param int $profileID do we have the profile ID?
711 * @return string the html for the form on success, otherwise empty string
715 static function getEditHTML($userID,
721 $doNotProcess = FALSE,
726 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
727 ts('Dynamic Form Creator'),
730 if ($reset ||
$doNotProcess) {
731 // hack to make sure we do not process this form
732 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
735 unset($_POST['_qf_default']);
736 unset($_REQUEST['_qf_default']);
738 $controller->reset();
742 $controller->set('id', $userID);
743 $controller->set('register', 1);
744 $controller->set('skipPermission', 1);
745 $controller->set('ctype', $ctype);
746 $controller->process();
747 if ($doNotProcess ||
!empty($_POST)) {
748 $controller->validate();
750 $controller->setEmbedded(TRUE);
752 //CRM-5839 - though we want to process form, get the control back.
753 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
757 // we are done processing so restore the POST/REQUEST vars
758 if (($reset ||
$doNotProcess) && $oldQFDefault) {
759 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
762 $template = CRM_Core_Smarty
::singleton();
764 // Hide CRM error messages if they are displayed using drupal form_set_error.
765 if (!empty($_POST)) {
766 $template->assign('suppressForm', TRUE);
769 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
773 // make sure we have a valid group
774 $group = new CRM_Core_DAO_UFGroup();
776 $group->title
= $title;
778 if ($group->find(TRUE)) {
779 $profileID = $group->id
;
784 // make sure profileID and ctype match if ctype exists
786 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
787 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
788 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
791 if (($profileType != 'Contact') && ($profileType != $ctype)) {
796 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
797 ts('Dynamic Form Creator'),
801 $controller->reset();
803 $controller->set('gid', $profileID);
804 $controller->set('id', $userID);
805 $controller->set('register', 0);
806 $controller->set('skipPermission', 1);
808 $controller->set('ctype', $ctype);
810 $controller->process();
811 $controller->setEmbedded(TRUE);
813 //CRM-5846 - give the control back to drupal.
814 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
817 $template = CRM_Core_Smarty
::singleton();
819 // Hide CRM error messages if they are displayed using drupal form_set_error.
820 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
821 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
822 $template->assign('suppressForm', TRUE);
826 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
827 if (!$template->template_exists($templateFile)) {
828 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
830 return trim($template->fetch($templateFile));
833 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
835 // if post not empty then only proceed
836 if (!empty($_POST)) {
838 $config = CRM_Core_Config
::singleton();
839 $email = CRM_Utils_Array
::value('mail', $_POST);
841 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
842 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
851 * searches for a contact in the db with similar attributes
853 * @param array $params the list of values to be used in the where clause
854 * @param int $id the current contact id (hence excluded from matching)
855 * @param boolean $flatten should we flatten the input params
857 * @return contact_id if found, null otherwise
861 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
862 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
863 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
864 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
866 return implode(',', $ids);
874 * Given a contact id and a field set, return the values from the db
877 * @param int $id the contact id
878 * @param array $fields the profile fields of interest
879 * @param array $values the values for the above fields
880 * @param boolean $searchable searchable or not
881 * @param array $componentWhere component condition
882 * @param boolean $absolute return urls in absolute form (useful when sending an email)
888 public static function getValues($cid, &$fields, &$values,
889 $searchable = TRUE, $componentWhere = NULL,
890 $absolute = FALSE, $additionalWhereClause = NULL
892 if (empty($cid) && empty($componentWhere)) {
896 // get the contact details (hier)
897 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
898 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
900 // add conditions specified by components. eg partcipant_id etc
901 if (!empty($componentWhere)) {
902 $params = array_merge($params, $componentWhere);
905 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
906 $options = &$query->_options
;
908 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
909 FALSE, FALSE, FALSE, $additionalWhereClause);
910 if (!$details->fetch()) {
913 $query->convertToPseudoNames($details);
914 $config = CRM_Core_Config
::singleton();
916 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
917 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
918 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
920 $multipleFields = array('url');
921 $nullIndex = $nullValueIndex = ' ';
923 //start of code to set the default values
924 foreach ($fields as $name => $field) {
927 $name = 'contact_id';
930 // skip fields that should not be displayed separately
931 if (!empty($field['skipDisplay'])) {
935 $index = $field['title'];
936 //handle for the label not set for the field
937 if (empty($field['title'])) {
939 $nullIndex .= $nullIndex;
942 //handle the case to avoid re-write where the profile field labels are the same
943 if (array_key_exists($index, $values)) {
944 $index .= $nullValueIndex;
945 $nullValueIndex .= $nullValueIndex;
947 $params[$index] = $values[$index] = '';
948 $customFieldName = NULL;
950 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
951 // to handle gender / suffix / prefix
952 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
953 $params[$index] = $details->$name;
954 $values[$index] = $details->$name;
956 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
957 $dname = $name . '_display';
958 $values[$index] = $details->$dname;
959 $name = $name . '_id';
960 $params[$index] = $details->$name;
962 elseif (in_array($name, array(
963 'state_province', 'country', 'county'))) {
964 $values[$index] = $details->$name;
965 $idx = $name . '_id';
966 $params[$index] = $details->$idx;
968 elseif ($name === 'preferred_communication_method') {
969 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
971 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
973 foreach ($pref as $k) {
975 $compref[] = $communicationFields[$k];
978 $params[$index] = $details->$name;
979 $values[$index] = implode(',', $compref);
981 elseif ($name === 'preferred_language') {
982 $params[$index] = $details->$name;
983 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
985 elseif ($name == 'group') {
986 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
987 $title = $ids = array();
989 foreach ($groups as $g) {
990 // CRM-8362: User and User Admin visibility groups should be included in display if user has
991 // VIEW permission on that group
992 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
994 if ($g['visibility'] != 'User and User Admin Only' ||
995 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
997 $title[] = $g['title'];
998 if ($g['visibility'] == 'Public Pages') {
999 $ids[] = $g['group_id'];
1003 $values[$index] = implode(', ', $title);
1004 $params[$index] = implode(',', $ids);
1006 elseif ($name == 'tag') {
1007 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1008 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1010 foreach ($entityTags as $tagId) {
1011 $title[] = $allTags[$tagId];
1013 $values[$index] = implode(', ', $title);
1014 $params[$index] = implode(',', $entityTags);
1016 elseif ($name == 'activity_status_id') {
1017 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1018 $values[$index] = $activityStatus[$details->$name];
1019 $params[$index] = $details->$name;
1021 elseif ($name == 'activity_date_time') {
1022 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1023 $params[$index] = $details->$name;
1025 elseif ($name == 'contact_sub_type') {
1026 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1027 if (!empty($contactSubTypeNames)) {
1028 $contactSubTypeLabels = array();
1029 // get all contact subtypes
1030 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1031 // build contact subtype labels array
1032 foreach( $contactSubTypeNames as $cstName ) {
1034 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1037 $values[$index] = implode(',', $contactSubTypeLabels);
1040 $params[$index] = $details->$name;
1043 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1044 if ($details->$name) {
1045 $values[$index] = '[ x ]';
1049 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1050 $htmlType = $field['html_type'];
1052 // field_type is only set when we are retrieving profile values
1053 // when sending email, we call the same function to get custom field
1054 // values etc, i.e. emulating a profile
1055 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1057 if ($htmlType == 'File') {
1060 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
1061 $entityId = $componentWhere[0][2];
1064 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1069 $params[$index] = $values[$index] = $fileURL['file_url'];
1073 if (isset($dao) && property_exists($dao, 'data_type') &&
1074 ($dao->data_type
== 'Int' ||
1075 $dao->data_type
== 'Boolean'
1078 $customVal = (int )($details->{$name});
1080 elseif (isset($dao) && property_exists($dao, 'data_type')
1081 && $dao->data_type
== 'Float'
1083 $customVal = (float )($details->{$name});
1085 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1088 $customVal = $details->{$name};
1092 if (CRM_Utils_System
::isNull($customVal)) {
1096 $params[$index] = $customVal;
1097 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1101 if ($field['data_type'] == 'ContactReference') {
1102 $params[$index] = $values[$index];
1104 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1105 $cfID, 'is_search_range'
1107 $customFieldName = "{$name}_from";
1111 elseif ($name == 'image_URL') {
1112 list($width, $height) = getimagesize($details->$name);
1113 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1115 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1116 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1118 elseif (in_array($name, array(
1119 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1120 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1121 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1125 if ($index == 'Campaign') {
1126 $dao = 'CRM_Campaign_DAO_Campaign';
1128 elseif ($index == 'Contribution Page') {
1129 $dao = 'CRM_Contribute_DAO_ContributionPage';
1132 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1135 $value = $details->$name;
1137 $values[$index] = $value;
1142 elseif (strpos($name, '-') !== FALSE) {
1143 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1145 if (!in_array($fieldName, $multipleFields)) {
1146 if ($id == 'Primary') {
1148 // not sure why we'd every use Primary location type id
1149 // we need to fix the source if we are using it
1150 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1151 $locationTypeName = 1;
1154 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1157 if (!$locationTypeName) {
1161 $detailName = "{$locationTypeName}-{$fieldName}";
1162 $detailName = str_replace(' ', '_', $detailName);
1164 if (in_array($fieldName, array(
1165 'phone', 'im', 'email', 'openid'))) {
1167 $detailName .= "-{$type}";
1171 if (in_array($fieldName, array(
1172 'state_province', 'country', 'county'))) {
1173 $values[$index] = $details->$detailName;
1174 $idx = $detailName . '_id';
1175 $params[$index] = $details->$idx;
1177 elseif ($fieldName == 'im') {
1178 $providerId = $detailName . '-provider_id';
1179 if (isset($imProviders[$details->$providerId])) {
1180 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1183 $values[$index] = $details->$detailName;
1185 $params[$index] = $details->$detailName;
1187 elseif ($fieldName == 'phone') {
1188 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1189 if (isset($details->$phoneExtField)) {
1190 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1193 $values[$index] = $details->$detailName;
1195 $params[$index] = $details->$detailName;
1198 $values[$index] = $params[$index] = $details->$detailName;
1202 $detailName = "website-{$id}-{$fieldName}";
1203 $url = CRM_Utils_System
::fixURL($details->$detailName);
1204 if ($details->$detailName) {
1205 $websiteTypeId = "website-{$id}-website_type_id";
1206 $websiteType = $websiteTypes[$details->$websiteTypeId];
1207 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1210 $values[$index] = '';
1215 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1216 CRM_Core_Permission
::check('profile listings and forms')
1219 if (CRM_Utils_System
::isNull($params[$index])) {
1220 $params[$index] = $values[$index];
1222 if (!isset($params[$index])) {
1225 if (!$customFieldName) {
1226 $fieldName = $field['name'];
1229 $fieldName = $customFieldName;
1233 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1234 $htmlType = $field['html_type'];
1235 if ($htmlType == 'Link') {
1236 $url = $params[$index];
1238 elseif (in_array($htmlType, array(
1239 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1240 'Multi-Select State/Province', 'Multi-Select Country',
1242 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1243 $selectedOptions = explode($valSeperator, $params[$index]);
1245 foreach ($selectedOptions as $key => $multiOption) {
1247 $url[] = CRM_Utils_System
::url('civicrm/profile',
1248 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1249 urlencode($fieldName) .
1251 urlencode($multiOption)
1257 $url = CRM_Utils_System
::url('civicrm/profile',
1258 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1259 urlencode($fieldName) .
1261 urlencode($params[$index])
1266 $url = CRM_Utils_System
::url('civicrm/profile',
1267 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1268 urlencode($fieldName) .
1270 urlencode($params[$index])
1275 !empty($values[$index]) &&
1279 if (is_array($url) && !empty($url)) {
1281 $eachMultiValue = explode(', ', $values[$index]);
1282 foreach ($eachMultiValue as $key => $valueLabel) {
1283 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1285 $values[$index] = implode(', ', $links);
1288 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1296 * Check if profile Group used by any module.
1298 * @param int $id profile Id
1306 public static function usedByModule($id) {
1307 //check whether this group is used by any module(check uf join records)
1309 FROM civicrm_uf_join
1310 WHERE civicrm_uf_join.uf_group_id=$id";
1312 $dao = new CRM_Core_DAO();
1314 if ($dao->fetch()) {
1323 * Delete the profile Group.
1325 * @param int $id profile Id
1333 public static function del($id) {
1334 //check whether this group contains any profile fields
1335 $profileField = new CRM_Core_DAO_UFField();
1336 $profileField->uf_group_id
= $id;
1337 $profileField->find();
1338 while ($profileField->fetch()) {
1339 CRM_Core_BAO_UFField
::del($profileField->id
);
1342 //delete records from uf join table
1343 $ufJoin = new CRM_Core_DAO_UFJoin();
1344 $ufJoin->uf_group_id
= $id;
1347 //delete profile group
1348 $group = new CRM_Core_DAO_UFGroup();
1355 * function to add the UF Group
1357 * @param array $params reference array contains the values submitted by the form
1358 * @param array $ids reference array contains the id
1365 static function add(&$params, $ids = array()) {
1366 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1367 foreach ($fields as $field) {
1368 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1371 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1372 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1374 $ufGroup = new CRM_Core_DAO_UFGroup();
1375 $ufGroup->copyValues($params);
1377 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1379 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1381 $ufGroup->id
= $ufGroupID;
1386 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1394 * Function to make uf join entries for an uf group
1396 * @param array $params (reference) an assoc array of name/value pairs
1397 * @param int $ufGroupId ufgroup id
1403 static function createUFJoin(&$params, $ufGroupId) {
1404 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1406 // get ufjoin records for uf group
1407 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1409 // get the list of all ufgroup types
1410 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1412 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1413 if (!is_array($groupTypes)) {
1414 $groupTypes = array();
1417 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1418 if (!is_array($ufGroupRecord)) {
1419 $ufGroupRecord = array();
1422 // check which values has to be inserted/deleted for contact
1423 $menuRebuild = FALSE;
1424 foreach ($allUFGroupType as $key => $value) {
1425 $joinParams = array();
1426 $joinParams['uf_group_id'] = $ufGroupId;
1427 $joinParams['module'] = $key;
1428 if ($key == 'User Account') {
1429 $menuRebuild = TRUE;
1431 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1432 // insert a new record
1433 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1435 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1436 // delete a record for existing ufgroup
1437 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1443 UPDATE civicrm_uf_join
1445 WHERE uf_group_id = %2
1446 AND ( entity_id IS NULL OR entity_id <= 0 )
1448 $p = array(1 => array($params['weight'], 'Integer'),
1449 2 => array($ufGroupId, 'Integer'),
1451 CRM_Core_DAO
::executeQuery($query, $p);
1453 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1455 $config = CRM_Core_Config
::singleton();
1457 $config->userSystem
->is_drupal
1464 * Function to get the UF Join records for an ufgroup id
1466 * @params int $ufGroupId uf group id
1467 * @params int $displayName if set return display name in array
1468 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1470 * @return array $ufGroupJoinRecords
1475 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1477 $UFGroupType = array();
1478 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1482 $dao = new CRM_Core_DAO_UFJoin();
1485 $dao->uf_group_id
= $ufGroupId;
1491 while ($dao->fetch()) {
1492 if (!$displayName) {
1493 $ufJoin[$dao->id
] = $dao->module
;
1496 if (isset($UFGroupType[$dao->module
])) {
1497 // skip the default modules
1499 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1501 // added for CRM-1475
1503 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1504 $ufJoin[$dao->id
] = $dao->module
;
1512 * Function takes an associative array and creates a ufjoin record for ufgroup
1514 * @param array $params (reference) an assoc array of name/value pairs
1516 * @return object CRM_Core_BAO_UFJoin object
1520 static function addUFJoin(&$params) {
1521 $ufJoin = new CRM_Core_DAO_UFJoin();
1522 $ufJoin->copyValues($params);
1528 * Function to delete the uf join record for an uf group
1530 * @param array $params (reference) an assoc array of name/value pairs
1536 static function delUFJoin(&$params) {
1537 $ufJoin = new CRM_Core_DAO_UFJoin();
1538 $ufJoin->copyValues($params);
1543 * Function to get the weight for ufjoin record
1545 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1547 * @return int weight of the UFGroup
1551 static function getWeight($ufGroupId = NULL) {
1552 //calculate the weight
1555 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1556 FROM civicrm_uf_join
1557 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1560 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1561 FROM civicrm_uf_join
1562 WHERE civicrm_uf_join.uf_group_id = %1
1563 AND ( entity_id IS NULL OR entity_id <= 0 )";
1564 $p[1] = array($ufGroupId, 'Integer');
1567 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1569 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1573 * Function to get the uf group for a module
1575 * @param string $moduleName module name
1576 * @param int $count no to increment the weight
1577 * @param bool $skipPermision - whether to add permission clause
1578 * @param int $op - which operation (view, edit, create, etc) to check permission for
1579 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1581 * @return array $ufGroups array of ufgroups for a module
1585 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1586 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1588 if (!CRM_Core_Config
::isUpgradeMode()) {
1589 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1590 $selectFields[] = 'description';
1593 if (!empty($returnFields)) {
1594 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1597 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1598 FROM civicrm_uf_group
1599 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1602 $queryString .= ' AND civicrm_uf_group.is_active = 1
1603 WHERE civicrm_uf_join.module = %2';
1604 $p[2] = array($moduleName, 'String');
1608 // add permissioning for profiles only if not registration
1609 if (!$skipPermission) {
1610 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1611 if (strpos($queryString, 'WHERE') !== FALSE) {
1612 $queryString .= " AND $permissionClause ";
1615 $queryString .= " $permissionClause ";
1619 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1620 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1622 $ufGroups = array();
1623 while ($dao->fetch()) {
1624 //skip mix profiles in user Registration / User Account
1625 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1626 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1630 foreach ($selectFields as $key => $field) {
1631 if($field == 'id') {
1634 elseif ($field == 'name') {
1635 $ufGroups[$dao->id
][$field] = $dao->title
;
1638 $ufGroups[$dao->id
][$field] = $dao->$field;
1642 // Allow other modules to alter/override the UFGroups.
1643 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1649 * Function to filter ufgroups based on logged in user contact type
1651 * @params int $ufGroupId uf group id (profile id)
1653 * @return boolean true or false
1657 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1659 $session = CRM_Core_Session
::singleton();
1660 $contactID = $session->get('userID');
1664 //get the contact type
1665 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1667 //match if exixting contact type is same as profile contact type
1668 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1670 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1671 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1674 //allow special mix profiles for Contribution and Participant
1675 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1677 if (in_array($profileType, $specialProfiles)) {
1681 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1690 * Function to build profile form
1692 * @params object $form form object
1693 * @params array $field array field properties
1694 * @params int $mode profile mode
1695 * @params int $contactID contact id
1696 * @params string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
1702 static function buildProfile(
1712 $defaultValues = array();
1713 $fieldName = $field['name'];
1714 $title = $field['title'];
1715 $attributes = $field['attributes'];
1716 $rule = $field['rule'];
1717 $view = $field['is_view'];
1718 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1719 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1720 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1722 // do not display view fields in drupal registration form
1724 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1728 if ($usedFor == 'onbehalf') {
1729 $name = "onbehalf[$fieldName]";
1731 elseif ($usedFor == 'honor') {
1732 $name = "honor[$fieldName]";
1734 elseif ($contactId && !$online) {
1735 $name = "field[$contactId][$fieldName]";
1737 elseif ($rowNumber) {
1738 $name = "field[$rowNumber][$fieldName]";
1740 elseif (!empty($prefix)) {
1741 $name = $prefix ."[$fieldName]";
1747 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1748 $deleteExtra = ts('Are you sure you want to delete contact image.');
1750 CRM_Core_Action
::DELETE
=>
1752 'name' => ts('Delete Contact Image'),
1753 'url' => 'civicrm/contact/image',
1754 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1756 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1759 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1760 CRM_Core_Action
::DELETE
,
1761 array('id' => $form->get('id'),
1762 'gid' => $form->get('gid'),
1766 'contact.profileimage.delete',
1770 $form->assign('deleteURL', $deleteURL);
1772 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1773 'address_options', TRUE, NULL, TRUE
1776 if (substr($fieldName, 0, 14) === 'state_province') {
1777 $form->add('select', $name, $title,
1779 '' => ts('- select -')) + CRM_Core_PseudoConstant
::stateProvince(), $required
1781 $config = CRM_Core_Config
::singleton();
1782 if (!in_array($mode, array(
1783 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1784 $config->defaultContactStateProvince
1786 $defaultValues[$name] = $config->defaultContactStateProvince
;
1787 $form->setDefaults($defaultValues);
1790 elseif (substr($fieldName, 0, 7) === 'country') {
1791 $form->add('select', $name, $title,
1793 '' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required
1795 $config = CRM_Core_Config
::singleton();
1796 if (!in_array($mode, array(
1797 CRM_Profile_Form
::MODE_EDIT
, CRM_Profile_Form
::MODE_SEARCH
)) &&
1798 $config->defaultContactCountry
1800 $defaultValues[$name] = $config->defaultContactCountry
;
1801 $form->setDefaults($defaultValues);
1804 elseif (substr($fieldName, 0, 6) === 'county') {
1805 if ($addressOptions['county']) {
1806 $form->add('select', $name, $title,
1808 '' => ts('(choose state first)')), $required
1812 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1813 $form->add('file', $name, $title, $attributes, $required);
1814 $form->addUploadElement($name);
1816 elseif (substr($fieldName, 0, 2) === 'im') {
1817 $form->add('text', $name, $title, $attributes, $required);
1820 if (substr($name, -1) == ']') {
1821 $providerName = substr($name, 0, -1) . '-provider_id]';
1823 $form->add('select', $providerName, NULL,
1825 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1829 $form->add('select', $name . '-provider_id', $title,
1831 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1835 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1836 $form->freeze($name . '-provider_id');
1840 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1841 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1843 elseif (in_array($fieldName, array(
1844 'membership_start_date', 'membership_end_date', 'join_date'))) {
1845 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1847 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_type') {
1848 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1849 $sel = &$form->addElement('hierselect', $name, $title);
1850 $select = array('' => ts('- select -') );
1851 if(count($orgInfo) == 1 && $field['is_required']) {
1852 // we only have one org - so we should default to it. Not sure about defaulting to first type
1853 // as it could be missed - so adding a select
1854 // however, possibly that is more similar to the membership form
1855 if(count($types[1]) > 1) {
1856 $types[1] = $select +
$types[1];
1860 $orgInfo = $select +
$orgInfo;
1862 $sel->setOptions(array($orgInfo, $types));
1864 elseif (CRM_Utils_Array
::value('name',$field) == 'membership_status') {
1865 $form->add('select', $name, $title,
1867 '' => ts('- select -')) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1870 elseif ($fieldName === 'gender_id') {
1871 $genderOptions = array();
1872 $gender = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'gender_id');
1873 foreach ($gender as $key => $var) {
1874 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1876 $group = $form->addGroup($genderOptions, $name, $title);
1878 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1881 $group->setAttribute('allowClear', TRUE);
1884 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1885 $form->add('select', $name, $title,
1887 '' => ts('- select -')) + CRM_Core_PseudoConstant
::get('CRM_Contact_BAO_Contact', $fieldName), $required
1890 elseif ($fieldName === 'contact_sub_type') {
1891 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1892 if ($usedFor == 'onbehalf') {
1893 $profileType = 'Organization';
1895 elseif ($usedFor == 'honor') {
1896 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1899 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1900 if ($profileType == 'Contact') {
1901 $profileType = 'Individual';
1905 $setSubtype = FALSE;
1906 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1907 $setSubtype = $profileType;
1908 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1911 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
1914 $subtypeList = array();
1915 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1918 $subtypeList = $subtypes;
1921 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1922 $sel->setMultiple(TRUE);
1924 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1925 //add email greeting, postal greeting, addressee, CRM-4575
1926 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1927 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
1929 if (empty($profileType) ||
in_array($profileType, array(
1930 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1931 $profileType = 'Individual';
1933 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1934 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1937 'contact_type' => $profileType,
1938 'greeting_type' => $fieldName,
1940 $form->add('select', $name, $title,
1942 '' => ts('- select -')) + CRM_Core_PseudoConstant
::greeting($greeting), $required
1944 // add custom greeting element
1945 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1949 elseif ($fieldName === 'preferred_communication_method') {
1950 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1951 foreach ($communicationFields as $key => $var) {
1955 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
1957 $form->addGroup($communicationOptions, $name, $title, '<br/>');
1959 elseif ($fieldName === 'preferred_mail_format') {
1960 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
1962 elseif ($fieldName === 'preferred_language') {
1963 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
1965 elseif ($fieldName == 'external_identifier') {
1966 $form->add('text', $name, $title, $attributes, $required);
1967 $contID = $contactId;
1969 $contID = $form->get('id');
1971 $form->addRule($name,
1972 ts('External ID already exists in Database.'),
1974 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
1977 elseif ($fieldName === 'group') {
1978 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
1979 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
1984 elseif ($fieldName === 'tag') {
1985 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
1986 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
1991 elseif (substr($fieldName, 0, 4) === 'url-') {
1992 $form->add('text', $name, $title,
1993 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
1995 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
1996 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2001 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2003 //Website type select
2005 if (substr($name, -1) == ']') {
2006 $websiteTypeName = substr($name, 0, -1) . '-website_type_id]';
2008 $form->addElement('select', $websiteTypeName, NULL, CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id'));
2011 $form->addElement('select', $name . '-website_type_id', NULL, CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id'));
2014 // Note should be rendered as textarea
2015 elseif (substr($fieldName, -4) == 'note') {
2016 $form->add('textarea', $name, $title, $attributes, $required);
2018 elseif (substr($fieldName, 0, 6) === 'custom') {
2019 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2020 if ($customFieldID) {
2021 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2024 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2025 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2026 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2027 if ($customFieldID) {
2028 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2031 elseif (in_array($fieldName, array(
2032 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2033 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2035 elseif ($fieldName == 'send_receipt') {
2036 $form->addElement('checkbox', $name, $title);
2038 elseif ($fieldName == 'soft_credit') {
2039 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2040 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2042 elseif ($fieldName == 'product_name') {
2043 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2044 $sel = &$form->addElement('hierselect', $name, $title);
2046 '0' => ts('- select -')) +
$products;
2047 $sel->setOptions(array($products, $options));
2049 elseif ($fieldName == 'payment_instrument') {
2050 $form->add('select', $name, $title,
2051 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant
::paymentInstrument( ), $required );
2053 else if ($fieldName == 'financial_type' ) {
2054 $form->add('select', $name, $title,
2056 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::financialType(), $required
2059 elseif ($fieldName == 'contribution_status_id') {
2060 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2061 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2067 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2070 $form->add('select', $name, $title,
2072 '' => ts('- select -')) +
$contributionStatuses, $required
2075 elseif ($fieldName == 'soft_credit_type') {
2076 $form->add('select', $name, $title,
2078 '' => ts('- select -')) + CRM_Core_OptionGroup
::values("soft_credit_type")
2080 $form->addElement('hidden', 'sct_default_id',
2081 CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type"),
2082 array('id' => 'sct_default_id')
2085 elseif ($fieldName == 'currency') {
2086 $form->addCurrency($name, $title, $required);
2088 elseif ($fieldName == 'contribution_page_id') {
2089 $form->add('select', $name, $title,
2091 '' => ts('- select -')) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2094 elseif ($fieldName == 'participant_register_date') {
2095 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2097 elseif ($fieldName == 'activity_status_id') {
2098 $form->add('select', $name, $title,
2100 '' => ts('- select -')) + CRM_Core_PseudoConstant
::activityStatus(), $required
2103 elseif ($fieldName == 'activity_engagement_level') {
2104 $form->add('select', $name, $title,
2106 '' => ts('- select -')) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2109 elseif ($fieldName == 'activity_date_time') {
2110 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2112 elseif ($fieldName == 'participant_status') {
2114 if ($online == TRUE) {
2115 $cond = 'visibility_id = 1';
2117 $form->add('select', $name, $title,
2119 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2122 elseif ($fieldName == 'participant_role') {
2123 if (!empty($field['is_multiple'])) {
2124 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2127 $form->add('select', $name, $title,
2129 '' => ts('- select -')) + CRM_Event_PseudoConstant
::participantRole(), $required
2133 elseif ($fieldName == 'world_region') {
2134 $form->add('select', $name, $title,
2136 '' => ts('- select -')) + CRM_Core_PseudoConstant
::worldRegion(), $required
2139 elseif ($fieldName == 'signature_html') {
2140 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2142 elseif ($fieldName == 'signature_text') {
2143 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2145 elseif (substr($fieldName, -11) == 'campaign_id') {
2146 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2147 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2148 $form->_componentCampaigns
2150 $form->add('select', $name, $title,
2152 '' => ts('- select -')) +
$campaigns, $required, 'class="big"'
2156 elseif ($fieldName == 'activity_details') {
2157 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2159 elseif ($fieldName == 'activity_duration') {
2160 $form->add('text', $name, $title, $attributes, $required);
2161 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2164 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2165 $form->add('advcheckbox', $name, $title, $attributes, $required);
2168 $form->add('text', $name, $title, $attributes, $required);
2172 static $hiddenSubtype = FALSE;
2173 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2174 // In registration mode params are submitted via POST and we don't have any clue
2175 // about profile-id or the profile-type (which could be a subtype)
2176 // To generalize the behavior and simplify the process,
2177 // lets always add the hidden
2178 //subtype value if there is any, and we won't have to
2179 // compute it while processing.
2181 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2184 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2186 $hiddenSubtype = TRUE;
2189 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2190 $form->freeze($name);
2194 if (in_array($fieldName, array(
2195 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2196 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2198 $stateCountryMap = array();
2199 if (!empty($form->_stateCountryMap
['state_province']) && !empty($form->_stateCountryMap
['country'])) {
2200 foreach ($form->_stateCountryMap
['state_province'] as $key => $value) {
2201 $stateCountryMap[$key]['state_province'] = $value;
2202 $stateCountryMap[$key]['country'] = $form->_stateCountryMap
['country'][$key];
2204 CRM_Core_BAO_Address
::addStateCountryMap($stateCountryMap);
2207 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2208 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2214 * Function to set profile defaults
2216 * @params int $contactId contact id
2217 * @params array $fields associative array of fields
2218 * @params array $defaults defaults array
2219 * @params boolean $singleProfile true for single profile else false(batch update)
2220 * @params int $componentId id for specific components like contribute, event etc
2226 static function setProfileDefaults($contactId, &$fields, &$defaults,
2227 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2229 if (!$componentId) {
2230 //get the contact details
2231 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2232 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2233 $multipleFields = array('website' => 'url');
2235 //start of code to set the default values
2236 foreach ($fields as $name => $field) {
2237 // skip pseudo fields
2238 if (substr($name, 0, 9) == 'phone_ext') {
2242 //set the field name depending upon the profile mode(single/batch)
2243 if ($singleProfile) {
2247 $fldName = "field[$contactId][$name]";
2250 if ($name == 'group') {
2251 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2253 if ($name == 'tag') {
2254 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2257 if (!empty($details[$name]) ||
isset($details[$name])) {
2258 //to handle custom data (checkbox) to be written
2259 // to handle birth/deceased date, greeting_type and few other fields
2260 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2261 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2263 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2264 $defaults[$fldName] = $details[$name . '_id'];
2265 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2267 elseif ($name == 'preferred_communication_method') {
2268 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2269 foreach ($v as $item) {
2271 $defaults[$fldName . "[$item]"] = 1;
2275 elseif ($name == 'world_region') {
2276 $defaults[$fldName] = $details['worldregion_id'];
2278 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2279 //fix for custom fields
2280 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2282 // hack to add custom data for components
2283 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2284 foreach ($components as $value) {
2285 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2286 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2290 switch ($customFields[$customFieldId]['html_type']) {
2291 case 'Multi-Select State/Province':
2292 case 'Multi-Select Country':
2293 case 'AdvMulti-Select':
2294 case 'Multi-Select':
2295 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2296 foreach ($v as $item) {
2298 $defaults[$fldName][$item] = $item;
2304 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2305 foreach ($v as $item) {
2307 $defaults[$fldName][$item] = 1;
2308 // seems like we need this for QF style checkboxes in profile where its multiindexed
2310 $defaults["{$fldName}[{$item}]"] = 1;
2315 case 'Autocomplete-Select':
2316 if ($customFields[$customFieldId]['data_type'] == 'ContactReference') {
2317 if (is_numeric($details[$name])) {
2318 $defaults[$fldName . '_id'] = $details[$name];
2319 $defaults[$fldName] = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact', $details[$name], 'sort_name');
2323 $defaults[$fldName] = $details[$name];
2328 // CRM-6681, set defult values according to date and time format (if any).
2330 if (!empty($customFields[$customFieldId]['date_format'])) {
2331 $dateFormat = $customFields[$customFieldId]['date_format'];
2334 if (empty($customFields[$customFieldId]['time_format'])) {
2335 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2340 $timeElement = $fldName . '_time';
2341 if (substr($fldName, -1) == ']') {
2342 $timeElement = substr($fldName, 0, -1) . '_time]';
2344 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2345 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2350 $defaults[$fldName] = $details[$name];
2355 $defaults[$fldName] = $details[$name];
2359 $blocks = array('email', 'phone', 'im', 'openid');
2360 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2361 if (!in_array($fieldName, $multipleFields)) {
2362 if (is_array($details)) {
2363 foreach ($details as $key => $value) {
2364 // when we fixed CRM-5319 - get primary loc
2365 // type as per loc field and removed below code.
2366 $primaryLocationType = FALSE;
2367 if ($locTypeId == 'Primary') {
2368 if (is_array($value) && array_key_exists($fieldName, $value)){
2369 $primaryLocationType = TRUE;
2370 if (in_array($fieldName, $blocks)){
2371 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2374 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2379 // fixed for CRM-665
2380 if (is_numeric($locTypeId)) {
2381 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2382 if (!empty($value[$fieldName])) {
2383 //to handle stateprovince and country
2384 if ($fieldName == 'state_province') {
2385 $defaults[$fldName] = $value['state_province_id'];
2387 elseif ($fieldName == 'county') {
2388 $defaults[$fldName] = $value['county_id'];
2390 elseif ($fieldName == 'country') {
2391 if (!isset($value['country_id']) ||
!$value['country_id']) {
2392 $config = CRM_Core_Config
::singleton();
2393 if ($config->defaultContactCountry
) {
2394 $defaults[$fldName] = $config->defaultContactCountry
;
2398 $defaults[$fldName] = $value['country_id'];
2401 elseif ($fieldName == 'phone') {
2403 if (isset($value['phone'][$phoneTypeId])) {
2404 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2406 if (isset($value['phone_ext'][$phoneTypeId])) {
2407 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2411 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2413 if (!is_array($phoneDefault)) {
2414 $defaults[$fldName] = $phoneDefault;
2418 elseif ($fieldName == 'email') {
2419 //adding the first email (currently we don't support multiple emails of same location type)
2420 $defaults[$fldName] = $value['email'];
2422 elseif ($fieldName == 'im') {
2423 //adding the first im (currently we don't support multiple ims of same location type)
2424 $defaults[$fldName] = $value['im'];
2425 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2428 $defaults[$fldName] = $value[$fieldName];
2431 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2432 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2434 $defaults[$fldName] = $value[substr($fieldName, 8)];
2442 if (is_array($details)) {
2443 if ($fieldName === 'url') {
2444 if (!empty($details['website'])) {
2445 foreach ($details['website'] as $val) {
2446 $defaults[$fldName] = CRM_Utils_Array
::value('url', $val);
2447 $defaults[$fldName . '-website_type_id'] = $val['website_type_id'];
2457 //Handling Contribution Part of the batch profile
2458 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2459 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2462 //Handling Event Participation Part of the batch profile
2463 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2464 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2467 //Handling membership Part of the batch profile
2468 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2469 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2472 //Handling Activity Part of the batch profile
2473 if ($component == 'Activity') {
2474 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2479 * Function to get profiles by type eg: pure Individual etc
2481 * @param array $types associative array of types eg: types('Individual')
2482 * @param boolean $onlyPure true if only pure profiles are required
2484 * @return array $profiles associative array of profiles
2488 static function getProfiles($types, $onlyPure = FALSE) {
2489 $profiles = array();
2490 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2492 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2494 // Exclude Batch Data Entry profiles - CRM-10901
2495 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2497 foreach ($ufGroups as $id => $title) {
2498 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2499 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2500 $profiles[$id] = $title;
2507 * Function to check whether a profile is valid combination of
2508 * required and/or optional profile types
2510 * @param array $required array of types those are required
2511 * @param array $optional array of types those are optional
2513 * @return array $profiles associative array of profiles
2517 static function getValidProfiles($required, $optional = NULL) {
2518 if (!is_array($required) ||
empty($required)) {
2522 $profiles = array();
2523 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2525 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2527 foreach ($ufGroups as $id => $title) {
2528 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2530 $profiles[$id] = $title;
2538 * Function to check whether a profile is valid combination of
2539 * required profile fields
2541 * @param array $ufId integer id of the profile
2542 * @param array $required array of fields those are required in the profile
2544 * @return array $profiles associative array of profiles
2548 static function checkValidProfile($ufId, $required = NULL) {
2549 $validProfile = FALSE;
2551 return $validProfile;
2554 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2555 return $validProfile;
2558 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2559 NULL, FALSE, NULL, FALSE, NULL,
2560 CRM_Core_Permission
::CREATE
, NULL
2563 $validProfile = array();
2564 if (!empty($profileFields)) {
2565 $fields = array_keys($profileFields);
2566 foreach ($fields as $val) {
2567 foreach ($required as $key => $field) {
2568 if (strpos($val, $field) === 0) {
2569 unset($required[$key]);
2574 $validProfile = (empty($required)) ?
TRUE : FALSE;
2577 return $validProfile;
2581 * Function to get default value for Register.
2587 static function setRegisterDefaults(&$fields, &$defaults) {
2588 $config = CRM_Core_Config
::singleton();
2589 foreach ($fields as $name => $field) {
2590 if (substr($name, 0, 8) == 'country-') {
2591 if (!empty($config->defaultContactCountry
)) {
2592 $defaults[$name] = $config->defaultContactCountry
;
2595 elseif (substr($name, 0, 15) == 'state_province-') {
2596 if (!empty($config->defaultContactStateProvince
)) {
2597 $defaults[$name] = $config->defaultContactStateProvince
;
2605 * This function is to make a copy of a profile, including
2606 * all the fields in the profile
2608 * @param int $id the profile id to copy
2613 static function copy($id) {
2614 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2615 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2621 if ($pos = strrpos($copy->name
, "_{$id}")) {
2622 $copy->name
= substr_replace($copy->name
, '', $pos);
2624 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2627 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2628 array('uf_group_id' => $id),
2629 array('uf_group_id' => $copy->id
),
2634 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2635 array('uf_group_id' => $id),
2636 array('uf_group_id' => $copy->id
)
2639 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2643 UPDATE civicrm_uf_join
2645 WHERE uf_group_id = %2
2646 AND ( entity_id IS NULL OR entity_id <= 0 )
2648 $p = array(1 => array($maxWeight +
1, 'Integer'),
2649 2 => array($copy->id
, 'Integer'),
2651 CRM_Core_DAO
::executeQuery($query, $p);
2652 if ($copy->is_reserved
) {
2653 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2654 $params = array(1 => array($copy->id
, 'Integer'));
2655 CRM_Core_DAO
::executeQuery($query, $params);
2657 CRM_Utils_Hook
::copy('UFGroup', $copy);
2663 * Process that send notification e-mails
2665 * @params int $contactId contact id
2666 * @params array $values associative array of name/value pair
2672 static function commonSendMail($contactID, &$values) {
2673 if (!$contactID ||
!$values) {
2677 $template = CRM_Core_Smarty
::singleton();
2679 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2684 self
::profileDisplay($values['id'], $values['values'], $template);
2685 $emailList = explode(',', $values['email']);
2687 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2688 "reset=1&cid=$contactID",
2689 TRUE, NULL, FALSE, FALSE, TRUE
2692 //get the default domain email address.
2693 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2695 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2696 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2697 CRM_Core_Error
::fatal(ts('The site administrator needs to enter a valid \'FROM Email Address\' in <a href="%1">Administer CiviCRM » Communications » FROM Email Addresses</a>. The email address used may need to be a valid mail account with your email service provider.', array(1 => $fixUrl)));
2700 foreach ($emailList as $emailTo) {
2701 // FIXME: take the below out of the foreach loop
2702 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2704 'groupName' => 'msg_tpl_workflow_uf',
2705 'valueName' => 'uf_notify',
2706 'contactId' => $contactID,
2707 'tplParams' => array(
2708 'displayName' => $displayName,
2709 'currentDate' => date('r'),
2710 'contactLink' => $contactLink,
2712 'from' => "$domainEmailName <$domainEmailAddress>",
2713 'toEmail' => $emailTo,
2720 * Given a contact id and a group id, returns the field values from the db
2721 * for this group and notify email only if group's notify field is
2722 * set and field values are not empty
2724 * @params $gid group id
2725 * @params $cid contact id
2726 * @params $params associative array
2731 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2733 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2735 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2736 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2738 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2740 if (!empty($values) &&
2745 'values' => $values,
2756 * Function to assign uf fields to template
2758 * @params int $gid group id
2759 * @params array $values associative array of fields
2764 function profileDisplay($gid, $values, $template) {
2765 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2766 $template->assign('grouptitle', $groupTitle);
2767 if (count($values)) {
2768 $template->assign('values', $values);
2773 * Format fields for dupe Contact Matching
2775 * @param array $params associated array
2777 * @return array $data assoicated formatted array
2781 static function formatFields($params, $contactId = NULL) {
2783 // get the primary location type id and email
2784 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2787 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2788 $primaryLocationType = $defaultLocationType->id
;
2792 $locationType = array();
2794 $primaryLocation = 0;
2795 foreach ($params as $key => $value) {
2796 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2798 if ($locTypeId == 'Primary') {
2799 $locTypeId = $primaryLocationType;
2802 if (is_numeric($locTypeId)) {
2803 if (!in_array($locTypeId, $locationType)) {
2804 $locationType[$count] = $locTypeId;
2807 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2809 $data['location'][$loc]['location_type_id'] = $locTypeId;
2811 // if we are getting in a new primary email, dont overwrite the new one
2812 if ($locTypeId == $primaryLocationType) {
2813 if (!empty($params['email-' . $primaryLocationType])) {
2814 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2816 elseif (isset($primaryEmail)) {
2817 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2823 $data['location'][$loc]['is_primary'] = 1;
2825 if ($fieldName == 'phone') {
2827 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2830 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2832 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2834 elseif ($fieldName == 'email') {
2835 $data['location'][$loc]['email'][$loc]['email'] = $value;
2837 elseif ($fieldName == 'im') {
2838 $data['location'][$loc]['im'][$loc]['name'] = $value;
2841 if ($fieldName === 'state_province') {
2842 $data['location'][$loc]['address']['state_province_id'] = $value;
2844 elseif ($fieldName === 'country') {
2845 $data['location'][$loc]['address']['country_id'] = $value;
2848 $data['location'][$loc]['address'][$fieldName] = $value;
2853 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2854 if ($key === 'individual_suffix') {
2855 $data['suffix_id'] = $value;
2857 elseif ($key === 'individual_prefix') {
2858 $data['prefix_id'] = $value;
2860 elseif ($key === 'gender') {
2861 $data['gender_id'] = $value;
2863 elseif (substr($key, 0, 6) === 'custom') {
2864 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2866 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2867 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2869 // fix the date field
2870 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2871 $date = CRM_Utils_Date
::format($value);
2878 $data['custom'][$customFieldID] = array(
2881 'extends' => $customFields[$customFieldID]['extends'],
2882 'type' => $customFields[$customFieldID]['data_type'],
2883 'custom_field_id' => $customFieldID,
2887 elseif ($key == 'edit') {
2891 $data[$key] = $value;
2896 if (!$primaryLocation) {
2898 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2906 * calculate the profile type 'group_type' as per profile fields.
2908 * @param int $gid profile id
2909 * @param int $ignoreFieldId ignore particular profile field
2911 * @return array list of calculated group type
2913 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2914 //get the profile fields.
2915 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2916 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2920 * calculate the profile type 'group_type' as per profile fields.
2922 * @param int $gid profile id
2923 * @param int $ignoreFieldId ignore perticular profile field
2925 * @return array list of calculated group type
2927 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2928 $groupType = $groupTypeValues = $customFieldIds = array();
2929 if (!empty($ufFields)) {
2930 foreach ($ufFields as $fieldName => $fieldValue) {
2931 //ignore field from group type when provided.
2932 //in case of update profile field.
2933 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2936 if (!in_array($fieldValue['field_type'], $groupType)) {
2937 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2940 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
2941 $customFieldIds[$fldId] = $fldId;
2946 if (!empty($customFieldIds)) {
2947 $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) . ')';
2949 $customGroups = CRM_Core_DAO
::executeQuery($query);
2950 while ($customGroups->fetch()) {
2951 if (!$customGroups->extends_entity_column_value
) {
2955 $groupTypeName = "{$customGroups->extends}Type";
2956 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
2957 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
2960 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
2962 $groupTypeValues[$groupTypeName][$val] = $val;
2967 if (!empty($groupTypeValues)) {
2968 $groupType = array_merge($groupType, $groupTypeValues);
2976 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
2977 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
2980 * BirthDate + Email Individual,Contact
2981 * BirthDate + Subject Individual,Activity
2982 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
2983 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
2984 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
2985 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2986 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2987 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
2988 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
2990 * @param Integer $gid profile id
2991 * @param Array $groupTypes With key having group type names
2995 static function updateGroupTypes($gId, $groupTypes = array(
2997 if (!is_array($groupTypes) ||
!$gId) {
3001 // If empty group types set group_type as 'null'
3002 if (empty($groupTypes)) {
3003 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3006 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3007 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3009 $gTypes = $gTypeValues = array();
3011 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3012 // Get valid group type and group subtypes
3013 foreach ($groupTypes as $groupType => $value) {
3014 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3015 $gTypes[] = $groupType;
3020 if (in_array($groupType, $participantExtends)) {
3021 $subTypesOf = $groupType;
3023 elseif (strpos($groupType, 'Type') > 0) {
3024 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3030 if (!empty($value) &&
3031 (in_array($subTypesOf, $componentGroupTypes) ||
3032 in_array($subTypesOf, $participantExtends)
3035 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3039 if (empty($gTypes)) {
3043 // Build String to store group types and group subtypes
3044 $groupTypeString = implode(',', $gTypes);
3045 if (!empty($gTypeValues)) {
3046 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3049 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3053 * Create a "group_type" string
3055 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3056 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3057 * @param string $delim
3058 * @throws CRM_Core_Exception
3060 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3061 $groupTypeExpr = '';
3063 $groupTypeExpr .= implode(',', $coreTypes);
3066 if (count($subTypes) > 1) {
3067 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3069 foreach ($subTypes as $subType => $subTypeIds) {
3070 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3073 return $groupTypeExpr;
3077 * This function is used to setDefault componet specific profile fields.
3079 * @param array $fields profile fields.
3080 * @param int $componentId componetID
3081 * @param string $component component name
3082 * @param array $defaults an array of default values.
3086 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3087 if (!$componentId ||
3088 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3093 $componentBAO = $componentSubType = NULL;
3094 switch ($component) {
3096 $componentBAO = 'CRM_Member_BAO_Membership';
3097 $componentBAOName = 'Membership';
3098 $componentSubType = array('membership_type_id');
3102 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3103 $componentBAOName = 'Contribution';
3104 $componentSubType = array( 'financial_type_id' );
3108 $componentBAO = 'CRM_Event_BAO_Participant';
3109 $componentBAOName = 'Participant';
3110 $componentSubType = array('role_id', 'event_id');
3114 $componentBAO = 'CRM_Activity_BAO_Activity';
3115 $componentBAOName = 'Activity';
3116 $componentSubType = array('activity_type_id');
3121 $params = array('id' => $componentId);
3123 //get the component values.
3124 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3126 $formattedGroupTree = array();
3127 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3128 foreach ($fields as $name => $field) {
3129 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3130 if (in_array($name, $dateTimeFields)) {
3131 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3132 if (!empty($values[$name])) {
3133 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3136 elseif (array_key_exists($name, $values)) {
3137 $defaults[$fldName] = $values[$name];
3139 elseif ($name == 'participant_note') {
3140 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3141 $defaults[$fldName] = array_pop($noteDetails);
3143 elseif (in_array($name, array(
3144 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3145 $defaults[$fldName] = $values["{$name}_id"];
3147 elseif ($name == 'membership_type') {
3148 // since membership_type field is a hierselect -
3149 $defaults[$fldName][0] =
3150 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3151 $defaults[$fldName][1] = $values['membership_type_id'];
3153 elseif ($name == 'membership_status') {
3154 $defaults[$fldName] = $values['status_id'];
3156 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3157 if (empty($formattedGroupTree)) {
3158 //get the groupTree as per subTypes.
3159 $groupTree = array();
3160 foreach ($componentSubType as $subType) {
3161 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3162 $componentId, 0, $values[$subType]
3164 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3166 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3167 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3170 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3171 foreach ($defaults as $customKey => $customValue) {
3172 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3173 if ($name == 'custom_' . $customFieldDetails[0]) {
3175 //hack to set default for checkbox
3176 //basically this is for weired field name like field[33][custom_19]
3177 //we are converting this field name to array structure and assign value.
3180 foreach ($formattedGroupTree as $tree) {
3181 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3183 $defaults['field'][$componentId][$name] = $customValue;
3186 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3189 // CRM-6681, $default contains formatted date, time values.
3190 $defaults[$fldName] = $customValue;
3191 if (!empty($defaults[$customKey . '_time'])) {
3192 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3197 if (!$skipValue ||
$isStandalone) {
3198 $defaults[$fldName] = $customValue;
3200 unset($defaults[$customKey]);
3210 * @param array|string $profiles - name of profile(s) to create links for
3211 * @param array $appendProfiles - name of profile(s) to append to each link
3213 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3214 // Default to contact profiles
3216 $profiles = array('new_individual', 'new_organization', 'new_household');
3218 $profiles = (array) $profiles;
3219 $toGet = array_merge($profiles, (array) $appendProfiles);
3220 $retrieved = civicrm_api3('uf_group', 'get', array(
3221 'name' => array('IN' => $toGet),
3224 $links = $append = array();
3225 if (!empty($retrieved['values'])) {
3226 foreach($retrieved['values'] as $id => $profile) {
3227 if (in_array($profile['name'], $profiles)) {
3229 'label' => $profile['title'],
3230 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3231 NULL, NULL, FALSE, NULL, FALSE) ,
3232 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3239 foreach ($append as $id) {
3240 foreach ($links as &$link) {
3241 $link['url'] .= ",$id";
3249 * Function to retrieve groups of profiles
3251 * @param integer $profileID id of the profile
3253 * @return array returns array
3256 static function profileGroups($profileID) {
3257 $groupTypes = array();
3258 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3259 if ($profileTypes) {
3260 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3261 $groupTypes = explode(',', $groupTypeParts[0]);
3267 * Function to alter contact params by filtering existing subscribed groups and returns
3268 * unsubscribed groups array for subscription.
3270 * @param array $params contact params
3271 * @param int $contactId user contact id
3273 * @return array $subscribeGroupIds This contains array of groups for subscription
3275 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3276 $config = CRM_Core_Config
::singleton();
3277 $subscribeGroupIds = array();
3279 // process further only if profileDoubleOptIn enabled and if groups exist
3280 if (!array_key_exists('group', $params) ||
3281 !self
::isProfileDoubleOptin() ||
3282 CRM_Utils_System
::isNull($params['group'])
3284 return $subscribeGroupIds;
3287 //check if contact email exist.
3289 foreach ($params as $name => $value) {
3290 if (strpos($name, 'email-') !== FALSE) {
3296 //Proceed furthur only if email present
3298 return $subscribeGroupIds;
3301 //do check for already subscriptions.
3302 $contactGroups = array();
3306 FROM civicrm_group_contact
3307 WHERE status = 'Added'
3308 AND contact_id = %1";
3310 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3311 while ($dao->fetch()) {
3312 $contactGroups[$dao->group_id
] = $dao->group_id
;
3316 //since we don't have names, compare w/ label.
3317 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3319 //actual processing start.
3320 foreach ($params['group'] as $groupId => $isSelected) {
3321 //unset group those are not selected.
3323 unset($params['group'][$groupId]);
3327 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3328 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3330 //get only mailing type group and unset it from params
3331 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3332 $subscribeGroupIds[$groupId] = $groupId;
3333 unset($params['group'][$groupId]);
3337 return $subscribeGroupIds;
3341 * Function to check if we are rendering mixed profiles
3343 * @param array $profileIds associated array of profile ids
3345 * @return boolean $mixProfile true if profile is mixed
3349 static function checkForMixProfiles($profileIds) {
3350 $mixProfile = FALSE;
3352 $contactTypes = array('Individual', 'Household', 'Organization');
3353 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3355 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3357 $typeCount = array('ctype' => array(), 'subtype' => array());
3358 foreach ($profileIds as $gid) {
3359 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3360 // ignore profile of type Contact
3361 if ($profileType == 'Contact') {
3364 if (in_array($profileType, $contactTypes)) {
3365 if (!isset($typeCount['ctype'][$profileType])) {
3366 $typeCount['ctype'][$profileType] = 1;
3369 // check if we are rendering profile of different contact types
3370 if (count($typeCount['ctype']) == 2) {
3375 elseif (in_array($profileType, $components)) {
3380 if (!isset($typeCount['subtype'][$profileType])) {
3381 $typeCount['subtype'][$profileType] = 1;
3383 // check if we are rendering profile of different contact sub types
3384 if (count($typeCount['subtype']) == 2) {
3394 * Funtion to determine of we show overlay profile or not
3396 * @return boolean true if profile should be shown else false
3400 static function showOverlayProfile() {
3401 $showOverlay = TRUE;
3403 // get the id of overlay profile
3404 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3405 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3407 $count = CRM_Core_DAO
::singleValueQuery($query);
3409 //check if there are no public fields and use is anonymous
3410 $session = CRM_Core_Session
::singleton();
3411 if (!$count && !$session->get('userID')) {
3412 $showOverlay = FALSE;
3415 return $showOverlay;
3419 * function to get group type values of the profile
3421 * @params Integer $profileId Profile Id
3422 * @params String $groupType Group Type
3424 * @return Array group type values
3428 static function groupTypeValues($profileId, $groupType = NULL) {
3429 $groupTypeValue = array();
3430 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3432 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3433 if (empty($groupTypeParts[1])) {
3434 return $groupTypeValue;
3436 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3438 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3440 $valueParts = explode(':', $groupTypeValues);
3442 ($valueParts[0] != "{$groupType}Type" ||
3443 ($groupType == 'Participant' &&
3444 !in_array($valueParts[0], $participantExtends)
3450 foreach ($valueParts as $val) {
3451 if (CRM_Utils_Rule
::integer($val)) {
3452 $values[$val] = $val;
3455 if (!empty($values)) {
3456 $typeName = substr($valueParts[0], 0, -4);
3457 if (in_array($valueParts[0], $participantExtends)) {
3458 $typeName = $valueParts[0];
3460 $groupTypeValue[$typeName] = $values;
3464 return $groupTypeValue;
3467 static function isProfileDoubleOptin() {
3468 // check for 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_double_optin', NULL, FALSE
3478 static function isProfileAddToGroupDoubleOptin() {
3479 // check for add to group double optin
3480 $config = CRM_Core_Config
::singleton();
3481 if (in_array('CiviMail', $config->enableComponents
)) {
3482 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3483 'profile_add_to_group_double_optin', NULL, FALSE
3490 * get profiles used for batch entry
3492 * @return array profileIds profile ids
3495 static function getBatchProfiles() {
3497 FROM civicrm_uf_group
3498 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3499 $dao = CRM_Core_DAO
::executeQuery( $query );
3500 $profileIds = array();
3501 while( $dao->fetch() ) {
3502 $profileIds[$dao->id
] = $dao->id
;
3507 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3508 $multiSummaryFields = $returnMultiSummaryFields ?
array( ) : NULL;
3509 foreach ($source as $field => $properties) {
3510 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3513 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3514 $destination[$field] = $properties;
3515 if ($returnMultiSummaryFields) {
3516 if ($properties['is_multi_summary']) {
3517 $multiSummaryFields[$field] = $properties;
3520 unset($source[$field]);
3523 return $multiSummaryFields;
3527 * This is function is used to format pseudo fields
3529 * @param array $fields associated array of profile fields
3533 static function reformatProfileFields(&$fields) {
3534 //reformat fields array
3535 foreach ($fields as $name => $field) {
3536 //reformat phone and extension field
3537 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3538 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3540 // retain existing element properties and just update and replace key
3541 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3542 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3543 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3545 // add additional phone extension field
3546 $fields["phone_ext-{$fieldSuffix}"] = $field;
3547 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3548 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3549 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3550 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3551 //ignore required for extension field
3552 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;