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
2702 public static function setRegisterDefaults(&$fields, &$defaults) {
2703 $config = CRM_Core_Config
::singleton();
2704 foreach ($fields as $name => $field) {
2705 if (substr($name, 0, 8) == 'country-') {
2706 if (!empty($config->defaultContactCountry
)) {
2707 $defaults[$name] = $config->defaultContactCountry
;
2710 elseif (substr($name, 0, 15) == 'state_province-') {
2711 if (!empty($config->defaultContactStateProvince
)) {
2712 $defaults[$name] = $config->defaultContactStateProvince
;
2720 * make a copy of a profile, including
2721 * all the fields in the profile
2724 * The profile id to copy.
2728 public static function copy($id) {
2729 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2730 $copy = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFGroup',
2736 if ($pos = strrpos($copy->name
, "_{$id}")) {
2737 $copy->name
= substr_replace($copy->name
, '', $pos);
2739 $copy->name
= CRM_Utils_String
::munge($copy->name
, '_', 56) . "_{$copy->id}";
2742 $copyUFJoin = &CRM_Core_DAO
::copyGeneric('CRM_Core_DAO_UFJoin',
2743 array('uf_group_id' => $id),
2744 array('uf_group_id' => $copy->id
),
2749 $copyUFField = &CRM_Core_DAO
::copyGeneric('CRM_Core_BAO_UFField',
2750 array('uf_group_id' => $id),
2751 array('uf_group_id' => $copy->id
)
2754 $maxWeight = CRM_Utils_Weight
::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2758 UPDATE civicrm_uf_join
2760 WHERE uf_group_id = %2
2761 AND ( entity_id IS NULL OR entity_id <= 0 )
2764 1 => array($maxWeight +
1, 'Integer'),
2765 2 => array($copy->id
, 'Integer'),
2767 CRM_Core_DAO
::executeQuery($query, $p);
2768 if ($copy->is_reserved
) {
2769 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2770 $params = array(1 => array($copy->id
, 'Integer'));
2771 CRM_Core_DAO
::executeQuery($query, $params);
2773 CRM_Utils_Hook
::copy('UFGroup', $copy);
2779 * Process that send notification e-mails
2781 * @param int $contactID
2783 * @param array $values
2784 * Associative array of name/value pair.
2789 public static function commonSendMail($contactID, &$values) {
2790 if (!$contactID ||
!$values) {
2794 $template = CRM_Core_Smarty
::singleton();
2796 $displayName = CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Contact',
2801 self
::profileDisplay($values['id'], $values['values'], $template);
2802 $emailList = explode(',', $values['email']);
2804 $contactLink = CRM_Utils_System
::url('civicrm/contact/view',
2805 "reset=1&cid=$contactID",
2806 TRUE, NULL, FALSE, FALSE, TRUE
2809 //get the default domain email address.
2810 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain
::getNameAndEmail();
2812 if (!$domainEmailAddress ||
$domainEmailAddress == 'info@EXAMPLE.ORG') {
2813 $fixUrl = CRM_Utils_System
::url('civicrm/admin/domain', 'action=update&reset=1');
2814 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)));
2817 foreach ($emailList as $emailTo) {
2818 // FIXME: take the below out of the foreach loop
2819 CRM_Core_BAO_MessageTemplate
::sendTemplate(
2821 'groupName' => 'msg_tpl_workflow_uf',
2822 'valueName' => 'uf_notify',
2823 'contactId' => $contactID,
2824 'tplParams' => array(
2825 'displayName' => $displayName,
2826 'currentDate' => date('r'),
2827 'contactLink' => $contactLink,
2829 'from' => "$domainEmailName <$domainEmailAddress>",
2830 'toEmail' => $emailTo,
2837 * Given a contact id and a group id, returns the field values from the db
2838 * for this group and notify email only if group's notify field is
2839 * set and field values are not empty
2845 * @param array $params
2846 * @param bool $skipCheck
2850 public function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2852 if (CRM_Core_BAO_UFGroup
::filterUFGroups($gid, $cid) ||
$skipCheck) {
2854 $fields = CRM_Core_BAO_UFGroup
::getFields($gid, FALSE, CRM_Core_Action
::VIEW
);
2855 CRM_Core_BAO_UFGroup
::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2857 $email = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2859 if (!empty($values) &&
2864 'values' => $values,
2875 * Assign uf fields to template
2879 * @param array $values
2880 * @param CRM_Core_Smarty $template
2884 public function profileDisplay($gid, $values, $template) {
2885 $groupTitle = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2886 $template->assign('grouptitle', $groupTitle);
2887 if (count($values)) {
2888 $template->assign('values', $values);
2893 * Format fields for dupe Contact Matching
2895 * @param array $params
2898 * @param int $contactId
2900 * @return array $data assoicated formatted array
2903 public static function formatFields($params, $contactId = NULL) {
2905 // get the primary location type id and email
2906 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location
::getEmailDetails($contactId);
2909 $defaultLocationType = CRM_Core_BAO_LocationType
::getDefault();
2910 $primaryLocationType = $defaultLocationType->id
;
2914 $locationType = array();
2916 $primaryLocation = 0;
2917 foreach ($params as $key => $value) {
2918 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2920 if ($locTypeId == 'Primary') {
2921 $locTypeId = $primaryLocationType;
2924 if (is_numeric($locTypeId)) {
2925 if (!in_array($locTypeId, $locationType)) {
2926 $locationType[$count] = $locTypeId;
2929 $loc = CRM_Utils_Array
::key($locTypeId, $locationType);
2931 $data['location'][$loc]['location_type_id'] = $locTypeId;
2933 // if we are getting in a new primary email, dont overwrite the new one
2934 if ($locTypeId == $primaryLocationType) {
2935 if (!empty($params['email-' . $primaryLocationType])) {
2936 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2938 elseif (isset($primaryEmail)) {
2939 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2945 $data['location'][$loc]['is_primary'] = 1;
2947 if ($fieldName == 'phone') {
2949 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2952 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2954 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2956 elseif ($fieldName == 'email') {
2957 $data['location'][$loc]['email'][$loc]['email'] = $value;
2959 elseif ($fieldName == 'im') {
2960 $data['location'][$loc]['im'][$loc]['name'] = $value;
2963 if ($fieldName === 'state_province') {
2964 $data['location'][$loc]['address']['state_province_id'] = $value;
2966 elseif ($fieldName === 'country') {
2967 $data['location'][$loc]['address']['country_id'] = $value;
2970 $data['location'][$loc]['address'][$fieldName] = $value;
2975 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
2976 if ($key === 'individual_suffix') {
2977 $data['suffix_id'] = $value;
2979 elseif ($key === 'individual_prefix') {
2980 $data['prefix_id'] = $value;
2982 elseif ($key === 'gender') {
2983 $data['gender_id'] = $value;
2985 elseif (substr($key, 0, 6) === 'custom') {
2986 if ($customFieldID = CRM_Core_BAO_CustomField
::getKeyID($key)) {
2988 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2989 $value = implode(CRM_Core_DAO
::VALUE_SEPARATOR
, array_keys($value));
2991 // fix the date field
2992 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2993 $date = CRM_Utils_Date
::format($value);
3000 $data['custom'][$customFieldID] = array(
3003 'extends' => $customFields[$customFieldID]['extends'],
3004 'type' => $customFields[$customFieldID]['data_type'],
3005 'custom_field_id' => $customFieldID,
3009 elseif ($key == 'edit') {
3013 $data[$key] = $value;
3018 if (!$primaryLocation) {
3020 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
3027 * Calculate the profile type 'group_type' as per profile fields.
3031 * @param bool $includeTypeValues
3032 * @param int $ignoreFieldId
3033 * Ignore particular profile field.
3035 * @return array list of calculated group type
3037 public static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3038 //get the profile fields.
3039 $ufFields = self
::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
3040 return self
::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
3044 * Calculate the profile type 'group_type' as per profile fields.
3047 * @param bool $includeTypeValues
3048 * @param int $ignoreFieldId
3049 * Ignore perticular profile field.
3051 * @return array list of calculated group type
3053 public static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
3054 $groupType = $groupTypeValues = $customFieldIds = array();
3055 if (!empty($ufFields)) {
3056 foreach ($ufFields as $fieldName => $fieldValue) {
3057 //ignore field from group type when provided.
3058 //in case of update profile field.
3059 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
3062 if (!in_array($fieldValue['field_type'], $groupType)) {
3063 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
3066 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField
::getKeyID($fieldName))) {
3067 $customFieldIds[$fldId] = $fldId;
3072 if (!empty($customFieldIds)) {
3073 $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) . ')';
3075 $customGroups = CRM_Core_DAO
::executeQuery($query);
3076 while ($customGroups->fetch()) {
3077 if (!$customGroups->extends_entity_column_value
) {
3081 $groupTypeName = "{$customGroups->extends}Type";
3082 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id
) {
3083 $groupTypeName = CRM_Core_OptionGroup
::getValue('custom_data_type', $customGroups->extends_entity_column_id
, 'value', 'String', 'name');
3086 foreach (explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $customGroups->extends_entity_column_value
) as $val) {
3088 $groupTypeValues[$groupTypeName][$val] = $val;
3093 if (!empty($groupTypeValues)) {
3094 $groupType = array_merge($groupType, $groupTypeValues);
3102 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
3103 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
3106 * BirthDate + Email Individual,Contact
3107 * BirthDate + Subject Individual,Activity
3108 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
3109 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
3110 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
3111 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3112 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
3113 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
3114 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
3117 * @param array $groupTypes
3118 * With key having group type names.
3122 public static function updateGroupTypes($gId, $groupTypes = array()) {
3123 if (!is_array($groupTypes) ||
!$gId) {
3127 // If empty group types set group_type as 'null'
3128 if (empty($groupTypes)) {
3129 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3132 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
3133 $validGroupTypes = array_merge(array(
3138 ), $componentGroupTypes, CRM_Contact_BAO_ContactType
::subTypes());
3140 $gTypes = $gTypeValues = array();
3142 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3143 // Get valid group type and group subtypes
3144 foreach ($groupTypes as $groupType => $value) {
3145 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3146 $gTypes[] = $groupType;
3151 if (in_array($groupType, $participantExtends)) {
3152 $subTypesOf = $groupType;
3154 elseif (strpos($groupType, 'Type') > 0) {
3155 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3161 if (!empty($value) &&
3162 (in_array($subTypesOf, $componentGroupTypes) ||
3163 in_array($subTypesOf, $participantExtends)
3166 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3170 if (empty($gTypes)) {
3174 // Build String to store group types and group subtypes
3175 $groupTypeString = implode(',', $gTypes);
3176 if (!empty($gTypeValues)) {
3177 $groupTypeString .= CRM_Core_DAO
::VALUE_SEPARATOR
. implode(',', $gTypeValues);
3180 return CRM_Core_DAO
::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3184 * Create a "group_type" string
3186 * @param array $coreTypes
3187 * E.g. array('Individual','Contact','Student').
3188 * @param array $subTypes
3189 * E.g. array('ActivityType' => array(7, 11)).
3190 * @param string $delim
3193 * @throws CRM_Core_Exception
3195 public static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO
::VALUE_SEPARATOR
) {
3196 $groupTypeExpr = '';
3198 $groupTypeExpr .= implode(',', $coreTypes);
3201 //CRM-15427 Allow Multiple subtype filtering
3202 //if (count($subTypes) > 1) {
3203 //throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3205 foreach ($subTypes as $subType => $subTypeIds) {
3206 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3209 return $groupTypeExpr;
3213 * setDefault componet specific profile fields.
3215 * @param array $fields
3217 * @param int $componentId
3219 * @param string $component
3221 * @param array $defaults
3222 * An array of default values.
3224 * @param bool $isStandalone
3228 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3229 if (!$componentId ||
3230 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3235 $componentBAO = $componentSubType = NULL;
3236 switch ($component) {
3238 $componentBAO = 'CRM_Member_BAO_Membership';
3239 $componentBAOName = 'Membership';
3240 $componentSubType = array('membership_type_id');
3244 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3245 $componentBAOName = 'Contribution';
3246 $componentSubType = array('financial_type_id');
3250 $componentBAO = 'CRM_Event_BAO_Participant';
3251 $componentBAOName = 'Participant';
3252 $componentSubType = array('role_id', 'event_id', 'event_type_id');
3256 $componentBAO = 'CRM_Activity_BAO_Activity';
3257 $componentBAOName = 'Activity';
3258 $componentSubType = array('activity_type_id');
3263 $params = array('id' => $componentId);
3265 //get the component values.
3266 CRM_Core_DAO
::commonRetrieve($componentBAO, $params, $values);
3267 if ($componentBAOName == 'Participant') {
3268 $values +
= array('event_type_id' => CRM_Core_DAO
::getFieldValue('CRM_Event_DAO_Event', $values['event_id'], 'event_type_id'));
3271 $formattedGroupTree = array();
3272 $dateTimeFields = array(
3273 'participant_register_date',
3274 'activity_date_time',
3279 'membership_start_date',
3280 'membership_end_date',
3283 foreach ($fields as $name => $field) {
3284 $fldName = $isStandalone ?
$name : "field[$componentId][$name]";
3285 if (in_array($name, $dateTimeFields)) {
3286 $timefldName = $isStandalone ?
"{$name}_time" : "field[$componentId][{$name}_time]";
3287 if (!empty($values[$name])) {
3288 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date
::setDateDefaults($values[$name]);
3291 elseif (array_key_exists($name, $values)) {
3292 $defaults[$fldName] = $values[$name];
3294 elseif ($name == 'participant_note') {
3295 $noteDetails = CRM_Core_BAO_Note
::getNote($componentId, 'civicrm_participant');
3296 $defaults[$fldName] = array_pop($noteDetails);
3298 elseif (in_array($name, array(
3300 'payment_instrument',
3301 'participant_status',
3304 $defaults[$fldName] = $values["{$name}_id"];
3306 elseif ($name == 'membership_type') {
3307 // since membership_type field is a hierselect -
3308 $defaults[$fldName][0] =
3309 CRM_Core_DAO
::getFieldValue('CRM_Member_DAO_MembershipType', $values['membership_type_id'], 'member_of_contact_id', 'id');
3310 $defaults[$fldName][1] = $values['membership_type_id'];
3312 elseif ($name == 'membership_status') {
3313 $defaults[$fldName] = $values['status_id'];
3315 elseif ($customFieldInfo = CRM_Core_BAO_CustomField
::getKeyID($name, TRUE)) {
3316 if (empty($formattedGroupTree)) {
3317 //get the groupTree as per subTypes.
3318 $groupTree = array();
3319 foreach ($componentSubType as $subType) {
3320 $subTree = CRM_Core_BAO_CustomGroup
::getTree($componentBAOName, CRM_Core_DAO
::$_nullObject,
3321 $componentId, 0, $values[$subType]
3323 $groupTree = CRM_Utils_Array
::crmArrayMerge($groupTree, $subTree);
3325 $formattedGroupTree = CRM_Core_BAO_CustomGroup
::formatGroupTree($groupTree, 1, CRM_Core_DAO
::$_nullObject);
3326 CRM_Core_BAO_CustomGroup
::setDefaults($formattedGroupTree, $defaults);
3329 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3330 foreach ($defaults as $customKey => $customValue) {
3331 if ($customFieldDetails = CRM_Core_BAO_CustomField
::getKeyID($customKey, TRUE)) {
3332 if ($name == 'custom_' . $customFieldDetails[0]) {
3334 //hack to set default for checkbox
3335 //basically this is for weired field name like field[33][custom_19]
3336 //we are converting this field name to array structure and assign value.
3339 foreach ($formattedGroupTree as $tree) {
3340 if (!empty($tree['fields'][$customFieldDetails[0]])) {
3341 if ('CheckBox' == CRM_Utils_Array
::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3343 $defaults['field'][$componentId][$name] = $customValue;
3346 elseif (CRM_Utils_Array
::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3349 // CRM-6681, $default contains formatted date, time values.
3350 $defaults[$fldName] = $customValue;
3351 if (!empty($defaults[$customKey . '_time'])) {
3352 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3358 if (!$skipValue ||
$isStandalone) {
3359 $defaults[$fldName] = $customValue;
3361 unset($defaults[$customKey]);
3371 * @param array|string $profiles - name of profile(s) to create links for
3372 * @param array $appendProfiles
3373 * Name of profile(s) to append to each link.
3377 public static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3378 // Default to contact profiles
3380 $profiles = array('new_individual', 'new_organization', 'new_household');
3382 $profiles = (array) $profiles;
3383 $toGet = array_merge($profiles, (array) $appendProfiles);
3384 $retrieved = civicrm_api3('uf_group', 'get', array(
3385 'name' => array('IN' => $toGet),
3388 $links = $append = array();
3389 if (!empty($retrieved['values'])) {
3390 foreach ($retrieved['values'] as $id => $profile) {
3391 if (in_array($profile['name'], $profiles)) {
3393 'label' => $profile['title'],
3394 'url' => CRM_Utils_System
::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3395 NULL, NULL, FALSE, FALSE, TRUE),
3396 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
3403 foreach ($append as $id) {
3404 foreach ($links as &$link) {
3405 $link['url'] .= ",$id";
3413 * Retrieve groups of profiles
3415 * @param int $profileID
3416 * Id of the profile.
3418 * @return array returns array
3421 public static function profileGroups($profileID) {
3422 $groupTypes = array();
3423 $profileTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3424 if ($profileTypes) {
3425 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $profileTypes);
3426 $groupTypes = explode(',', $groupTypeParts[0]);
3432 * Alter contact params by filtering existing subscribed groups and returns
3433 * unsubscribed groups array for subscription.
3435 * @param array $params
3437 * @param int $contactId
3440 * @return array $subscribeGroupIds This contains array of groups for subscription
3442 public static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3443 $config = CRM_Core_Config
::singleton();
3444 $subscribeGroupIds = array();
3446 // process further only if profileDoubleOptIn enabled and if groups exist
3447 if (!array_key_exists('group', $params) ||
3448 !self
::isProfileDoubleOptin() ||
3449 CRM_Utils_System
::isNull($params['group'])
3451 return $subscribeGroupIds;
3454 //check if contact email exist.
3456 foreach ($params as $name => $value) {
3457 if (strpos($name, 'email-') !== FALSE) {
3463 //Proceed furthur only if email present
3465 return $subscribeGroupIds;
3468 //do check for already subscriptions.
3469 $contactGroups = array();
3473 FROM civicrm_group_contact
3474 WHERE status = 'Added'
3475 AND contact_id = %1";
3477 $dao = CRM_Core_DAO
::executeQuery($query, array(1 => array($contactId, 'Integer')));
3478 while ($dao->fetch()) {
3479 $contactGroups[$dao->group_id
] = $dao->group_id
;
3483 //since we don't have names, compare w/ label.
3484 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup
::values('group_type'));
3486 //actual processing start.
3487 foreach ($params['group'] as $groupId => $isSelected) {
3488 //unset group those are not selected.
3490 unset($params['group'][$groupId]);
3494 $groupTypes = explode(CRM_Core_DAO
::VALUE_SEPARATOR
,
3495 CRM_Core_DAO
::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3497 //get only mailing type group and unset it from params
3498 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3499 $subscribeGroupIds[$groupId] = $groupId;
3500 unset($params['group'][$groupId]);
3504 return $subscribeGroupIds;
3508 * Check if we are rendering mixed profiles
3510 * @param array $profileIds
3511 * Associated array of profile ids.
3513 * @return boolean $mixProfile true if profile is mixed
3516 public static function checkForMixProfiles($profileIds) {
3517 $mixProfile = FALSE;
3519 $contactTypes = array('Individual', 'Household', 'Organization');
3520 $subTypes = CRM_Contact_BAO_ContactType
::subTypes();
3522 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3524 $typeCount = array('ctype' => array(), 'subtype' => array());
3525 foreach ($profileIds as $gid) {
3526 $profileType = CRM_Core_BAO_UFField
::getProfileType($gid);
3527 // ignore profile of type Contact
3528 if ($profileType == 'Contact') {
3531 if (in_array($profileType, $contactTypes)) {
3532 if (!isset($typeCount['ctype'][$profileType])) {
3533 $typeCount['ctype'][$profileType] = 1;
3536 // check if we are rendering profile of different contact types
3537 if (count($typeCount['ctype']) == 2) {
3542 elseif (in_array($profileType, $components)) {
3547 if (!isset($typeCount['subtype'][$profileType])) {
3548 $typeCount['subtype'][$profileType] = 1;
3550 // check if we are rendering profile of different contact sub types
3551 if (count($typeCount['subtype']) == 2) {
3561 * Determine of we show overlay profile or not
3563 * @return boolean true if profile should be shown else false
3566 public static function showOverlayProfile() {
3567 $showOverlay = TRUE;
3569 // get the id of overlay profile
3570 $overlayProfileId = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3571 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3573 $count = CRM_Core_DAO
::singleValueQuery($query);
3575 //check if there are no public fields and use is anonymous
3576 $session = CRM_Core_Session
::singleton();
3577 if (!$count && !$session->get('userID')) {
3578 $showOverlay = FALSE;
3581 return $showOverlay;
3585 * Get group type values of the profile
3587 * @param int $profileId
3588 * @param string $groupType
3590 * @return Array group type values
3593 public static function groupTypeValues($profileId, $groupType = NULL) {
3594 $groupTypeValue = array();
3595 $groupTypes = CRM_Core_DAO
::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3597 $groupTypeParts = explode(CRM_Core_DAO
::VALUE_SEPARATOR
, $groupTypes);
3598 if (empty($groupTypeParts[1])) {
3599 return $groupTypeValue;
3601 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3603 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3605 $valueParts = explode(':', $groupTypeValues);
3607 ($valueParts[0] != "{$groupType}Type" ||
3608 ($groupType == 'Participant' &&
3609 !in_array($valueParts[0], $participantExtends)
3615 foreach ($valueParts as $val) {
3616 if (CRM_Utils_Rule
::integer($val)) {
3617 $values[$val] = $val;
3620 if (!empty($values)) {
3621 $typeName = substr($valueParts[0], 0, -4);
3622 if (in_array($valueParts[0], $participantExtends)) {
3623 $typeName = $valueParts[0];
3625 $groupTypeValue[$typeName] = $values;
3629 return $groupTypeValue;
3633 * @return bool|object
3635 public static function isProfileDoubleOptin() {
3636 // check for double optin
3637 $config = CRM_Core_Config
::singleton();
3638 if (in_array('CiviMail', $config->enableComponents
)) {
3639 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3640 'profile_double_optin', NULL, FALSE
3647 * @return bool|object
3649 public static function isProfileAddToGroupDoubleOptin() {
3650 // check for add to group double optin
3651 $config = CRM_Core_Config
::singleton();
3652 if (in_array('CiviMail', $config->enableComponents
)) {
3653 return CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::MAILING_PREFERENCES_NAME
,
3654 'profile_add_to_group_double_optin', NULL, FALSE
3661 * Get profiles used for batch entry
3663 * @return array profileIds profile ids
3666 public static function getBatchProfiles() {
3668 FROM civicrm_uf_group
3669 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3670 $dao = CRM_Core_DAO
::executeQuery($query);
3671 $profileIds = array();
3672 while ($dao->fetch()) {
3673 $profileIds[$dao->id
] = $dao->id
;
3679 * @todo what do I do?
3681 * @param $destination
3682 * @param bool $returnMultiSummaryFields
3684 * @return array|null
3686 public static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3687 $multiSummaryFields = $returnMultiSummaryFields ?
array() : NULL;
3688 foreach ($source as $field => $properties) {
3689 if (!CRM_Core_BAO_CustomField
::getKeyID($field)) {
3692 if (CRM_Core_BAO_CustomField
::isMultiRecordField($field)) {
3693 $destination[$field] = $properties;
3694 if ($returnMultiSummaryFields) {
3695 if ($properties['is_multi_summary']) {
3696 $multiSummaryFields[$field] = $properties;
3699 unset($source[$field]);
3702 return $multiSummaryFields;
3706 * This is function is used to format pseudo fields
3708 * @param array $fields
3709 * Associated array of profile fields.
3713 public static function reformatProfileFields(&$fields) {
3714 //reformat fields array
3715 foreach ($fields as $name => $field) {
3716 //reformat phone and extension field
3717 if (substr($field['name'], 0, 13) == 'phone_and_ext') {
3718 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3720 // retain existing element properties and just update and replace key
3721 CRM_Utils_Array
::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3722 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3723 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3725 // add additional phone extension field
3726 $fields["phone_ext-{$fieldSuffix}"] = $field;
3727 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] . ' - ' . ts('Ext.');
3728 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3729 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3730 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3731 //ignore required for extension field
3732 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;