copyright and version fixes
[civicrm-core.git] / CRM / Core / BAO / UFGroup.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
06b69b18 4 | CiviCRM version 4.5 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
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. |
13 | |
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. |
18 | |
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 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 *
38 */
39class CRM_Core_BAO_UFGroup extends CRM_Core_DAO_UFGroup {
40 CONST PUBLIC_VISIBILITY = 1,
41 ADMIN_VISIBILITY = 2,
42 LISTINGS_VISIBILITY = 4;
43
44 /**
45 * cache the match clause used in this transaction
46 *
47 * @var string
48 */
49 static $_matchFields = NULL;
50
51 /**
52 * Takes a bunch of params that are needed to match certain criteria and
53 * retrieves the relevant objects. Typically the valid params are only
54 * contact_id. We'll tweak this function to be more full featured over a period
55 * of time. This is the inverse function of create. It also stores all the retrieved
56 * values in the default array
57 *
58 * @param array $params (reference) an assoc array of name/value pairs
59 * @param array $defaults (reference) an assoc array to hold the flattened values
60 *
61 * @return object CRM_Core_DAO_UFGroup object
62 * @access public
63 * @static
64 */
65 static function retrieve(&$params, &$defaults) {
66 return CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_UFGroup', $params, $defaults);
67 }
68
69 /**
70 * Retrieve the first non-generic contact type
71 *
72 * @param int $id id of uf_group
73 *
74 * @return string contact type
75 */
76 static function getContactType($id) {
77
78 $validTypes = array_filter(array_keys(CRM_Core_SelectValues::contactType()));
79 $validSubTypes = CRM_Contact_BAO_ContactType::subTypeInfo();
80
81 $typesParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'group_type'));
82 $types = explode(',', $typesParts[0]);
83
84 $cType = NULL;
85 foreach ($types as $type) {
86 if (in_array($type, $validTypes)) {
87 $cType = $type;
88 }
89 elseif (array_key_exists($type, $validSubTypes)) {
90 $cType = CRM_Utils_Array::value('parent', $validSubTypes[$type]);
91 }
92 if ($cType)
93 break;
94 }
95
96 return $cType;
97 }
98
99 /**
100 * Get the form title.
101 *
102 * @param int $id id of uf_form
103 *
104 * @return string title
105 *
106 * @access public
107 * @static
108 *
109 */
110 public static function getTitle($id) {
111 return CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $id, 'title');
112 }
113
114 /**
115 * update the is_active flag in the db
116 *
117 * @param int $id id of the database record
118 * @param boolean $is_active value we want to set the is_active field
119 *
120 * @return Object CRM_Core_DAO_UFGroup object on success, null otherwise
121 * @access public
122 * @static
123 */
124 static function setIsActive($id, $is_active) {
125 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $id, 'is_active', $is_active);
126 }
127
128 /**
129 * get all the registration fields
130 *
131 * @param int $action what action are we doing
132 * @param int $mode mode
133 *
134 * @return array the fields that are needed for registration
135 * @static
136 * @access public
137 */
138 static function getRegistrationFields($action, $mode, $ctype = NULL) {
139 if ($mode & CRM_Profile_Form::MODE_REGISTER) {
140 $ufGroups = CRM_Core_BAO_UFGroup::getModuleUFGroup('User Registration');
141 }
142 else {
143 $ufGroups = CRM_Core_BAO_UFGroup::getModuleUFGroup('Profile');
144 }
145
146 if (!is_array($ufGroups)) {
147 return FALSE;
148 }
149
150 $fields = array();
151
152 foreach ($ufGroups as $id => $title) {
153 if ($ctype) {
154 $fieldType = CRM_Core_BAO_UFField::getProfileType($id);
155 if (($fieldType != 'Contact') &&
156 ($fieldType != $ctype) &&
157 !CRM_Contact_BAO_ContactType::isExtendsContactType($fieldType, $ctype)
158 ) {
159 continue;
160 }
161 if (CRM_Contact_BAO_ContactType::isaSubType($fieldType)) {
162 $profileSubType = $fieldType;
163 }
164 }
165
166 $subset = self::getFields($id, TRUE, $action,
167 NULL, NULL, FALSE, NULL, TRUE, $ctype
168 );
169
170 // we do not allow duplicates. the first field is the winner
171 foreach ($subset as $name => $field) {
a7488080 172 if (empty($fields[$name])) {
6a488035
TO
173 $fields[$name] = $field;
174 }
175 }
176 }
177
178 return $fields;
179 }
180
181 /**
182 * get all the listing fields
183 *
184 * @param int $action what action are we doing
185 * @param int $visibility visibility of fields we are interested in
186 * @param bool $considerSelector whether to consider the in_selector parameter
187 * @param array $ufGroupIds
188 * @param boolean $searchable
189 *
190 * @return array the fields that are listings related
191 * @static
192 * @access public
193 */
194 static function getListingFields(
195 $action,
196 $visibility,
197 $considerSelector = FALSE,
198 $ufGroupIds = NULL,
199 $searchable = NULL,
200 $restrict = NULL,
201 $skipPermission = FALSE,
202 $permissionType = CRM_Core_Permission::SEARCH
203 ) {
204 if ($ufGroupIds) {
205 $subset = self::getFields($ufGroupIds, FALSE, $action,
206 $visibility, $searchable,
207 FALSE, $restrict,
208 $skipPermission,
209 NULL,
210 $permissionType
211 );
212 if ($considerSelector) {
213 // drop the fields not meant for the selector
214 foreach ($subset as $name => $field) {
215 if (!$field['in_selector']) {
216 unset($subset[$name]);
217 }
218 }
219 }
220 $fields = $subset;
221 }
222 else {
ff4f7744 223 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
224
225 $fields = array();
226 foreach ($ufGroups as $id => $title) {
227 $subset = self::getFields($id, FALSE, $action,
228 $visibility, $searchable,
229 FALSE, $restrict,
230 $skipPermission,
231 NULL,
232 $permissionType
233 );
234 if ($considerSelector) {
235 // drop the fields not meant for the selector
236 foreach ($subset as $name => $field) {
237 if (!$field['in_selector'])unset($subset[$name]);
238 }
239 }
240 $fields = array_merge($fields, $subset);
241 }
242 }
243 return $fields;
244 }
245
246 /**
247 * Get all the fields that belong to the group with the name title,
248 * and format for use with buildProfile. This is the SQL analog of
249 * formatUFFields().
250 *
251 * @param mix $id the id of the UF group or ids of ufgroup
252 * @param int $register are we interested in registration fields
253 * @param int $action what action are we doing
254 * @param int $visibility visibility of fields we are interested in
255 * @param $searchable
256 * @param boolean $showall
257 * @param string $restrict should we restrict based on a specified profile type
258 *
259 * @return array the fields that belong to this ufgroup(s)
260 * @static
261 * @access public
262 */
263 static function getFields(
264 $id,
265 $register = FALSE,
266 $action = NULL,
267 $visibility = NULL,
268 $searchable = NULL,
269 $showAll = FALSE,
270 $restrict = NULL,
271 $skipPermission = FALSE,
272 $ctype = NULL,
273 $permissionType = CRM_Core_Permission::CREATE,
274 $orderBy = 'field_name',
275 $orderProfiles = NULL
276 ) {
277 if (!is_array($id)) {
278 $id = CRM_Utils_Type::escape($id, 'Positive');
279 $profileIds = array($id);
280 }
281 else {
282 $profileIds = $id;
283 }
284
285 $gids = implode(',', $profileIds);
286 $params = array();
287 if ($restrict) {
288 $query = "SELECT g.* from civicrm_uf_group g, civicrm_uf_join j
289 WHERE g.id IN ( {$gids} )
290 AND j.uf_group_id IN ( {$gids} )
291 AND j.module = %1
292 ";
293 $params = array(1 => array($restrict, 'String'));
294 }
295 else {
296 $query = "SELECT g.* from civicrm_uf_group g WHERE g.id IN ( {$gids} ) ";
297 }
298
299 if (!$showAll) {
300 $query .= " AND g.is_active = 1";
301 }
302
303 // add permissioning for profiles only if not registration
304 if (!$skipPermission) {
305 $permissionClause = CRM_Core_Permission::ufGroupClause($permissionType, 'g.');
306 $query .= " AND $permissionClause ";
307 }
308
309 if ($orderProfiles AND count($profileIds) > 1) {
310 $query .= " ORDER BY FIELD( g.id, {$gids} )";
311 }
312 $group = CRM_Core_DAO::executeQuery($query, $params);
313 $fields = array();
314 $validGroup = FALSE;
315
316 while ($group->fetch()) {
317 $validGroup = TRUE;
318 $query = self::createUFFieldQuery($group->id, $searchable, $showAll, $visibility, $orderBy);
319 $field = CRM_Core_DAO::executeQuery($query);
320
321 $profileType = CRM_Core_BAO_UFField::getProfileType($group->id);
322 $contactActivityProfile = CRM_Core_BAO_UFField::checkContactActivityProfileType($group->id);
323 $importableFields = self::getImportableFields($showAll, $profileType, $contactActivityProfile);
324 list($customFields, $addressCustomFields) = self::getCustomFields($ctype);
325
326 while ($field->fetch()) {
327 list($name, $formattedField) = self::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
328 if ($formattedField !== NULL) {
329 $fields[$name] = $formattedField;
330 }
331 }
332 $field->free();
333 }
334
335 if (empty($fields) && !$validGroup) {
336 CRM_Core_Error::fatal(ts('The requested Profile (gid=%1) is disabled OR it is not configured to be used for \'Profile\' listings in its Settings OR there is no Profile with that ID OR you do not have permission to access this profile. Please contact the site administrator if you need assistance.',
337 array(1 => implode(',', $profileIds))
338 ));
339 }
340 else {
341 self::reformatProfileFields($fields);
342 }
343
344 return $fields;
345 }
346
347 /**
348 * Format a list of UFFields for use with buildProfile. This is the in-memory analog
349 * of getFields().
350 *
351 * @param array $groupArr (mimic CRM_UF_DAO_UFGroup)
352 * @param array $fieldArrs list of fields (each mimics CRM_UF_DAO_UFField)
353 * @param bool $visibility visibility of fields we are interested in
354 * @param bool $searchable
355 * @param bool $showall
356 * @return array
357 * @see getFields
358 */
359 public static function formatUFFields(
360 $groupArr,
361 $fieldArrs,
362 $visibility = NULL,
363 $searchable = NULL,
364 $showAll = FALSE,
365 $ctype = NULL,
366 $permissionType = CRM_Core_Permission::CREATE
367 ) {
368 // $group = new CRM_Core_DAO_UFGroup();
369 // $group->copyValues($groupArr); // no... converts string('') to string('null')
370 $group = (object) $groupArr;
371
372 // Refactoring note: The $fieldArrs here may be slightly different than the $ufFields
373 // used by calculateGroupType, but I don't think the missing fields matter, and -- if
374 // they did -- the obvious fix would produce mutual recursion.
375 $ufGroupType = self::_calculateGroupType($fieldArrs);
376 $profileType = CRM_Core_BAO_UFField::calculateProfileType(implode(',',$ufGroupType));
377 $contactActivityProfile = CRM_Core_BAO_UFField::checkContactActivityProfileTypeByGroupType(implode(',',$ufGroupType));
378 $importableFields = self::getImportableFields($showAll, $profileType, $contactActivityProfile);
379 list($customFields, $addressCustomFields) = self::getCustomFields($ctype);
380
381 $formattedFields = array();
382 foreach ($fieldArrs as $fieldArr) {
6a488035
TO
383 $field = (object) $fieldArr;
384 if (!self::filterUFField($field, $searchable, $showAll, $visibility)) {
385 continue;
386 }
387
388 list($name, $formattedField) = self::formatUFField($group, $field, $customFields, $addressCustomFields, $importableFields, $permissionType);
389 if ($formattedField !== NULL) {
390 $formattedFields[$name] = $formattedField;
391 }
392 }
393 return $formattedFields;
394 }
395
396 /**
397 * Prepare a field for rendering with CRM_Core_BAO_UFGroup::buildProfile.
398 *
399 * @param CRM_Core_DAO_UFGroup|CRM_Core_DAO $group
400 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
401 * @param array $addressCustomFields
402 * @param array $importableFields
403 * @param array $customFields
404 * @param int $permissionType eg CRM_Core_Permission::CREATE
405 * @return array
406 */
407 protected static function formatUFField(
408 $group,
409 $field,
410 $customFields,
411 $addressCustomFields,
412 $importableFields,
413 $permissionType = CRM_Core_Permission::CREATE
414 ) {
415 $name = $field->field_name;
416 $title = $field->label;
417
418 $addressCustom = FALSE;
419 if (in_array($permissionType, array(
420 CRM_Core_Permission::CREATE,
421 CRM_Core_Permission::EDIT,
422 )) &&
423 in_array($field->field_name, array_keys($addressCustomFields))
424 ) {
425 $addressCustom = TRUE;
426 $name = "address_{$name}";
427 }
428
429 if (!empty($field->location_type_id)) {
430 $name .= "-{$field->location_type_id}";
431 }
432 else {
433 $locationFields = self::getLocationFields();
434 if (in_array($field->field_name, $locationFields) || $addressCustom) {
435 $name .= '-Primary';
436 }
437 }
438
439 if (isset($field->phone_type_id)) {
440 $name .= "-{$field->phone_type_id}";
441 }
442
443 // No lie: this is bizarre; why do we need to mix so many UFGroup properties into UFFields?
444 // I guess to make field self sufficient with all the required data and avoid additional calls
445 $formattedField = array(
446 'name' => $name,
447 'groupTitle' => $group->title,
4a1143a1 448 'groupName' => $group->name,
6a488035
TO
449 'groupHelpPre' => empty($group->help_pre) ? '' : $group->help_pre,
450 'groupHelpPost' => empty($group->help_post) ? '' : $group->help_post,
451 'title' => $title,
452 'where' => CRM_Utils_Array::value('where', CRM_Utils_Array::value($field->field_name, $importableFields)),
453 'attributes' => CRM_Core_DAO::makeAttribute(CRM_Utils_Array::value($field->field_name, $importableFields)),
454 'is_required' => $field->is_required,
455 'is_view' => $field->is_view,
456 'help_pre' => $field->help_pre,
457 'help_post' => $field->help_post,
458 'visibility' => $field->visibility,
459 'in_selector' => $field->in_selector,
460 'rule' => CRM_Utils_Array::value('rule', CRM_Utils_Array::value($field->field_name, $importableFields)),
461 'location_type_id' => isset($field->location_type_id) ? $field->location_type_id : NULL,
462 'phone_type_id' => isset($field->phone_type_id) ? $field->phone_type_id : NULL,
463 'group_id' => $group->id,
cd0dd278
DG
464 'add_to_group_id' => isset($group->add_to_group_id) ? $group->add_to_group_id : NULL,
465 'add_captcha' => isset($group->add_captcha) ? $group->add_captcha : NULL,
6a488035
TO
466 'field_type' => $field->field_type,
467 'field_id' => $field->id,
0c145cc0
DL
468 'pseudoconstant' => CRM_Utils_Array::value(
469 'pseudoconstant',
470 CRM_Utils_Array::value($field->field_name, $importableFields)
471 ),
472 // obsolete this when we remove the name / dbName discrepancy with gender/suffix/prefix
473 'dbName' => CRM_Utils_Array::value(
474 'dbName',
475 CRM_Utils_Array::value($field->field_name, $importableFields)
476 ),
6a488035
TO
477 'skipDisplay' => 0,
478 );
479
480 //adding custom field property
481 if (substr($field->field_name, 0, 6) == 'custom' ||
482 substr($field->field_name, 0, 14) === 'address_custom'
483 ) {
484 // if field is not present in customFields, that means the user
485 // DOES NOT HAVE permission to access that field
486 if (array_key_exists($field->field_name, $customFields)) {
487 $formattedField['is_search_range'] = $customFields[$field->field_name]['is_search_range'];
488 // fix for CRM-1994
489 $formattedField['options_per_line'] = $customFields[$field->field_name]['options_per_line'];
490 $formattedField['data_type'] = $customFields[$field->field_name]['data_type'];
491 $formattedField['html_type'] = $customFields[$field->field_name]['html_type'];
492
493 if (CRM_Utils_Array::value('html_type', $formattedField) == 'Select Date') {
494 $formattedField['date_format'] = $customFields[$field->field_name]['date_format'];
495 $formattedField['time_format'] = $customFields[$field->field_name]['time_format'];
496 }
497
498 $formattedField['is_multi_summary'] = $field->is_multi_summary;
499 return array($name, $formattedField);
500 }
501 else {
502 $formattedField = NULL;
503 return array($name, $formattedField);
504 }
505 }
506 return array($name, $formattedField);
507 }
508
509 /**
510 * Create a query to find all visible UFFields in a UFGroup
511 *
512 * This is the SQL-variant of checkUFFieldDisplayable().
513 *
514 * @param int $groupId
515 * @param bool $searchable
516 * @param bool $showAll
517 * @param int $visibility
518 * @param string $orderBy comma-delimited list of SQL columns
519 * @return string
520 */
521 protected static function createUFFieldQuery($groupId, $searchable, $showAll, $visibility, $orderBy) {
522 $where = " WHERE uf_group_id = {$groupId}";
523
524 if ($searchable) {
525 $where .= " AND is_searchable = 1";
526 }
527
528 if (!$showAll) {
529 $where .= " AND is_active = 1";
530 }
531
532 if ($visibility) {
533 $clause = array();
534 if ($visibility & self::PUBLIC_VISIBILITY) {
535 $clause[] = 'visibility = "Public Pages"';
536 }
537 if ($visibility & self::ADMIN_VISIBILITY) {
538 $clause[] = 'visibility = "User and User Admin Only"';
539 }
540 if ($visibility & self::LISTINGS_VISIBILITY) {
541 $clause[] = 'visibility = "Public Pages and Listings"';
542 }
543 if (!empty($clause)) {
544 $where .= ' AND ( ' . implode(' OR ', $clause) . ' ) ';
545 }
546 }
547
548 $query = "SELECT * FROM civicrm_uf_field $where ORDER BY weight";
549 if ($orderBy) {
550 $query .= ", " . $orderBy;
551 return $query;
552 }
553 return $query;
554 }
555
556 /**
557 * Create a query to find all visible UFFields in a UFGroup
558 *
559 * This is the PHP in-memory variant of createUFFieldQuery().
560 *
561 * @param CRM_Core_DAO_UFField|CRM_Core_DAO $field
562 * @param bool $searchable
563 * @param bool $showAll
564 * @param int $visibility
565 * @return bool TRUE if field is displayable
566 */
567 protected static function filterUFField($field, $searchable, $showAll, $visibility) {
568 if ($searchable && $field->is_searchable != 1) {
569 return FALSE;
570 }
571
572 if (!$showAll && $field->is_active != 1) {
573 return FALSE;
574 }
575
576 if ($visibility) {
577 $allowedVisibilities = array();
578 if ($visibility & self::PUBLIC_VISIBILITY) {
579 $allowedVisibilities[] = 'Public Pages';
580 }
581 if ($visibility & self::ADMIN_VISIBILITY) {
582 $allowedVisibilities[] = 'User and User Admin Only';
583 }
584 if ($visibility & self::LISTINGS_VISIBILITY) {
585 $allowedVisibilities[] = 'Public Pages and Listings';
586 }
587 // !empty($allowedVisibilities) seems silly to me, but it is equivalent to the pre-existing SQL
588 if (!empty($allowedVisibilities) && !in_array($field->visibility, $allowedVisibilities)) {
589 return FALSE;
590 }
591 }
592
593 return TRUE;
594 }
595
596 protected static function getImportableFields($showAll, $profileType, $contactActivityProfile) {
597 if (!$showAll) {
598 $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, FALSE, FALSE, TRUE, TRUE);
599 }
600 else {
601 $importableFields = CRM_Contact_BAO_Contact::importableFields('All', FALSE, TRUE, FALSE, TRUE, TRUE);
602 }
603
604 if ($profileType == 'Activity' || $contactActivityProfile) {
605 $componentFields = CRM_Activity_BAO_Activity::getProfileFields();
606 }
607 else {
608 $componentFields = CRM_Core_Component::getQueryFields();
609 }
610
611 $importableFields = array_merge($importableFields, $componentFields);
612
613 $importableFields['group']['title'] = ts('Group(s)');
614 $importableFields['group']['where'] = NULL;
615 $importableFields['tag']['title'] = ts('Tag(s)');
616 $importableFields['tag']['where'] = NULL;
617 return $importableFields;
618 }
619
620 public static function getLocationFields() {
621 static $locationFields = array(
622 'street_address',
623 'supplemental_address_1',
624 'supplemental_address_2',
625 'city',
626 'postal_code',
627 'postal_code_suffix',
628 'geo_code_1',
629 'geo_code_2',
630 'state_province',
631 'country',
632 'county',
633 'phone',
634 'phone_and_ext',
635 'email',
636 'im',
637 'address_name',
638 'phone_ext',
639 );
640 return $locationFields;
641 }
642
643 protected static function getCustomFields($ctype) {
644 static $customFieldCache = array();
645 if (!isset($customFieldCache[$ctype])) {
646 $customFields = CRM_Core_BAO_CustomField::getFieldsForImport($ctype, FALSE, FALSE, FALSE, TRUE, TRUE);
647
648 // hack to add custom data for components
1cb28d5d 649 $components = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
6a488035
TO
650 foreach ($components as $value) {
651 $customFields = array_merge($customFields, CRM_Core_BAO_CustomField::getFieldsForImport($value));
652 }
653 $addressCustomFields = CRM_Core_BAO_CustomField::getFieldsForImport('Address');
654 $customFields = array_merge($customFields, $addressCustomFields);
655 $customFieldCache[$ctype] = array($customFields, $addressCustomFields);
656 }
657 return $customFieldCache[$ctype];
658 }
659
660 /**
661 * check the data validity
662 *
663 * @param int $userID the user id that we are actually editing
664 * @param string $title the title of the group we are interested in
665 * @pram boolean $register is this the registrtion form
666 * @param int $action the action of the form
667 *
668 * @return boolean true if form is valid
669 * @static
670 * @access public
671 */
672 static function isValid($userID, $title, $register = FALSE, $action = NULL) {
673 if ($register) {
674 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
675 ts('Dynamic Form Creator'),
676 $action
677 );
678 $controller->set('id', $userID);
679 $controller->set('register', 1);
680 $controller->process();
681 return $controller->validate();
682 }
683 else {
684 // make sure we have a valid group
685 $group = new CRM_Core_DAO_UFGroup();
686
687 $group->title = $title;
688
689 if ($group->find(TRUE) && $userID) {
690 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic', ts('Dynamic Form Creator'), $action);
691 $controller->set('gid', $group->id);
692 $controller->set('id', $userID);
693 $controller->set('register', 0);
694 $controller->process();
695 return $controller->validate();
696 }
697 return TRUE;
698 }
699 }
700
701 /**
702 * get the html for the form that represents this particular group
703 *
704 * @param int $userID the user id that we are actually editing
705 * @param string $title the title of the group we are interested in
706 * @param int $action the action of the form
707 * @param boolean $register is this the registration form
708 * @param boolean $reset should we reset the form?
709 * @param int $profileID do we have the profile ID?
710 *
711 * @return string the html for the form on success, otherwise empty string
712 * @static
713 * @access public
714 */
715 static function getEditHTML($userID,
716 $title,
717 $action = NULL,
718 $register = FALSE,
719 $reset = FALSE,
720 $profileID = NULL,
721 $doNotProcess = FALSE,
722 $ctype = NULL
723 ) {
724
725 if ($register) {
726 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
727 ts('Dynamic Form Creator'),
728 $action
729 );
730 if ($reset || $doNotProcess) {
731 // hack to make sure we do not process this form
732 $oldQFDefault = CRM_Utils_Array::value('_qf_default',
733 $_POST
734 );
735 unset($_POST['_qf_default']);
736 unset($_REQUEST['_qf_default']);
737 if ($reset) {
738 $controller->reset();
739 }
740 }
741
742 $controller->set('id', $userID);
743 $controller->set('register', 1);
744 $controller->set('skipPermission', 1);
745 $controller->set('ctype', $ctype);
746 $controller->process();
747 if ($doNotProcess || !empty($_POST)) {
748 $controller->validate();
749 }
750 $controller->setEmbedded(TRUE);
751
752 //CRM-5839 - though we want to process form, get the control back.
753 $controller->setSkipRedirection(($doNotProcess) ? FALSE : TRUE);
754
755 $controller->run();
756
757 // we are done processing so restore the POST/REQUEST vars
758 if (($reset || $doNotProcess) && $oldQFDefault) {
759 $_POST['_qf_default'] = $_REQUEST['_qf_default'] = $oldQFDefault;
760 }
761
762 $template = CRM_Core_Smarty::singleton();
763
764 // Hide CRM error messages if they are displayed using drupal form_set_error.
765 if (!empty($_POST)) {
766 $template->assign('suppressForm', TRUE);
767 }
768
769 return trim($template->fetch('CRM/Profile/Form/Dynamic.tpl'));
770 }
771 else {
772 if (!$profileID) {
773 // make sure we have a valid group
774 $group = new CRM_Core_DAO_UFGroup();
775
776 $group->title = $title;
777
778 if ($group->find(TRUE)) {
779 $profileID = $group->id;
780 }
781 }
782
783 if ($profileID) {
784 // make sure profileID and ctype match if ctype exists
785 if ($ctype) {
786 $profileType = CRM_Core_BAO_UFField::getProfileType($profileID);
787 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
788 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
789 }
790
791 if (($profileType != 'Contact') && ($profileType != $ctype)) {
792 return NULL;
793 }
794 }
795
796 $controller = new CRM_Core_Controller_Simple('CRM_Profile_Form_Dynamic',
797 ts('Dynamic Form Creator'),
798 $action
799 );
800 if ($reset) {
801 $controller->reset();
802 }
803 $controller->set('gid', $profileID);
804 $controller->set('id', $userID);
805 $controller->set('register', 0);
806 $controller->set('skipPermission', 1);
807 if ($ctype) {
808 $controller->set('ctype', $ctype);
809 }
810 $controller->process();
811 $controller->setEmbedded(TRUE);
812
813 //CRM-5846 - give the control back to drupal.
814 $controller->setSkipRedirection(($doNotProcess) ? FALSE : TRUE);
815 $controller->run();
816
817 $template = CRM_Core_Smarty::singleton();
818
819 // Hide CRM error messages if they are displayed using drupal form_set_error.
820 if (!empty($_POST) && CRM_Core_Config::singleton()->userFramework == 'Drupal') {
821 if (arg(0) == 'user' || (arg(0) == 'admin' && arg(1) == 'people')) {
822 $template->assign('suppressForm', TRUE);
823 }
824 }
825
826 $templateFile = "CRM/Profile/Form/{$profileID}/Dynamic.tpl";
827 if (!$template->template_exists($templateFile)) {
828 $templateFile = 'CRM/Profile/Form/Dynamic.tpl';
829 }
830 return trim($template->fetch($templateFile));
831 }
832 else {
833 $userEmail = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID);
834
835 // if post not empty then only proceed
836 if (!empty($_POST)) {
837 // get the new email
838 $config = CRM_Core_Config::singleton();
839 $email = CRM_Utils_Array::value('mail', $_POST);
840
841 if (CRM_Utils_Rule::email($email) && ($email != $userEmail[1])) {
842 CRM_Core_BAO_UFMatch::updateContactEmail($userID, $email);
843 }
844 }
845 }
846 }
847 return '';
848 }
849
850 /**
851 * searches for a contact in the db with similar attributes
852 *
853 * @param array $params the list of values to be used in the where clause
854 * @param int $id the current contact id (hence excluded from matching)
855 * @param boolean $flatten should we flatten the input params
856 *
857 * @return contact_id if found, null otherwise
858 * @access public
859 * @static
860 */
861 public static function findContact(&$params, $id = NULL, $contactType = 'Individual') {
862 $dedupeParams = CRM_Dedupe_Finder::formatParams($params, $contactType);
863 $dedupeParams['check_permission'] = CRM_Utils_Array::value('check_permission', $params, TRUE);
864 $ids = CRM_Dedupe_Finder::dupesByParams($dedupeParams, $contactType, 'Supervised', array($id));
865 if (!empty($ids)) {
866 return implode(',', $ids);
867 }
868 else {
869 return NULL;
870 }
871 }
872
873 /**
874 * Given a contact id and a field set, return the values from the db
875 * for this contact
876 *
877 * @param int $id the contact id
878 * @param array $fields the profile fields of interest
879 * @param array $values the values for the above fields
880 * @param boolean $searchable searchable or not
881 * @param array $componentWhere component condition
882 * @param boolean $absolute return urls in absolute form (useful when sending an email)
883 *
884 * @return void
885 * @access public
886 * @static
887 */
888 public static function getValues($cid, &$fields, &$values,
889 $searchable = TRUE, $componentWhere = NULL,
890 $absolute = FALSE, $additionalWhereClause = NULL
891 ) {
892 if (empty($cid) && empty($componentWhere)) {
893 return NULL;
894 }
895
896 // get the contact details (hier)
897 $returnProperties = CRM_Contact_BAO_Contact::makeHierReturnProperties($fields);
898 $params = $cid ? array(array('contact_id', '=', $cid, 0, 0)) : array();
899
900 // add conditions specified by components. eg partcipant_id etc
901 if (!empty($componentWhere)) {
902 $params = array_merge($params, $componentWhere);
903 }
904
905 $query = new CRM_Contact_BAO_Query($params, $returnProperties, $fields);
906 $options = &$query->_options;
907
908 $details = $query->searchQuery( 0, 0, NULL, FALSE, FALSE,
909 FALSE, FALSE, FALSE, $additionalWhereClause);
910 if (!$details->fetch()) {
911 return;
912 }
d9ab802d 913 $query->convertToPseudoNames($details);
6a488035
TO
914 $config = CRM_Core_Config::singleton();
915
b2b0530a 916 $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id');
e7e657f0 917 $imProviders = CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id');
cbf48754 918 $websiteTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id');
6a488035
TO
919
920 $multipleFields = array('url');
921 $nullIndex = $nullValueIndex = ' ';
922
923 //start of code to set the default values
924 foreach ($fields as $name => $field) {
925 // fix for CRM-3962
926 if ($name == 'id') {
927 $name = 'contact_id';
928 }
929
930 // skip fields that should not be displayed separately
a7488080 931 if (!empty($field['skipDisplay'])) {
6a488035
TO
932 continue;
933 }
934
935 $index = $field['title'];
936 //handle for the label not set for the field
937 if (empty($field['title'])) {
938 $index = $nullIndex;
939 $nullIndex .= $nullIndex;
940 }
941
942 //handle the case to avoid re-write where the profile field labels are the same
46796b19 943 if (array_key_exists($index, $values)) {
6a488035
TO
944 $index .= $nullValueIndex;
945 $nullValueIndex .= $nullValueIndex;
946 }
947 $params[$index] = $values[$index] = '';
948 $customFieldName = NULL;
949 // hack for CRM-665
950 if (isset($details->$name) || $name == 'group' || $name == 'tag') {
951 // to handle gender / suffix / prefix
04ffef8d 952 if (in_array(substr($name, 0, -3), array('gender', 'prefix', 'suffix'))) {
04ffef8d 953 $params[$index] = $details->$name;
46796b19 954 $values[$index] = $details->$name;
6a488035
TO
955 }
956 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)) {
957 $dname = $name . '_display';
958 $values[$index] = $details->$dname;
959 $name = $name . '_id';
960 $params[$index] = $details->$name;
961 }
962 elseif (in_array($name, array(
963 'state_province', 'country', 'county'))) {
964 $values[$index] = $details->$name;
965 $idx = $name . '_id';
966 $params[$index] = $details->$idx;
967 }
968 elseif ($name === 'preferred_communication_method') {
e7e657f0 969 $communicationFields = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
6a488035
TO
970 $compref = array();
971 $pref = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details->$name);
972
973 foreach ($pref as $k) {
974 if ($k) {
975 $compref[] = $communicationFields[$k];
976 }
977 }
978 $params[$index] = $details->$name;
979 $values[$index] = implode(',', $compref);
980 }
981 elseif ($name === 'preferred_language') {
6a488035 982 $params[$index] = $details->$name;
a8c23526 983 $values[$index] = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
6a488035
TO
984 }
985 elseif ($name == 'group') {
986 $groups = CRM_Contact_BAO_GroupContact::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
987 $title = $ids = array();
988
989 foreach ($groups as $g) {
990 // CRM-8362: User and User Admin visibility groups should be included in display if user has
991 // VIEW permission on that group
992 $groupPerm = CRM_Contact_BAO_Group::checkPermission($g['group_id'], $g['title']);
993
994 if ($g['visibility'] != 'User and User Admin Only' ||
995 CRM_Utils_Array::key(CRM_Core_Permission::VIEW, $groupPerm)
996 ) {
997 $title[] = $g['title'];
998 if ($g['visibility'] == 'Public Pages') {
999 $ids[] = $g['group_id'];
1000 }
1001 }
1002 }
1003 $values[$index] = implode(', ', $title);
1004 $params[$index] = implode(',', $ids);
1005 }
1006 elseif ($name == 'tag') {
1007 $entityTags = CRM_Core_BAO_EntityTag::getTag($cid);
cd43c5e3 1008 $allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
1009 $title = array();
1010 foreach ($entityTags as $tagId) {
1011 $title[] = $allTags[$tagId];
1012 }
1013 $values[$index] = implode(', ', $title);
1014 $params[$index] = implode(',', $entityTags);
1015 }
1016 elseif ($name == 'activity_status_id') {
1017 $activityStatus = CRM_Core_PseudoConstant::activityStatus();
1018 $values[$index] = $activityStatus[$details->$name];
1019 $params[$index] = $details->$name;
1020 }
1021 elseif ($name == 'activity_date_time') {
1022 $values[$index] = CRM_Utils_Date::customFormat($details->$name);
1023 $params[$index] = $details->$name;
1024 }
1025 elseif ($name == 'contact_sub_type') {
1026 $contactSubTypeNames = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details->$name);
1027 if (!empty($contactSubTypeNames)) {
1028 $contactSubTypeLabels = array();
1029 // get all contact subtypes
1030 $allContactSubTypes = CRM_Contact_BAO_ContactType::subTypeInfo();
1031 // build contact subtype labels array
1032 foreach( $contactSubTypeNames as $cstName ) {
1033 if ($cstName) {
1034 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1035 }
1036 }
1037 $values[$index] = implode(',', $contactSubTypeLabels);
1038 }
1039
1040 $params[$index] = $details->$name;
1041 }
1042 else {
1043 if (substr($name, 0, 7) === 'do_not_' || substr($name, 0, 3) === 'is_') {
1044 if ($details->$name) {
1045 $values[$index] = '[ x ]';
1046 }
1047 }
1048 else {
1049 if ($cfID = CRM_Core_BAO_CustomField::getKeyID($name)) {
1050 $htmlType = $field['html_type'];
1051
1052 // field_type is only set when we are retrieving profile values
1053 // when sending email, we call the same function to get custom field
1054 // values etc, i.e. emulating a profile
1055 $fieldType = CRM_Utils_Array::value('field_type', $field);
1056
1057 if ($htmlType == 'File') {
1058 $entityId = $cid;
1059 if (!$cid &&
8cc574cf 1060 $fieldType == 'Activity' && !empty($componentWhere[0][2])) {
6a488035
TO
1061 $entityId = $componentWhere[0][2];
1062 }
1063
1064 $fileURL = CRM_Core_BAO_CustomField::getFileURL($entityId,
1065 $cfID,
1066 NULL,
1067 $absolute
1068 );
1069 $params[$index] = $values[$index] = $fileURL['file_url'];
1070 }
1071 else {
1072 $customVal = NULL;
1073 if (isset($dao) && property_exists($dao, 'data_type') &&
1074 ($dao->data_type == 'Int' ||
1075 $dao->data_type == 'Boolean'
1076 )
1077 ) {
1078 $customVal = (int )($details->{$name});
1079 }
1080 elseif (isset($dao) && property_exists($dao, 'data_type')
1081 && $dao->data_type == 'Float'
1082 ) {
1083 $customVal = (float )($details->{$name});
1084 }
1085 elseif (!CRM_Utils_System::isNull(explode(CRM_Core_DAO::VALUE_SEPARATOR,
1086 $details->{$name}
1087 ))) {
1088 $customVal = $details->{$name};
1089 }
1090
1091 //CRM-4582
1092 if (CRM_Utils_System::isNull($customVal)) {
1093 continue;
1094 }
1095
1096 $params[$index] = $customVal;
1097 $values[$index] = CRM_Core_BAO_CustomField::getDisplayValue($customVal,
1098 $cfID,
1099 $options
1100 );
1b4d9e39 1101 if ($field['data_type'] == 'ContactReference') {
6a488035
TO
1102 $params[$index] = $values[$index];
1103 }
1104 if (CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField',
1105 $cfID, 'is_search_range'
1106 )) {
1107 $customFieldName = "{$name}_from";
1108 }
1109 }
1110 }
1111 elseif ($name == 'image_URL') {
1112 list($width, $height) = getimagesize($details->$name);
1113 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact::getThumbSize($width, $height);
1114
1115 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1116 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1117 }
1118 elseif (in_array($name, array(
1119 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1120 $values[$index] = CRM_Utils_Date::customFormat($details->$name);
1121 $params[$index] = CRM_Utils_Date::isoToMysql($details->$name);
1122 }
1123 else {
1124 $dao = '';
1125 if ($index == 'Campaign') {
1126 $dao = 'CRM_Campaign_DAO_Campaign';
1127 }
1128 elseif ($index == 'Contribution Page') {
1129 $dao = 'CRM_Contribute_DAO_ContributionPage';
1130 }
1131 if ($dao) {
1132 $value = CRM_Core_DAO::getFieldValue($dao, $details->$name, 'title');
1133 }
1134 else {
1135 $value = $details->$name;
1136 }
1137 $values[$index] = $value;
1138 }
1139 }
1140 }
1141 }
1142 elseif (strpos($name, '-') !== FALSE) {
1143 list($fieldName, $id, $type) = CRM_Utils_System::explode('-', $name, 3);
1144
1145 if (!in_array($fieldName, $multipleFields)) {
1146 if ($id == 'Primary') {
1147 // fix for CRM-1543
1148 // not sure why we'd every use Primary location type id
1149 // we need to fix the source if we are using it
1150 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1151 $locationTypeName = 1;
1152 }
1153 else {
1154 $locationTypeName = CRM_Utils_Array::value($id, $locationTypes);
1155 }
1156
1157 if (!$locationTypeName) {
1158 continue;
1159 }
1160
1161 $detailName = "{$locationTypeName}-{$fieldName}";
1162 $detailName = str_replace(' ', '_', $detailName);
1163
1164 if (in_array($fieldName, array(
1165 'phone', 'im', 'email', 'openid'))) {
1166 if ($type) {
1167 $detailName .= "-{$type}";
1168 }
1169 }
1170
1171 if (in_array($fieldName, array(
1172 'state_province', 'country', 'county'))) {
1173 $values[$index] = $details->$detailName;
1174 $idx = $detailName . '_id';
1175 $params[$index] = $details->$idx;
1176 }
1177 elseif ($fieldName == 'im') {
1178 $providerId = $detailName . '-provider_id';
38913d36
TO
1179 if (isset($imProviders[$details->$providerId])) {
1180 $values[$index] = $details->$detailName . " (" . $imProviders[$details->$providerId] . ")";
6a488035
TO
1181 }
1182 else {
1183 $values[$index] = $details->$detailName;
1184 }
1185 $params[$index] = $details->$detailName;
1186 }
1187 elseif ($fieldName == 'phone') {
1188 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1189 if (isset($details->$phoneExtField)) {
1190 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1191 }
1192 else {
1193 $values[$index] = $details->$detailName;
1194 }
1195 $params[$index] = $details->$detailName;
1196 }
1197 else {
1198 $values[$index] = $params[$index] = $details->$detailName;
1199 }
1200 }
1201 else {
1202 $detailName = "website-{$id}-{$fieldName}";
1203 $url = CRM_Utils_System::fixURL($details->$detailName);
1204 if ($details->$detailName) {
1205 $websiteTypeId = "website-{$id}-website_type_id";
1206 $websiteType = $websiteTypes[$details->$websiteTypeId];
1207 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1208 }
1209 else {
1210 $values[$index] = '';
1211 }
1212 }
1213 }
1214
1215 if ((CRM_Utils_Array::value('visibility', $field) == 'Public Pages and Listings') &&
1216 CRM_Core_Permission::check('profile listings and forms')
1217 ) {
1218
1219 if (CRM_Utils_System::isNull($params[$index])) {
1220 $params[$index] = $values[$index];
1221 }
1222 if (!isset($params[$index])) {
1223 continue;
1224 }
1225 if (!$customFieldName) {
1226 $fieldName = $field['name'];
1227 }
1228 else {
1229 $fieldName = $customFieldName;
1230 }
1231
1232 $url = NULL;
1233 if (CRM_Core_BAO_CustomField::getKeyID($field['name'])) {
1234 $htmlType = $field['html_type'];
1235 if ($htmlType == 'Link') {
1236 $url = $params[$index];
1237 }
1238 elseif (in_array($htmlType, array(
1239 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1240 'Multi-Select State/Province', 'Multi-Select Country',
1241 ))) {
1242 $valSeperator = CRM_Core_DAO::VALUE_SEPARATOR;
1243 $selectedOptions = explode($valSeperator, $params[$index]);
1244
1245 foreach ($selectedOptions as $key => $multiOption) {
1246 if ($multiOption) {
1247 $url[] = CRM_Utils_System::url('civicrm/profile',
1248 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1249 urlencode($fieldName) .
1250 '=' .
1251 urlencode($multiOption)
1252 );
1253 }
1254 }
1255 }
1256 else {
1257 $url = CRM_Utils_System::url('civicrm/profile',
1258 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1259 urlencode($fieldName) .
1260 '=' .
1261 urlencode($params[$index])
1262 );
1263 }
1264 }
1265 else {
1266 $url = CRM_Utils_System::url('civicrm/profile',
1267 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1268 urlencode($fieldName) .
1269 '=' .
1270 urlencode($params[$index])
1271 );
1272 }
1273
1274 if ($url &&
1275 !empty($values[$index]) &&
1276 $searchable
1277 ) {
1278
1279 if (is_array($url) && !empty($url)) {
1280 $links = array();
1281 $eachMultiValue = explode(', ', $values[$index]);
1282 foreach ($eachMultiValue as $key => $valueLabel) {
1283 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1284 }
1285 $values[$index] = implode(', ', $links);
1286 }
1287 else {
1288 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1289 }
1290 }
1291 }
1292 }
1293 }
1294
1295 /**
1296 * Check if profile Group used by any module.
1297 *
1298 * @param int $id profile Id
1299 *
1300 * @return boolean
1301 *
1302 * @access public
1303 * @static
1304 *
1305 */
1306 public static function usedByModule($id) {
1307 //check whether this group is used by any module(check uf join records)
1308 $sql = "SELECT id
1309 FROM civicrm_uf_join
1310 WHERE civicrm_uf_join.uf_group_id=$id";
1311
1312 $dao = new CRM_Core_DAO();
1313 $dao->query($sql);
1314 if ($dao->fetch()) {
1315 return TRUE;
1316 }
1317 else {
1318 return FALSE;
1319 }
1320 }
1321
1322 /**
1323 * Delete the profile Group.
1324 *
1325 * @param int $id profile Id
1326 *
1327 * @return boolean
1328 *
1329 * @access public
1330 * @static
1331 *
1332 */
1333 public static function del($id) {
1334 //check whether this group contains any profile fields
1335 $profileField = new CRM_Core_DAO_UFField();
1336 $profileField->uf_group_id = $id;
1337 $profileField->find();
1338 while ($profileField->fetch()) {
1339 CRM_Core_BAO_UFField::del($profileField->id);
1340 }
1341
1342 //delete records from uf join table
1343 $ufJoin = new CRM_Core_DAO_UFJoin();
1344 $ufJoin->uf_group_id = $id;
1345 $ufJoin->delete();
1346
1347 //delete profile group
1348 $group = new CRM_Core_DAO_UFGroup();
1349 $group->id = $id;
1350 $group->delete();
1351 return 1;
1352 }
1353
1354 /**
1355 * function to add the UF Group
1356 *
1357 * @param array $params reference array contains the values submitted by the form
1358 * @param array $ids reference array contains the id
1359 *
1360 * @access public
1361 * @static
1362 *
1363 * @return object
1364 */
6a73ef3f 1365 static function add(&$params, $ids = array()) {
6a488035
TO
1366 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1367 foreach ($fields as $field) {
1368 $params[$field] = CRM_Utils_Array::value($field, $params, FALSE);
1369 }
1370
1371 $params['limit_listings_group_id'] = CRM_Utils_Array::value('group', $params);
1372 $params['add_to_group_id'] = CRM_Utils_Array::value('add_contact_to_group', $params);
1373
1374 $ufGroup = new CRM_Core_DAO_UFGroup();
1375 $ufGroup->copyValues($params);
1376
6a73ef3f 1377 $ufGroupID = CRM_Utils_Array::value('ufgroup', $ids, CRM_Utils_Array::value('id', $params));
6a488035
TO
1378 if (!$ufGroupID) {
1379 $ufGroup->name = CRM_Utils_String::munge($ufGroup->title, '_', 56);
1380 }
1381 $ufGroup->id = $ufGroupID;
1382
1383 $ufGroup->save();
1384
1385 if (!$ufGroupID) {
1386 $ufGroup->name = $ufGroup->name . "_{$ufGroup->id}";
1387 $ufGroup->save();
1388 }
1389
1390 return $ufGroup;
1391 }
1392
1393 /**
1394 * Function to make uf join entries for an uf group
1395 *
1396 * @param array $params (reference) an assoc array of name/value pairs
1397 * @param int $ufGroupId ufgroup id
1398 *
1399 * @return void
1400 * @access public
1401 * @static
1402 */
1403 static function createUFJoin(&$params, $ufGroupId) {
1404 $groupTypes = CRM_Utils_Array::value('uf_group_type', $params);
1405
1406 // get ufjoin records for uf group
1407 $ufGroupRecord = CRM_Core_BAO_UFGroup::getUFJoinRecord($ufGroupId);
1408
1409 // get the list of all ufgroup types
1410 $allUFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1411
1412 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1413 if (!is_array($groupTypes)) {
1414 $groupTypes = array();
1415 }
1416
1417 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1418 if (!is_array($ufGroupRecord)) {
1419 $ufGroupRecord = array();
1420 }
1421
1422 // check which values has to be inserted/deleted for contact
1423 $menuRebuild = FALSE;
1424 foreach ($allUFGroupType as $key => $value) {
1425 $joinParams = array();
1426 $joinParams['uf_group_id'] = $ufGroupId;
1427 $joinParams['module'] = $key;
1428 if ($key == 'User Account') {
1429 $menuRebuild = TRUE;
1430 }
1431 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1432 // insert a new record
1433 CRM_Core_BAO_UFGroup::addUFJoin($joinParams);
1434 }
1435 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1436 // delete a record for existing ufgroup
1437 CRM_Core_BAO_UFGroup::delUFJoin($joinParams);
1438 }
1439 }
1440
1441 //update the weight
1442 $query = "
1443UPDATE civicrm_uf_join
1444SET weight = %1
1445WHERE uf_group_id = %2
1446AND ( entity_id IS NULL OR entity_id <= 0 )
1447";
1448 $p = array(1 => array($params['weight'], 'Integer'),
1449 2 => array($ufGroupId, 'Integer'),
1450 );
1451 CRM_Core_DAO::executeQuery($query, $p);
1452
1453 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1454 // for user account
1455 $config = CRM_Core_Config::singleton();
1456 if ($menuRebuild &&
1457 $config->userSystem->is_drupal
1458 ) {
1459 menu_rebuild();
1460 }
1461 }
1462
1463 /**
1464 * Function to get the UF Join records for an ufgroup id
1465 *
1466 * @params int $ufGroupId uf group id
1467 * @params int $displayName if set return display name in array
1468 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1469 *
1470 * @return array $ufGroupJoinRecords
1471 *
1472 * @access public
1473 * @static
1474 */
1475 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1476 if ($displayName) {
1477 $UFGroupType = array();
1478 $UFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1479 }
1480
1481 $ufJoin = array();
1482 $dao = new CRM_Core_DAO_UFJoin();
1483
1484 if ($ufGroupId) {
1485 $dao->uf_group_id = $ufGroupId;
1486 }
1487
1488 $dao->find();
1489 $ufJoin = array();
1490
1491 while ($dao->fetch()) {
1492 if (!$displayName) {
1493 $ufJoin[$dao->id] = $dao->module;
1494 }
1495 else {
1496 if (isset($UFGroupType[$dao->module])) {
1497 // skip the default modules
1498 if (!$status) {
1499 $ufJoin[$dao->id] = $UFGroupType[$dao->module];
1500 }
1501 // added for CRM-1475
1502 }
1503 elseif (!CRM_Utils_Array::key($dao->module, $ufJoin)) {
1504 $ufJoin[$dao->id] = $dao->module;
1505 }
1506 }
1507 }
1508 return $ufJoin;
1509 }
1510
1511 /**
1512 * Function takes an associative array and creates a ufjoin record for ufgroup
1513 *
1514 * @param array $params (reference) an assoc array of name/value pairs
1515 *
1516 * @return object CRM_Core_BAO_UFJoin object
1517 * @access public
1518 * @static
1519 */
1520 static function addUFJoin(&$params) {
1521 $ufJoin = new CRM_Core_DAO_UFJoin();
1522 $ufJoin->copyValues($params);
1523 $ufJoin->save();
1524 return $ufJoin;
1525 }
1526
1527 /**
1528 * Function to delete the uf join record for an uf group
1529 *
1530 * @param array $params (reference) an assoc array of name/value pairs
1531 *
1532 * @return void
1533 * @access public
1534 * @static
1535 */
1536 static function delUFJoin(&$params) {
1537 $ufJoin = new CRM_Core_DAO_UFJoin();
1538 $ufJoin->copyValues($params);
1539 $ufJoin->delete();
1540 }
1541
1542 /**
1543 * Function to get the weight for ufjoin record
1544 *
1545 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1546 *
1547 * @return int weight of the UFGroup
1548 * @access public
1549 * @static
1550 */
1551 static function getWeight($ufGroupId = NULL) {
1552 //calculate the weight
1553 $p = array();
1554 if (!$ufGroupId) {
1555 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1556 FROM civicrm_uf_join
1557 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1558 }
1559 else {
1560 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1561 FROM civicrm_uf_join
1562 WHERE civicrm_uf_join.uf_group_id = %1
1563 AND ( entity_id IS NULL OR entity_id <= 0 )";
1564 $p[1] = array($ufGroupId, 'Integer');
1565 }
1566
1567 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1568 $dao->fetch();
1569 return ($dao->new_weight) ? $dao->new_weight : 1;
1570 }
1571
1572 /**
1573 * Function to get the uf group for a module
1574 *
1575 * @param string $moduleName module name
2141efbf
TO
1576 * @param int $count no to increment the weight
1577 * @param bool $skipPermision - whether to add permission clause
1578 * @param int $op - which operation (view, edit, create, etc) to check permission for
1579 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
6a488035
TO
1580 *
1581 * @return array $ufGroups array of ufgroups for a module
1582 * @access public
1583 * @static
1584 */
2141efbf 1585 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission::VIEW, $returnFields = NULL) {
290d4ccc
DS
1586 $selectFields = array('id', 'title', 'created_id', 'is_active', 'is_reserved', 'group_type');
1587
1588 if (!CRM_Core_Config::isUpgradeMode()) {
1589 // CRM-13555, since description field was added later (4.4), and to avoid any problems with upgrade
1590 $selectFields[] = 'description';
1591 }
7ba38389 1592
1593 if (!empty($returnFields)) {
1594 $selectFields = array_merge($returnFields, array_diff($selectFields, $returnFields));
2141efbf 1595 }
7ba38389 1596
1597 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $selectFields) . '
6a488035
TO
1598 FROM civicrm_uf_group
1599 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1600 $p = array();
1601 if ($moduleName) {
1602 $queryString .= ' AND civicrm_uf_group.is_active = 1
1603 WHERE civicrm_uf_join.module = %2';
1604 $p[2] = array($moduleName, 'String');
1605 }
1606
1607
1608 // add permissioning for profiles only if not registration
1609 if (!$skipPermission) {
1610 $permissionClause = CRM_Core_Permission::ufGroupClause($op, 'civicrm_uf_group.');
1611 if (strpos($queryString, 'WHERE') !== FALSE) {
1612 $queryString .= " AND $permissionClause ";
1613 }
1614 else {
1615 $queryString .= " $permissionClause ";
1616 }
1617 }
1618
1619 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1620 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1621
1622 $ufGroups = array();
1623 while ($dao->fetch()) {
1624 //skip mix profiles in user Registration / User Account
1625 if (($moduleName == 'User Registration' || $moduleName == 'User Account') &&
1626 CRM_Core_BAO_UFField::checkProfileType($dao->id)
1627 ) {
1628 continue;
1629 }
7ba38389 1630 foreach ($selectFields as $key => $field) {
1631 if($field == 'id') {
1632 continue;
1633 }
1634 elseif ($field == 'name') {
1635 $ufGroups[$dao->id][$field] = $dao->title;
1636 continue;
1637 }
1638 $ufGroups[$dao->id][$field] = $dao->$field;
1639 }
6a488035
TO
1640 }
1641
1642 // Allow other modules to alter/override the UFGroups.
1643 CRM_Utils_Hook::buildUFGroupsForModule($moduleName, $ufGroups);
1644
1645 return $ufGroups;
1646 }
1647
1648 /**
1649 * Function to filter ufgroups based on logged in user contact type
1650 *
1651 * @params int $ufGroupId uf group id (profile id)
1652 *
1653 * @return boolean true or false
1654 * @static
1655 * @access public
1656 */
1657 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1658 if (!$contactID) {
1659 $session = CRM_Core_Session::singleton();
1660 $contactID = $session->get('userID');
1661 }
1662
1663 if ($contactID) {
1664 //get the contact type
1665 $contactType = CRM_Contact_BAO_Contact::getContactType($contactID);
1666
1667 //match if exixting contact type is same as profile contact type
1668 $profileType = CRM_Core_BAO_UFField::getProfileType($ufGroupId);
1669
1670 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1671 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
1672 }
1673
1674 //allow special mix profiles for Contribution and Participant
1675 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1676
1677 if (in_array($profileType, $specialProfiles)) {
1678 return TRUE;
1679 }
1680
1681 if (($contactType == $profileType) || $profileType == 'Contact') {
1682 return TRUE;
1683 }
1684 }
1685
1686 return FALSE;
1687 }
1688
1689 /**
1690 * Function to build profile form
1691 *
1692 * @params object $form form object
1693 * @params array $field array field properties
1694 * @params int $mode profile mode
1695 * @params int $contactID contact id
133e2c99 1696 * @params string $usedFor for building up prefixed fieldname for special cases (e.g. onBehalf, Honor)
6a488035
TO
1697 *
1698 * @return null
1699 * @static
1700 * @access public
1701 */
1702 static function buildProfile(
1703 &$form,
1704 &$field,
1705 $mode,
1706 $contactId = NULL,
1707 $online = FALSE,
133e2c99 1708 $usedFor = NULL,
6a488035
TO
1709 $rowNumber = NULL ,
1710 $prefix = ''
1711 ) {
1712 $defaultValues = array();
1713 $fieldName = $field['name'];
1714 $title = $field['title'];
1715 $attributes = $field['attributes'];
1716 $rule = $field['rule'];
1717 $view = $field['is_view'];
1718 $required = ($mode == CRM_Profile_Form::MODE_SEARCH) ? FALSE : $field['is_required'];
1719 $search = ($mode == CRM_Profile_Form::MODE_SEARCH) ? TRUE : FALSE;
1720 $isShared = CRM_Utils_Array::value('is_shared', $field, 0);
1721
1722 // do not display view fields in drupal registration form
1723 // CRM-4632
1724 if ($view && $mode == CRM_Profile_Form::MODE_REGISTER) {
1725 return;
1726 }
1727
133e2c99 1728 if ($usedFor == 'onbehalf') {
6a488035
TO
1729 $name = "onbehalf[$fieldName]";
1730 }
133e2c99 1731 elseif ($usedFor == 'honor') {
1732 $name = "honor[$fieldName]";
1733 }
6a488035
TO
1734 elseif ($contactId && !$online) {
1735 $name = "field[$contactId][$fieldName]";
1736 }
1737 elseif ($rowNumber) {
1738 $name = "field[$rowNumber][$fieldName]";
1739 }
1740 elseif (!empty($prefix)) {
1741 $name = $prefix ."[$fieldName]";
1742 }
1743 else {
1744 $name = $fieldName;
1745 }
1746
1747 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form::MODE_EDIT) {
1748 $deleteExtra = ts('Are you sure you want to delete contact image.');
1749 $deleteURL = array(
1750 CRM_Core_Action::DELETE =>
1751 array(
1752 'name' => ts('Delete Contact Image'),
1753 'url' => 'civicrm/contact/image',
1754 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1755 'extra' =>
1756 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&amp;confirmed=1\'; else return false;"',
1757 ),
1758 );
1759 $deleteURL = CRM_Core_Action::formLink($deleteURL,
1760 CRM_Core_Action::DELETE,
1761 array('id' => $form->get('id'),
1762 'gid' => $form->get('gid'),
87dab4a4
AH
1763 ),
1764 ts('more'),
1765 FALSE,
1766 'contact.profileimage.delete',
1767 'Contact',
1768 $form->get('id')
6a488035
TO
1769 );
1770 $form->assign('deleteURL', $deleteURL);
1771 }
1772 $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
1773 'address_options', TRUE, NULL, TRUE
1774 );
1775
1776 if (substr($fieldName, 0, 14) === 'state_province') {
1777 $form->add('select', $name, $title,
1778 array(
1779 '' => ts('- select -')) + CRM_Core_PseudoConstant::stateProvince(), $required
1780 );
1781 $config = CRM_Core_Config::singleton();
1782 if (!in_array($mode, array(
1783 CRM_Profile_Form::MODE_EDIT, CRM_Profile_Form::MODE_SEARCH)) &&
1784 $config->defaultContactStateProvince
1785 ) {
1786 $defaultValues[$name] = $config->defaultContactStateProvince;
1787 $form->setDefaults($defaultValues);
1788 }
1789 }
1790 elseif (substr($fieldName, 0, 7) === 'country') {
1791 $form->add('select', $name, $title,
1792 array(
1793 '' => ts('- select -')) + CRM_Core_PseudoConstant::country(), $required
1794 );
1795 $config = CRM_Core_Config::singleton();
1796 if (!in_array($mode, array(
1797 CRM_Profile_Form::MODE_EDIT, CRM_Profile_Form::MODE_SEARCH)) &&
1798 $config->defaultContactCountry
1799 ) {
1800 $defaultValues[$name] = $config->defaultContactCountry;
1801 $form->setDefaults($defaultValues);
1802 }
1803 }
1804 elseif (substr($fieldName, 0, 6) === 'county') {
1805 if ($addressOptions['county']) {
1806 $form->add('select', $name, $title,
1807 array(
75e14bbf 1808 '' => ts('(choose state first)')), $required
6a488035
TO
1809 );
1810 }
1811 }
1812 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1813 $form->add('file', $name, $title, $attributes, $required);
1814 $form->addUploadElement($name);
1815 }
1816 elseif (substr($fieldName, 0, 2) === 'im') {
1817 $form->add('text', $name, $title, $attributes, $required);
1818 if (!$contactId) {
133e2c99 1819 if ($usedFor) {
6a488035
TO
1820 if (substr($name, -1) == ']') {
1821 $providerName = substr($name, 0, -1) . '-provider_id]';
1822 }
1823 $form->add('select', $providerName, NULL,
1824 array(
e7e657f0 1825 '' => ts('- select -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1826 );
1827 }
1828 else {
1829 $form->add('select', $name . '-provider_id', $title,
1830 array(
e7e657f0 1831 '' => ts('- select -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1832 );
1833 }
1834
1835 if ($view && $mode != CRM_Profile_Form::MODE_SEARCH) {
1836 $form->freeze($name . '-provider_id');
1837 }
1838 }
1839 }
1840 elseif (($fieldName === 'birth_date') || ($fieldName === 'deceased_date')) {
1841 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1842 }
1843 elseif (in_array($fieldName, array(
1844 'membership_start_date', 'membership_end_date', 'join_date'))) {
1845 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1846 }
1847 elseif (CRM_Utils_Array::value('name',$field) == 'membership_type') {
1848 list($orgInfo, $types) = CRM_Member_BAO_MembershipType::getMembershipTypeInfo();
1849 $sel = &$form->addElement('hierselect', $name, $title);
53cfc93c 1850 $select = array('' => ts('- select -') );
1851 if(count($orgInfo) == 1 && $field['is_required']) {
1852 // we only have one org - so we should default to it. Not sure about defaulting to first type
1853 // as it could be missed - so adding a select
1854 // however, possibly that is more similar to the membership form
1855 if(count($types[1]) > 1) {
1856 $types[1] = $select + $types[1];
1857 }
1858 }
1859 else {
1860 $orgInfo = $select + $orgInfo;
1861 }
1862 $sel->setOptions(array($orgInfo, $types));
6a488035
TO
1863 }
1864 elseif (CRM_Utils_Array::value('name',$field) == 'membership_status') {
1865 $form->add('select', $name, $title,
1866 array(
1867 '' => ts('- select -')) + CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label'), $required
1868 );
1869 }
04ffef8d 1870 elseif ($fieldName === 'gender_id') {
6a488035 1871 $genderOptions = array();
26cf88b5 1872 $gender = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
6a488035
TO
1873 foreach ($gender as $key => $var) {
1874 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1875 }
8a4f27dc 1876 $group = $form->addGroup($genderOptions, $name, $title);
6a488035
TO
1877 if ($required) {
1878 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1879 }
8a4f27dc 1880 else {
b847e6e7 1881 $group->setAttribute('allowClear', TRUE);
8a4f27dc 1882 }
6a488035 1883 }
f45334bd 1884 elseif ($fieldName === 'prefix_id' || $fieldName === 'suffix_id') {
6a488035
TO
1885 $form->add('select', $name, $title,
1886 array(
f45334bd 1887 '' => ts('- select -')) + CRM_Core_PseudoConstant::get('CRM_Contact_BAO_Contact', $fieldName), $required
6a488035
TO
1888 );
1889 }
1890 elseif ($fieldName === 'contact_sub_type') {
1891 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
133e2c99 1892 if ($usedFor == 'onbehalf') {
6a488035
TO
1893 $profileType = 'Organization';
1894 }
133e2c99 1895 elseif ($usedFor == 'honor') {
1896 $profileType = CRM_Core_BAO_UFField::getProfileType($form->_params['honoree_profile_id']);
1897 }
6a488035
TO
1898 else {
1899 $profileType = $gId ? CRM_Core_BAO_UFField::getProfileType($gId) : NULL;
1900 if ($profileType == 'Contact') {
1901 $profileType = 'Individual';
1902 }
1903 }
1904
1905 $setSubtype = FALSE;
1906 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1907 $setSubtype = $profileType;
1908 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
1909 }
1910
1911 $subtypes = $profileType ? CRM_Contact_BAO_ContactType::subTypePairs($profileType) : array();
1912
1913 if ($setSubtype) {
1914 $subtypeList = array();
1915 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1916 }
1917 else {
1918 $subtypeList = $subtypes;
1919 }
1920
1921 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1922 $sel->setMultiple(TRUE);
1923 }
1924 elseif (in_array($fieldName, CRM_Contact_BAO_Contact::$_greetingTypes)) {
1925 //add email greeting, postal greeting, addressee, CRM-4575
1926 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
1927 $profileType = CRM_Core_BAO_UFField::getProfileType($gId, TRUE, FALSE, TRUE);
1928
1929 if (empty($profileType) || in_array($profileType, array(
1930 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1931 $profileType = 'Individual';
1932 }
1933 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1934 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
1935 }
1936 $greeting = array(
1937 'contact_type' => $profileType,
1938 'greeting_type' => $fieldName,
1939 );
1940 $form->add('select', $name, $title,
1941 array(
1942 '' => ts('- select -')) + CRM_Core_PseudoConstant::greeting($greeting), $required
1943 );
1944 // add custom greeting element
1945 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1946 NULL, FALSE
1947 );
1948 }
1949 elseif ($fieldName === 'preferred_communication_method') {
e7e657f0 1950 $communicationFields = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
6a488035
TO
1951 foreach ($communicationFields as $key => $var) {
1952 if ($key == '') {
1953 continue;
1954 }
1955 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
1956 }
1957 $form->addGroup($communicationOptions, $name, $title, '<br/>');
1958 }
1959 elseif ($fieldName === 'preferred_mail_format') {
1960 $form->add('select', $name, $title, CRM_Core_SelectValues::pmf());
1961 }
1962 elseif ($fieldName === 'preferred_language') {
c0c9cd82 1963 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact::buildOptions('preferred_language'));
6a488035
TO
1964 }
1965 elseif ($fieldName == 'external_identifier') {
1966 $form->add('text', $name, $title, $attributes, $required);
1967 $contID = $contactId;
1968 if (!$contID) {
1969 $contID = $form->get('id');
1970 }
1971 $form->addRule($name,
1972 ts('External ID already exists in Database.'),
1973 'objectExists',
1974 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
1975 );
1976 }
1977 elseif ($fieldName === 'group') {
1978 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
1979 CRM_Contact_Form_Edit_TagsAndGroups::GROUP,
1980 TRUE, $required,
1981 $title, NULL, $name
1982 );
1983 }
1984 elseif ($fieldName === 'tag') {
1985 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
1986 CRM_Contact_Form_Edit_TagsAndGroups::TAG,
1987 FALSE, $required,
1988 NULL, $title, $name
1989 );
1990 }
1991 elseif (substr($fieldName, 0, 4) === 'url-') {
1992 $form->add('text', $name, $title,
1993 array_merge(CRM_Core_DAO::getAttribute('CRM_Core_DAO_Website', 'url'),
1994 array(
1995 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
1996 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
1997 )
1998 ), $required
1999 );
2000
2001 $form->addRule($name, ts('Enter a valid Website.'), 'url');
2002
2003 //Website type select
133e2c99 2004 if ($usedFor) {
6a488035
TO
2005 if (substr($name, -1) == ']') {
2006 $websiteTypeName = substr($name, 0, -1) . '-website_type_id]';
2007 }
cbf48754 2008 $form->addElement('select', $websiteTypeName, NULL, CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id'));
6a488035
TO
2009 }
2010 else {
cbf48754 2011 $form->addElement('select', $name . '-website_type_id', NULL, CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id'));
6a488035
TO
2012 }
2013 }
2014 // Note should be rendered as textarea
2015 elseif (substr($fieldName, -4) == 'note') {
2016 $form->add('textarea', $name, $title, $attributes, $required);
2017 }
2018 elseif (substr($fieldName, 0, 6) === 'custom') {
2019 $customFieldID = CRM_Core_BAO_CustomField::getKeyID($fieldName);
2020 if ($customFieldID) {
2021 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2022 }
2023 }
2024 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2025 list($fName, $locTypeId) = CRM_Utils_System::explode('-', $fieldName, 2);
2026 $customFieldID = CRM_Core_BAO_CustomField::getKeyID(substr($fName, 8));
2027 if ($customFieldID) {
2028 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2029 }
2030 }
2031 elseif (in_array($fieldName, array(
2032 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2033 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2034 }
2035 elseif ($fieldName == 'send_receipt') {
2036 $form->addElement('checkbox', $name, $title);
2037 }
2038 elseif ($fieldName == 'soft_credit') {
ccec9d6b 2039 $form->addEntityRef("soft_credit_contact_id[$rowNumber]", ts('Soft Credit To'), array('create' => TRUE));
5ee60152 2040 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
6a488035
TO
2041 }
2042 elseif ($fieldName == 'product_name') {
2043 list($products, $options) = CRM_Contribute_BAO_Premium::getPremiumProductInfo();
2044 $sel = &$form->addElement('hierselect', $name, $title);
2045 $products = array(
2046 '0' => ts('- select -')) + $products;
2047 $sel->setOptions(array($products, $options));
2048 }
2049 elseif ($fieldName == 'payment_instrument') {
2050 $form->add('select', $name, $title,
2051 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant::paymentInstrument( ), $required );
2052 }
2053 else if ($fieldName == 'financial_type' ) {
2054 $form->add('select', $name, $title,
2055 array(
2056 '' => ts('- select -')) + CRM_Contribute_PseudoConstant::financialType(), $required
2057 );
2058 }
2059 elseif ($fieldName == 'contribution_status_id') {
aaf5ca44
DG
2060 $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus();
2061 $statusName = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
2062 foreach (array(
2063 'In Progress',
2064 'Overdue',
2065 'Refunded'
2066 ) as $suppress) {
2067 unset($contributionStatuses[CRM_Utils_Array::key($suppress, $statusName)]);
2068 }
6a73ef3f 2069
6a488035
TO
2070 $form->add('select', $name, $title,
2071 array(
aaf5ca44 2072 '' => ts('- select -')) + $contributionStatuses, $required
6a488035
TO
2073 );
2074 }
51fa20cb 2075 elseif ($fieldName == 'soft_credit_type') {
2076 $form->add('select', $name, $title,
2077 array(
2078 '' => ts('- select -')) + CRM_Core_OptionGroup::values("soft_credit_type")
2079 );
2080 $form->addElement('hidden', 'sct_default_id',
2081 CRM_Core_OptionGroup::getDefaultValue("soft_credit_type"),
2082 array('id' => 'sct_default_id')
2083 );
2084 }
6a488035
TO
2085 elseif ($fieldName == 'currency') {
2086 $form->addCurrency($name, $title, $required);
2087 }
2088 elseif ($fieldName == 'contribution_page_id') {
2089 $form->add('select', $name, $title,
2090 array(
2091 '' => ts('- select -')) + CRM_Contribute_PseudoConstant::contributionPage(), $required, 'class="big"'
2092 );
2093 }
2094 elseif ($fieldName == 'participant_register_date') {
2095 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2096 }
2097 elseif ($fieldName == 'activity_status_id') {
2098 $form->add('select', $name, $title,
2099 array(
2100 '' => ts('- select -')) + CRM_Core_PseudoConstant::activityStatus(), $required
2101 );
2102 }
2103 elseif ($fieldName == 'activity_engagement_level') {
2104 $form->add('select', $name, $title,
2105 array(
2106 '' => ts('- select -')) + CRM_Campaign_PseudoConstant::engagementLevel(), $required
2107 );
2108 }
2109 elseif ($fieldName == 'activity_date_time') {
2110 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2111 }
2112 elseif ($fieldName == 'participant_status') {
2113 $cond = NULL;
2114 if ($online == TRUE) {
2115 $cond = 'visibility_id = 1';
2116 }
2117 $form->add('select', $name, $title,
2118 array(
2119 '' => ts('- select -')) + CRM_Event_PseudoConstant::participantStatus(NULL, $cond, 'label'), $required
2120 );
2121 }
2122 elseif ($fieldName == 'participant_role') {
a7488080 2123 if (!empty($field['is_multiple'])) {
6a488035
TO
2124 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant::participantRole(), NULL, NULL, NULL, NULL, '&nbsp', TRUE);
2125 }
2126 else {
2127 $form->add('select', $name, $title,
2128 array(
2129 '' => ts('- select -')) + CRM_Event_PseudoConstant::participantRole(), $required
2130 );
2131 }
2132 }
2133 elseif ($fieldName == 'world_region') {
2134 $form->add('select', $name, $title,
2135 array(
2136 '' => ts('- select -')) + CRM_Core_PseudoConstant::worldRegion(), $required
2137 );
2138 }
2139 elseif ($fieldName == 'signature_html') {
2140 $form->addWysiwyg($name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
2141 }
2142 elseif ($fieldName == 'signature_text') {
2143 $form->add('textarea', $name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
2144 }
2145 elseif (substr($fieldName, -11) == 'campaign_id') {
2146 if (CRM_Campaign_BAO_Campaign::isCampaignEnable()) {
2147 $campaigns = CRM_Campaign_BAO_Campaign::getCampaigns(CRM_Utils_Array::value($contactId,
2148 $form->_componentCampaigns
2149 ));
2150 $form->add('select', $name, $title,
2151 array(
2152 '' => ts('- select -')) + $campaigns, $required, 'class="big"'
2153 );
2154 }
2155 }
2156 elseif ($fieldName == 'activity_details') {
2157 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2158 }
2159 elseif ($fieldName == 'activity_duration') {
2160 $form->add('text', $name, $title, $attributes, $required);
2161 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2162 }
2163 else {
2164 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2165 $form->add('advcheckbox', $name, $title, $attributes, $required);
2166 }
2167 else {
2168 $form->add('text', $name, $title, $attributes, $required);
2169 }
2170 }
2171
2172 static $hiddenSubtype = FALSE;
2173 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType::isaSubType($field['field_type'])) {
2174 // In registration mode params are submitted via POST and we don't have any clue
2175 // about profile-id or the profile-type (which could be a subtype)
2176 // To generalize the behavior and simplify the process,
2177 // lets always add the hidden
2178 //subtype value if there is any, and we won't have to
2179 // compute it while processing.
133e2c99 2180 if ($usedFor) {
2181 $form->addElement('hidden', $usedFor . '[contact_sub_type]', $field['field_type']);
6a488035
TO
2182 }
2183 else {
2184 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2185 }
2186 $hiddenSubtype = TRUE;
2187 }
2188
2189 if (($view && $mode != CRM_Profile_Form::MODE_SEARCH) || $isShared) {
2190 $form->freeze($name);
2191 }
2192
2193 //add the rules
2194 if (in_array($fieldName, array(
2195 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2196 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2197 }
faf468e7 2198 $stateCountryMap = array();
2199 if (!empty($form->_stateCountryMap['state_province']) && !empty($form->_stateCountryMap['country'])) {
2200 foreach ($form->_stateCountryMap['state_province'] as $key => $value) {
2201 $stateCountryMap[$key]['state_province'] = $value;
2202 $stateCountryMap[$key]['country'] = $form->_stateCountryMap['country'][$key];
2203 }
2204 CRM_Core_BAO_Address::addStateCountryMap($stateCountryMap);
2205 }
6a488035
TO
2206 if ($rule) {
2207 if (!($rule == 'email' && $mode == CRM_Profile_Form::MODE_SEARCH)) {
2208 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2209 }
2210 }
2211 }
2212
2213 /**
2214 * Function to set profile defaults
2215 *
2216 * @params int $contactId contact id
2217 * @params array $fields associative array of fields
2218 * @params array $defaults defaults array
2219 * @params boolean $singleProfile true for single profile else false(batch update)
2220 * @params int $componentId id for specific components like contribute, event etc
2221 *
2222 * @return null
2223 * @static
2224 * @access public
2225 */
2226 static function setProfileDefaults($contactId, &$fields, &$defaults,
2227 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2228 ) {
2229 if (!$componentId) {
2230 //get the contact details
2231 list($contactDetails, $options) = CRM_Contact_BAO_Contact::getHierContactDetails($contactId, $fields);
2232 $details = CRM_Utils_Array::value($contactId, $contactDetails);
2233 $multipleFields = array('website' => 'url');
2234
2235 //start of code to set the default values
2236 foreach ($fields as $name => $field) {
2237 // skip pseudo fields
2238 if (substr($name, 0, 9) == 'phone_ext') {
2239 continue;
2240 }
2241
2242 //set the field name depending upon the profile mode(single/batch)
2243 if ($singleProfile) {
2244 $fldName = $name;
2245 }
2246 else {
2247 $fldName = "field[$contactId][$name]";
2248 }
2249
2250 if ($name == 'group') {
2251 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::GROUP, $fldName);
2252 }
2253 if ($name == 'tag') {
2254 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::TAG, $fldName);
2255 }
2256
a7488080 2257 if (!empty($details[$name]) || isset($details[$name])) {
6a488035 2258 //to handle custom data (checkbox) to be written
58f00377 2259 // to handle birth/deceased date, greeting_type and few other fields
2260 if (($name == 'birth_date') || ($name == 'deceased_date')) {
6a488035
TO
2261 list($defaults[$fldName]) = CRM_Utils_Date::setDateDefaults($details[$name], 'birth');
2262 }
2263 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)) {
2264 $defaults[$fldName] = $details[$name . '_id'];
2265 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2266 }
2267 elseif ($name == 'preferred_communication_method') {
2268 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2269 foreach ($v as $item) {
2270 if ($item) {
2271 $defaults[$fldName . "[$item]"] = 1;
2272 }
2273 }
2274 }
2275 elseif ($name == 'world_region') {
2276 $defaults[$fldName] = $details['worldregion_id'];
2277 }
2278 elseif ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($name)) {
2279 //fix for custom fields
2280 $customFields = CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $details));
2281
2282 // hack to add custom data for components
2283 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2284 foreach ($components as $value) {
2285 $customFields = CRM_Utils_Array::crmArrayMerge($customFields,
2286 CRM_Core_BAO_CustomField::getFieldsForImport($value)
2287 );
2288 }
2289
2290 switch ($customFields[$customFieldId]['html_type']) {
2291 case 'Multi-Select State/Province':
2292 case 'Multi-Select Country':
2293 case 'AdvMulti-Select':
2294 case 'Multi-Select':
2295 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2296 foreach ($v as $item) {
2297 if ($item) {
2298 $defaults[$fldName][$item] = $item;
2299 }
2300 }
2301 break;
2302
2303 case 'CheckBox':
2304 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2305 foreach ($v as $item) {
2306 if ($item) {
2307 $defaults[$fldName][$item] = 1;
2308 // seems like we need this for QF style checkboxes in profile where its multiindexed
2309 // CRM-2969
2310 $defaults["{$fldName}[{$item}]"] = 1;
2311 }
2312 }
2313 break;
2314
2315 case 'Autocomplete-Select':
2316 if ($customFields[$customFieldId]['data_type'] == 'ContactReference') {
2317 if (is_numeric($details[$name])) {
2318 $defaults[$fldName . '_id'] = $details[$name];
2319 $defaults[$fldName] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $details[$name], 'sort_name');
2320 }
2321 }
2322 else {
1b4d9e39 2323 $defaults[$fldName] = $details[$name];
6a488035
TO
2324 }
2325 break;
2326
2327 case 'Select Date':
2328 // CRM-6681, set defult values according to date and time format (if any).
2329 $dateFormat = NULL;
a7488080 2330 if (!empty($customFields[$customFieldId]['date_format'])) {
fd933dc5 2331 $dateFormat = $customFields[$customFieldId]['date_format'];
6a488035
TO
2332 }
2333
a7488080 2334 if (empty($customFields[$customFieldId]['time_format'])) {
6a488035
TO
2335 list($defaults[$fldName]) = CRM_Utils_Date::setDateDefaults($details[$name], NULL,
2336 $dateFormat
2337 );
2338 }
2339 else {
2340 $timeElement = $fldName . '_time';
2341 if (substr($fldName, -1) == ']') {
2342 $timeElement = substr($fldName, 0, -1) . '_time]';
2343 }
fd933dc5
KJ
2344 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date::setDateDefaults($details[$name],
2345 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
6a488035
TO
2346 }
2347 break;
2348
2349 default:
2350 $defaults[$fldName] = $details[$name];
2351 break;
2352 }
2353 }
2354 else {
2355 $defaults[$fldName] = $details[$name];
2356 }
2357 }
2358 else {
2359 $blocks = array('email', 'phone', 'im', 'openid');
2360 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System::explode('-', $name, 3);
2361 if (!in_array($fieldName, $multipleFields)) {
2362 if (is_array($details)) {
2363 foreach ($details as $key => $value) {
2364 // when we fixed CRM-5319 - get primary loc
2365 // type as per loc field and removed below code.
2366 $primaryLocationType = FALSE;
2367 if ($locTypeId == 'Primary') {
2368 if (is_array($value) && array_key_exists($fieldName, $value)){
2369 $primaryLocationType = TRUE;
2370 if (in_array($fieldName, $blocks)){
2371 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, $fieldName);
2372 }
2373 else{
2374 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, 'address');
2375 }
2376 }
2377 }
2378
2379 // fixed for CRM-665
2380 if (is_numeric($locTypeId)) {
2381 if ($primaryLocationType || $locTypeId == CRM_Utils_Array::value('location_type_id', $value)) {
a7488080 2382 if (!empty($value[$fieldName])) {
6a488035
TO
2383 //to handle stateprovince and country
2384 if ($fieldName == 'state_province') {
2385 $defaults[$fldName] = $value['state_province_id'];
2386 }
2387 elseif ($fieldName == 'county') {
2388 $defaults[$fldName] = $value['county_id'];
2389 }
2390 elseif ($fieldName == 'country') {
6a488035
TO
2391 if (!isset($value['country_id']) || !$value['country_id']) {
2392 $config = CRM_Core_Config::singleton();
2393 if ($config->defaultContactCountry) {
2394 $defaults[$fldName] = $config->defaultContactCountry;
2395 }
2396 }
b3071092
DL
2397 else {
2398 $defaults[$fldName] = $value['country_id'];
2399 }
6a488035
TO
2400 }
2401 elseif ($fieldName == 'phone') {
2402 if ($phoneTypeId) {
2403 if (isset($value['phone'][$phoneTypeId])) {
2404 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2405 }
2406 if (isset($value['phone_ext'][$phoneTypeId])) {
2407 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2408 }
2409 }
2410 else {
2411 $phoneDefault = CRM_Utils_Array::value('phone', $value);
2412 // CRM-9216
2413 if (!is_array($phoneDefault)) {
2414 $defaults[$fldName] = $phoneDefault;
2415 }
2416 }
2417 }
2418 elseif ($fieldName == 'email') {
2419 //adding the first email (currently we don't support multiple emails of same location type)
2420 $defaults[$fldName] = $value['email'];
2421 }
2422 elseif ($fieldName == 'im') {
2423 //adding the first im (currently we don't support multiple ims of same location type)
2424 $defaults[$fldName] = $value['im'];
2425 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2426 }
2427 else {
2428 $defaults[$fldName] = $value[$fieldName];
2429 }
2430 }
2431 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2432 CRM_Utils_Array::value(substr($fieldName, 8), $value)
2433 ) {
2434 $defaults[$fldName] = $value[substr($fieldName, 8)];
2435 }
2436 }
2437 }
2438 }
2439 }
2440 }
2441 else {
2442 if (is_array($details)) {
2443 if ($fieldName === 'url') {
2444 if (!empty($details['website'])) {
2445 foreach ($details['website'] as $val) {
2446 $defaults[$fldName] = CRM_Utils_Array::value('url', $val);
2447 $defaults[$fldName . '-website_type_id'] = $val['website_type_id'];
2448 }
2449 }
2450 }
2451 }
2452 }
2453 }
2454 }
2455 }
2456
2457 //Handling Contribution Part of the batch profile
2458 if (CRM_Core_Permission::access('CiviContribute') && $component == 'Contribute') {
2459 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2460 }
2461
2462 //Handling Event Participation Part of the batch profile
2463 if (CRM_Core_Permission::access('CiviEvent') && $component == 'Event') {
2464 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2465 }
2466
2467 //Handling membership Part of the batch profile
2468 if (CRM_Core_Permission::access('CiviMember') && $component == 'Membership') {
2469 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2470 }
2471
2472 //Handling Activity Part of the batch profile
2473 if ($component == 'Activity') {
2474 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2475 }
2476 }
2477
2478 /**
2479 * Function to get profiles by type eg: pure Individual etc
2480 *
2481 * @param array $types associative array of types eg: types('Individual')
2482 * @param boolean $onlyPure true if only pure profiles are required
2483 *
2484 * @return array $profiles associative array of profiles
2485 * @static
2486 * @access public
2487 */
2488 static function getProfiles($types, $onlyPure = FALSE) {
2489 $profiles = array();
ff4f7744 2490 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
2491
2492 CRM_Utils_Hook::aclGroup(CRM_Core_Permission::ADMIN, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2493
2494 // Exclude Batch Data Entry profiles - CRM-10901
2495 $batchProfiles = CRM_Core_BAO_UFGroup::getBatchProfiles();
2496
2497 foreach ($ufGroups as $id => $title) {
2498 $ptype = CRM_Core_BAO_UFField::getProfileType($id, FALSE, $onlyPure);
2499 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2500 $profiles[$id] = $title;
2501 }
2502 }
2503 return $profiles;
2504 }
2505
2506 /**
2507 * Function to check whether a profile is valid combination of
2508 * required and/or optional profile types
2509 *
2510 * @param array $required array of types those are required
2511 * @param array $optional array of types those are optional
2512 *
2513 * @return array $profiles associative array of profiles
2514 * @static
2515 * @access public
2516 */
2517 static function getValidProfiles($required, $optional = NULL) {
2518 if (!is_array($required) || empty($required)) {
2519 return;
2520 }
2521
2522 $profiles = array();
ff4f7744 2523 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
2524
2525 CRM_Utils_Hook::aclGroup(CRM_Core_Permission::ADMIN, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2526
2527 foreach ($ufGroups as $id => $title) {
2528 $type = CRM_Core_BAO_UFField::checkValidProfileType($id, $required, $optional);
2529 if ($type) {
2530 $profiles[$id] = $title;
2531 }
2532 }
2533
2534 return $profiles;
2535 }
2536
2537 /**
2538 * Function to check whether a profile is valid combination of
2539 * required profile fields
2540 *
2541 * @param array $ufId integer id of the profile
2542 * @param array $required array of fields those are required in the profile
2543 *
2544 * @return array $profiles associative array of profiles
2545 * @static
2546 * @access public
2547 */
2548 static function checkValidProfile($ufId, $required = NULL) {
2549 $validProfile = FALSE;
2550 if (!$ufId) {
2551 return $validProfile;
2552 }
2553
2554 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2555 return $validProfile;
2556 }
2557
2558 $profileFields = self::getFields($ufId, FALSE, CRM_Core_Action::VIEW, NULL,
2559 NULL, FALSE, NULL, FALSE, NULL,
2560 CRM_Core_Permission::CREATE, NULL
2561 );
2562
2563 $validProfile = array();
2564 if (!empty($profileFields)) {
2565 $fields = array_keys($profileFields);
2566 foreach ($fields as $val) {
2567 foreach ($required as $key => $field) {
2568 if (strpos($val, $field) === 0) {
2569 unset($required[$key]);
2570 }
2571 }
2572 }
2573
2574 $validProfile = (empty($required)) ? TRUE : FALSE;
2575 }
2576
2577 return $validProfile;
2578 }
2579
2580 /**
2581 * Function to get default value for Register.
2582 *
2583 * @return $defaults
2584 * @static
2585 * @access public
2586 */
2587 static function setRegisterDefaults(&$fields, &$defaults) {
b525f1cc 2588 $config = CRM_Core_Config::singleton();
6a488035
TO
2589 foreach ($fields as $name => $field) {
2590 if (substr($name, 0, 8) == 'country-') {
b525f1cc 2591 if (!empty($config->defaultContactCountry)) {
6a488035
TO
2592 $defaults[$name] = $config->defaultContactCountry;
2593 }
2594 }
2595 elseif (substr($name, 0, 15) == 'state_province-') {
b525f1cc 2596 if (!empty($config->defaultContactStateProvince)) {
6a488035
TO
2597 $defaults[$name] = $config->defaultContactStateProvince;
2598 }
2599 }
2600 }
2601 return $defaults;
2602 }
2603
2604 /**
2605 * This function is to make a copy of a profile, including
2606 * all the fields in the profile
2607 *
2608 * @param int $id the profile id to copy
2609 *
2610 * @return void
2611 * @access public
2612 */
2613 static function copy($id) {
2614 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2615 $copy = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFGroup',
2616 array('id' => $id),
2617 NULL,
2618 $fieldsFix
2619 );
2620
2621 if ($pos = strrpos($copy->name, "_{$id}")) {
2622 $copy->name = substr_replace($copy->name, '', $pos);
2623 }
2624 $copy->name = CRM_Utils_String::munge($copy->name, '_', 56) . "_{$copy->id}";
2625 $copy->save();
2626
2627 $copyUFJoin = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFJoin',
2628 array('uf_group_id' => $id),
2629 array('uf_group_id' => $copy->id),
2630 NULL,
2631 'entity_table'
2632 );
2633
2634 $copyUFField = &CRM_Core_DAO::copyGeneric('CRM_Core_BAO_UFField',
2635 array('uf_group_id' => $id),
2636 array('uf_group_id' => $copy->id)
2637 );
2638
2639 $maxWeight = CRM_Utils_Weight::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2640
2641 //update the weight
2642 $query = "
2643UPDATE civicrm_uf_join
2644SET weight = %1
2645WHERE uf_group_id = %2
2646AND ( entity_id IS NULL OR entity_id <= 0 )
2647";
2648 $p = array(1 => array($maxWeight + 1, 'Integer'),
2649 2 => array($copy->id, 'Integer'),
2650 );
2651 CRM_Core_DAO::executeQuery($query, $p);
2652 if ($copy->is_reserved) {
2653 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2654 $params = array(1 => array($copy->id, 'Integer'));
2655 CRM_Core_DAO::executeQuery($query, $params);
2656 }
2657 CRM_Utils_Hook::copy('UFGroup', $copy);
2658
2659 return $copy;
2660 }
2661
2662 /**
2663 * Process that send notification e-mails
2664 *
2665 * @params int $contactId contact id
2666 * @params array $values associative array of name/value pair
2667 *
2668 * @return void
2669 * @access public
2670 */
2671
2672 static function commonSendMail($contactID, &$values) {
2673 if (!$contactID || !$values) {
2674 return;
2675
2676 }
2677 $template = CRM_Core_Smarty::singleton();
2678
2679 $displayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
2680 $contactID,
2681 'display_name'
2682 );
2683
2684 self::profileDisplay($values['id'], $values['values'], $template);
2685 $emailList = explode(',', $values['email']);
2686
2687 $contactLink = CRM_Utils_System::url('civicrm/contact/view',
2688 "reset=1&cid=$contactID",
2689 TRUE, NULL, FALSE, FALSE, TRUE
2690 );
2691
2692 //get the default domain email address.
2693 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
2694
2695 if (!$domainEmailAddress || $domainEmailAddress == 'info@EXAMPLE.ORG') {
2696 $fixUrl = CRM_Utils_System::url('civicrm/admin/domain', 'action=update&reset=1');
2697 CRM_Core_Error::fatal(ts('The site administrator needs to enter a valid \'FROM Email Address\' in <a href="%1">Administer CiviCRM &raquo; Communications &raquo; FROM Email Addresses</a>. The email address used may need to be a valid mail account with your email service provider.', array(1 => $fixUrl)));
2698 }
2699
2700 foreach ($emailList as $emailTo) {
2701 // FIXME: take the below out of the foreach loop
c6327d7d 2702 CRM_Core_BAO_MessageTemplate::sendTemplate(
6a488035
TO
2703 array(
2704 'groupName' => 'msg_tpl_workflow_uf',
2705 'valueName' => 'uf_notify',
2706 'contactId' => $contactID,
2707 'tplParams' => array(
2708 'displayName' => $displayName,
2709 'currentDate' => date('r'),
2710 'contactLink' => $contactLink,
2711 ),
2712 'from' => "$domainEmailName <$domainEmailAddress>",
2713 'toEmail' => $emailTo,
2714 )
2715 );
2716 }
2717 }
2718
2719 /**
2720 * Given a contact id and a group id, returns the field values from the db
2721 * for this group and notify email only if group's notify field is
2722 * set and field values are not empty
2723 *
2724 * @params $gid group id
2725 * @params $cid contact id
2726 * @params $params associative array
2727 *
2728 * @return array
2729 * @access public
2730 */
2731 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2732 if ($gid) {
2733 if (CRM_Core_BAO_UFGroup::filterUFGroups($gid, $cid) || $skipCheck) {
2734 $values = array();
2735 $fields = CRM_Core_BAO_UFGroup::getFields($gid, FALSE, CRM_Core_Action::VIEW);
2736 CRM_Core_BAO_UFGroup::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2737
2738 $email = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2739
2740 if (!empty($values) &&
2741 !empty($email)
2742 ) {
2743 $val = array(
2744 'id' => $gid,
2745 'values' => $values,
2746 'email' => $email,
2747 );
2748 return $val;
2749 }
2750 }
2751 }
2752 return NULL;
2753 }
2754
2755 /**
2756 * Function to assign uf fields to template
2757 *
2758 * @params int $gid group id
2759 * @params array $values associative array of fields
2760 *
2761 * @return void
2762 * @access public
2763 */
2764 function profileDisplay($gid, $values, $template) {
2765 $groupTitle = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2766 $template->assign('grouptitle', $groupTitle);
2767 if (count($values)) {
2768 $template->assign('values', $values);
2769 }
2770 }
2771
2772 /**
2773 * Format fields for dupe Contact Matching
2774 *
2775 * @param array $params associated array
2776 *
2777 * @return array $data assoicated formatted array
2778 * @access public
2779 * @static
2780 */
2781 static function formatFields($params, $contactId = NULL) {
2782 if ($contactId) {
2783 // get the primary location type id and email
2784 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactId);
2785 }
2786 else {
2787 $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
2788 $primaryLocationType = $defaultLocationType->id;
2789 }
2790
2791 $data = array();
2792 $locationType = array();
2793 $count = 1;
2794 $primaryLocation = 0;
2795 foreach ($params as $key => $value) {
2796 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2797
2798 if ($locTypeId == 'Primary') {
2799 $locTypeId = $primaryLocationType;
2800 }
2801
2802 if (is_numeric($locTypeId)) {
2803 if (!in_array($locTypeId, $locationType)) {
2804 $locationType[$count] = $locTypeId;
2805 $count++;
2806 }
2807 $loc = CRM_Utils_Array::key($locTypeId, $locationType);
2808
2809 $data['location'][$loc]['location_type_id'] = $locTypeId;
2810
2811 // if we are getting in a new primary email, dont overwrite the new one
2812 if ($locTypeId == $primaryLocationType) {
a7488080 2813 if (!empty($params['email-' . $primaryLocationType])) {
6a488035
TO
2814 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2815 }
2816 elseif (isset($primaryEmail)) {
2817 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2818 }
2819 $primaryLocation++;
2820 }
2821
2822 if ($loc == 1) {
2823 $data['location'][$loc]['is_primary'] = 1;
2824 }
2825 if ($fieldName == 'phone') {
2826 if ($phoneTypeId) {
2827 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2828 }
2829 else {
2830 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2831 }
2832 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2833 }
2834 elseif ($fieldName == 'email') {
2835 $data['location'][$loc]['email'][$loc]['email'] = $value;
2836 }
2837 elseif ($fieldName == 'im') {
2838 $data['location'][$loc]['im'][$loc]['name'] = $value;
2839 }
2840 else {
2841 if ($fieldName === 'state_province') {
2842 $data['location'][$loc]['address']['state_province_id'] = $value;
2843 }
2844 elseif ($fieldName === 'country') {
2845 $data['location'][$loc]['address']['country_id'] = $value;
2846 }
2847 else {
2848 $data['location'][$loc]['address'][$fieldName] = $value;
2849 }
2850 }
2851 }
2852 else {
67744c4e 2853 // TODO: prefix, suffix and gender translation may no longer be necessary - check inputs
6a488035
TO
2854 if ($key === 'individual_suffix') {
2855 $data['suffix_id'] = $value;
2856 }
2857 elseif ($key === 'individual_prefix') {
2858 $data['prefix_id'] = $value;
2859 }
2860 elseif ($key === 'gender') {
2861 $data['gender_id'] = $value;
2862 }
2863 elseif (substr($key, 0, 6) === 'custom') {
2864 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
2865 //fix checkbox
2866 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2867 $value = implode(CRM_Core_DAO::VALUE_SEPARATOR, array_keys($value));
2868 }
2869 // fix the date field
2870 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2871 $date = CRM_Utils_Date::format($value);
2872 if (!$date) {
2873 $date = '';
2874 }
2875 $value = $date;
2876 }
2877
2878 $data['custom'][$customFieldID] = array(
2879 'id' => $id,
2880 'value' => $value,
2881 'extends' => $customFields[$customFieldID]['extends'],
2882 'type' => $customFields[$customFieldID]['data_type'],
2883 'custom_field_id' => $customFieldID,
2884 );
2885 }
2886 }
2887 elseif ($key == 'edit') {
2888 continue;
2889 }
2890 else {
2891 $data[$key] = $value;
2892 }
2893 }
2894 }
2895
2896 if (!$primaryLocation) {
2897 $loc++;
2898 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2899 }
2900
2901
2902 return $data;
2903 }
2904
2905 /**
2906 * calculate the profile type 'group_type' as per profile fields.
2907 *
2908 * @param int $gid profile id
2909 * @param int $ignoreFieldId ignore particular profile field
2910 *
2911 * @return array list of calculated group type
2912 */
2913 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2914 //get the profile fields.
2915 $ufFields = self::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2916 return self::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2917 }
2918
2919 /**
2920 * calculate the profile type 'group_type' as per profile fields.
2921 *
2922 * @param int $gid profile id
2923 * @param int $ignoreFieldId ignore perticular profile field
2924 *
2925 * @return array list of calculated group type
2926 */
2927 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2928 $groupType = $groupTypeValues = $customFieldIds = array();
2929 if (!empty($ufFields)) {
2930 foreach ($ufFields as $fieldName => $fieldValue) {
2931 //ignore field from group type when provided.
2932 //in case of update profile field.
2933 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2934 continue;
2935 }
2936 if (!in_array($fieldValue['field_type'], $groupType)) {
2937 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2938 }
2939
2940 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField::getKeyID($fieldName))) {
2941 $customFieldIds[$fldId] = $fldId;
2942 }
2943 }
2944 }
2945
2946 if (!empty($customFieldIds)) {
2947 $query = 'SELECT DISTINCT(cg.id), cg.extends, cg.extends_entity_column_id, cg.extends_entity_column_value FROM civicrm_custom_group cg LEFT JOIN civicrm_custom_field cf ON cf.custom_group_id = cg.id WHERE cg.extends_entity_column_value IS NOT NULL AND cf.id IN (' . implode(',', $customFieldIds) . ')';
2948
2949 $customGroups = CRM_Core_DAO::executeQuery($query);
2950 while ($customGroups->fetch()) {
2951 if (!$customGroups->extends_entity_column_value) {
2952 continue;
2953 }
2954
2955 $groupTypeName = "{$customGroups->extends}Type";
2956 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id) {
2957 $groupTypeName = CRM_Core_OptionGroup::getValue('custom_data_type', $customGroups->extends_entity_column_id, 'value', 'String', 'name');
2958 }
2959
2960 foreach (explode(CRM_Core_DAO::VALUE_SEPARATOR, $customGroups->extends_entity_column_value) as $val) {
2961 if ($val) {
2962 $groupTypeValues[$groupTypeName][$val] = $val;
2963 }
2964 }
2965 }
2966
2967 if (!empty($groupTypeValues)) {
2968 $groupType = array_merge($groupType, $groupTypeValues);
2969 }
2970 }
2971
2972 return $groupType;
2973 }
2974
2975 /**
2976 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
2977 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
2978 *
2979 * FIELDS GROUP_TYPE
2980 * BirthDate + Email Individual,Contact
2981 * BirthDate + Subject Individual,Activity
2982 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
2983 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
2984 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
2985 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2986 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2987 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
2988 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
2989 *
2990 * @param Integer $gid profile id
2991 * @param Array $groupTypes With key having group type names
2992 *
2993 * @return Boolean
2994 */
2995 static function updateGroupTypes($gId, $groupTypes = array(
2996 )) {
2997 if (!is_array($groupTypes) || !$gId) {
2998 return FALSE;
2999 }
3000
3001 // If empty group types set group_type as 'null'
3002 if (empty($groupTypes)) {
3003 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
3004 }
3005
1cb28d5d 3006 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity', 'Case');
6a488035
TO
3007 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType::subTypes());
3008
3009 $gTypes = $gTypeValues = array();
3010
3011 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3012 // Get valid group type and group subtypes
3013 foreach ($groupTypes as $groupType => $value) {
3014 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
3015 $gTypes[] = $groupType;
3016 }
3017
3018 $subTypesOf = NULL;
3019
3020 if (in_array($groupType, $participantExtends)) {
3021 $subTypesOf = $groupType;
3022 }
3023 elseif (strpos($groupType, 'Type') > 0) {
3024 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
3025 }
3026 else {
3027 continue;
3028 }
3029
3030 if (!empty($value) &&
3031 (in_array($subTypesOf, $componentGroupTypes) ||
3032 in_array($subTypesOf, $participantExtends)
3033 )
3034 ) {
3035 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3036 }
3037 }
3038
3039 if (empty($gTypes)) {
3040 return FALSE;
3041 }
3042
3043 // Build String to store group types and group subtypes
3044 $groupTypeString = implode(',', $gTypes);
3045 if (!empty($gTypeValues)) {
3046 $groupTypeString .= CRM_Core_DAO::VALUE_SEPARATOR . implode(',', $gTypeValues);
3047 }
3048
3049 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3050 }
3051
3052 /**
3053 * Create a "group_type" string
3054 *
3055 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3056 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3057 * @param string $delim
3058 * @throws CRM_Core_Exception
3059 */
3060 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO::VALUE_SEPARATOR) {
3061 $groupTypeExpr = '';
3062 if ($coreTypes) {
3063 $groupTypeExpr .= implode(',', $coreTypes);
3064 }
3065 if ($subTypes) {
3066 if (count($subTypes) > 1) {
3067 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3068 }
3069 foreach ($subTypes as $subType => $subTypeIds) {
3070 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3071 }
3072 }
3073 return $groupTypeExpr;
3074 }
3075
3076 /**
3077 * This function is used to setDefault componet specific profile fields.
3078 *
3079 * @param array $fields profile fields.
3080 * @param int $componentId componetID
3081 * @param string $component component name
3082 * @param array $defaults an array of default values.
3083 *
3084 * @return void.
3085 */
f0385140 3086 public static function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
6a488035
TO
3087 if (!$componentId ||
3088 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3089 ) {
3090 return;
3091 }
3092
3093 $componentBAO = $componentSubType = NULL;
3094 switch ($component) {
3095 case 'Membership':
3096 $componentBAO = 'CRM_Member_BAO_Membership';
3097 $componentBAOName = 'Membership';
3098 $componentSubType = array('membership_type_id');
3099 break;
3100
3101 case 'Contribute':
3102 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3103 $componentBAOName = 'Contribution';
3104 $componentSubType = array( 'financial_type_id' );
3105 break;
3106
3107 case 'Event':
3108 $componentBAO = 'CRM_Event_BAO_Participant';
3109 $componentBAOName = 'Participant';
3110 $componentSubType = array('role_id', 'event_id');
3111 break;
3112
3113 case 'Activity':
3114 $componentBAO = 'CRM_Activity_BAO_Activity';
3115 $componentBAOName = 'Activity';
3116 $componentSubType = array('activity_type_id');
3117 break;
3118 }
3119
3120 $values = array();
3121 $params = array('id' => $componentId);
3122
3123 //get the component values.
3124 CRM_Core_DAO::commonRetrieve($componentBAO, $params, $values);
3125
3126 $formattedGroupTree = array();
3127 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3128 foreach ($fields as $name => $field) {
3129 $fldName = $isStandalone ? $name : "field[$componentId][$name]";
3130 if (in_array($name, $dateTimeFields)) {
3131 $timefldName = $isStandalone ? "{$name}_time" : "field[$componentId][{$name}_time]";
a7488080 3132 if (!empty($values[$name])) {
6a488035
TO
3133 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date::setDateDefaults($values[$name]);
3134 }
3135 }
3136 elseif (array_key_exists($name, $values)) {
3137 $defaults[$fldName] = $values[$name];
3138 }
3139 elseif ($name == 'participant_note') {
3140 $noteDetails = CRM_Core_BAO_Note::getNote($componentId, 'civicrm_participant');
3141 $defaults[$fldName] = array_pop($noteDetails);
3142 }
3143 elseif (in_array($name, array(
3144 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3145 $defaults[$fldName] = $values["{$name}_id"];
3146 }
3147 elseif ($name == 'membership_type') {
3148 // since membership_type field is a hierselect -
3149 $defaults[$fldName][0] =
3150 CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3151 $defaults[$fldName][1] = $values['membership_type_id'];
3152 }
3153 elseif ($name == 'membership_status') {
3154 $defaults[$fldName] = $values['status_id'];
3155 }
3156 elseif ($customFieldInfo = CRM_Core_BAO_CustomField::getKeyID($name, TRUE)) {
3157 if (empty($formattedGroupTree)) {
3158 //get the groupTree as per subTypes.
3159 $groupTree = array();
3160 foreach ($componentSubType as $subType) {
3161 $subTree = CRM_Core_BAO_CustomGroup::getTree($componentBAOName, CRM_Core_DAO::$_nullObject,
3162 $componentId, 0, $values[$subType]
3163 );
3164 $groupTree = CRM_Utils_Array::crmArrayMerge($groupTree, $subTree);
3165 }
3166 $formattedGroupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree, 1, CRM_Core_DAO::$_nullObject);
3167 CRM_Core_BAO_CustomGroup::setDefaults($formattedGroupTree, $defaults);
3168 }
3169
3170 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3171 foreach ($defaults as $customKey => $customValue) {
3172 if ($customFieldDetails = CRM_Core_BAO_CustomField::getKeyID($customKey, TRUE)) {
3173 if ($name == 'custom_' . $customFieldDetails[0]) {
3174
3175 //hack to set default for checkbox
3176 //basically this is for weired field name like field[33][custom_19]
3177 //we are converting this field name to array structure and assign value.
3178 $skipValue = FALSE;
3179
3180 foreach ($formattedGroupTree as $tree) {
3181 if ('CheckBox' == CRM_Utils_Array::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3182 $skipValue = TRUE;
3183 $defaults['field'][$componentId][$name] = $customValue;
3184 break;
3185 }
3186 elseif (CRM_Utils_Array::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3187 $skipValue = TRUE;
3188
3189 // CRM-6681, $default contains formatted date, time values.
3190 $defaults[$fldName] = $customValue;
a7488080 3191 if (!empty($defaults[$customKey . '_time'])) {
6a488035
TO
3192 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3193 }
3194 }
3195 }
3196
3197 if (!$skipValue || $isStandalone) {
3198 $defaults[$fldName] = $customValue;
3199 }
3200 unset($defaults[$customKey]);
3201 break;
3202 }
3203 }
3204 }
3205 }
3206 }
3207 }
3208
79ae07d9
CW
3209 /**
3210 * @param array|string $profiles - name of profile(s) to create links for
3211 * @param array $appendProfiles - name of profile(s) to append to each link
3212 */
a4799f04
CW
3213 static function getCreateLinks($profiles = '', $appendProfiles = array()) {
3214 // Default to contact profiles
3215 if (!$profiles) {
3216 $profiles = array('new_individual', 'new_organization', 'new_household');
3217 }
79ae07d9 3218 $profiles = (array) $profiles;
1a90e0dd 3219 $toGet = array_merge($profiles, (array) $appendProfiles);
79ae07d9
CW
3220 $retrieved = civicrm_api3('uf_group', 'get', array(
3221 'name' => array('IN' => $toGet),
3222 'is_active' => 1,
3223 ));
3224 $links = $append = array();
3225 if (!empty($retrieved['values'])) {
3226 foreach($retrieved['values'] as $id => $profile) {
3227 if (in_array($profile['name'], $profiles)) {
3228 $links[] = array(
3229 'label' => $profile['title'],
a4799f04
CW
3230 'url' => CRM_Utils_System::url('civicrm/profile/create', "reset=1&context=dialog&gid=$id",
3231 NULL, NULL, FALSE, NULL, FALSE) ,
3232 'type' => ucfirst(str_replace('new_', '', $profile['name'])),
79ae07d9
CW
3233 );
3234 }
3235 else {
3236 $append[] = $id;
3237 }
3238 }
3239 foreach ($append as $id) {
3240 foreach ($links as &$link) {
3241 $link['url'] .= ",$id";
3242 }
3243 }
3244 }
3245 return $links;
3246 }
3247
6a488035
TO
3248 /**
3249 * Function to retrieve groups of profiles
3250 *
3251 * @param integer $profileID id of the profile
3252 *
3253 * @return array returns array
3254 * @static
3255 */
3256 static function profileGroups($profileID) {
3257 $groupTypes = array();
3258 $profileTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3259 if ($profileTypes) {
3260 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $profileTypes);
3261 $groupTypes = explode(',', $groupTypeParts[0]);
3262 }
3263 return $groupTypes;
3264 }
3265
3266 /**
3267 * Function to alter contact params by filtering existing subscribed groups and returns
3268 * unsubscribed groups array for subscription.
3269 *
3270 * @param array $params contact params
3271 * @param int $contactId user contact id
3272 *
3273 * @return array $subscribeGroupIds This contains array of groups for subscription
3274 */
3275 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3276 $config = CRM_Core_Config::singleton();
3277 $subscribeGroupIds = array();
3278
3279 // process further only if profileDoubleOptIn enabled and if groups exist
3280 if (!array_key_exists('group', $params) ||
3281 !self::isProfileDoubleOptin() ||
3282 CRM_Utils_System::isNull($params['group'])
3283 ) {
3284 return $subscribeGroupIds;
3285 }
3286
3287 //check if contact email exist.
3288 $hasEmails = FALSE;
3289 foreach ($params as $name => $value) {
3290 if (strpos($name, 'email-') !== FALSE) {
3291 $hasEmails = TRUE;
3292 break;
3293 }
3294 }
3295
3296 //Proceed furthur only if email present
3297 if (!$hasEmails) {
3298 return $subscribeGroupIds;
3299 }
3300
3301 //do check for already subscriptions.
3302 $contactGroups = array();
3303 if ($contactId) {
3304 $query = "
3305SELECT group_id
3306 FROM civicrm_group_contact
3307 WHERE status = 'Added'
3308 AND contact_id = %1";
3309
3310 $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($contactId, 'Integer')));
3311 while ($dao->fetch()) {
3312 $contactGroups[$dao->group_id] = $dao->group_id;
3313 }
3314 }
3315
3316 //since we don't have names, compare w/ label.
3317 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup::values('group_type'));
3318
3319 //actual processing start.
3320 foreach ($params['group'] as $groupId => $isSelected) {
3321 //unset group those are not selected.
3322 if (!$isSelected) {
3323 unset($params['group'][$groupId]);
3324 continue;
3325 }
3326
3327 $groupTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR,
3328 CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3329 );
3330 //get only mailing type group and unset it from params
3331 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3332 $subscribeGroupIds[$groupId] = $groupId;
3333 unset($params['group'][$groupId]);
3334 }
3335 }
3336
3337 return $subscribeGroupIds;
3338 }
3339
3340 /**
3341 * Function to check if we are rendering mixed profiles
3342 *
3343 * @param array $profileIds associated array of profile ids
3344 *
3345 * @return boolean $mixProfile true if profile is mixed
3346 * @static
3347 * @access public
3348 */
3349 static function checkForMixProfiles($profileIds) {
3350 $mixProfile = FALSE;
3351
3352 $contactTypes = array('Individual', 'Household', 'Organization');
3353 $subTypes = CRM_Contact_BAO_ContactType::subTypes();
3354
3355 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3356
3357 $typeCount = array('ctype' => array(), 'subtype' => array());
3358 foreach ($profileIds as $gid) {
3359 $profileType = CRM_Core_BAO_UFField::getProfileType($gid);
3360 // ignore profile of type Contact
3361 if ($profileType == 'Contact') {
3362 continue;
3363 }
3364 if (in_array($profileType, $contactTypes)) {
3365 if (!isset($typeCount['ctype'][$profileType])) {
3366 $typeCount['ctype'][$profileType] = 1;
3367 }
3368
3369 // check if we are rendering profile of different contact types
3370 if (count($typeCount['ctype']) == 2) {
3371 $mixProfile = TRUE;
3372 break;
3373 }
3374 }
3375 elseif (in_array($profileType, $components)) {
3376 $mixProfile = TRUE;
3377 break;
3378 }
3379 else {
3380 if (!isset($typeCount['subtype'][$profileType])) {
3381 $typeCount['subtype'][$profileType] = 1;
3382 }
3383 // check if we are rendering profile of different contact sub types
3384 if (count($typeCount['subtype']) == 2) {
3385 $mixProfile = TRUE;
3386 break;
3387 }
3388 }
3389 }
3390 return $mixProfile;
3391 }
3392
3393 /**
3394 * Funtion to determine of we show overlay profile or not
3395 *
3396 * @return boolean true if profile should be shown else false
3397 * @static
3398 * @access public
3399 */
3400 static function showOverlayProfile() {
3401 $showOverlay = TRUE;
3402
3403 // get the id of overlay profile
3404 $overlayProfileId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3405 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3406
3407 $count = CRM_Core_DAO::singleValueQuery($query);
3408
3409 //check if there are no public fields and use is anonymous
3410 $session = CRM_Core_Session::singleton();
3411 if (!$count && !$session->get('userID')) {
3412 $showOverlay = FALSE;
3413 }
3414
3415 return $showOverlay;
3416 }
3417
3418 /**
3419 * function to get group type values of the profile
3420 *
3421 * @params Integer $profileId Profile Id
3422 * @params String $groupType Group Type
3423 *
3424 * @return Array group type values
3425 * @static
3426 * @access public
3427 */
3428 static function groupTypeValues($profileId, $groupType = NULL) {
3429 $groupTypeValue = array();
3430 $groupTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3431
3432 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $groupTypes);
a7488080 3433 if (empty($groupTypeParts[1])) {
6a488035
TO
3434 return $groupTypeValue;
3435 }
3436 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3437
3438 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3439 $values = array();
3440 $valueParts = explode(':', $groupTypeValues);
3441 if ($groupType &&
3442 ($valueParts[0] != "{$groupType}Type" ||
3443 ($groupType == 'Participant' &&
3444 !in_array($valueParts[0], $participantExtends)
3445 )
3446 )
3447 ) {
3448 continue;
3449 }
3450 foreach ($valueParts as $val) {
3451 if (CRM_Utils_Rule::integer($val)) {
3452 $values[$val] = $val;
3453 }
3454 }
3455 if (!empty($values)) {
3456 $typeName = substr($valueParts[0], 0, -4);
3457 if (in_array($valueParts[0], $participantExtends)) {
3458 $typeName = $valueParts[0];
3459 }
3460 $groupTypeValue[$typeName] = $values;
3461 }
3462 }
3463
3464 return $groupTypeValue;
3465 }
3466
3467 static function isProfileDoubleOptin() {
3468 // check for double optin
3469 $config = CRM_Core_Config::singleton();
3470 if (in_array('CiviMail', $config->enableComponents)) {
3471 return CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
3472 'profile_double_optin', NULL, FALSE
3473 );
3474 }
3475 return FALSE;
3476 }
3477
3478 static function isProfileAddToGroupDoubleOptin() {
3479 // check for add to group double optin
3480 $config = CRM_Core_Config::singleton();
3481 if (in_array('CiviMail', $config->enableComponents)) {
3482 return CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
3483 'profile_add_to_group_double_optin', NULL, FALSE
3484 );
3485 }
3486 return FALSE;
3487 }
3488
3489 /**
3490 * get profiles used for batch entry
3491 *
3492 * @return array profileIds profile ids
3493 * @static
3494 */
3495 static function getBatchProfiles() {
3496 $query = "SELECT id
3497 FROM civicrm_uf_group
3498 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3499 $dao = CRM_Core_DAO::executeQuery( $query );
3500 $profileIds = array();
3501 while( $dao->fetch() ) {
3502 $profileIds[$dao->id] = $dao->id;
3503 }
3504 return $profileIds;
3505 }
3506
3507 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3508 $multiSummaryFields = $returnMultiSummaryFields ? array( ) : NULL;
3509 foreach ($source as $field => $properties) {
3510 if (!CRM_Core_BAO_CustomField::getKeyID($field)) {
3511 continue;
3512 }
3513 if (CRM_Core_BAO_CustomField::isMultiRecordField($field)) {
3514 $destination[$field] = $properties;
3515 if ($returnMultiSummaryFields) {
3516 if ($properties['is_multi_summary']) {
3517 $multiSummaryFields[$field] = $properties;
3518 }
3519 }
3520 unset($source[$field]);
3521 }
3522 }
3523 return $multiSummaryFields;
3524 }
3525
3526 /**
3527 * This is function is used to format pseudo fields
3528 *
3529 * @param array $fields associated array of profile fields
3530 *
3531 * @static
3532 */
3533 static function reformatProfileFields(&$fields) {
3534 //reformat fields array
3535 foreach ($fields as $name => $field) {
3536 //reformat phone and extension field
3537 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3538 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3539
3540 // retain existing element properties and just update and replace key
3541 CRM_Utils_Array::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3542 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3543 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3544
3545 // add additional phone extension field
3546 $fields["phone_ext-{$fieldSuffix}"] = $field;
3547 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3548 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3549 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3550 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3551 //ignore required for extension field
3552 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;
3553 }
3554 }
3555 }
3556}