3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
31 * @copyright CiviCRM LLC (c) 2004-2014
39 class CRM_Core_BAO_UFGroup
extends CRM_Core_DAO_UFGroup
{
40 const PUBLIC_VISIBILITY
= 1,
42 LISTINGS_VISIBILITY
= 4;
45 * Cache the match clause used in this transaction.
49 static $_matchFields = NULL;
52 * Fetch object based on array of properties.
54 * @param array $params
55 * (reference) an assoc array of name/value pairs.
56 * @param array $defaults
57 * (reference) an assoc array to hold the flattened values.
60 * CRM_Core_DAO_UFGroup object
62 public static function retrieve(&$params, &$defaults) {
63 return CRM_Core_DAO
::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
67 * Retrieve the first non-generic contact type
75 public static function getContactType($id) {
77 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
78 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
80 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
81 $types = explode(',', $typesParts[0]);
84 foreach ($types as $type) {
85 if (in_array($type, $validTypes)) {
88 elseif (array_key_exists($type, $validSubTypes)) {
89 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
100 * Get the form title.
109 public static function getTitle($id) {
110 return CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
114 * Update the is_active flag in the db.
117 * Id of the database record.
118 * @param bool $is_active
119 * Value we want to set the is_active field.
122 * CRM_Core_DAO_UFGroup object on success, null otherwise
124 public 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.
132 * What action are we doing.
139 * the fields that are needed for registration
141 public static function getRegistrationFields($action, $mode, $ctype = NULL) {
142 if ($mode & CRM_Profile_Form
::MODE_REGISTER
) {
143 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('User Registration');
146 $ufGroups = CRM_Core_BAO_UFGroup
::getModuleUFGroup('Profile');
149 if (!is_array($ufGroups)) {
155 foreach ($ufGroups as $id => $title) {
157 $fieldType = CRM_Core_BAO_UFField
::getProfileType($id);
158 if (($fieldType != 'Contact') &&
159 ($fieldType != $ctype) &&
160 !CRM_Contact_BAO_ContactType
::isExtendsContactType($fieldType, $ctype)
164 if (CRM_Contact_BAO_ContactType
::isaSubType($fieldType)) {
165 $profileSubType = $fieldType;
169 $subset = self
::getFields($id, TRUE, $action,
170 NULL, NULL, FALSE, NULL, TRUE, $ctype
173 // we do not allow duplicates. the first field is the winner
174 foreach ($subset as $name => $field) {
175 if (empty($fields[$name])) {
176 $fields[$name] = $field;
185 * Get all the listing fields.
188 * What action are we doing.
189 * @param int $visibility
190 * Visibility of fields we are interested in.
191 * @param bool $considerSelector
192 * Whether to consider the in_selector parameter.
193 * @param array $ufGroupIds
194 * @param bool $searchable
196 * @param null $restrict
197 * @param bool $skipPermission
198 * @param int $permissionType
200 * the fields that are listings related
202 public static function getListingFields(
205 $considerSelector = FALSE,
209 $skipPermission = FALSE,
210 $permissionType = CRM_Core_Permission
::SEARCH
213 $subset = self
::getFields($ufGroupIds, FALSE, $action,
214 $visibility, $searchable,
220 if ($considerSelector) {
221 // drop the fields not meant for the selector
222 foreach ($subset as $name => $field) {
223 if (!$field['in_selector']) {
224 unset($subset[$name]);
231 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
234 foreach ($ufGroups as $id => $title) {
235 $subset = self
::getFields($id, FALSE, $action,
236 $visibility, $searchable,
242 if ($considerSelector) {
243 // drop the fields not meant for the selector
244 foreach ($subset as $name => $field) {
245 if (!$field['in_selector']) {
246 unset($subset[$name]);
250 $fields = array_merge($fields, $subset);
257 * Get all the fields that belong to the group with the name title,
258 * and format for use with buildProfile. This is the SQL analog of
262 * The id of the UF group or ids of ufgroup.
263 * @param bool|int $register are we interested in registration fields
265 * What action are we doing.
266 * @param int $visibility
267 * Visibility of fields we are interested in.
269 * @param bool $showAll
270 * @param string $restrict
271 * Should we restrict based on a specified profile type.
272 * @param bool $skipPermission
274 * @param int $permissionType
275 * @param string $orderBy
276 * @param null $orderProfiles
279 * the fields that belong to this ufgroup(s)
281 public static function getFields(
289 $skipPermission = FALSE,
291 $permissionType = CRM_Core_Permission
::CREATE
,
292 $orderBy = 'field_name',
293 $orderProfiles = NULL
295 if (!is_array($id)) {
296 $id = CRM_Utils_Type
::escape($id, 'Positive');
297 $profileIds = array($id);
303 $gids = implode(',', $profileIds);
306 $query = "SELECT g.* from civicrm_uf_group g
307 LEFT JOIN civicrm_uf_join j ON (j.uf_group_id = g.id)
308 WHERE g.id IN ( {$gids} )
309 AND ((j.uf_group_id IN ( {$gids} ) AND j.module = %1) OR g.is_reserved = 1 )
311 $params = array(1 => array($restrict, 'String'));
314 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
318 $query .= " AND g.is_active = 1";
321 // add permissioning for profiles only if not registration
322 if (!$skipPermission) {
323 $permissionClause = CRM_Core_Permission
::ufGroupClause($permissionType, 'g.');
324 $query .= " AND $permissionClause ";
327 if ($orderProfiles AND count($profileIds) > 1) {
328 $query .= " ORDER BY FIELD( g.id, {$gids} )";
330 $group = CRM_Core_DAO
::executeQuery($query, $params);
334 while ($group->fetch()) {
336 $query = self
::createUFFieldQuery($group->id
, $searchable, $showAll, $visibility, $orderBy);
337 $field = CRM_Core_DAO
::executeQuery($query);
339 $profileType = CRM_Core_BAO_UFField
::getProfileType($group->id
);
340 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileType($group->id
);
341 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
342 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
344 while ($field->fetch()) {
345 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
346 if ($formattedField !== NULL) {
347 $fields[$name] = $formattedField;
353 if (empty($fields) && !$validGroup) {
354 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.',
355 array(1 => implode(',', $profileIds))
359 self
::reformatProfileFields($fields);
366 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
369 * @param array $groupArr
370 * (mimic CRM_UF_DAO_UFGroup).
371 * @param array $fieldArrs
372 * List of fields (each mimics CRM_UF_DAO_UFField).
373 * @param bool $visibility
374 * Visibility of fields we are interested in.
375 * @param bool $searchable
376 * @param bool $showAll
378 * @param int $permissionType
381 * @see self::getFields
383 public static function formatUFFields(
390 $permissionType = CRM_Core_Permission
::CREATE
392 // $group = new CRM_Core_DAO_UFGroup();
393 // $group->copyValues($groupArr); // no... converts string('') to string('null')
394 $group = (object) $groupArr;
396 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
397 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
398 // they did -- the obvious fix would produce mutual recursion.
399 $ufGroupType = self
::_calculateGroupType($fieldArrs);
400 $profileType = CRM_Core_BAO_UFField
::calculateProfileType(implode(',', $ufGroupType));
401 $contactActivityProfile = CRM_Core_BAO_UFField
::checkContactActivityProfileTypeByGroupType(implode(',', $ufGroupType));
402 $importableFields = self
::getImportableFields($showAll, $profileType, $contactActivityProfile);
403 list($customFields, $addressCustomFields) = self
::getCustomFields($ctype);
405 $formattedFields = array();
406 foreach ($fieldArrs as $fieldArr) {
407 $field = (object) $fieldArr;
408 if (!self
::filterUFField($field, $searchable, $showAll, $visibility)) {
412 list($name, $formattedField) = self
::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
413 if ($formattedField !== NULL) {
414 $formattedFields[$name] = $formattedField;
417 return $formattedFields;
421 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
423 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
424 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
425 * @param array $customFields
426 * @param array $addressCustomFields
427 * @param array $importableFields
428 * @param int $permissionType
429 * Eg CRM_Core_Permission::CREATE.
432 protected static function formatUFField(
436 $addressCustomFields,
438 $permissionType = CRM_Core_Permission
::CREATE
440 $name = $field->field_name
;
441 $title = $field->label
;
443 $addressCustom = FALSE;
444 if (in_array($permissionType, array(
445 CRM_Core_Permission
::CREATE
,
446 CRM_Core_Permission
::EDIT
,
448 in_array($field->field_name
, array_keys($addressCustomFields))
450 $addressCustom = TRUE;
451 $name = "address_{$name}";
453 if ($field->field_name
== 'url') {
454 $name .= "-{$field->website_type_id}";
456 elseif (!empty($field->location_type_id
)) {
457 $name .= "-{$field->location_type_id}";
460 $locationFields = self
::getLocationFields();
461 if (in_array($field->field_name
, $locationFields) ||
$addressCustom) {
466 if (isset($field->phone_type_id
)) {
467 $name .= "-{$field->phone_type_id}";
470 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
471 // I guess to make field self sufficient with all the required data and avoid additional calls
472 $formattedField = array(
474 'groupTitle' => $group->title
,
475 'groupName' => $group->name
,
476 'groupHelpPre' => empty($group->help_pre
) ?
'' : $group->help_pre
,
477 'groupHelpPost' => empty($group->help_post
) ?
'' : $group->help_post
,
479 'where' => CRM_Utils_Array
::value('where', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
480 'attributes' => CRM_Core_DAO
::makeAttribute(CRM_Utils_Array
::value($field->field_name
, $importableFields)),
481 'is_required' => $field->is_required
,
482 'is_view' => $field->is_view
,
483 'help_pre' => $field->help_pre
,
484 'help_post' => $field->help_post
,
485 'visibility' => $field->visibility
,
486 'in_selector' => $field->in_selector
,
487 'rule' => CRM_Utils_Array
::value('rule', CRM_Utils_Array
::value($field->field_name
, $importableFields)),
488 'location_type_id' => isset($field->location_type_id
) ?
$field->location_type_id
: NULL,
489 'website_type_id' => isset($field->website_type_id
) ?
$field->website_type_id
: NULL,
490 'phone_type_id' => isset($field->phone_type_id
) ?
$field->phone_type_id
: NULL,
491 'group_id' => $group->id
,
492 'add_to_group_id' => isset($group->add_to_group_id
) ?
$group->add_to_group_id
: NULL,
493 'add_captcha' => isset($group->add_captcha
) ?
$group->add_captcha
: NULL,
494 'field_type' => $field->field_type
,
495 'field_id' => $field->id
,
496 'pseudoconstant' => CRM_Utils_Array
::value(
498 CRM_Utils_Array
::value($field->field_name
, $importableFields)
500 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
501 'dbName' => CRM_Utils_Array
::value(
503 CRM_Utils_Array
::value($field->field_name
, $importableFields)
508 //adding custom field property
509 if (substr($field->field_name
, 0, 6) == 'custom' ||
510 substr($field->field_name
, 0, 14) === 'address_custom'
512 // if field is not present in customFields, that means the user
513 // DOES NOT HAVE permission to access that field
514 if (array_key_exists($field->field_name
, $customFields)) {
515 $formattedField['is_search_range'] = $customFields[$field->field_name
]['is_search_range'];
517 $formattedField['options_per_line'] = $customFields[$field->field_name
]['options_per_line'];
518 $formattedField['data_type'] = $customFields[$field->field_name
]['data_type'];
519 $formattedField['html_type'] = $customFields[$field->field_name
]['html_type'];
521 if (CRM_Utils_Array
::value('html_type', $formattedField) == 'Select Date') {
522 $formattedField['date_format'] = $customFields[$field->field_name
]['date_format'];
523 $formattedField['time_format'] = $customFields[$field->field_name
]['time_format'];
526 $formattedField['is_multi_summary'] = $field->is_multi_summary
;
527 return array($name, $formattedField);
530 $formattedField = NULL;
531 return array($name, $formattedField);
534 return array($name, $formattedField);
538 * Create a query to find all visible UFFields in a UFGroup.
540 * This is the SQL-variant of checkUFFieldDisplayable().
542 * @param int $groupId
543 * @param bool $searchable
544 * @param bool $showAll
545 * @param int $visibility
546 * @param string $orderBy
547 * Comma-delimited list of SQL columns.
550 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
551 $where = " WHERE uf_group_id = {$groupId}";
554 $where .= " AND is_searchable = 1";
558 $where .= " AND is_active = 1";
563 if ($visibility & self
::PUBLIC_VISIBILITY
) {
564 $clause[] = 'visibility = "Public Pages"';
566 if ($visibility & self
::ADMIN_VISIBILITY
) {
567 $clause[] = 'visibility = "User and User Admin Only"';
569 if ($visibility & self
::LISTINGS_VISIBILITY
) {
570 $clause[] = 'visibility = "Public Pages and Listings"';
572 if (!empty($clause)) {
573 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
577 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
579 $query .= ", " . $orderBy;
586 * Create a query to find all visible UFFields in a UFGroup.
588 * This is the PHP in-memory variant of createUFFieldQuery().
590 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
591 * @param bool $searchable
592 * @param bool $showAll
593 * @param int $visibility
595 * TRUE if field is displayable
597 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
598 if ($searchable && $field->is_searchable
!= 1) {
602 if (!$showAll && $field->is_active
!= 1) {
607 $allowedVisibilities = array();
608 if ($visibility & self
::PUBLIC_VISIBILITY
) {
609 $allowedVisibilities[] = 'Public Pages';
611 if ($visibility & self
::ADMIN_VISIBILITY
) {
612 $allowedVisibilities[] = 'User and User Admin Only';
614 if ($visibility & self
::LISTINGS_VISIBILITY
) {
615 $allowedVisibilities[] = 'Public Pages and Listings';
617 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
618 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
628 * @param $profileType
629 * @param $contactActivityProfile
633 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
635 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
638 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
641 if ($profileType == 'Activity' ||
$contactActivityProfile) {
642 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
645 $componentFields = CRM_Core_Component
::getQueryFields();
648 $importableFields = array_merge($importableFields, $componentFields);
650 $importableFields['group']['title'] = ts('Group(s)');
651 $importableFields['group']['where'] = NULL;
652 $importableFields['tag']['title'] = ts('Tag(s)');
653 $importableFields['tag']['where'] = NULL;
654 return $importableFields;
657 public static function getLocationFields() {
658 static $locationFields = array(
660 'supplemental_address_1',
661 'supplemental_address_2',
664 'postal_code_suffix',
677 return $locationFields;
685 protected static function getCustomFields($ctype) {
686 static $customFieldCache = array();
687 if (!isset($customFieldCache[$ctype])) {
688 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
690 // hack to add custom data for components
691 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
692 foreach ($components as $value) {
693 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
695 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
696 $customFields = array_merge($customFields, $addressCustomFields);
697 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
699 return $customFieldCache[$ctype];
703 * Check the data validity.
706 * The user id that we are actually editing.
707 * @param string $title
708 * The title of the group we are interested in.
709 * @param bool $register
711 * The action of the form.
713 * @pram boolean $register is this the registrtion form
715 * true if form is valid
717 public static function isValid($userID, $title, $register = FALSE, $action = NULL) {
719 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
720 ts('Dynamic Form Creator'),
723 $controller->set('id', $userID);
724 $controller->set('register', 1);
725 $controller->process();
726 return $controller->validate();
729 // make sure we have a valid group
730 $group = new CRM_Core_DAO_UFGroup();
732 $group->title
= $title;
734 if ($group->find(TRUE) && $userID) {
735 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
736 $controller->set('gid', $group->id
);
737 $controller->set('id', $userID);
738 $controller->set('register', 0);
739 $controller->process();
740 return $controller->validate();
747 * Get the html for the form that represents this particular group.
750 * The user id that we are actually editing.
751 * @param string $title
752 * The title of the group we are interested in.
754 * The action of the form.
755 * @param bool $register
756 * Is this the registration form.
758 * Should we reset the form?.
759 * @param int $profileID
760 * Do we have the profile ID?.
762 * @param bool $doNotProcess
766 * the html for the form on success, otherwise empty string
768 public static function getEditHTML(
775 $doNotProcess = FALSE,
780 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
781 ts('Dynamic Form Creator'),
784 if ($reset ||
$doNotProcess) {
785 // hack to make sure we do not process this form
786 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
789 unset($_POST['_qf_default']);
790 unset($_REQUEST['_qf_default']);
792 $controller->reset();
796 $controller->set('id', $userID);
797 $controller->set('register', 1);
798 $controller->set('skipPermission', 1);
799 $controller->set('ctype', $ctype);
800 $controller->process();
801 if ($doNotProcess ||
!empty($_POST)) {
802 $controller->validate();
804 $controller->setEmbedded(TRUE);
806 //CRM-5839 - though we want to process form, get the control back.
807 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
811 // we are done processing so restore the POST/REQUEST vars
812 if (($reset ||
$doNotProcess) && $oldQFDefault) {
813 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
816 $template = CRM_Core_Smarty
::singleton();
818 // Hide CRM error messages if they are displayed using drupal form_set_error.
819 if (!empty($_POST)) {
820 $template->assign('suppressForm', TRUE);
823 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
827 // make sure we have a valid group
828 $group = new CRM_Core_DAO_UFGroup();
830 $group->title
= $title;
832 if ($group->find(TRUE)) {
833 $profileID = $group->id
;
838 // make sure profileID and ctype match if ctype exists
840 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
841 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
842 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
845 if (($profileType != 'Contact') && ($profileType != $ctype)) {
850 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
851 ts('Dynamic Form Creator'),
855 $controller->reset();
857 $controller->set('gid', $profileID);
858 $controller->set('id', $userID);
859 $controller->set('register', 0);
860 $controller->set('skipPermission', 1);
862 $controller->set('ctype', $ctype);
864 $controller->process();
865 $controller->setEmbedded(TRUE);
867 //CRM-5846 - give the control back to drupal.
868 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
871 $template = CRM_Core_Smarty
::singleton();
873 // Hide CRM error messages if they are displayed using drupal form_set_error.
874 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
875 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
876 $template->assign('suppressForm', TRUE);
880 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
881 if (!$template->template_exists($templateFile)) {
882 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
884 return trim($template->fetch($templateFile));
887 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
889 // if post not empty then only proceed
890 if (!empty($_POST)) {
892 $config = CRM_Core_Config
::singleton();
893 $email = CRM_Utils_Array
::value('mail', $_POST);
895 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
896 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
905 * Searches for a contact in the db with similar attributes.
907 * @param array $params
908 * The list of values to be used in the where clause.
910 * The current contact id (hence excluded from matching).
911 * @param string $contactType
914 * contact_id if found, null otherwise
916 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
917 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
918 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
919 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
921 return implode(',', $ids);
929 * Given a contact id and a field set, return the values from the db
933 * @param array $fields
934 * The profile fields of interest.
935 * @param array $values
936 * The values for the above fields.
937 * @param bool $searchable
939 * @param array $componentWhere
940 * Component condition.
941 * @param bool $absolute
942 * Return urls in absolute form (useful when sending an email).
943 * @param null $additionalWhereClause
947 public static function getValues(
948 $cid, &$fields, &$values,
949 $searchable = TRUE, $componentWhere = NULL,
950 $absolute = FALSE, $additionalWhereClause = NULL
952 if (empty($cid) && empty($componentWhere)) {
956 // get the contact details (hier)
957 $returnProperties = CRM_Contact_BAO_Contact
::makeHierReturnProperties($fields);
958 $params = $cid ?
array(array('contact_id', '=', $cid, 0, 0)) : array();
960 // add conditions specified by components. eg partcipant_id etc
961 if (!empty($componentWhere)) {
962 $params = array_merge($params, $componentWhere);
965 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
966 $options = &$query->_options
;
968 $details = $query->searchQuery(0, 0, NULL, FALSE, FALSE,
969 FALSE, FALSE, FALSE, $additionalWhereClause);
970 if (!$details->fetch()) {
973 $query->convertToPseudoNames($details);
974 $config = CRM_Core_Config
::singleton();
976 $locationTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Address', 'location_type_id');
977 $imProviders = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id');
978 $websiteTypes = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_Website', 'website_type_id');
980 $multipleFields = array('url');
982 //start of code to set the default values
983 foreach ($fields as $name => $field) {
986 $name = 'contact_id';
989 // skip fields that should not be displayed separately
990 if (!empty($field['skipDisplay'])) {
994 // Create a unique, non-empty index for each field.
995 $index = $field['title'];
999 while (array_key_exists($index, $values)) {
1003 $params[$index] = $values[$index] = '';
1004 $customFieldName = NULL;
1006 if (isset($details->$name) ||
$name == 'group' ||
$name == 'tag') {
1007 // to handle gender / suffix / prefix
1008 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
1009 $params[$index] = $details->$name;
1010 $values[$index] = $details->$name;
1012 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
1013 $dname = $name . '_display';
1014 $values[$index] = $details->$dname;
1015 $name = $name . '_id';
1016 $params[$index] = $details->$name;
1018 elseif (in_array($name, array(
1023 $values[$index] = $details->$name;
1024 $idx = $name . '_id';
1025 $params[$index] = $details->$idx;
1027 elseif ($name === 'preferred_communication_method') {
1028 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
1030 $pref = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1032 foreach ($pref as $k) {
1034 $compref[] = $communicationFields[$k];
1037 $params[$index] = $details->$name;
1038 $values[$index] = implode(',', $compref);
1040 elseif ($name === 'preferred_language') {
1041 $params[$index] = $details->$name;
1042 $values[$index] = CRM_Core_PseudoConstant
::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
1044 elseif ($name == 'group') {
1045 $groups = CRM_Contact_BAO_GroupContact
::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
1046 $title = $ids = array();
1048 foreach ($groups as $g) {
1049 // CRM-8362: User and User Admin visibility groups should be included in display if user has
1050 // VIEW permission on that group
1051 $groupPerm = CRM_Contact_BAO_Group
::checkPermission($g['group_id'], $g['title']);
1053 if ($g['visibility'] != 'User and User Admin Only' ||
1054 CRM_Utils_Array
::key(CRM_Core_Permission
::VIEW
, $groupPerm)
1056 $title[] = $g['title'];
1057 if ($g['visibility'] == 'Public Pages') {
1058 $ids[] = $g['group_id'];
1062 $values[$index] = implode(', ', $title);
1063 $params[$index] = implode(',', $ids);
1065 elseif ($name == 'tag') {
1066 $entityTags = CRM_Core_BAO_EntityTag
::getTag($cid);
1067 $allTags = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
1069 foreach ($entityTags as $tagId) {
1070 $title[] = $allTags[$tagId];
1072 $values[$index] = implode(', ', $title);
1073 $params[$index] = implode(',', $entityTags);
1075 elseif ($name == 'activity_status_id') {
1076 $activityStatus = CRM_Core_PseudoConstant
::activityStatus();
1077 $values[$index] = $activityStatus[$details->$name];
1078 $params[$index] = $details->$name;
1080 elseif ($name == 'activity_date_time') {
1081 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1082 $params[$index] = $details->$name;
1084 elseif ($name == 'contact_sub_type') {
1085 $contactSubTypeNames = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details->$name);
1086 if (!empty($contactSubTypeNames)) {
1087 $contactSubTypeLabels = array();
1088 // get all contact subtypes
1089 $allContactSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
1090 // build contact subtype labels array
1091 foreach ($contactSubTypeNames as $cstName) {
1093 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1096 $values[$index] = implode(',', $contactSubTypeLabels);
1099 $params[$index] = $details->$name;
1102 if (substr($name, 0, 7) === 'do_not_' ||
substr($name, 0, 3) === 'is_') {
1103 if ($details->$name) {
1104 $values[$index] = '[ x ]';
1108 if ($cfID = CRM_Core_BAO_CustomField
::getKeyID($name)) {
1109 $htmlType = $field['html_type'];
1111 // field_type is only set when we are retrieving profile values
1112 // when sending email, we call the same function to get custom field
1113 // values etc, i.e. emulating a profile
1114 $fieldType = CRM_Utils_Array
::value('field_type', $field);
1116 if ($htmlType == 'File') {
1119 $fieldType == 'Activity' && !empty($componentWhere[0][2])
1121 $entityId = $componentWhere[0][2];
1124 $fileURL = CRM_Core_BAO_CustomField
::getFileURL($entityId,
1128 $additionalWhereClause
1130 $params[$index] = $values[$index] = $fileURL['file_url'];
1134 if (isset($dao) && property_exists($dao, 'data_type') &&
1135 ($dao->data_type
== 'Int' ||
1136 $dao->data_type
== 'Boolean'
1139 $customVal = (int ) ($details->{$name});
1141 elseif (isset($dao) && property_exists($dao, 'data_type')
1142 && $dao->data_type
== 'Float'
1144 $customVal = (float ) ($details->{$name});
1146 elseif (!CRM_Utils_System
::isNull(explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
1150 $customVal = $details->{$name};
1154 if (CRM_Utils_System
::isNull($customVal)) {
1158 $params[$index] = $customVal;
1159 $values[$index] = CRM_Core_BAO_CustomField
::getDisplayValue($customVal,
1163 if ($field['data_type'] == 'ContactReference') {
1164 $params[$index] = $values[$index];
1166 if (CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_CustomField',
1167 $cfID, 'is_search_range'
1170 $customFieldName = "{$name}_from";
1174 elseif ($name == 'image_URL') {
1175 list($width, $height) = getimagesize(CRM_Utils_String
::unstupifyUrl($details->$name));
1176 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact
::getThumbSize($width, $height);
1178 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1179 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1181 elseif (in_array($name, array(
1184 'membership_start_date',
1185 'membership_end_date',
1188 $values[$index] = CRM_Utils_Date
::customFormat($details->$name);
1189 $params[$index] = CRM_Utils_Date
::isoToMysql($details->$name);
1193 if ($index == 'Campaign') {
1194 $dao = 'CRM_Campaign_DAO_Campaign';
1196 elseif ($index == 'Contribution Page') {
1197 $dao = 'CRM_Contribute_DAO_ContributionPage';
1200 $value = CRM_Core_DAO
::getFieldValue($dao, $details->$name, 'title');
1203 $value = $details->$name;
1205 $values[$index] = $value;
1210 elseif (strpos($name, '-') !== FALSE) {
1211 list($fieldName, $id, $type) = CRM_Utils_System
::explode('-', $name, 3);
1213 if (!in_array($fieldName, $multipleFields)) {
1214 if ($id == 'Primary') {
1216 // not sure why we'd every use Primary location type id
1217 // we need to fix the source if we are using it
1218 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1219 $locationTypeName = 1;
1222 $locationTypeName = CRM_Utils_Array
::value($id, $locationTypes);
1225 if (!$locationTypeName) {
1229 $detailName = "{$locationTypeName}-{$fieldName}";
1230 $detailName = str_replace(' ', '_', $detailName);
1232 if (in_array($fieldName, array(
1239 $detailName .= "-{$type}";
1243 if (in_array($fieldName, array(
1248 $values[$index] = $details->$detailName;
1249 $idx = $detailName . '_id';
1250 $params[$index] = $details->$idx;
1252 elseif ($fieldName == 'im') {
1253 $providerId = $detailName . '-provider_id';
1254 if (isset($imProviders[$details->$providerId])) {
1255 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
1258 $values[$index] = $details->$detailName;
1260 $params[$index] = $details->$detailName;
1262 elseif ($fieldName == 'phone') {
1263 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1264 if (isset($details->$phoneExtField)) {
1265 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1268 $values[$index] = $details->$detailName;
1270 $params[$index] = $details->$detailName;
1273 $values[$index] = $params[$index] = $details->$detailName;
1277 $detailName = "website-{$id}-{$fieldName}";
1278 $url = CRM_Utils_System
::fixURL($details->$detailName);
1279 if ($details->$detailName) {
1280 $websiteTypeId = "website-{$id}-website_type_id";
1281 $websiteType = $websiteTypes[$details->$websiteTypeId];
1282 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1285 $values[$index] = '';
1290 if ((CRM_Utils_Array
::value('visibility', $field) == 'Public Pages and Listings') &&
1291 CRM_Core_Permission
::check('profile listings and forms')
1294 if (CRM_Utils_System
::isNull($params[$index])) {
1295 $params[$index] = $values[$index];
1297 if (!isset($params[$index])) {
1300 if (!$customFieldName) {
1301 $fieldName = $field['name'];
1304 $fieldName = $customFieldName;
1308 if (CRM_Core_BAO_CustomField
::getKeyID($field['name'])) {
1309 $htmlType = $field['html_type'];
1310 if ($htmlType == 'Link') {
1311 $url = $params[$index];
1313 elseif (in_array($htmlType, array(
1317 'Multi-Select State/Province',
1318 'Multi-Select Country',
1320 $valSeperator = CRM_Core_DAO
::VALUE_SEPARATOR
;
1321 $selectedOptions = explode($valSeperator, $params[$index]);
1323 foreach ($selectedOptions as $key => $multiOption) {
1325 $url[] = CRM_Utils_System
::url('civicrm/profile',
1326 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1327 urlencode($fieldName) .
1329 urlencode($multiOption)
1335 $url = CRM_Utils_System
::url('civicrm/profile',
1336 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1337 urlencode($fieldName) .
1339 urlencode($params[$index])
1344 $url = CRM_Utils_System
::url('civicrm/profile',
1345 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1346 urlencode($fieldName) .
1348 urlencode($params[$index])
1353 !empty($values[$index]) &&
1357 if (is_array($url) && !empty($url)) {
1359 $eachMultiValue = explode(', ', $values[$index]);
1360 foreach ($eachMultiValue as $key => $valueLabel) {
1361 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1363 $values[$index] = implode(', ', $links);
1366 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1374 * Check if profile Group used by any module.
1382 public static function usedByModule($id) {
1383 //check whether this group is used by any module(check uf join records)
1385 FROM civicrm_uf_join
1386 WHERE civicrm_uf_join.uf_group_id=$id";
1388 $dao = new CRM_Core_DAO();
1390 if ($dao->fetch()) {
1399 * Delete the profile Group.
1407 public static function del($id) {
1408 //check whether this group contains any profile fields
1409 $profileField = new CRM_Core_DAO_UFField();
1410 $profileField->uf_group_id
= $id;
1411 $profileField->find();
1412 while ($profileField->fetch()) {
1413 CRM_Core_BAO_UFField
::del($profileField->id
);
1416 //delete records from uf join table
1417 $ufJoin = new CRM_Core_DAO_UFJoin();
1418 $ufJoin->uf_group_id
= $id;
1421 //delete profile group
1422 $group = new CRM_Core_DAO_UFGroup();
1431 * @param array $params
1432 * Reference array contains the values submitted by the form.
1434 * Reference array contains the id.
1439 public static function add(&$params, $ids = array()) {
1449 foreach ($fields as $field) {
1450 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1453 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1454 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1457 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1458 $params['group_type'] = implode(',', $params['group_type']);
1460 $ufGroup = new CRM_Core_DAO_UFGroup();
1461 $ufGroup->copyValues($params);
1463 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1465 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1467 $ufGroup->id
= $ufGroupID;
1472 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1480 * Make uf join entries for an uf group.
1482 * @param array $params
1483 * (reference) an assoc array of name/value pairs.
1484 * @param int $ufGroupId
1489 public static function createUFJoin(&$params, $ufGroupId) {
1490 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1492 // get ufjoin records for uf group
1493 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1495 // get the list of all ufgroup types
1496 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1498 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1499 if (!is_array($groupTypes)) {
1500 $groupTypes = array();
1503 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1504 if (!is_array($ufGroupRecord)) {
1505 $ufGroupRecord = array();
1508 // check which values has to be inserted/deleted for contact
1509 $menuRebuild = FALSE;
1510 foreach ($allUFGroupType as $key => $value) {
1511 $joinParams = array();
1512 $joinParams['uf_group_id'] = $ufGroupId;
1513 $joinParams['module'] = $key;
1514 if ($key == 'User Account') {
1515 $menuRebuild = TRUE;
1517 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1518 // insert a new record
1519 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1521 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1522 // delete a record for existing ufgroup
1523 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1529 UPDATE civicrm_uf_join
1531 WHERE uf_group_id = %2
1532 AND ( entity_id IS NULL OR entity_id <= 0 )
1535 1 => array($params['weight'], 'Integer'),
1536 2 => array($ufGroupId, 'Integer'),
1538 CRM_Core_DAO
::executeQuery($query, $p);
1540 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1542 $config = CRM_Core_Config
::singleton();
1544 $config->userSystem
->is_drupal
1551 * Get the UF Join records for an ufgroup id.
1553 * @param int $ufGroupId
1555 * @param int $displayName
1556 * If set return display name in array.
1557 * @param int $status
1558 * If set return module other than default modules (User Account/User registration/Profile).
1563 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1565 $UFGroupType = array();
1566 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1570 $dao = new CRM_Core_DAO_UFJoin();
1573 $dao->uf_group_id
= $ufGroupId;
1579 while ($dao->fetch()) {
1580 if (!$displayName) {
1581 $ufJoin[$dao->id
] = $dao->module
;
1584 if (isset($UFGroupType[$dao->module
])) {
1585 // skip the default modules
1587 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1589 // added for CRM-1475
1591 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1592 $ufJoin[$dao->id
] = $dao->module
;
1600 * Function takes an associative array and creates a ufjoin record for ufgroup.
1602 * @param array $params
1603 * (reference) an assoc array of name/value pairs.
1605 * @return CRM_Core_BAO_UFJoin
1607 public static function addUFJoin(&$params) {
1608 $ufJoin = new CRM_Core_DAO_UFJoin();
1609 $ufJoin->copyValues($params);
1615 * Delete the uf join record for an uf group.
1617 * @param array $params
1618 * (reference) an assoc array of name/value pairs.
1622 public static function delUFJoin(&$params) {
1623 $ufJoin = new CRM_Core_DAO_UFJoin();
1624 $ufJoin->copyValues($params);
1629 * Get the weight for ufjoin record.
1631 * @param int $ufGroupId
1632 * If $ufGroupId get update weight or add weight.
1635 * weight of the UFGroup
1637 public static function getWeight($ufGroupId = NULL) {
1638 //calculate the weight
1641 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1642 FROM civicrm_uf_join
1643 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1646 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1647 FROM civicrm_uf_join
1648 WHERE civicrm_uf_join.uf_group_id = %1
1649 AND ( entity_id IS NULL OR entity_id <= 0 )";
1650 $p[1] = array($ufGroupId, 'Integer');
1653 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1655 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1659 * Get the uf group for a module.
1661 * @param string $moduleName
1664 * No to increment the weight.
1665 * @param bool $skipPermission
1667 * Which operation (view, edit, create, etc) to check permission for.
1668 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1671 * array of ufgroups for a module
1673 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1674 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1676 if (!CRM_Core_Config
::isUpgradeMode()) {
1677 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1678 $selectFields[] = 'description';
1681 if (!empty($returnFields)) {
1682 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1685 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1686 FROM civicrm_uf_group
1687 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1690 $queryString .= ' AND civicrm_uf_group.is_active = 1
1691 WHERE civicrm_uf_join.module = %2';
1692 $p[2] = array($moduleName, 'String');
1695 // add permissioning for profiles only if not registration
1696 if (!$skipPermission) {
1697 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1698 if (strpos($queryString, 'WHERE') !== FALSE) {
1699 $queryString .= " AND $permissionClause ";
1702 $queryString .= " $permissionClause ";
1706 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1707 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1709 $ufGroups = array();
1710 while ($dao->fetch()) {
1711 //skip mix profiles in user Registration / User Account
1712 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1713 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1717 foreach ($selectFields as $key => $field) {
1718 if ($field == 'id') {
1721 $ufGroups[$dao->id
][$field] = $dao->$field;
1725 // Allow other modules to alter/override the UFGroups.
1726 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1732 * Filter ufgroups based on logged in user contact type.
1734 * @param int $ufGroupId
1735 * Uf group id (profile id).
1736 * @param int $contactID
1741 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1743 $session = CRM_Core_Session
::singleton();
1744 $contactID = $session->get('userID');
1748 //get the contact type
1749 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1751 //match if exixting contact type is same as profile contact type
1752 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1754 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1755 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1758 //allow special mix profiles for Contribution and Participant
1759 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1761 if (in_array($profileType, $specialProfiles)) {
1765 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1774 * Add profile field to a form.
1776 * @param CRM_Core_Form $form
1777 * @param array $field
1781 * @param int $contactId
1782 * @param bool $online
1783 * @param string $usedFor
1784 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1785 * @param int $rowNumber
1786 * @param string $prefix
1790 public static function buildProfile(
1800 $defaultValues = array();
1801 $fieldName = $field['name'];
1802 $title = $field['title'];
1803 $attributes = $field['attributes'];
1804 $rule = $field['rule'];
1805 $view = $field['is_view'];
1806 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1807 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1808 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1810 // do not display view fields in drupal registration form
1812 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1816 if ($usedFor == 'onbehalf') {
1817 $name = "onbehalf[$fieldName]";
1819 elseif ($usedFor == 'honor') {
1820 $name = "honor[$fieldName]";
1822 elseif ($contactId && !$online) {
1823 $name = "field[$contactId][$fieldName]";
1825 elseif ($rowNumber) {
1826 $name = "field[$rowNumber][$fieldName]";
1828 elseif (!empty($prefix)) {
1829 $name = $prefix . "[$fieldName]";
1835 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1837 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1838 $deleteExtra = ts('Are you sure you want to delete contact image.');
1840 CRM_Core_Action
::DELETE
=> array(
1841 'name' => ts('Delete Contact Image'),
1842 'url' => 'civicrm/contact/image',
1843 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1845 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1848 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1849 CRM_Core_Action
::DELETE
,
1851 'id' => $form->get('id'),
1852 'gid' => $form->get('gid'),
1856 'contact.profileimage.delete',
1860 $form->assign('deleteURL', $deleteURL);
1862 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1863 'address_options', TRUE, NULL, TRUE
1866 if (substr($fieldName, 0, 14) === 'state_province') {
1867 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1868 $config = CRM_Core_Config
::singleton();
1869 if (!in_array($mode, array(
1870 CRM_Profile_Form
::MODE_EDIT
,
1871 CRM_Profile_Form
::MODE_SEARCH
,
1873 $config->defaultContactStateProvince
1875 $defaultValues[$name] = $config->defaultContactStateProvince
;
1876 $form->setDefaults($defaultValues);
1879 elseif (substr($fieldName, 0, 7) === 'country') {
1880 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1881 $config = CRM_Core_Config
::singleton();
1882 if (!in_array($mode, array(
1883 CRM_Profile_Form
::MODE_EDIT
,
1884 CRM_Profile_Form
::MODE_SEARCH
,
1886 $config->defaultContactCountry
1888 $defaultValues[$name] = $config->defaultContactCountry
;
1889 $form->setDefaults($defaultValues);
1892 elseif (substr($fieldName, 0, 6) === 'county') {
1893 if ($addressOptions['county']) {
1894 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1897 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1898 $form->add('file', $name, $title, $attributes, $required);
1899 $form->addUploadElement($name);
1901 elseif (substr($fieldName, 0, 2) === 'im') {
1902 $form->add('text', $name, $title, $attributes, $required);
1905 if (substr($name, -1) == ']') {
1906 $providerName = substr($name, 0, -1) . '-provider_id]';
1908 $form->add('select', $providerName, NULL,
1910 '' => ts('- select -'),
1911 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1915 $form->add('select', $name . '-provider_id', $title,
1917 '' => ts('- select -'),
1918 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1922 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1923 $form->freeze($name . '-provider_id');
1927 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1928 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1930 elseif (in_array($fieldName, array(
1931 'membership_start_date',
1932 'membership_end_date',
1935 $form->addDate($name, $title, $required, array('formatType' => 'activityDate'));
1937 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1938 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1939 $sel = &$form->addElement('hierselect', $name, $title);
1940 $select = array('' => ts('- select -'));
1941 if (count($orgInfo) == 1 && $field['is_required']) {
1942 // we only have one org - so we should default to it. Not sure about defaulting to first type
1943 // as it could be missed - so adding a select
1944 // however, possibly that is more similar to the membership form
1945 if (count($types[1]) > 1) {
1946 $types[1] = $select +
$types[1];
1950 $orgInfo = $select +
$orgInfo;
1952 $sel->setOptions(array($orgInfo, $types));
1954 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1955 $form->add('select', $name, $title,
1957 '' => ts('- select -'),
1958 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1961 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1963 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1964 foreach ($pseudoValues as $key => $var) {
1965 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1967 $group = $form->addGroup($options, $name, $title);
1969 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1972 $group->setAttribute('allowClear', TRUE);
1975 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1976 $form->addSelect($name, array(
1978 'entity' => 'contact',
1979 'field' => $fieldName,
1981 'placeholder' => '',
1984 elseif ($fieldName === 'contact_sub_type') {
1985 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
1986 if ($usedFor == 'onbehalf') {
1987 $profileType = 'Organization';
1989 elseif ($usedFor == 'honor') {
1990 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
1993 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
1994 if ($profileType == 'Contact') {
1995 $profileType = 'Individual';
1999 $setSubtype = FALSE;
2000 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2001 $setSubtype = $profileType;
2002 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2005 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2008 $subtypeList = array();
2009 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2012 $subtypeList = $subtypes;
2015 $sel = $form->add('select', $name, $title, $subtypeList, $required);
2016 $sel->setMultiple(TRUE);
2018 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2019 //add email greeting, postal greeting, addressee, CRM-4575
2020 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2021 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2023 if (empty($profileType) ||
in_array($profileType, array(
2030 $profileType = 'Individual';
2032 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2033 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2036 'contact_type' => $profileType,
2037 'greeting_type' => $fieldName,
2039 $form->add('select', $name, $title,
2041 '' => ts('- select -'),
2042 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2044 // add custom greeting element
2045 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2049 elseif ($fieldName === 'preferred_communication_method') {
2050 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2051 foreach ($communicationFields as $key => $var) {
2055 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2057 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2059 elseif ($fieldName === 'preferred_mail_format') {
2060 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2062 elseif ($fieldName === 'preferred_language') {
2063 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2065 elseif ($fieldName == 'external_identifier') {
2066 $form->add('text', $name, $title, $attributes, $required);
2067 $contID = $contactId;
2069 $contID = $form->get('id');
2071 $form->addRule($name,
2072 ts('External ID already exists in Database.'),
2074 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2077 elseif ($fieldName === 'group') {
2078 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2079 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2084 elseif ($fieldName === 'tag') {
2085 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2086 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2091 elseif (substr($fieldName, 0, 4) === 'url-') {
2092 $form->add('text', $name, $title,
2093 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2095 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2096 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2101 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2103 // Note should be rendered as textarea
2104 elseif (substr($fieldName, -4) == 'note') {
2105 $form->add('textarea', $name, $title, $attributes, $required);
2107 elseif (substr($fieldName, 0, 6) === 'custom') {
2108 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2109 if ($customFieldID) {
2110 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2113 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2114 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2115 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2116 if ($customFieldID) {
2117 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2120 elseif (in_array($fieldName, array(
2126 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2128 elseif ($fieldName == 'send_receipt') {
2129 $form->addElement('checkbox', $name, $title);
2131 elseif ($fieldName == 'soft_credit') {
2132 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2133 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2135 elseif ($fieldName == 'product_name') {
2136 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2137 $sel = &$form->addElement('hierselect', $name, $title);
2139 '0' => ts('- select -'),
2141 $sel->setOptions(array($products, $options));
2143 elseif ($fieldName == 'payment_instrument') {
2144 $form->add('select', $name, $title,
2145 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2147 elseif ($fieldName == 'financial_type') {
2148 $form->add('select', $name, $title,
2150 '' => ts('- select -'),
2151 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2154 elseif ($fieldName == 'contribution_status_id') {
2155 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2156 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2162 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2165 $form->add('select', $name, $title,
2167 '' => ts('- select -'),
2168 ) +
$contributionStatuses, $required
2171 elseif ($fieldName == 'soft_credit_type') {
2172 $name = "soft_credit_type[$rowNumber]";
2173 $form->add('select', $name, $title,
2175 '' => ts('- select -'),
2176 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2178 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2179 //else (for contribution), use configured SCT default value
2180 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2181 if ($field['field_type'] == 'Membership') {
2182 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2184 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2186 elseif ($fieldName == 'currency') {
2187 $form->addCurrency($name, $title, $required);
2189 elseif ($fieldName == 'contribution_page_id') {
2190 $form->add('select', $name, $title,
2192 '' => ts('- select -'),
2193 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2196 elseif ($fieldName == 'participant_register_date') {
2197 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2199 elseif ($fieldName == 'activity_status_id') {
2200 $form->add('select', $name, $title,
2202 '' => ts('- select -'),
2203 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2206 elseif ($fieldName == 'activity_engagement_level') {
2207 $form->add('select', $name, $title,
2209 '' => ts('- select -'),
2210 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2213 elseif ($fieldName == 'activity_date_time') {
2214 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2216 elseif ($fieldName == 'participant_status') {
2218 if ($online == TRUE) {
2219 $cond = 'visibility_id = 1';
2221 $form->add('select', $name, $title,
2223 '' => ts('- select -'),
2224 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2227 elseif ($fieldName == 'participant_role') {
2228 if (!empty($field['is_multiple'])) {
2229 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2232 $form->add('select', $name, $title,
2234 '' => ts('- select -'),
2235 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2239 elseif ($fieldName == 'world_region') {
2240 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2242 elseif ($fieldName == 'signature_html') {
2243 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2245 elseif ($fieldName == 'signature_text') {
2246 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2248 elseif (substr($fieldName, -11) == 'campaign_id') {
2249 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2250 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2251 $form->_componentCampaigns
2253 $form->add('select', $name, $title,
2255 '' => ts('- select -'),
2256 ) +
$campaigns, $required, 'class="crm-select2 big"'
2260 elseif ($fieldName == 'activity_details') {
2261 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2263 elseif ($fieldName == 'activity_duration') {
2264 $form->add('text', $name, $title, $attributes, $required);
2265 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2268 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2269 $form->add('advcheckbox', $name, $title, $attributes, $required);
2272 $form->add('text', $name, $title, $attributes, $required);
2276 static $hiddenSubtype = FALSE;
2277 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2278 // In registration mode params are submitted via POST and we don't have any clue
2279 // about profile-id or the profile-type (which could be a subtype)
2280 // To generalize the behavior and simplify the process,
2281 // lets always add the hidden
2282 //subtype value if there is any, and we won't have to
2283 // compute it while processing.
2285 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2288 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2290 $hiddenSubtype = TRUE;
2293 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2294 $form->freeze($name);
2298 if (in_array($fieldName, array(
2299 'non_deductible_amount',
2304 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2307 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2308 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2314 * Set profile defaults.
2316 * @param int $contactId
2318 * @param array $fields
2319 * Associative array of fields.
2320 * @param array $defaults
2322 * @param bool $singleProfile
2323 * True for single profile else false(batch update).
2324 * @param int $componentId
2325 * Id for specific components like contribute, event etc.
2326 * @param null $component
2328 public static function setProfileDefaults(
2329 $contactId, &$fields, &$defaults,
2330 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2332 if (!$componentId) {
2333 //get the contact details
2334 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2335 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2336 $multipleFields = array('website' => 'url');
2338 //start of code to set the default values
2339 foreach ($fields as $name => $field) {
2340 // skip pseudo fields
2341 if (substr($name, 0, 9) == 'phone_ext') {
2345 //set the field name depending upon the profile mode(single/batch)
2346 if ($singleProfile) {
2350 $fldName = "field[$contactId][$name]";
2353 if ($name == 'group') {
2354 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2356 if ($name == 'tag') {
2357 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2360 if (!empty($details[$name]) ||
isset($details[$name])) {
2361 //to handle custom data (checkbox) to be written
2362 // to handle birth/deceased date, greeting_type and few other fields
2363 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2364 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2366 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2367 $defaults[$fldName] = $details[$name . '_id'];
2368 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2370 elseif ($name == 'preferred_communication_method') {
2371 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2372 foreach ($v as $item) {
2374 $defaults[$fldName . "[$item]"] = 1;
2378 elseif ($name == 'contact_sub_type') {
2379 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2381 elseif ($name == 'world_region') {
2382 $defaults[$fldName] = $details['worldregion_id'];
2384 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2385 //fix for custom fields
2386 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2388 // hack to add custom data for components
2389 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2390 foreach ($components as $value) {
2391 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2392 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2396 switch ($customFields[$customFieldId]['html_type']) {
2397 case 'Multi-Select State/Province':
2398 case 'Multi-Select Country':
2399 case 'AdvMulti-Select':
2400 case 'Multi-Select':
2401 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2402 foreach ($v as $item) {
2404 $defaults[$fldName][$item] = $item;
2410 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2411 foreach ($v as $item) {
2413 $defaults[$fldName][$item] = 1;
2414 // seems like we need this for QF style checkboxes in profile where its multiindexed
2416 $defaults["{$fldName}[{$item}]"] = 1;
2422 // CRM-6681, set defult values according to date and time format (if any).
2424 if (!empty($customFields[$customFieldId]['date_format'])) {
2425 $dateFormat = $customFields[$customFieldId]['date_format'];
2428 if (empty($customFields[$customFieldId]['time_format'])) {
2429 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2434 $timeElement = $fldName . '_time';
2435 if (substr($fldName, -1) == ']') {
2436 $timeElement = substr($fldName, 0, -1) . '_time]';
2438 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2439 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2444 $defaults[$fldName] = $details[$name];
2449 $defaults[$fldName] = $details[$name];
2453 $blocks = array('email', 'phone', 'im', 'openid');
2454 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2455 if (!in_array($fieldName, $multipleFields)) {
2456 if (is_array($details)) {
2457 foreach ($details as $key => $value) {
2458 // when we fixed CRM-5319 - get primary loc
2459 // type as per loc field and removed below code.
2460 $primaryLocationType = FALSE;
2461 if ($locTypeId == 'Primary') {
2462 if (is_array($value) && array_key_exists($fieldName, $value)) {
2463 $primaryLocationType = TRUE;
2464 if (in_array($fieldName, $blocks)) {
2465 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2468 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2473 // fixed for CRM-665
2474 if (is_numeric($locTypeId)) {
2475 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2476 if (!empty($value[$fieldName])) {
2477 //to handle stateprovince and country
2478 if ($fieldName == 'state_province') {
2479 $defaults[$fldName] = $value['state_province_id'];
2481 elseif ($fieldName == 'county') {
2482 $defaults[$fldName] = $value['county_id'];
2484 elseif ($fieldName == 'country') {
2485 if (!isset($value['country_id']) ||
!$value['country_id']) {
2486 $config = CRM_Core_Config
::singleton();
2487 if ($config->defaultContactCountry
) {
2488 $defaults[$fldName] = $config->defaultContactCountry
;
2492 $defaults[$fldName] = $value['country_id'];
2495 elseif ($fieldName == 'phone') {
2497 if (isset($value['phone'][$phoneTypeId])) {
2498 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2500 if (isset($value['phone_ext'][$phoneTypeId])) {
2501 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2505 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2507 if (!is_array($phoneDefault)) {
2508 $defaults[$fldName] = $phoneDefault;
2512 elseif ($fieldName == 'email') {
2513 //adding the first email (currently we don't support multiple emails of same location type)
2514 $defaults[$fldName] = $value['email'];
2516 elseif ($fieldName == 'im') {
2517 //adding the first im (currently we don't support multiple ims of same location type)
2518 $defaults[$fldName] = $value['im'];
2519 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2522 $defaults[$fldName] = $value[$fieldName];
2525 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2526 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2528 $defaults[$fldName] = $value[substr($fieldName, 8)];
2536 if (is_array($details)) {
2537 if ($fieldName === 'url'
2538 && !empty($details['website'])
2539 && !empty($details['website'][$locTypeId])
2541 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2549 //Handling Contribution Part of the batch profile
2550 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2551 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2554 //Handling Event Participation Part of the batch profile
2555 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2556 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2559 //Handling membership Part of the batch profile
2560 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2561 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2564 //Handling Activity Part of the batch profile
2565 if ($component == 'Activity') {
2566 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2571 * Get profiles by type eg: pure Individual etc
2573 * @param array $types
2574 * Associative array of types eg: types('Individual').
2575 * @param bool $onlyPure
2576 * True if only pure profiles are required.
2579 * associative array of profiles
2581 public static function getProfiles($types, $onlyPure = FALSE) {
2582 $profiles = array();
2583 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2585 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2587 // Exclude Batch Data Entry profiles - CRM-10901
2588 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2590 foreach ($ufGroups as $id => $title) {
2591 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2592 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2593 $profiles[$id] = $title;
2600 * Check whether a profile is valid combination of
2601 * required and/or optional profile types
2603 * @param array $required
2604 * Array of types those are required.
2605 * @param array $optional
2606 * Array of types those are optional.
2609 * associative array of profiles
2611 public static function getValidProfiles($required, $optional = NULL) {
2612 if (!is_array($required) ||
empty($required)) {
2616 $profiles = array();
2617 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2619 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2621 foreach ($ufGroups as $id => $title) {
2622 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2624 $profiles[$id] = $title;
2632 * Check whether a profile is valid combination of
2633 * required profile fields
2635 * @param array $ufId
2636 * Integer id of the profile.
2637 * @param array $required
2638 * Array of fields those are required in the profile.
2641 * associative array of profiles
2643 public static function checkValidProfile($ufId, $required = NULL) {
2644 $validProfile = FALSE;
2646 return $validProfile;
2649 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2650 return $validProfile;
2653 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2654 NULL, FALSE, NULL, FALSE, NULL,
2655 CRM_Core_Permission
::CREATE
, NULL
2658 $validProfile = array();
2659 if (!empty($profileFields)) {
2660 $fields = array_keys($profileFields);
2661 foreach ($fields as $val) {
2662 foreach ($required as $key => $field) {
2663 if (strpos($val, $field) === 0) {
2664 unset($required[$key]);
2669 $validProfile = (empty($required)) ?
TRUE : FALSE;
2672 return $validProfile;
2676 * Get default value for Register.
2678 * @param array $fields
2679 * @param array $defaults
2683 public static function setRegisterDefaults(&$fields, &$defaults) {
2684 $config = CRM_Core_Config
::singleton();
2685 foreach ($fields as $name => $field) {
2686 if (substr($name, 0, 8) == 'country-') {
2687 if (!empty($config->defaultContactCountry
)) {
2688 $defaults[$name] = $config->defaultContactCountry
;
2691 elseif (substr($name, 0, 15) == 'state_province-') {
2692 if (!empty($config->defaultContactStateProvince
)) {
2693 $defaults[$name] = $config->defaultContactStateProvince
;
2701 * make a copy of a profile, including
2702 * all the fields in the profile
2705 * The profile id to copy.
2709 public static function copy($id) {
2710 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2711 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2717 if ($pos = strrpos($copy->name
, "_{$id}")) {
2718 $copy->name
= substr_replace($copy->name
, '', $pos);
2720 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2723 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2724 array('uf_group_id' => $id),
2725 array('uf_group_id' => $copy->id
),
2730 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2731 array('uf_group_id' => $id),
2732 array('uf_group_id' => $copy->id
)
2735 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2739 UPDATE civicrm_uf_join
2741 WHERE uf_group_id = %2
2742 AND ( entity_id IS NULL OR entity_id <= 0 )
2745 1 => array($maxWeight +
1, 'Integer'),
2746 2 => array($copy->id
, 'Integer'),
2748 CRM_Core_DAO
::executeQuery($query, $p);
2749 if ($copy->is_reserved
) {
2750 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2751 $params = array(1 => array($copy->id
, 'Integer'));
2752 CRM_Core_DAO
::executeQuery($query, $params);
2754 CRM_Utils_Hook
::copy('UFGroup', $copy);
2760 * Process that send notification e-mails
2762 * @param int $contactID
2764 * @param array $values
2765 * Associative array of name/value pair.
2769 public static function commonSendMail($contactID, &$values) {
2770 if (!$contactID ||
!$values) {
2774 $template = CRM_Core_Smarty
::singleton();
2776 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2781 self
::profileDisplay($values['id'], $values['values'], $template);
2782 $emailList = explode(',', $values['email']);
2784 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2785 "reset=1&cid=$contactID",
2786 TRUE, NULL, FALSE, FALSE, TRUE
2789 //get the default domain email address.
2790 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2792 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2793 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2794 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)));
2797 foreach ($emailList as $emailTo) {
2798 // FIXME: take the below out of the foreach loop
2799 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2801 'groupName' => 'msg_tpl_workflow_uf',
2802 'valueName' => 'uf_notify',
2803 'contactId' => $contactID,
2804 'tplParams' => array(
2805 'displayName' => $displayName,
2806 'currentDate' => date('r'),
2807 'contactLink' => $contactLink,
2809 'from' => "$domainEmailName <$domainEmailAddress>",
2810 'toEmail' => $emailTo,
2817 * Given a contact id and a group id, returns the field values from the db
2818 * for this group and notify email only if group's notify field is
2819 * set and field values are not empty
2825 * @param array $params
2826 * @param bool $skipCheck
2830 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2832 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2834 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2835 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2837 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2839 if (!empty($values) &&
2844 'values' => $values,
2855 * Assign uf fields to template.
2859 * @param array $values
2860 * @param CRM_Core_Smarty $template
2864 public function profileDisplay($gid, $values, $template) {
2865 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2866 $template->assign('grouptitle', $groupTitle);
2867 if (count($values)) {
2868 $template->assign('values', $values);
2873 * Format fields for dupe Contact Matching.
2875 * @param array $params
2877 * @param int $contactId
2880 * assoicated formatted array
2882 public static function formatFields($params, $contactId = NULL) {
2884 // get the primary location type id and email
2885 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2888 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2889 $primaryLocationType = $defaultLocationType->id
;
2893 $locationType = array();
2895 $primaryLocation = 0;
2896 foreach ($params as $key => $value) {
2897 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2899 if ($locTypeId == 'Primary') {
2900 $locTypeId = $primaryLocationType;
2903 if (is_numeric($locTypeId)) {
2904 if (!in_array($locTypeId, $locationType)) {
2905 $locationType[$count] = $locTypeId;
2908 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2910 $data['location'][$loc]['location_type_id'] = $locTypeId;
2912 // if we are getting in a new primary email, dont overwrite the new one
2913 if ($locTypeId == $primaryLocationType) {
2914 if (!empty($params['email-' . $primaryLocationType])) {
2915 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2917 elseif (isset($primaryEmail)) {
2918 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2924 $data['location'][$loc]['is_primary'] = 1;
2926 if ($fieldName == 'phone') {
2928 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2931 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2933 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2935 elseif ($fieldName == 'email') {
2936 $data['location'][$loc]['email'][$loc]['email'] = $value;
2938 elseif ($fieldName == 'im') {
2939 $data['location'][$loc]['im'][$loc]['name'] = $value;
2942 if ($fieldName === 'state_province') {
2943 $data['location'][$loc]['address']['state_province_id'] = $value;
2945 elseif ($fieldName === 'country') {
2946 $data['location'][$loc]['address']['country_id'] = $value;
2949 $data['location'][$loc]['address'][$fieldName] = $value;
2954 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2955 if ($key === 'individual_suffix') {
2956 $data['suffix_id'] = $value;
2958 elseif ($key === 'individual_prefix') {
2959 $data['prefix_id'] = $value;
2961 elseif ($key === 'gender') {
2962 $data['gender_id'] = $value;
2964 elseif (substr($key, 0, 6) === 'custom') {
2965 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2967 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2968 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2970 // fix the date field
2971 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2972 $date = CRM_Utils_Date
::format($value);
2979 $data['custom'][$customFieldID] = array(
2982 'extends' => $customFields[$customFieldID]['extends'],
2983 'type' => $customFields[$customFieldID]['data_type'],
2984 'custom_field_id' => $customFieldID,
2988 elseif ($key == 'edit') {
2992 $data[$key] = $value;
2997 if (!$primaryLocation) {
2999 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
3006 * Calculate the profile type 'group_type' as per profile fields.
3010 * @param bool $includeTypeValues
3011 * @param int $ignoreFieldId
3012 * Ignore particular profile field.
3015 * list of calculated group type
3017 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3018 //get the profile fields.
3019 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3020 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3024 * Calculate the profile type 'group_type' as per profile fields.
3027 * @param bool $includeTypeValues
3028 * @param int $ignoreFieldId
3029 * Ignore perticular profile field.
3032 * list of calculated group type
3034 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3035 $groupType = $groupTypeValues = $customFieldIds = array();
3036 if (!empty($ufFields)) {
3037 foreach ($ufFields as $fieldName => $fieldValue) {
3038 //ignore field from group type when provided.
3039 //in case of update profile field.
3040 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3043 if (!in_array($fieldValue['field_type'], $groupType)) {
3044 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3047 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3048 $customFieldIds[$fldId] = $fldId;
3053 if (!empty($customFieldIds)) {
3054 $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) . ')';
3056 $customGroups = CRM_Core_DAO
::executeQuery($query);
3057 while ($customGroups->fetch()) {
3058 if (!$customGroups->extends_entity_column_value
) {
3062 $groupTypeName = "{$customGroups->extends}Type";
3063 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3064 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3067 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3069 $groupTypeValues[$groupTypeName][$val] = $val;
3074 if (!empty($groupTypeValues)) {
3075 $groupType = array_merge($groupType, $groupTypeValues);
3083 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3084 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3087 * BirthDate + Email Individual,Contact
3088 * BirthDate + Subject Individual,Activity
3089 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3090 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3091 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3092 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3093 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3094 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3095 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3098 * @param array $groupTypes
3099 * With key having group type names.
3103 public static function updateGroupTypes($gId, $groupTypes = array()) {
3104 if (!is_array($groupTypes) ||
!$gId) {
3108 // If empty group types set group_type as 'null'
3109 if (empty($groupTypes)) {
3110 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3113 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3114 $validGroupTypes = array_merge(array(
3119 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3121 $gTypes = $gTypeValues = array();
3123 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3124 // Get valid group type and group subtypes
3125 foreach ($groupTypes as $groupType => $value) {
3126 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3127 $gTypes[] = $groupType;
3132 if (in_array($groupType, $participantExtends)) {
3133 $subTypesOf = $groupType;
3135 elseif (strpos($groupType, 'Type') > 0) {
3136 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3142 if (!empty($value) &&
3143 (in_array($subTypesOf, $componentGroupTypes) ||
3144 in_array($subTypesOf, $participantExtends)
3147 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3151 if (empty($gTypes)) {
3155 // Build String to store group types and group subtypes
3156 $groupTypeString = implode(',', $gTypes);
3157 if (!empty($gTypeValues)) {
3158 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3161 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3165 * Create a "group_type" string.
3167 * @param array $coreTypes
3168 * E.g. array('Individual','Contact','Student').
3169 * @param array $subTypes
3170 * E.g. array('ActivityType' => array(7, 11)).
3171 * @param string $delim
3174 * @throws CRM_Core_Exception
3176 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3177 $groupTypeExpr = '';
3179 $groupTypeExpr .= implode(',', $coreTypes);
3182 //CRM-15427 Allow Multiple subtype filtering
3183 //if (count($subTypes) > 1) {
3184 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3186 foreach ($subTypes as $subType => $subTypeIds) {
3187 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3190 return $groupTypeExpr;
3194 * setDefault componet specific profile fields.
3196 * @param array $fields
3198 * @param int $componentId
3200 * @param string $component
3202 * @param array $defaults
3203 * An array of default values.
3205 * @param bool $isStandalone
3209 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3210 if (!$componentId ||
3211 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3216 $componentBAO = $componentSubType = NULL;
3217 switch ($component) {
3219 $componentBAO = 'CRM_Member_BAO_Membership';
3220 $componentBAOName = 'Membership';
3221 $componentSubType = array('membership_type_id');
3225 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3226 $componentBAOName = 'Contribution';
3227 $componentSubType = array('financial_type_id');
3231 $componentBAO = 'CRM_Event_BAO_Participant';
3232 $componentBAOName = 'Participant';
3233 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3237 $componentBAO = 'CRM_Activity_BAO_Activity';
3238 $componentBAOName = 'Activity';
3239 $componentSubType = array('activity_type_id');
3244 $params = array('id' => $componentId);
3246 //get the component values.
3247 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3248 if ($componentBAOName == 'Participant') {
3249 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3252 $formattedGroupTree = array();
3253 $dateTimeFields = array(
3254 'participant_register_date',
3255 'activity_date_time',
3260 'membership_start_date',
3261 'membership_end_date',
3264 foreach ($fields as $name => $field) {
3265 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3266 if (in_array($name, $dateTimeFields)) {
3267 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3268 if (!empty($values[$name])) {
3269 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3272 elseif (array_key_exists($name, $values)) {
3273 $defaults[$fldName] = $values[$name];
3275 elseif ($name == 'participant_note') {
3276 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3277 $defaults[$fldName] = array_pop($noteDetails);
3279 elseif (in_array($name, array(
3281 'payment_instrument',
3282 'participant_status',
3285 $defaults[$fldName] = $values["{$name}_id"];
3287 elseif ($name == 'membership_type') {
3288 // since membership_type field is a hierselect -
3289 $defaults[$fldName][0]
3290 = CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3291 $defaults[$fldName][1] = $values['membership_type_id'];
3293 elseif ($name == 'membership_status') {
3294 $defaults[$fldName] = $values['status_id'];
3296 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3297 if (empty($formattedGroupTree)) {
3298 //get the groupTree as per subTypes.
3299 $groupTree = array();
3300 foreach ($componentSubType as $subType) {
3301 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3302 $componentId, 0, $values[$subType]
3304 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3306 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3307 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3310 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3311 foreach ($defaults as $customKey => $customValue) {
3312 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3313 if ($name == 'custom_' . $customFieldDetails[0]) {
3315 //hack to set default for checkbox
3316 //basically this is for weired field name like field[33][custom_19]
3317 //we are converting this field name to array structure and assign value.
3320 foreach ($formattedGroupTree as $tree) {
3321 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3322 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3324 $defaults['field'][$componentId][$name] = $customValue;
3327 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3330 // CRM-6681, $default contains formatted date, time values.
3331 $defaults[$fldName] = $customValue;
3332 if (!empty($defaults[$customKey . '_time'])) {
3333 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3339 if (!$skipValue ||
$isStandalone) {
3340 $defaults[$fldName] = $customValue;
3342 unset($defaults[$customKey]);
3352 * @param array|string $profiles - name of profile(s) to create links for
3353 * @param array $appendProfiles
3354 * Name of profile(s) to append to each link.
3358 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3359 // Default to contact profiles
3361 $profiles = array('new_individual', 'new_organization', 'new_household');
3363 $profiles = (array) $profiles;
3364 $toGet = array_merge($profiles, (array) $appendProfiles);
3365 $retrieved = civicrm_api3('uf_group', 'get', array(
3366 'name' => array('IN' => $toGet),
3369 $links = $append = array();
3370 if (!empty($retrieved['values'])) {
3371 foreach ($retrieved['values'] as $id => $profile) {
3372 if (in_array($profile['name'], $profiles)) {
3374 'label' => $profile['title'],
3375 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3376 NULL, NULL, FALSE, FALSE, TRUE),
3377 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3384 foreach ($append as $id) {
3385 foreach ($links as &$link) {
3386 $link['url'] .= ",$id";
3394 * Retrieve groups of profiles.
3396 * @param int $profileID
3397 * Id of the profile.
3402 public static function profileGroups($profileID) {
3403 $groupTypes = array();
3404 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3405 if ($profileTypes) {
3406 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3407 $groupTypes = explode(',', $groupTypeParts[0]);
3413 * Alter contact params by filtering existing subscribed groups and returns
3414 * unsubscribed groups array for subscription.
3416 * @param array $params
3418 * @param int $contactId
3422 * This contains array of groups for subscription
3424 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3425 $config = CRM_Core_Config
::singleton();
3426 $subscribeGroupIds = array();
3428 // process further only if profileDoubleOptIn enabled and if groups exist
3429 if (!array_key_exists('group', $params) ||
3430 !self
::isProfileDoubleOptin() ||
3431 CRM_Utils_System
::isNull($params['group'])
3433 return $subscribeGroupIds;
3436 //check if contact email exist.
3438 foreach ($params as $name => $value) {
3439 if (strpos($name, 'email-') !== FALSE) {
3445 //Proceed furthur only if email present
3447 return $subscribeGroupIds;
3450 //do check for already subscriptions.
3451 $contactGroups = array();
3455 FROM civicrm_group_contact
3456 WHERE status = 'Added'
3457 AND contact_id = %1";
3459 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3460 while ($dao->fetch()) {
3461 $contactGroups[$dao->group_id
] = $dao->group_id
;
3465 //since we don't have names, compare w/ label.
3466 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3468 //actual processing start.
3469 foreach ($params['group'] as $groupId => $isSelected) {
3470 //unset group those are not selected.
3472 unset($params['group'][$groupId]);
3476 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3477 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3479 //get only mailing type group and unset it from params
3480 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3481 $subscribeGroupIds[$groupId] = $groupId;
3482 unset($params['group'][$groupId]);
3486 return $subscribeGroupIds;
3490 * Check if we are rendering mixed profiles.
3492 * @param array $profileIds
3493 * Associated array of profile ids.
3496 * true if profile is mixed
3498 public static function checkForMixProfiles($profileIds) {
3499 $mixProfile = FALSE;
3501 $contactTypes = array('Individual', 'Household', 'Organization');
3502 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3504 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3506 $typeCount = array('ctype' => array(), 'subtype' => array());
3507 foreach ($profileIds as $gid) {
3508 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3509 // ignore profile of type Contact
3510 if ($profileType == 'Contact') {
3513 if (in_array($profileType, $contactTypes)) {
3514 if (!isset($typeCount['ctype'][$profileType])) {
3515 $typeCount['ctype'][$profileType] = 1;
3518 // check if we are rendering profile of different contact types
3519 if (count($typeCount['ctype']) == 2) {
3524 elseif (in_array($profileType, $components)) {
3529 if (!isset($typeCount['subtype'][$profileType])) {
3530 $typeCount['subtype'][$profileType] = 1;
3532 // check if we are rendering profile of different contact sub types
3533 if (count($typeCount['subtype']) == 2) {
3543 * Determine of we show overlay profile or not.
3546 * true if profile should be shown else false
3548 public static function showOverlayProfile() {
3549 $showOverlay = TRUE;
3551 // get the id of overlay profile
3552 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3553 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3555 $count = CRM_Core_DAO
::singleValueQuery($query);
3557 //check if there are no public fields and use is anonymous
3558 $session = CRM_Core_Session
::singleton();
3559 if (!$count && !$session->get('userID')) {
3560 $showOverlay = FALSE;
3563 return $showOverlay;
3567 * Get group type values of the profile.
3569 * @param int $profileId
3570 * @param string $groupType
3575 public static function groupTypeValues($profileId, $groupType = NULL) {
3576 $groupTypeValue = array();
3577 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3579 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3580 if (empty($groupTypeParts[1])) {
3581 return $groupTypeValue;
3583 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3585 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3587 $valueParts = explode(':', $groupTypeValues);
3589 ($valueParts[0] != "{$groupType}Type" ||
3590 ($groupType == 'Participant' &&
3591 !in_array($valueParts[0], $participantExtends)
3597 foreach ($valueParts as $val) {
3598 if (CRM_Utils_Rule
::integer($val)) {
3599 $values[$val] = $val;
3602 if (!empty($values)) {
3603 $typeName = substr($valueParts[0], 0, -4);
3604 if (in_array($valueParts[0], $participantExtends)) {
3605 $typeName = $valueParts[0];
3607 $groupTypeValue[$typeName] = $values;
3611 return $groupTypeValue;
3615 * @return bool|object
3617 public static function isProfileDoubleOptin() {
3618 // check for double optin
3619 $config = CRM_Core_Config
::singleton();
3620 if (in_array('CiviMail', $config->enableComponents
)) {
3621 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3622 'profile_double_optin', NULL, FALSE
3629 * @return bool|object
3631 public static function isProfileAddToGroupDoubleOptin() {
3632 // check for add to group double optin
3633 $config = CRM_Core_Config
::singleton();
3634 if (in_array('CiviMail', $config->enableComponents
)) {
3635 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3636 'profile_add_to_group_double_optin', NULL, FALSE
3643 * Get profiles used for batch entry.
3646 * profileIds profile ids
3648 public static function getBatchProfiles() {
3650 FROM civicrm_uf_group
3651 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3652 $dao = CRM_Core_DAO
::executeQuery($query);
3653 $profileIds = array();
3654 while ($dao->fetch()) {
3655 $profileIds[$dao->id
] = $dao->id
;
3661 * @todo what do I do?
3663 * @param $destination
3664 * @param bool $returnMultiSummaryFields
3666 * @return array|null
3668 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3669 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3670 foreach ($source as $field => $properties) {
3671 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3674 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3675 $destination[$field] = $properties;
3676 if ($returnMultiSummaryFields) {
3677 if ($properties['is_multi_summary']) {
3678 $multiSummaryFields[$field] = $properties;
3681 unset($source[$field]);
3684 return $multiSummaryFields;
3688 * This is function is used to format pseudo fields.
3690 * @param array $fields
3691 * Associated array of profile fields.
3694 public static function reformatProfileFields(&$fields) {
3695 //reformat fields array
3696 foreach ($fields as $name => $field) {
3697 //reformat phone and extension field
3698 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3699 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3701 // retain existing element properties and just update and replace key
3702 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3703 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3704 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3706 // add additional phone extension field
3707 $fields["phone_ext-{$fieldSuffix}"] = $field;
3708 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3709 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3710 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3711 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3712 //ignore required for extension field
3713 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;