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.
59 * @return object 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
72 * @return string contact type
74 public static function getContactType($id) {
76 $validTypes = array_filter(array_keys(CRM_Core_SelectValues
::contactType()));
77 $validSubTypes = CRM_Contact_BAO_ContactType
::subTypeInfo();
79 $typesParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
80 $types = explode(',', $typesParts[0]);
83 foreach ($types as $type) {
84 if (in_array($type, $validTypes)) {
87 elseif (array_key_exists($type, $validSubTypes)) {
88 $cType = CRM_Utils_Array
::value('parent', $validSubTypes[$type]);
104 * @return string 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.
121 * @return Object 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.
138 * @return array 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
199 * @return array the fields that are listings related
202 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
278 * @return array the fields that belong to this ufgroup(s)
281 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 $addressCustomFields
426 * @param array $importableFields
427 * @param array $customFields
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
594 * @return bool TRUE if field is displayable
596 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
597 if ($searchable && $field->is_searchable
!= 1) {
601 if (!$showAll && $field->is_active
!= 1) {
606 $allowedVisibilities = array();
607 if ($visibility & self
::PUBLIC_VISIBILITY
) {
608 $allowedVisibilities[] = 'Public Pages';
610 if ($visibility & self
::ADMIN_VISIBILITY
) {
611 $allowedVisibilities[] = 'User and User Admin Only';
613 if ($visibility & self
::LISTINGS_VISIBILITY
) {
614 $allowedVisibilities[] = 'Public Pages and Listings';
616 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
617 if (!empty($allowedVisibilities) && !in_array($field->visibility
, $allowedVisibilities)) {
627 * @param $profileType
628 * @param $contactActivityProfile
632 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
634 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
637 $importableFields = CRM_Contact_BAO_Contact
::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
640 if ($profileType == 'Activity' ||
$contactActivityProfile) {
641 $componentFields = CRM_Activity_BAO_Activity
::getProfileFields();
644 $componentFields = CRM_Core_Component
::getQueryFields();
647 $importableFields = array_merge($importableFields, $componentFields);
649 $importableFields['group']['title'] = ts('Group(s)');
650 $importableFields['group']['where'] = NULL;
651 $importableFields['tag']['title'] = ts('Tag(s)');
652 $importableFields['tag']['where'] = NULL;
653 return $importableFields;
656 public static function getLocationFields() {
657 static $locationFields = array(
659 'supplemental_address_1',
660 'supplemental_address_2',
663 'postal_code_suffix',
676 return $locationFields;
684 protected static function getCustomFields($ctype) {
685 static $customFieldCache = array();
686 if (!isset($customFieldCache[$ctype])) {
687 $customFields = CRM_Core_BAO_CustomField
::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
689 // hack to add custom data for components
690 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
691 foreach ($components as $value) {
692 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField
::getFieldsForImport($value));
694 $addressCustomFields = CRM_Core_BAO_CustomField
::getFieldsForImport('Address');
695 $customFields = array_merge($customFields, $addressCustomFields);
696 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
698 return $customFieldCache[$ctype];
702 * Check the data validity
705 * The user id that we are actually editing.
706 * @param string $title
707 * The title of the group we are interested in.
708 * @param bool $register
710 * The action of the form.
712 * @pram boolean $register is this the registrtion form
713 * @return boolean true if form is valid
716 public static function isValid($userID, $title, $register = FALSE, $action = NULL) {
718 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
719 ts('Dynamic Form Creator'),
722 $controller->set('id', $userID);
723 $controller->set('register', 1);
724 $controller->process();
725 return $controller->validate();
728 // make sure we have a valid group
729 $group = new CRM_Core_DAO_UFGroup();
731 $group->title
= $title;
733 if ($group->find(TRUE) && $userID) {
734 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
735 $controller->set('gid', $group->id
);
736 $controller->set('id', $userID);
737 $controller->set('register', 0);
738 $controller->process();
739 return $controller->validate();
746 * Get the html for the form that represents this particular group
749 * The user id that we are actually editing.
750 * @param string $title
751 * The title of the group we are interested in.
753 * The action of the form.
754 * @param bool $register
755 * Is this the registration form.
757 * Should we reset the form?.
758 * @param int $profileID
759 * Do we have the profile ID?.
761 * @param bool $doNotProcess
764 * @return string the html for the form on success, otherwise empty string
767 static function getEditHTML(
774 $doNotProcess = FALSE,
779 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
780 ts('Dynamic Form Creator'),
783 if ($reset ||
$doNotProcess) {
784 // hack to make sure we do not process this form
785 $oldQFDefault = CRM_Utils_Array
::value('_qf_default',
788 unset($_POST['_qf_default']);
789 unset($_REQUEST['_qf_default']);
791 $controller->reset();
795 $controller->set('id', $userID);
796 $controller->set('register', 1);
797 $controller->set('skipPermission', 1);
798 $controller->set('ctype', $ctype);
799 $controller->process();
800 if ($doNotProcess ||
!empty($_POST)) {
801 $controller->validate();
803 $controller->setEmbedded(TRUE);
805 //CRM-5839 - though we want to process form, get the control back.
806 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
810 // we are done processing so restore the POST/REQUEST vars
811 if (($reset ||
$doNotProcess) && $oldQFDefault) {
812 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
815 $template = CRM_Core_Smarty
::singleton();
817 // Hide CRM error messages if they are displayed using drupal form_set_error.
818 if (!empty($_POST)) {
819 $template->assign('suppressForm', TRUE);
822 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
826 // make sure we have a valid group
827 $group = new CRM_Core_DAO_UFGroup();
829 $group->title
= $title;
831 if ($group->find(TRUE)) {
832 $profileID = $group->id
;
837 // make sure profileID and ctype match if ctype exists
839 $profileType = CRM_Core_BAO_UFField
::getProfileType($profileID);
840 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
841 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
844 if (($profileType != 'Contact') && ($profileType != $ctype)) {
849 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
850 ts('Dynamic Form Creator'),
854 $controller->reset();
856 $controller->set('gid', $profileID);
857 $controller->set('id', $userID);
858 $controller->set('register', 0);
859 $controller->set('skipPermission', 1);
861 $controller->set('ctype', $ctype);
863 $controller->process();
864 $controller->setEmbedded(TRUE);
866 //CRM-5846 - give the control back to drupal.
867 $controller->setSkipRedirection(($doNotProcess) ?
FALSE : TRUE);
870 $template = CRM_Core_Smarty
::singleton();
872 // Hide CRM error messages if they are displayed using drupal form_set_error.
873 if (!empty($_POST) && CRM_Core_Config
::singleton()->userFramework
== 'Drupal') {
874 if (arg(0) == 'user' ||
(arg(0) == 'admin' && arg(1) == 'people')) {
875 $template->assign('suppressForm', TRUE);
879 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
880 if (!$template->template_exists($templateFile)) {
881 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
883 return trim($template->fetch($templateFile));
886 $userEmail = CRM_Contact_BAO_Contact_Location
::getEmailDetails($userID);
888 // if post not empty then only proceed
889 if (!empty($_POST)) {
891 $config = CRM_Core_Config
::singleton();
892 $email = CRM_Utils_Array
::value('mail', $_POST);
894 if (CRM_Utils_Rule
::email($email) && ($email != $userEmail[1])) {
895 CRM_Core_BAO_UFMatch
::updateContactEmail($userID, $email);
904 * Searches for a contact in the db with similar attributes
906 * @param array $params
907 * The list of values to be used in the where clause.
909 * The current contact id (hence excluded from matching).
910 * @param string $contactType
912 * @return int|null contact_id if found, null otherwise
915 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
916 $dedupeParams = CRM_Dedupe_Finder
::formatParams($params, $contactType);
917 $dedupeParams['check_permission'] = CRM_Utils_Array
::value('check_permission', $params, TRUE);
918 $ids = CRM_Dedupe_Finder
::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
920 return implode(',', $ids);
928 * Given a contact id and a field set, return the values from the db
932 * @param array $fields
933 * The profile fields of interest.
934 * @param array $values
935 * The values for the above fields.
936 * @param bool $searchable
938 * @param array $componentWhere
939 * Component condition.
940 * @param bool $absolute
941 * Return urls in absolute form (useful when sending an email).
942 * @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.
1384 public static function usedByModule($id) {
1385 //check whether this group is used by any module(check uf join records)
1387 FROM civicrm_uf_join
1388 WHERE civicrm_uf_join.uf_group_id=$id";
1390 $dao = new CRM_Core_DAO();
1392 if ($dao->fetch()) {
1401 * Delete the profile Group.
1411 public static function del($id) {
1412 //check whether this group contains any profile fields
1413 $profileField = new CRM_Core_DAO_UFField();
1414 $profileField->uf_group_id
= $id;
1415 $profileField->find();
1416 while ($profileField->fetch()) {
1417 CRM_Core_BAO_UFField
::del($profileField->id
);
1420 //delete records from uf join table
1421 $ufJoin = new CRM_Core_DAO_UFJoin();
1422 $ufJoin->uf_group_id
= $id;
1425 //delete profile group
1426 $group = new CRM_Core_DAO_UFGroup();
1435 * @param array $params
1436 * Reference array contains the values submitted by the form.
1438 * Reference array contains the id.
1444 public static function add(&$params, $ids = array()) {
1454 foreach ($fields as $field) {
1455 $params[$field] = CRM_Utils_Array
::value($field, $params, FALSE);
1458 $params['limit_listings_group_id'] = CRM_Utils_Array
::value('group', $params);
1459 $params['add_to_group_id'] = CRM_Utils_Array
::value('add_contact_to_group', $params);
1462 if (!empty($params['group_type']) && is_array($params['group_type'])) {
1463 $params['group_type'] = implode(',', $params['group_type']);
1465 $ufGroup = new CRM_Core_DAO_UFGroup();
1466 $ufGroup->copyValues($params);
1468 $ufGroupID = CRM_Utils_Array
::value('ufgroup', $ids, CRM_Utils_Array
::value('id', $params));
1470 $ufGroup->name
= CRM_Utils_String
::munge($ufGroup->title
, '_', 56);
1472 $ufGroup->id
= $ufGroupID;
1477 $ufGroup->name
= $ufGroup->name
. "_{$ufGroup->id}";
1485 * Make uf join entries for an uf group
1487 * @param array $params
1488 * (reference) an assoc array of name/value pairs.
1489 * @param int $ufGroupId
1495 public static function createUFJoin(&$params, $ufGroupId) {
1496 $groupTypes = CRM_Utils_Array
::value('uf_group_type', $params);
1498 // get ufjoin records for uf group
1499 $ufGroupRecord = CRM_Core_BAO_UFGroup
::getUFJoinRecord($ufGroupId);
1501 // get the list of all ufgroup types
1502 $allUFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1504 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1505 if (!is_array($groupTypes)) {
1506 $groupTypes = array();
1509 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1510 if (!is_array($ufGroupRecord)) {
1511 $ufGroupRecord = array();
1514 // check which values has to be inserted/deleted for contact
1515 $menuRebuild = FALSE;
1516 foreach ($allUFGroupType as $key => $value) {
1517 $joinParams = array();
1518 $joinParams['uf_group_id'] = $ufGroupId;
1519 $joinParams['module'] = $key;
1520 if ($key == 'User Account') {
1521 $menuRebuild = TRUE;
1523 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1524 // insert a new record
1525 CRM_Core_BAO_UFGroup
::addUFJoin($joinParams);
1527 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1528 // delete a record for existing ufgroup
1529 CRM_Core_BAO_UFGroup
::delUFJoin($joinParams);
1535 UPDATE civicrm_uf_join
1537 WHERE uf_group_id = %2
1538 AND ( entity_id IS NULL OR entity_id <= 0 )
1541 1 => array($params['weight'], 'Integer'),
1542 2 => array($ufGroupId, 'Integer'),
1544 CRM_Core_DAO
::executeQuery($query, $p);
1546 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1548 $config = CRM_Core_Config
::singleton();
1550 $config->userSystem
->is_drupal
1557 * Get the UF Join records for an ufgroup id
1559 * @param int $ufGroupId
1561 * @param int $displayName
1562 * If set return display name in array.
1563 * @param int $status
1564 * If set return module other than default modules (User Account/User registration/Profile).
1566 * @return array $ufGroupJoinRecords
1570 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1572 $UFGroupType = array();
1573 $UFGroupType = CRM_Core_SelectValues
::ufGroupTypes();
1577 $dao = new CRM_Core_DAO_UFJoin();
1580 $dao->uf_group_id
= $ufGroupId;
1586 while ($dao->fetch()) {
1587 if (!$displayName) {
1588 $ufJoin[$dao->id
] = $dao->module
;
1591 if (isset($UFGroupType[$dao->module
])) {
1592 // skip the default modules
1594 $ufJoin[$dao->id
] = $UFGroupType[$dao->module
];
1596 // added for CRM-1475
1598 elseif (!CRM_Utils_Array
::key($dao->module
, $ufJoin)) {
1599 $ufJoin[$dao->id
] = $dao->module
;
1607 * Function takes an associative array and creates a ufjoin record for ufgroup
1609 * @param array $params
1610 * (reference) an assoc array of name/value pairs.
1612 * @return CRM_Core_BAO_UFJoin object
1615 public static function addUFJoin(&$params) {
1616 $ufJoin = new CRM_Core_DAO_UFJoin();
1617 $ufJoin->copyValues($params);
1623 * Delete the uf join record for an uf group
1625 * @param array $params
1626 * (reference) an assoc array of name/value pairs.
1631 public static function delUFJoin(&$params) {
1632 $ufJoin = new CRM_Core_DAO_UFJoin();
1633 $ufJoin->copyValues($params);
1638 * Get the weight for ufjoin record
1640 * @param int $ufGroupId
1641 * If $ufGroupId get update weight or add weight.
1643 * @return int weight of the UFGroup
1646 public static function getWeight($ufGroupId = NULL) {
1647 //calculate the weight
1650 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1651 FROM civicrm_uf_join
1652 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1655 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1656 FROM civicrm_uf_join
1657 WHERE civicrm_uf_join.uf_group_id = %1
1658 AND ( entity_id IS NULL OR entity_id <= 0 )";
1659 $p[1] = array($ufGroupId, 'Integer');
1662 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1664 return ($dao->new_weight
) ?
$dao->new_weight
: 1;
1668 * Get the uf group for a module
1670 * @param string $moduleName
1673 * No to increment the weight.
1674 * @param bool $skipPermission
1676 * Which operation (view, edit, create, etc) to check permission for.
1677 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
1679 * @return array $ufGroups array of ufgroups for a module
1682 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission
::VIEW
, $returnFields = NULL) {
1683 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1685 if (!CRM_Core_Config
::isUpgradeMode()) {
1686 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1687 $selectFields[] = 'description';
1690 if (!empty($returnFields)) {
1691 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
1694 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
1695 FROM civicrm_uf_group
1696 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1699 $queryString .= ' AND civicrm_uf_group.is_active = 1
1700 WHERE civicrm_uf_join.module = %2';
1701 $p[2] = array($moduleName, 'String');
1704 // add permissioning for profiles only if not registration
1705 if (!$skipPermission) {
1706 $permissionClause = CRM_Core_Permission
::ufGroupClause($op, 'civicrm_uf_group.');
1707 if (strpos($queryString, 'WHERE') !== FALSE) {
1708 $queryString .= " AND $permissionClause ";
1711 $queryString .= " $permissionClause ";
1715 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1716 $dao = CRM_Core_DAO
::executeQuery($queryString, $p);
1718 $ufGroups = array();
1719 while ($dao->fetch()) {
1720 //skip mix profiles in user Registration / User Account
1721 if (($moduleName == 'User Registration' ||
$moduleName == 'User Account') &&
1722 CRM_Core_BAO_UFField
::checkProfileType($dao->id
)
1726 foreach ($selectFields as $key => $field) {
1727 if ($field == 'id') {
1730 elseif ($field == 'name') {
1731 $ufGroups[$dao->id
][$field] = $dao->title
;
1734 $ufGroups[$dao->id
][$field] = $dao->$field;
1738 // Allow other modules to alter/override the UFGroups.
1739 CRM_Utils_Hook
::buildUFGroupsForModule($moduleName, $ufGroups);
1745 * Filter ufgroups based on logged in user contact type
1747 * @param int $ufGroupId
1748 * Uf group id (profile id).
1749 * @param int $contactID
1751 * @return boolean true or false
1754 public static function filterUFGroups($ufGroupId, $contactID = NULL) {
1756 $session = CRM_Core_Session
::singleton();
1757 $contactID = $session->get('userID');
1761 //get the contact type
1762 $contactType = CRM_Contact_BAO_Contact
::getContactType($contactID);
1764 //match if exixting contact type is same as profile contact type
1765 $profileType = CRM_Core_BAO_UFField
::getProfileType($ufGroupId);
1767 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
1768 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
1771 //allow special mix profiles for Contribution and Participant
1772 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1774 if (in_array($profileType, $specialProfiles)) {
1778 if (($contactType == $profileType) ||
$profileType == 'Contact') {
1787 * Add profile field to a form
1789 * @param CRM_Core_Form $form
1790 * @param array $field
1794 * @param int $contactId
1795 * @param bool $online
1796 * @param string $usedFor
1797 * For building up prefixed fieldname for special cases (e.g. onBehalf, Honor).
1798 * @param int $rowNumber
1799 * @param string $prefix
1804 static function buildProfile(
1814 $defaultValues = array();
1815 $fieldName = $field['name'];
1816 $title = $field['title'];
1817 $attributes = $field['attributes'];
1818 $rule = $field['rule'];
1819 $view = $field['is_view'];
1820 $required = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
FALSE : $field['is_required'];
1821 $search = ($mode == CRM_Profile_Form
::MODE_SEARCH
) ?
TRUE : FALSE;
1822 $isShared = CRM_Utils_Array
::value('is_shared', $field, 0);
1824 // do not display view fields in drupal registration form
1826 if ($view && $mode == CRM_Profile_Form
::MODE_REGISTER
) {
1830 if ($usedFor == 'onbehalf') {
1831 $name = "onbehalf[$fieldName]";
1833 elseif ($usedFor == 'honor') {
1834 $name = "honor[$fieldName]";
1836 elseif ($contactId && !$online) {
1837 $name = "field[$contactId][$fieldName]";
1839 elseif ($rowNumber) {
1840 $name = "field[$rowNumber][$fieldName]";
1842 elseif (!empty($prefix)) {
1843 $name = $prefix . "[$fieldName]";
1849 $selectAttributes = array('class' => 'crm-select2', 'placeholder' => TRUE);
1851 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form
::MODE_EDIT
) {
1852 $deleteExtra = ts('Are you sure you want to delete contact image.');
1854 CRM_Core_Action
::DELETE
=>
1856 'name' => ts('Delete Contact Image'),
1857 'url' => 'civicrm/contact/image',
1858 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1860 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&confirmed=1\'; else return false;"',
1863 $deleteURL = CRM_Core_Action
::formLink($deleteURL,
1864 CRM_Core_Action
::DELETE
,
1866 'id' => $form->get('id'),
1867 'gid' => $form->get('gid'),
1871 'contact.profileimage.delete',
1875 $form->assign('deleteURL', $deleteURL);
1877 $addressOptions = CRM_Core_BAO_Setting
::valueOptions(CRM_Core_BAO_Setting
::SYSTEM_PREFERENCES_NAME
,
1878 'address_options', TRUE, NULL, TRUE
1881 if (substr($fieldName, 0, 14) === 'state_province') {
1882 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1883 $config = CRM_Core_Config
::singleton();
1884 if (!in_array($mode, array(
1885 CRM_Profile_Form
::MODE_EDIT
,
1886 CRM_Profile_Form
::MODE_SEARCH
1888 $config->defaultContactStateProvince
1890 $defaultValues[$name] = $config->defaultContactStateProvince
;
1891 $form->setDefaults($defaultValues);
1894 elseif (substr($fieldName, 0, 7) === 'country') {
1895 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Core_PseudoConstant
::country(), $required, $selectAttributes);
1896 $config = CRM_Core_Config
::singleton();
1897 if (!in_array($mode, array(
1898 CRM_Profile_Form
::MODE_EDIT
,
1899 CRM_Profile_Form
::MODE_SEARCH
1901 $config->defaultContactCountry
1903 $defaultValues[$name] = $config->defaultContactCountry
;
1904 $form->setDefaults($defaultValues);
1907 elseif (substr($fieldName, 0, 6) === 'county') {
1908 if ($addressOptions['county']) {
1909 $form->addChainSelect($name, array('label' => $title, 'required' => $required));
1912 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1913 $form->add('file', $name, $title, $attributes, $required);
1914 $form->addUploadElement($name);
1916 elseif (substr($fieldName, 0, 2) === 'im') {
1917 $form->add('text', $name, $title, $attributes, $required);
1920 if (substr($name, -1) == ']') {
1921 $providerName = substr($name, 0, -1) . '-provider_id]';
1923 $form->add('select', $providerName, NULL,
1925 '' => ts('- select -')
1926 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1930 $form->add('select', $name . '-provider_id', $title,
1932 '' => ts('- select -')
1933 ) + CRM_Core_PseudoConstant
::get('CRM_Core_DAO_IM', 'provider_id'), $required
1937 if ($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) {
1938 $form->freeze($name . '-provider_id');
1942 elseif (($fieldName === 'birth_date') ||
($fieldName === 'deceased_date')) {
1943 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1945 elseif (in_array($fieldName, array(
1946 'membership_start_date',
1947 'membership_end_date',
1950 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1952 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_type') {
1953 list($orgInfo, $types) = CRM_Member_BAO_MembershipType
::getMembershipTypeInfo();
1954 $sel = &$form->addElement('hierselect', $name, $title);
1955 $select = array('' => ts('- select -'));
1956 if (count($orgInfo) == 1 && $field['is_required']) {
1957 // we only have one org - so we should default to it. Not sure about defaulting to first type
1958 // as it could be missed - so adding a select
1959 // however, possibly that is more similar to the membership form
1960 if (count($types[1]) > 1) {
1961 $types[1] = $select +
$types[1];
1965 $orgInfo = $select +
$orgInfo;
1967 $sel->setOptions(array($orgInfo, $types));
1969 elseif (CRM_Utils_Array
::value('name', $field) == 'membership_status') {
1970 $form->add('select', $name, $title,
1972 '' => ts('- select -')
1973 ) + CRM_Member_PseudoConstant
::membershipStatus(NULL, NULL, 'label'), $required
1976 elseif (in_array($fieldName, array('gender_id', 'communication_style_id'))) {
1978 $pseudoValues = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', $fieldName);
1979 foreach ($pseudoValues as $key => $var) {
1980 $options[$key] = $form->createElement('radio', NULL, ts($title), $var, $key);
1982 $group = $form->addGroup($options, $name, $title);
1984 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1987 $group->setAttribute('allowClear', TRUE);
1990 elseif ($fieldName === 'prefix_id' ||
$fieldName === 'suffix_id') {
1991 $form->addSelect($name, array(
1993 'entity' => 'contact',
1994 'field' => $fieldName,
1996 'placeholder' => '',
1999 elseif ($fieldName === 'contact_sub_type') {
2000 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2001 if ($usedFor == 'onbehalf') {
2002 $profileType = 'Organization';
2004 elseif ($usedFor == 'honor') {
2005 $profileType = CRM_Core_BAO_UFField
::getProfileType($form->_params
['honoree_profile_id']);
2008 $profileType = $gId ? CRM_Core_BAO_UFField
::getProfileType($gId) : NULL;
2009 if ($profileType == 'Contact') {
2010 $profileType = 'Individual';
2014 $setSubtype = FALSE;
2015 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2016 $setSubtype = $profileType;
2017 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2020 $subtypes = $profileType ? CRM_Contact_BAO_ContactType
::subTypePairs($profileType) : array();
2023 $subtypeList = array();
2024 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
2027 $subtypeList = $subtypes;
2030 $sel = $form->add('select', $name, $title, $subtypeList, $required);
2031 $sel->setMultiple(TRUE);
2033 elseif (in_array($fieldName, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2034 //add email greeting, postal greeting, addressee, CRM-4575
2035 $gId = $form->get('gid') ?
$form->get('gid') : CRM_Utils_Array
::value('group_id', $field);
2036 $profileType = CRM_Core_BAO_UFField
::getProfileType($gId, TRUE, FALSE, TRUE);
2038 if (empty($profileType) ||
in_array($profileType, array(
2045 $profileType = 'Individual';
2047 if (CRM_Contact_BAO_ContactType
::isaSubType($profileType)) {
2048 $profileType = CRM_Contact_BAO_ContactType
::getBasicType($profileType);
2051 'contact_type' => $profileType,
2052 'greeting_type' => $fieldName,
2054 $form->add('select', $name, $title,
2056 '' => ts('- select -')
2057 ) + CRM_Core_PseudoConstant
::greeting($greeting), $required
2059 // add custom greeting element
2060 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
2064 elseif ($fieldName === 'preferred_communication_method') {
2065 $communicationFields = CRM_Core_PseudoConstant
::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
2066 foreach ($communicationFields as $key => $var) {
2070 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
2072 $form->addGroup($communicationOptions, $name, $title, '<br/>');
2074 elseif ($fieldName === 'preferred_mail_format') {
2075 $form->add('select', $name, $title, CRM_Core_SelectValues
::pmf());
2077 elseif ($fieldName === 'preferred_language') {
2078 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact
::buildOptions('preferred_language'));
2080 elseif ($fieldName == 'external_identifier') {
2081 $form->add('text', $name, $title, $attributes, $required);
2082 $contID = $contactId;
2084 $contID = $form->get('id');
2086 $form->addRule($name,
2087 ts('External ID already exists in Database.'),
2089 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
2092 elseif ($fieldName === 'group') {
2093 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2094 CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
,
2099 elseif ($fieldName === 'tag') {
2100 CRM_Contact_Form_Edit_TagsAndGroups
::buildQuickForm($form, $contactId,
2101 CRM_Contact_Form_Edit_TagsAndGroups
::TAG
,
2106 elseif (substr($fieldName, 0, 4) === 'url-') {
2107 $form->add('text', $name, $title,
2108 array_merge(CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Website', 'url'),
2110 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
2111 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
2116 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2118 // Note should be rendered as textarea
2119 elseif (substr($fieldName, -4) == 'note') {
2120 $form->add('textarea', $name, $title, $attributes, $required);
2122 elseif (substr($fieldName, 0, 6) === 'custom') {
2123 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID($fieldName);
2124 if ($customFieldID) {
2125 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2128 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2129 list($fName, $locTypeId) = CRM_Utils_System
::explode('-', $fieldName, 2);
2130 $customFieldID = CRM_Core_BAO_CustomField
::getKeyID(substr($fName, 8));
2131 if ($customFieldID) {
2132 CRM_Core_BAO_CustomField
::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2135 elseif (in_array($fieldName, array(
2141 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2143 elseif ($fieldName == 'send_receipt') {
2144 $form->addElement('checkbox', $name, $title);
2146 elseif ($fieldName == 'soft_credit') {
2147 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
2148 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
2150 elseif ($fieldName == 'product_name') {
2151 list($products, $options) = CRM_Contribute_BAO_Premium
::getPremiumProductInfo();
2152 $sel = &$form->addElement('hierselect', $name, $title);
2154 '0' => ts('- select -')
2156 $sel->setOptions(array($products, $options));
2158 elseif ($fieldName == 'payment_instrument') {
2159 $form->add('select', $name, $title,
2160 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant
::paymentInstrument(), $required);
2162 elseif ($fieldName == 'financial_type') {
2163 $form->add('select', $name, $title,
2165 '' => ts('- select -')
2166 ) + CRM_Contribute_PseudoConstant
::financialType(), $required
2169 elseif ($fieldName == 'contribution_status_id') {
2170 $contributionStatuses = CRM_Contribute_PseudoConstant
::contributionStatus();
2171 $statusName = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
2177 unset($contributionStatuses[CRM_Utils_Array
::key($suppress, $statusName)]);
2180 $form->add('select', $name, $title,
2182 '' => ts('- select -')
2183 ) +
$contributionStatuses, $required
2186 elseif ($fieldName == 'soft_credit_type') {
2187 $name = "soft_credit_type[$rowNumber]";
2188 $form->add('select', $name, $title,
2190 '' => ts('- select -')
2191 ) + CRM_Core_OptionGroup
::values("soft_credit_type")
2193 //CRM-15350: choose SCT field default value as 'Gift' for membership use
2194 //else (for contribution), use configured SCT default value
2195 $SCTDefaultValue = CRM_Core_OptionGroup
::getDefaultValue("soft_credit_type");
2196 if ($field['field_type'] == 'Membership') {
2197 $SCTDefaultValue = CRM_Core_OptionGroup
::getValue('soft_credit_type', 'Gift', 'name');
2199 $form->addElement('hidden', 'sct_default_id', $SCTDefaultValue, array('id' => 'sct_default_id'));
2201 elseif ($fieldName == 'currency') {
2202 $form->addCurrency($name, $title, $required);
2204 elseif ($fieldName == 'contribution_page_id') {
2205 $form->add('select', $name, $title,
2207 '' => ts('- select -')
2208 ) + CRM_Contribute_PseudoConstant
::contributionPage(), $required, 'class="big"'
2211 elseif ($fieldName == 'participant_register_date') {
2212 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2214 elseif ($fieldName == 'activity_status_id') {
2215 $form->add('select', $name, $title,
2217 '' => ts('- select -')
2218 ) + CRM_Core_PseudoConstant
::activityStatus(), $required
2221 elseif ($fieldName == 'activity_engagement_level') {
2222 $form->add('select', $name, $title,
2224 '' => ts('- select -')
2225 ) + CRM_Campaign_PseudoConstant
::engagementLevel(), $required
2228 elseif ($fieldName == 'activity_date_time') {
2229 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2231 elseif ($fieldName == 'participant_status') {
2233 if ($online == TRUE) {
2234 $cond = 'visibility_id = 1';
2236 $form->add('select', $name, $title,
2238 '' => ts('- select -')
2239 ) + CRM_Event_PseudoConstant
::participantStatus(NULL, $cond, 'label'), $required
2242 elseif ($fieldName == 'participant_role') {
2243 if (!empty($field['is_multiple'])) {
2244 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant
::participantRole(), NULL, NULL, NULL, NULL, ' ', TRUE);
2247 $form->add('select', $name, $title,
2249 '' => ts('- select -')
2250 ) + CRM_Event_PseudoConstant
::participantRole(), $required
2254 elseif ($fieldName == 'world_region') {
2255 $form->add('select', $name, $title, CRM_Core_PseudoConstant
::worldRegion(), $required, $selectAttributes);
2257 elseif ($fieldName == 'signature_html') {
2258 $form->addWysiwyg($name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2260 elseif ($fieldName == 'signature_text') {
2261 $form->add('textarea', $name, $title, CRM_Core_DAO
::getAttribute('CRM_Core_DAO_Email', $fieldName));
2263 elseif (substr($fieldName, -11) == 'campaign_id') {
2264 if (CRM_Campaign_BAO_Campaign
::isCampaignEnable()) {
2265 $campaigns = CRM_Campaign_BAO_Campaign
::getCampaigns(CRM_Utils_Array
::value($contactId,
2266 $form->_componentCampaigns
2268 $form->add('select', $name, $title,
2270 '' => ts('- select -')
2271 ) +
$campaigns, $required, 'class="crm-select2 big"'
2275 elseif ($fieldName == 'activity_details') {
2276 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2278 elseif ($fieldName == 'activity_duration') {
2279 $form->add('text', $name, $title, $attributes, $required);
2280 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2283 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2284 $form->add('advcheckbox', $name, $title, $attributes, $required);
2287 $form->add('text', $name, $title, $attributes, $required);
2291 static $hiddenSubtype = FALSE;
2292 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType
::isaSubType($field['field_type'])) {
2293 // In registration mode params are submitted via POST and we don't have any clue
2294 // about profile-id or the profile-type (which could be a subtype)
2295 // To generalize the behavior and simplify the process,
2296 // lets always add the hidden
2297 //subtype value if there is any, and we won't have to
2298 // compute it while processing.
2300 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
2303 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2305 $hiddenSubtype = TRUE;
2308 if (($view && $mode != CRM_Profile_Form
::MODE_SEARCH
) ||
$isShared) {
2309 $form->freeze($name);
2313 if (in_array($fieldName, array(
2314 'non_deductible_amount',
2319 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2322 if (!($rule == 'email' && $mode == CRM_Profile_Form
::MODE_SEARCH
)) {
2323 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2329 * Set profile defaults
2331 * @param int $contactId
2333 * @param array $fields
2334 * Associative array of fields.
2335 * @param array $defaults
2337 * @param bool $singleProfile
2338 * True for single profile else false(batch update).
2339 * @param int $componentId
2340 * Id for specific components like contribute, event etc.
2341 * @param null $component
2346 static function setProfileDefaults(
2347 $contactId, &$fields, &$defaults,
2348 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2350 if (!$componentId) {
2351 //get the contact details
2352 list($contactDetails, $options) = CRM_Contact_BAO_Contact
::getHierContactDetails($contactId, $fields);
2353 $details = CRM_Utils_Array
::value($contactId, $contactDetails);
2354 $multipleFields = array('website' => 'url');
2356 //start of code to set the default values
2357 foreach ($fields as $name => $field) {
2358 // skip pseudo fields
2359 if (substr($name, 0, 9) == 'phone_ext') {
2363 //set the field name depending upon the profile mode(single/batch)
2364 if ($singleProfile) {
2368 $fldName = "field[$contactId][$name]";
2371 if ($name == 'group') {
2372 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::GROUP
, $fldName);
2374 if ($name == 'tag') {
2375 CRM_Contact_Form_Edit_TagsAndGroups
::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups
::TAG
, $fldName);
2378 if (!empty($details[$name]) ||
isset($details[$name])) {
2379 //to handle custom data (checkbox) to be written
2380 // to handle birth/deceased date, greeting_type and few other fields
2381 if (($name == 'birth_date') ||
($name == 'deceased_date')) {
2382 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], 'birth');
2384 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)) {
2385 $defaults[$fldName] = $details[$name . '_id'];
2386 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2388 elseif ($name == 'preferred_communication_method') {
2389 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2390 foreach ($v as $item) {
2392 $defaults[$fldName . "[$item]"] = 1;
2396 elseif ($name == 'contact_sub_type') {
2397 $defaults[$fldName] = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, trim($details[$name], CRM_Core_DAO
::VALUE_SEPARATOR
));
2399 elseif ($name == 'world_region') {
2400 $defaults[$fldName] = $details['worldregion_id'];
2402 elseif ($customFieldId = CRM_Core_BAO_CustomField
::getKeyID($name)) {
2403 //fix for custom fields
2404 $customFields = CRM_Core_BAO_CustomField
::getFields(CRM_Utils_Array
::value('contact_type', $details));
2406 // hack to add custom data for components
2407 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2408 foreach ($components as $value) {
2409 $customFields = CRM_Utils_Array
::crmArrayMerge($customFields,
2410 CRM_Core_BAO_CustomField
::getFieldsForImport($value)
2414 switch ($customFields[$customFieldId]['html_type']) {
2415 case 'Multi-Select State/Province':
2416 case 'Multi-Select Country':
2417 case 'AdvMulti-Select':
2418 case 'Multi-Select':
2419 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2420 foreach ($v as $item) {
2422 $defaults[$fldName][$item] = $item;
2428 $v = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $details[$name]);
2429 foreach ($v as $item) {
2431 $defaults[$fldName][$item] = 1;
2432 // seems like we need this for QF style checkboxes in profile where its multiindexed
2434 $defaults["{$fldName}[{$item}]"] = 1;
2440 // CRM-6681, set defult values according to date and time format (if any).
2442 if (!empty($customFields[$customFieldId]['date_format'])) {
2443 $dateFormat = $customFields[$customFieldId]['date_format'];
2446 if (empty($customFields[$customFieldId]['time_format'])) {
2447 list($defaults[$fldName]) = CRM_Utils_Date
::setDateDefaults($details[$name], NULL,
2452 $timeElement = $fldName . '_time';
2453 if (substr($fldName, -1) == ']') {
2454 $timeElement = substr($fldName, 0, -1) . '_time]';
2456 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date
::setDateDefaults($details[$name],
2457 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
2462 $defaults[$fldName] = $details[$name];
2467 $defaults[$fldName] = $details[$name];
2471 $blocks = array('email', 'phone', 'im', 'openid');
2472 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System
::explode('-', $name, 3);
2473 if (!in_array($fieldName, $multipleFields)) {
2474 if (is_array($details)) {
2475 foreach ($details as $key => $value) {
2476 // when we fixed CRM-5319 - get primary loc
2477 // type as per loc field and removed below code.
2478 $primaryLocationType = FALSE;
2479 if ($locTypeId == 'Primary') {
2480 if (is_array($value) && array_key_exists($fieldName, $value)) {
2481 $primaryLocationType = TRUE;
2482 if (in_array($fieldName, $blocks)) {
2483 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, $fieldName);
2486 $locTypeId = CRM_Contact_BAO_Contact
::getPrimaryLocationType($contactId, FALSE, 'address');
2491 // fixed for CRM-665
2492 if (is_numeric($locTypeId)) {
2493 if ($primaryLocationType ||
$locTypeId == CRM_Utils_Array
::value('location_type_id', $value)) {
2494 if (!empty($value[$fieldName])) {
2495 //to handle stateprovince and country
2496 if ($fieldName == 'state_province') {
2497 $defaults[$fldName] = $value['state_province_id'];
2499 elseif ($fieldName == 'county') {
2500 $defaults[$fldName] = $value['county_id'];
2502 elseif ($fieldName == 'country') {
2503 if (!isset($value['country_id']) ||
!$value['country_id']) {
2504 $config = CRM_Core_Config
::singleton();
2505 if ($config->defaultContactCountry
) {
2506 $defaults[$fldName] = $config->defaultContactCountry
;
2510 $defaults[$fldName] = $value['country_id'];
2513 elseif ($fieldName == 'phone') {
2515 if (isset($value['phone'][$phoneTypeId])) {
2516 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2518 if (isset($value['phone_ext'][$phoneTypeId])) {
2519 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2523 $phoneDefault = CRM_Utils_Array
::value('phone', $value);
2525 if (!is_array($phoneDefault)) {
2526 $defaults[$fldName] = $phoneDefault;
2530 elseif ($fieldName == 'email') {
2531 //adding the first email (currently we don't support multiple emails of same location type)
2532 $defaults[$fldName] = $value['email'];
2534 elseif ($fieldName == 'im') {
2535 //adding the first im (currently we don't support multiple ims of same location type)
2536 $defaults[$fldName] = $value['im'];
2537 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2540 $defaults[$fldName] = $value[$fieldName];
2543 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2544 CRM_Utils_Array
::value(substr($fieldName, 8), $value)
2546 $defaults[$fldName] = $value[substr($fieldName, 8)];
2554 if (is_array($details)) {
2555 if ($fieldName === 'url'
2556 && !empty($details['website'])
2557 && !empty($details['website'][$locTypeId])
2559 $defaults[$fldName] = CRM_Utils_Array
::value('url', $details['website'][$locTypeId]);
2567 //Handling Contribution Part of the batch profile
2568 if (CRM_Core_Permission
::access('CiviContribute') && $component == 'Contribute') {
2569 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2572 //Handling Event Participation Part of the batch profile
2573 if (CRM_Core_Permission
::access('CiviEvent') && $component == 'Event') {
2574 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2577 //Handling membership Part of the batch profile
2578 if (CRM_Core_Permission
::access('CiviMember') && $component == 'Membership') {
2579 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2582 //Handling Activity Part of the batch profile
2583 if ($component == 'Activity') {
2584 self
::setComponentDefaults($fields, $componentId, $component, $defaults);
2589 * Get profiles by type eg: pure Individual etc
2591 * @param array $types
2592 * Associative array of types eg: types('Individual').
2593 * @param bool $onlyPure
2594 * True if only pure profiles are required.
2596 * @return array $profiles associative array of profiles
2599 public static function getProfiles($types, $onlyPure = FALSE) {
2600 $profiles = array();
2601 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2603 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2605 // Exclude Batch Data Entry profiles - CRM-10901
2606 $batchProfiles = CRM_Core_BAO_UFGroup
::getBatchProfiles();
2608 foreach ($ufGroups as $id => $title) {
2609 $ptype = CRM_Core_BAO_UFField
::getProfileType($id, FALSE, $onlyPure);
2610 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2611 $profiles[$id] = $title;
2618 * Check whether a profile is valid combination of
2619 * required and/or optional profile types
2621 * @param array $required
2622 * Array of types those are required.
2623 * @param array $optional
2624 * Array of types those are optional.
2626 * @return array $profiles associative array of profiles
2629 public static function getValidProfiles($required, $optional = NULL) {
2630 if (!is_array($required) ||
empty($required)) {
2634 $profiles = array();
2635 $ufGroups = CRM_Core_PseudoConstant
::get('CRM_Core_DAO_UFField', 'uf_group_id');
2637 CRM_Utils_Hook
::aclGroup(CRM_Core_Permission
::ADMIN
, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2639 foreach ($ufGroups as $id => $title) {
2640 $type = CRM_Core_BAO_UFField
::checkValidProfileType($id, $required, $optional);
2642 $profiles[$id] = $title;
2650 * Check whether a profile is valid combination of
2651 * required profile fields
2653 * @param array $ufId
2654 * Integer id of the profile.
2655 * @param array $required
2656 * Array of fields those are required in the profile.
2658 * @return array $profiles associative array of profiles
2661 public static function checkValidProfile($ufId, $required = NULL) {
2662 $validProfile = FALSE;
2664 return $validProfile;
2667 if (!CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2668 return $validProfile;
2671 $profileFields = self
::getFields($ufId, FALSE, CRM_Core_Action
::VIEW
, NULL,
2672 NULL, FALSE, NULL, FALSE, NULL,
2673 CRM_Core_Permission
::CREATE
, NULL
2676 $validProfile = array();
2677 if (!empty($profileFields)) {
2678 $fields = array_keys($profileFields);
2679 foreach ($fields as $val) {
2680 foreach ($required as $key => $field) {
2681 if (strpos($val, $field) === 0) {
2682 unset($required[$key]);
2687 $validProfile = (empty($required)) ?
TRUE : FALSE;
2690 return $validProfile;
2694 * Get default value for Register.
2699 * @return mixed $defaults@static
2701 public static function setRegisterDefaults(&$fields, &$defaults) {
2702 $config = CRM_Core_Config
::singleton();
2703 foreach ($fields as $name => $field) {
2704 if (substr($name, 0, 8) == 'country-') {
2705 if (!empty($config->defaultContactCountry
)) {
2706 $defaults[$name] = $config->defaultContactCountry
;
2709 elseif (substr($name, 0, 15) == 'state_province-') {
2710 if (!empty($config->defaultContactStateProvince
)) {
2711 $defaults[$name] = $config->defaultContactStateProvince
;
2719 * This function is to make a copy of a profile, including
2720 * all the fields in the profile
2723 * The profile id to copy.
2727 public static function copy($id) {
2728 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2729 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2735 if ($pos = strrpos($copy->name
, "_{$id}")) {
2736 $copy->name
= substr_replace($copy->name
, '', $pos);
2738 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2741 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2742 array('uf_group_id' => $id),
2743 array('uf_group_id' => $copy->id
),
2748 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2749 array('uf_group_id' => $id),
2750 array('uf_group_id' => $copy->id
)
2753 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2757 UPDATE civicrm_uf_join
2759 WHERE uf_group_id = %2
2760 AND ( entity_id IS NULL OR entity_id <= 0 )
2763 1 => array($maxWeight +
1, 'Integer'),
2764 2 => array($copy->id
, 'Integer'),
2766 CRM_Core_DAO
::executeQuery($query, $p);
2767 if ($copy->is_reserved
) {
2768 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2769 $params = array(1 => array($copy->id
, 'Integer'));
2770 CRM_Core_DAO
::executeQuery($query, $params);
2772 CRM_Utils_Hook
::copy('UFGroup', $copy);
2778 * Process that send notification e-mails
2780 * @param int $contactID
2782 * @param array $values
2783 * Associative array of name/value pair.
2788 public static function commonSendMail($contactID, &$values) {
2789 if (!$contactID ||
!$values) {
2793 $template = CRM_Core_Smarty
::singleton();
2795 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2800 self
::profileDisplay($values['id'], $values['values'], $template);
2801 $emailList = explode(',', $values['email']);
2803 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2804 "reset=1&cid=$contactID",
2805 TRUE, NULL, FALSE, FALSE, TRUE
2808 //get the default domain email address.
2809 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2811 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2812 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2813 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)));
2816 foreach ($emailList as $emailTo) {
2817 // FIXME: take the below out of the foreach loop
2818 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2820 'groupName' => 'msg_tpl_workflow_uf',
2821 'valueName' => 'uf_notify',
2822 'contactId' => $contactID,
2823 'tplParams' => array(
2824 'displayName' => $displayName,
2825 'currentDate' => date('r'),
2826 'contactLink' => $contactLink,
2828 'from' => "$domainEmailName <$domainEmailAddress>",
2829 'toEmail' => $emailTo,
2836 * Given a contact id and a group id, returns the field values from the db
2837 * for this group and notify email only if group's notify field is
2838 * set and field values are not empty
2844 * @param array $params
2845 * @param bool $skipCheck
2849 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2851 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2853 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2854 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2856 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2858 if (!empty($values) &&
2863 'values' => $values,
2874 * Assign uf fields to template
2878 * @param array $values
2879 * @param CRM_Core_Smarty $template
2883 public function profileDisplay($gid, $values, $template) {
2884 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2885 $template->assign('grouptitle', $groupTitle);
2886 if (count($values)) {
2887 $template->assign('values', $values);
2892 * Format fields for dupe Contact Matching
2894 * @param array $params
2897 * @param int $contactId
2899 * @return array $data assoicated formatted array
2902 public static function formatFields($params, $contactId = NULL) {
2904 // get the primary location type id and email
2905 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2908 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2909 $primaryLocationType = $defaultLocationType->id
;
2913 $locationType = array();
2915 $primaryLocation = 0;
2916 foreach ($params as $key => $value) {
2917 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2919 if ($locTypeId == 'Primary') {
2920 $locTypeId = $primaryLocationType;
2923 if (is_numeric($locTypeId)) {
2924 if (!in_array($locTypeId, $locationType)) {
2925 $locationType[$count] = $locTypeId;
2928 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2930 $data['location'][$loc]['location_type_id'] = $locTypeId;
2932 // if we are getting in a new primary email, dont overwrite the new one
2933 if ($locTypeId == $primaryLocationType) {
2934 if (!empty($params['email-' . $primaryLocationType])) {
2935 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2937 elseif (isset($primaryEmail)) {
2938 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2944 $data['location'][$loc]['is_primary'] = 1;
2946 if ($fieldName == 'phone') {
2948 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2951 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2953 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2955 elseif ($fieldName == 'email') {
2956 $data['location'][$loc]['email'][$loc]['email'] = $value;
2958 elseif ($fieldName == 'im') {
2959 $data['location'][$loc]['im'][$loc]['name'] = $value;
2962 if ($fieldName === 'state_province') {
2963 $data['location'][$loc]['address']['state_province_id'] = $value;
2965 elseif ($fieldName === 'country') {
2966 $data['location'][$loc]['address']['country_id'] = $value;
2969 $data['location'][$loc]['address'][$fieldName] = $value;
2974 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2975 if ($key === 'individual_suffix') {
2976 $data['suffix_id'] = $value;
2978 elseif ($key === 'individual_prefix') {
2979 $data['prefix_id'] = $value;
2981 elseif ($key === 'gender') {
2982 $data['gender_id'] = $value;
2984 elseif (substr($key, 0, 6) === 'custom') {
2985 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2987 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2988 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2990 // fix the date field
2991 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2992 $date = CRM_Utils_Date
::format($value);
2999 $data['custom'][$customFieldID] = array(
3002 'extends' => $customFields[$customFieldID]['extends'],
3003 'type' => $customFields[$customFieldID]['data_type'],
3004 'custom_field_id' => $customFieldID,
3008 elseif ($key == 'edit') {
3012 $data[$key] = $value;
3017 if (!$primaryLocation) {
3019 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
3026 * Calculate the profile type 'group_type' as per profile fields.
3030 * @param bool $includeTypeValues
3031 * @param int $ignoreFieldId
3032 * Ignore particular profile field.
3034 * @return array list of calculated group type
3036 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3037 //get the profile fields.
3038 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3039 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3043 * Calculate the profile type 'group_type' as per profile fields.
3046 * @param bool $includeTypeValues
3047 * @param int $ignoreFieldId
3048 * Ignore perticular profile field.
3050 * @return array list of calculated group type
3052 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3053 $groupType = $groupTypeValues = $customFieldIds = array();
3054 if (!empty($ufFields)) {
3055 foreach ($ufFields as $fieldName => $fieldValue) {
3056 //ignore field from group type when provided.
3057 //in case of update profile field.
3058 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3061 if (!in_array($fieldValue['field_type'], $groupType)) {
3062 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3065 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3066 $customFieldIds[$fldId] = $fldId;
3071 if (!empty($customFieldIds)) {
3072 $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) . ')';
3074 $customGroups = CRM_Core_DAO
::executeQuery($query);
3075 while ($customGroups->fetch()) {
3076 if (!$customGroups->extends_entity_column_value
) {
3080 $groupTypeName = "{$customGroups->extends}Type";
3081 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3082 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3085 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3087 $groupTypeValues[$groupTypeName][$val] = $val;
3092 if (!empty($groupTypeValues)) {
3093 $groupType = array_merge($groupType, $groupTypeValues);
3101 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3102 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3105 * BirthDate + Email Individual,Contact
3106 * BirthDate + Subject Individual,Activity
3107 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3108 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3109 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3110 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3111 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3112 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3113 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3116 * @param array $groupTypes
3117 * With key having group type names.
3121 public static function updateGroupTypes($gId, $groupTypes = array()) {
3122 if (!is_array($groupTypes) ||
!$gId) {
3126 // If empty group types set group_type as 'null'
3127 if (empty($groupTypes)) {
3128 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3131 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3132 $validGroupTypes = array_merge(array(
3137 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3139 $gTypes = $gTypeValues = array();
3141 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3142 // Get valid group type and group subtypes
3143 foreach ($groupTypes as $groupType => $value) {
3144 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3145 $gTypes[] = $groupType;
3150 if (in_array($groupType, $participantExtends)) {
3151 $subTypesOf = $groupType;
3153 elseif (strpos($groupType, 'Type') > 0) {
3154 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3160 if (!empty($value) &&
3161 (in_array($subTypesOf, $componentGroupTypes) ||
3162 in_array($subTypesOf, $participantExtends)
3165 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3169 if (empty($gTypes)) {
3173 // Build String to store group types and group subtypes
3174 $groupTypeString = implode(',', $gTypes);
3175 if (!empty($gTypeValues)) {
3176 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3179 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3183 * Create a "group_type" string
3185 * @param array $coreTypes
3186 * E.g. array('Individual','Contact','Student').
3187 * @param array $subTypes
3188 * E.g. array('ActivityType' => array(7, 11)).
3189 * @param string $delim
3192 * @throws CRM_Core_Exception
3194 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3195 $groupTypeExpr = '';
3197 $groupTypeExpr .= implode(',', $coreTypes);
3200 //CRM-15427 Allow Multiple subtype filtering
3201 //if (count($subTypes) > 1) {
3202 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3204 foreach ($subTypes as $subType => $subTypeIds) {
3205 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3208 return $groupTypeExpr;
3212 * This function is used to setDefault componet specific profile fields.
3214 * @param array $fields
3216 * @param int $componentId
3218 * @param string $component
3220 * @param array $defaults
3221 * An array of default values.
3223 * @param bool $isStandalone
3227 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3228 if (!$componentId ||
3229 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3234 $componentBAO = $componentSubType = NULL;
3235 switch ($component) {
3237 $componentBAO = 'CRM_Member_BAO_Membership';
3238 $componentBAOName = 'Membership';
3239 $componentSubType = array('membership_type_id');
3243 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3244 $componentBAOName = 'Contribution';
3245 $componentSubType = array('financial_type_id');
3249 $componentBAO = 'CRM_Event_BAO_Participant';
3250 $componentBAOName = 'Participant';
3251 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3255 $componentBAO = 'CRM_Activity_BAO_Activity';
3256 $componentBAOName = 'Activity';
3257 $componentSubType = array('activity_type_id');
3262 $params = array('id' => $componentId);
3264 //get the component values.
3265 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3266 if ($componentBAOName == 'Participant') {
3267 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3270 $formattedGroupTree = array();
3271 $dateTimeFields = array(
3272 'participant_register_date',
3273 'activity_date_time',
3278 'membership_start_date',
3279 'membership_end_date',
3282 foreach ($fields as $name => $field) {
3283 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3284 if (in_array($name, $dateTimeFields)) {
3285 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3286 if (!empty($values[$name])) {
3287 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3290 elseif (array_key_exists($name, $values)) {
3291 $defaults[$fldName] = $values[$name];
3293 elseif ($name == 'participant_note') {
3294 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3295 $defaults[$fldName] = array_pop($noteDetails);
3297 elseif (in_array($name, array(
3299 'payment_instrument',
3300 'participant_status',
3303 $defaults[$fldName] = $values["{$name}_id"];
3305 elseif ($name == 'membership_type') {
3306 // since membership_type field is a hierselect -
3307 $defaults[$fldName][0] =
3308 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3309 $defaults[$fldName][1] = $values['membership_type_id'];
3311 elseif ($name == 'membership_status') {
3312 $defaults[$fldName] = $values['status_id'];
3314 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3315 if (empty($formattedGroupTree)) {
3316 //get the groupTree as per subTypes.
3317 $groupTree = array();
3318 foreach ($componentSubType as $subType) {
3319 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3320 $componentId, 0, $values[$subType]
3322 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3324 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3325 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3328 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3329 foreach ($defaults as $customKey => $customValue) {
3330 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3331 if ($name == 'custom_' . $customFieldDetails[0]) {
3333 //hack to set default for checkbox
3334 //basically this is for weired field name like field[33][custom_19]
3335 //we are converting this field name to array structure and assign value.
3338 foreach ($formattedGroupTree as $tree) {
3339 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3340 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3342 $defaults['field'][$componentId][$name] = $customValue;
3345 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3348 // CRM-6681, $default contains formatted date, time values.
3349 $defaults[$fldName] = $customValue;
3350 if (!empty($defaults[$customKey . '_time'])) {
3351 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3357 if (!$skipValue ||
$isStandalone) {
3358 $defaults[$fldName] = $customValue;
3360 unset($defaults[$customKey]);
3370 * @param array|string $profiles - name of profile(s) to create links for
3371 * @param array $appendProfiles
3372 * Name of profile(s) to append to each link.
3376 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3377 // Default to contact profiles
3379 $profiles = array('new_individual', 'new_organization', 'new_household');
3381 $profiles = (array) $profiles;
3382 $toGet = array_merge($profiles, (array) $appendProfiles);
3383 $retrieved = civicrm_api3('uf_group', 'get', array(
3384 'name' => array('IN' => $toGet),
3387 $links = $append = array();
3388 if (!empty($retrieved['values'])) {
3389 foreach ($retrieved['values'] as $id => $profile) {
3390 if (in_array($profile['name'], $profiles)) {
3392 'label' => $profile['title'],
3393 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3394 NULL, NULL, FALSE, FALSE, TRUE),
3395 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3402 foreach ($append as $id) {
3403 foreach ($links as &$link) {
3404 $link['url'] .= ",$id";
3412 * Retrieve groups of profiles
3414 * @param int $profileID
3415 * Id of the profile.
3417 * @return array returns array
3420 public static function profileGroups($profileID) {
3421 $groupTypes = array();
3422 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3423 if ($profileTypes) {
3424 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3425 $groupTypes = explode(',', $groupTypeParts[0]);
3431 * Alter contact params by filtering existing subscribed groups and returns
3432 * unsubscribed groups array for subscription.
3434 * @param array $params
3436 * @param int $contactId
3439 * @return array $subscribeGroupIds This contains array of groups for subscription
3441 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3442 $config = CRM_Core_Config
::singleton();
3443 $subscribeGroupIds = array();
3445 // process further only if profileDoubleOptIn enabled and if groups exist
3446 if (!array_key_exists('group', $params) ||
3447 !self
::isProfileDoubleOptin() ||
3448 CRM_Utils_System
::isNull($params['group'])
3450 return $subscribeGroupIds;
3453 //check if contact email exist.
3455 foreach ($params as $name => $value) {
3456 if (strpos($name, 'email-') !== FALSE) {
3462 //Proceed furthur only if email present
3464 return $subscribeGroupIds;
3467 //do check for already subscriptions.
3468 $contactGroups = array();
3472 FROM civicrm_group_contact
3473 WHERE status = 'Added'
3474 AND contact_id = %1";
3476 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3477 while ($dao->fetch()) {
3478 $contactGroups[$dao->group_id
] = $dao->group_id
;
3482 //since we don't have names, compare w/ label.
3483 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3485 //actual processing start.
3486 foreach ($params['group'] as $groupId => $isSelected) {
3487 //unset group those are not selected.
3489 unset($params['group'][$groupId]);
3493 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3494 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3496 //get only mailing type group and unset it from params
3497 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3498 $subscribeGroupIds[$groupId] = $groupId;
3499 unset($params['group'][$groupId]);
3503 return $subscribeGroupIds;
3507 * Check if we are rendering mixed profiles
3509 * @param array $profileIds
3510 * Associated array of profile ids.
3512 * @return boolean $mixProfile true if profile is mixed
3515 public static function checkForMixProfiles($profileIds) {
3516 $mixProfile = FALSE;
3518 $contactTypes = array('Individual', 'Household', 'Organization');
3519 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3521 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3523 $typeCount = array('ctype' => array(), 'subtype' => array());
3524 foreach ($profileIds as $gid) {
3525 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3526 // ignore profile of type Contact
3527 if ($profileType == 'Contact') {
3530 if (in_array($profileType, $contactTypes)) {
3531 if (!isset($typeCount['ctype'][$profileType])) {
3532 $typeCount['ctype'][$profileType] = 1;
3535 // check if we are rendering profile of different contact types
3536 if (count($typeCount['ctype']) == 2) {
3541 elseif (in_array($profileType, $components)) {
3546 if (!isset($typeCount['subtype'][$profileType])) {
3547 $typeCount['subtype'][$profileType] = 1;
3549 // check if we are rendering profile of different contact sub types
3550 if (count($typeCount['subtype']) == 2) {
3560 * Determine of we show overlay profile or not
3562 * @return boolean true if profile should be shown else false
3565 public static function showOverlayProfile() {
3566 $showOverlay = TRUE;
3568 // get the id of overlay profile
3569 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3570 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3572 $count = CRM_Core_DAO
::singleValueQuery($query);
3574 //check if there are no public fields and use is anonymous
3575 $session = CRM_Core_Session
::singleton();
3576 if (!$count && !$session->get('userID')) {
3577 $showOverlay = FALSE;
3580 return $showOverlay;
3584 * Get group type values of the profile
3586 * @param int $profileId
3587 * @param string $groupType
3589 * @return Array group type values
3592 public static function groupTypeValues($profileId, $groupType = NULL) {
3593 $groupTypeValue = array();
3594 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3596 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3597 if (empty($groupTypeParts[1])) {
3598 return $groupTypeValue;
3600 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3602 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3604 $valueParts = explode(':', $groupTypeValues);
3606 ($valueParts[0] != "{$groupType}Type" ||
3607 ($groupType == 'Participant' &&
3608 !in_array($valueParts[0], $participantExtends)
3614 foreach ($valueParts as $val) {
3615 if (CRM_Utils_Rule
::integer($val)) {
3616 $values[$val] = $val;
3619 if (!empty($values)) {
3620 $typeName = substr($valueParts[0], 0, -4);
3621 if (in_array($valueParts[0], $participantExtends)) {
3622 $typeName = $valueParts[0];
3624 $groupTypeValue[$typeName] = $values;
3628 return $groupTypeValue;
3632 * @return bool|object
3634 public static function isProfileDoubleOptin() {
3635 // check for double optin
3636 $config = CRM_Core_Config
::singleton();
3637 if (in_array('CiviMail', $config->enableComponents
)) {
3638 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3639 'profile_double_optin', NULL, FALSE
3646 * @return bool|object
3648 public static function isProfileAddToGroupDoubleOptin() {
3649 // check for add to group double optin
3650 $config = CRM_Core_Config
::singleton();
3651 if (in_array('CiviMail', $config->enableComponents
)) {
3652 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3653 'profile_add_to_group_double_optin', NULL, FALSE
3660 * Get profiles used for batch entry
3662 * @return array profileIds profile ids
3665 public static function getBatchProfiles() {
3667 FROM civicrm_uf_group
3668 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3669 $dao = CRM_Core_DAO
::executeQuery($query);
3670 $profileIds = array();
3671 while ($dao->fetch()) {
3672 $profileIds[$dao->id
] = $dao->id
;
3678 * @todo what do I do?
3680 * @param $destination
3681 * @param bool $returnMultiSummaryFields
3683 * @return array|null
3685 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3686 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3687 foreach ($source as $field => $properties) {
3688 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3691 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3692 $destination[$field] = $properties;
3693 if ($returnMultiSummaryFields) {
3694 if ($properties['is_multi_summary']) {
3695 $multiSummaryFields[$field] = $properties;
3698 unset($source[$field]);
3701 return $multiSummaryFields;
3705 * This is function is used to format pseudo fields
3707 * @param array $fields
3708 * Associated array of profile fields.
3712 public static function reformatProfileFields(&$fields) {
3713 //reformat fields array
3714 foreach ($fields as $name => $field) {
3715 //reformat phone and extension field
3716 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3717 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3719 // retain existing element properties and just update and replace key
3720 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3721 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3722 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3724 // add additional phone extension field
3725 $fields["phone_ext-{$fieldSuffix}"] = $field;
3726 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3727 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3728 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3729 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3730 //ignore required for extension field
3731 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;