Merge remote-tracking branch 'upstream/4.3' into 4.3-master-2013-09-25-01-46-57
[civicrm-core.git] / CRM / Core / BAO / UFGroup.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
232624b1 4 | CiviCRM version 4.4 |
6a488035
TO
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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
31 * @copyright CiviCRM LLC (c) 2004-2013
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) {
172 if (!CRM_Utils_Array::value($name, $fields)) {
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
649 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
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
931 if (CRM_Utils_Array::value('skipDisplay', $field)) {
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
943 if (CRM_Utils_Array::value($index, $values)) {
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
827659b2 952 if (in_array(substr($name, -6), array('gender', 'prefix', 'suffix'))) {
953 $values[$index] = $details->$name;
954 $idColumn = "{$name}_id";
955 $params[$index] = $details->$idColumn;
6a488035
TO
956 }
957 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)) {
958 $dname = $name . '_display';
959 $values[$index] = $details->$dname;
960 $name = $name . '_id';
961 $params[$index] = $details->$name;
962 }
963 elseif (in_array($name, array(
964 'state_province', 'country', 'county'))) {
965 $values[$index] = $details->$name;
966 $idx = $name . '_id';
967 $params[$index] = $details->$idx;
968 }
969 elseif ($name === 'preferred_communication_method') {
e7e657f0 970 $communicationFields = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
6a488035
TO
971 $compref = array();
972 $pref = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details->$name);
973
974 foreach ($pref as $k) {
975 if ($k) {
976 $compref[] = $communicationFields[$k];
977 }
978 }
979 $params[$index] = $details->$name;
980 $values[$index] = implode(',', $compref);
981 }
982 elseif ($name === 'preferred_language') {
6a488035 983 $params[$index] = $details->$name;
a8c23526 984 $values[$index] = CRM_Core_PseudoConstant::getLabel('CRM_Contact_DAO_Contact', 'preferred_language', $details->$name);
6a488035
TO
985 }
986 elseif ($name == 'group') {
987 $groups = CRM_Contact_BAO_GroupContact::getContactGroup($cid, 'Added', NULL, FALSE, TRUE);
988 $title = $ids = array();
989
990 foreach ($groups as $g) {
991 // CRM-8362: User and User Admin visibility groups should be included in display if user has
992 // VIEW permission on that group
993 $groupPerm = CRM_Contact_BAO_Group::checkPermission($g['group_id'], $g['title']);
994
995 if ($g['visibility'] != 'User and User Admin Only' ||
996 CRM_Utils_Array::key(CRM_Core_Permission::VIEW, $groupPerm)
997 ) {
998 $title[] = $g['title'];
999 if ($g['visibility'] == 'Public Pages') {
1000 $ids[] = $g['group_id'];
1001 }
1002 }
1003 }
1004 $values[$index] = implode(', ', $title);
1005 $params[$index] = implode(',', $ids);
1006 }
1007 elseif ($name == 'tag') {
1008 $entityTags = CRM_Core_BAO_EntityTag::getTag($cid);
cd43c5e3 1009 $allTags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
1010 $title = array();
1011 foreach ($entityTags as $tagId) {
1012 $title[] = $allTags[$tagId];
1013 }
1014 $values[$index] = implode(', ', $title);
1015 $params[$index] = implode(',', $entityTags);
1016 }
1017 elseif ($name == 'activity_status_id') {
1018 $activityStatus = CRM_Core_PseudoConstant::activityStatus();
1019 $values[$index] = $activityStatus[$details->$name];
1020 $params[$index] = $details->$name;
1021 }
1022 elseif ($name == 'activity_date_time') {
1023 $values[$index] = CRM_Utils_Date::customFormat($details->$name);
1024 $params[$index] = $details->$name;
1025 }
1026 elseif ($name == 'contact_sub_type') {
1027 $contactSubTypeNames = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details->$name);
1028 if (!empty($contactSubTypeNames)) {
1029 $contactSubTypeLabels = array();
1030 // get all contact subtypes
1031 $allContactSubTypes = CRM_Contact_BAO_ContactType::subTypeInfo();
1032 // build contact subtype labels array
1033 foreach( $contactSubTypeNames as $cstName ) {
1034 if ($cstName) {
1035 $contactSubTypeLabels[] = $allContactSubTypes[$cstName]['label'];
1036 }
1037 }
1038 $values[$index] = implode(',', $contactSubTypeLabels);
1039 }
1040
1041 $params[$index] = $details->$name;
1042 }
1043 else {
1044 if (substr($name, 0, 7) === 'do_not_' || substr($name, 0, 3) === 'is_') {
1045 if ($details->$name) {
1046 $values[$index] = '[ x ]';
1047 }
1048 }
1049 else {
1050 if ($cfID = CRM_Core_BAO_CustomField::getKeyID($name)) {
1051 $htmlType = $field['html_type'];
1052
1053 // field_type is only set when we are retrieving profile values
1054 // when sending email, we call the same function to get custom field
1055 // values etc, i.e. emulating a profile
1056 $fieldType = CRM_Utils_Array::value('field_type', $field);
1057
1058 if ($htmlType == 'File') {
1059 $entityId = $cid;
1060 if (!$cid &&
1061 $fieldType == 'Activity' &&
1062 CRM_Utils_Array::value(2, $componentWhere[0])
1063 ) {
1064 $entityId = $componentWhere[0][2];
1065 }
1066
1067 $fileURL = CRM_Core_BAO_CustomField::getFileURL($entityId,
1068 $cfID,
1069 NULL,
1070 $absolute
1071 );
1072 $params[$index] = $values[$index] = $fileURL['file_url'];
1073 }
1074 else {
1075 $customVal = NULL;
1076 if (isset($dao) && property_exists($dao, 'data_type') &&
1077 ($dao->data_type == 'Int' ||
1078 $dao->data_type == 'Boolean'
1079 )
1080 ) {
1081 $customVal = (int )($details->{$name});
1082 }
1083 elseif (isset($dao) && property_exists($dao, 'data_type')
1084 && $dao->data_type == 'Float'
1085 ) {
1086 $customVal = (float )($details->{$name});
1087 }
1088 elseif (!CRM_Utils_System::isNull(explode(CRM_Core_DAO::VALUE_SEPARATOR,
1089 $details->{$name}
1090 ))) {
1091 $customVal = $details->{$name};
1092 }
1093
1094 //CRM-4582
1095 if (CRM_Utils_System::isNull($customVal)) {
1096 continue;
1097 }
1098
1099 $params[$index] = $customVal;
1100 $values[$index] = CRM_Core_BAO_CustomField::getDisplayValue($customVal,
1101 $cfID,
1102 $options
1103 );
1104 if ($htmlType == 'Autocomplete-Select') {
1105 $params[$index] = $values[$index];
1106 }
1107 if (CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField',
1108 $cfID, 'is_search_range'
1109 )) {
1110 $customFieldName = "{$name}_from";
1111 }
1112 }
1113 }
1114 elseif ($name == 'image_URL') {
1115 list($width, $height) = getimagesize($details->$name);
1116 list($thumbWidth, $thumbHeight) = CRM_Contact_BAO_Contact::getThumbSize($width, $height);
1117
1118 $image_URL = '<img src="' . $details->$name . '" height= ' . $thumbHeight . ' width= ' . $thumbWidth . ' />';
1119 $values[$index] = "<a href='#' onclick='contactImagePopUp(\"{$details->$name}\", {$width}, {$height});'>{$image_URL}</a>";
1120 }
1121 elseif (in_array($name, array(
1122 'birth_date', 'deceased_date', 'membership_start_date', 'membership_end_date', 'join_date'))) {
1123 $values[$index] = CRM_Utils_Date::customFormat($details->$name);
1124 $params[$index] = CRM_Utils_Date::isoToMysql($details->$name);
1125 }
1126 else {
1127 $dao = '';
1128 if ($index == 'Campaign') {
1129 $dao = 'CRM_Campaign_DAO_Campaign';
1130 }
1131 elseif ($index == 'Contribution Page') {
1132 $dao = 'CRM_Contribute_DAO_ContributionPage';
1133 }
1134 if ($dao) {
1135 $value = CRM_Core_DAO::getFieldValue($dao, $details->$name, 'title');
1136 }
1137 else {
1138 $value = $details->$name;
1139 }
1140 $values[$index] = $value;
1141 }
1142 }
1143 }
1144 }
1145 elseif (strpos($name, '-') !== FALSE) {
1146 list($fieldName, $id, $type) = CRM_Utils_System::explode('-', $name, 3);
1147
1148 if (!in_array($fieldName, $multipleFields)) {
1149 if ($id == 'Primary') {
1150 // fix for CRM-1543
1151 // not sure why we'd every use Primary location type id
1152 // we need to fix the source if we are using it
1153 // $locationTypeName = CRM_Contact_BAO_Contact::getPrimaryLocationType( $cid );
1154 $locationTypeName = 1;
1155 }
1156 else {
1157 $locationTypeName = CRM_Utils_Array::value($id, $locationTypes);
1158 }
1159
1160 if (!$locationTypeName) {
1161 continue;
1162 }
1163
1164 $detailName = "{$locationTypeName}-{$fieldName}";
1165 $detailName = str_replace(' ', '_', $detailName);
1166
1167 if (in_array($fieldName, array(
1168 'phone', 'im', 'email', 'openid'))) {
1169 if ($type) {
1170 $detailName .= "-{$type}";
1171 }
1172 }
1173
1174 if (in_array($fieldName, array(
1175 'state_province', 'country', 'county'))) {
1176 $values[$index] = $details->$detailName;
1177 $idx = $detailName . '_id';
1178 $params[$index] = $details->$idx;
1179 }
1180 elseif ($fieldName == 'im') {
1181 $providerId = $detailName . '-provider_id';
1182 $providerName = $imProviders[$details->$providerId];
1183 if ($providerName) {
1184 $values[$index] = $details->$detailName . " (" . $providerName . ")";
1185 }
1186 else {
1187 $values[$index] = $details->$detailName;
1188 }
1189 $params[$index] = $details->$detailName;
1190 }
1191 elseif ($fieldName == 'phone') {
1192 $phoneExtField = str_replace('phone', 'phone_ext', $detailName);
1193 if (isset($details->$phoneExtField)) {
1194 $values[$index] = $details->$detailName . " (" . $details->$phoneExtField . ")";
1195 }
1196 else {
1197 $values[$index] = $details->$detailName;
1198 }
1199 $params[$index] = $details->$detailName;
1200 }
1201 else {
1202 $values[$index] = $params[$index] = $details->$detailName;
1203 }
1204 }
1205 else {
1206 $detailName = "website-{$id}-{$fieldName}";
1207 $url = CRM_Utils_System::fixURL($details->$detailName);
1208 if ($details->$detailName) {
1209 $websiteTypeId = "website-{$id}-website_type_id";
1210 $websiteType = $websiteTypes[$details->$websiteTypeId];
1211 $values[$index] = "<a href=\"$url\">{$details->$detailName} ( {$websiteType} )</a>";
1212 }
1213 else {
1214 $values[$index] = '';
1215 }
1216 }
1217 }
1218
1219 if ((CRM_Utils_Array::value('visibility', $field) == 'Public Pages and Listings') &&
1220 CRM_Core_Permission::check('profile listings and forms')
1221 ) {
1222
1223 if (CRM_Utils_System::isNull($params[$index])) {
1224 $params[$index] = $values[$index];
1225 }
1226 if (!isset($params[$index])) {
1227 continue;
1228 }
1229 if (!$customFieldName) {
1230 $fieldName = $field['name'];
1231 }
1232 else {
1233 $fieldName = $customFieldName;
1234 }
1235
1236 $url = NULL;
1237 if (CRM_Core_BAO_CustomField::getKeyID($field['name'])) {
1238 $htmlType = $field['html_type'];
1239 if ($htmlType == 'Link') {
1240 $url = $params[$index];
1241 }
1242 elseif (in_array($htmlType, array(
1243 'CheckBox', 'Multi-Select', 'AdvMulti-Select',
1244 'Multi-Select State/Province', 'Multi-Select Country',
1245 ))) {
1246 $valSeperator = CRM_Core_DAO::VALUE_SEPARATOR;
1247 $selectedOptions = explode($valSeperator, $params[$index]);
1248
1249 foreach ($selectedOptions as $key => $multiOption) {
1250 if ($multiOption) {
1251 $url[] = CRM_Utils_System::url('civicrm/profile',
1252 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1253 urlencode($fieldName) .
1254 '=' .
1255 urlencode($multiOption)
1256 );
1257 }
1258 }
1259 }
1260 else {
1261 $url = CRM_Utils_System::url('civicrm/profile',
1262 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1263 urlencode($fieldName) .
1264 '=' .
1265 urlencode($params[$index])
1266 );
1267 }
1268 }
1269 else {
1270 $url = CRM_Utils_System::url('civicrm/profile',
1271 'reset=1&force=1&gid=' . $field['group_id'] . '&' .
1272 urlencode($fieldName) .
1273 '=' .
1274 urlencode($params[$index])
1275 );
1276 }
1277
1278 if ($url &&
1279 !empty($values[$index]) &&
1280 $searchable
1281 ) {
1282
1283 if (is_array($url) && !empty($url)) {
1284 $links = array();
1285 $eachMultiValue = explode(', ', $values[$index]);
1286 foreach ($eachMultiValue as $key => $valueLabel) {
1287 $links[] = '<a href="' . $url[$key] . '">' . $valueLabel . '</a>';
1288 }
1289 $values[$index] = implode(', ', $links);
1290 }
1291 else {
1292 $values[$index] = '<a href="' . $url . '">' . $values[$index] . '</a>';
1293 }
1294 }
1295 }
1296 }
1297 }
1298
1299 /**
1300 * Check if profile Group used by any module.
1301 *
1302 * @param int $id profile Id
1303 *
1304 * @return boolean
1305 *
1306 * @access public
1307 * @static
1308 *
1309 */
1310 public static function usedByModule($id) {
1311 //check whether this group is used by any module(check uf join records)
1312 $sql = "SELECT id
1313 FROM civicrm_uf_join
1314 WHERE civicrm_uf_join.uf_group_id=$id";
1315
1316 $dao = new CRM_Core_DAO();
1317 $dao->query($sql);
1318 if ($dao->fetch()) {
1319 return TRUE;
1320 }
1321 else {
1322 return FALSE;
1323 }
1324 }
1325
1326 /**
1327 * Delete the profile Group.
1328 *
1329 * @param int $id profile Id
1330 *
1331 * @return boolean
1332 *
1333 * @access public
1334 * @static
1335 *
1336 */
1337 public static function del($id) {
1338 //check whether this group contains any profile fields
1339 $profileField = new CRM_Core_DAO_UFField();
1340 $profileField->uf_group_id = $id;
1341 $profileField->find();
1342 while ($profileField->fetch()) {
1343 CRM_Core_BAO_UFField::del($profileField->id);
1344 }
1345
1346 //delete records from uf join table
1347 $ufJoin = new CRM_Core_DAO_UFJoin();
1348 $ufJoin->uf_group_id = $id;
1349 $ufJoin->delete();
1350
1351 //delete profile group
1352 $group = new CRM_Core_DAO_UFGroup();
1353 $group->id = $id;
1354 $group->delete();
1355 return 1;
1356 }
1357
1358 /**
1359 * function to add the UF Group
1360 *
1361 * @param array $params reference array contains the values submitted by the form
1362 * @param array $ids reference array contains the id
1363 *
1364 * @access public
1365 * @static
1366 *
1367 * @return object
1368 */
6a73ef3f 1369 static function add(&$params, $ids = array()) {
6a488035
TO
1370 $fields = array('is_active', 'add_captcha', 'is_map', 'is_update_dupe', 'is_edit_link', 'is_uf_link', 'is_cms_user');
1371 foreach ($fields as $field) {
1372 $params[$field] = CRM_Utils_Array::value($field, $params, FALSE);
1373 }
1374
1375 $params['limit_listings_group_id'] = CRM_Utils_Array::value('group', $params);
1376 $params['add_to_group_id'] = CRM_Utils_Array::value('add_contact_to_group', $params);
1377
1378 $ufGroup = new CRM_Core_DAO_UFGroup();
1379 $ufGroup->copyValues($params);
1380
6a73ef3f 1381 $ufGroupID = CRM_Utils_Array::value('ufgroup', $ids, CRM_Utils_Array::value('id', $params));
6a488035
TO
1382 if (!$ufGroupID) {
1383 $ufGroup->name = CRM_Utils_String::munge($ufGroup->title, '_', 56);
1384 }
1385 $ufGroup->id = $ufGroupID;
1386
1387 $ufGroup->save();
1388
1389 if (!$ufGroupID) {
1390 $ufGroup->name = $ufGroup->name . "_{$ufGroup->id}";
1391 $ufGroup->save();
1392 }
1393
1394 return $ufGroup;
1395 }
1396
1397 /**
1398 * Function to make uf join entries for an uf group
1399 *
1400 * @param array $params (reference) an assoc array of name/value pairs
1401 * @param int $ufGroupId ufgroup id
1402 *
1403 * @return void
1404 * @access public
1405 * @static
1406 */
1407 static function createUFJoin(&$params, $ufGroupId) {
1408 $groupTypes = CRM_Utils_Array::value('uf_group_type', $params);
1409
1410 // get ufjoin records for uf group
1411 $ufGroupRecord = CRM_Core_BAO_UFGroup::getUFJoinRecord($ufGroupId);
1412
1413 // get the list of all ufgroup types
1414 $allUFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1415
1416 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1417 if (!is_array($groupTypes)) {
1418 $groupTypes = array();
1419 }
1420
1421 // this fix is done to prevent warning generated by array_key_exits incase of empty array is given as input
1422 if (!is_array($ufGroupRecord)) {
1423 $ufGroupRecord = array();
1424 }
1425
1426 // check which values has to be inserted/deleted for contact
1427 $menuRebuild = FALSE;
1428 foreach ($allUFGroupType as $key => $value) {
1429 $joinParams = array();
1430 $joinParams['uf_group_id'] = $ufGroupId;
1431 $joinParams['module'] = $key;
1432 if ($key == 'User Account') {
1433 $menuRebuild = TRUE;
1434 }
1435 if (array_key_exists($key, $groupTypes) && !in_array($key, $ufGroupRecord)) {
1436 // insert a new record
1437 CRM_Core_BAO_UFGroup::addUFJoin($joinParams);
1438 }
1439 elseif (!array_key_exists($key, $groupTypes) && in_array($key, $ufGroupRecord)) {
1440 // delete a record for existing ufgroup
1441 CRM_Core_BAO_UFGroup::delUFJoin($joinParams);
1442 }
1443 }
1444
1445 //update the weight
1446 $query = "
1447UPDATE civicrm_uf_join
1448SET weight = %1
1449WHERE uf_group_id = %2
1450AND ( entity_id IS NULL OR entity_id <= 0 )
1451";
1452 $p = array(1 => array($params['weight'], 'Integer'),
1453 2 => array($ufGroupId, 'Integer'),
1454 );
1455 CRM_Core_DAO::executeQuery($query, $p);
1456
1457 // do a menu rebuild if we are on drupal, so it gets all the new menu entries
1458 // for user account
1459 $config = CRM_Core_Config::singleton();
1460 if ($menuRebuild &&
1461 $config->userSystem->is_drupal
1462 ) {
1463 menu_rebuild();
1464 }
1465 }
1466
1467 /**
1468 * Function to get the UF Join records for an ufgroup id
1469 *
1470 * @params int $ufGroupId uf group id
1471 * @params int $displayName if set return display name in array
1472 * @params int $status if set return module other than default modules (User Account/User registration/Profile)
1473 *
1474 * @return array $ufGroupJoinRecords
1475 *
1476 * @access public
1477 * @static
1478 */
1479 public static function getUFJoinRecord($ufGroupId = NULL, $displayName = NULL, $status = NULL) {
1480 if ($displayName) {
1481 $UFGroupType = array();
1482 $UFGroupType = CRM_Core_SelectValues::ufGroupTypes();
1483 }
1484
1485 $ufJoin = array();
1486 $dao = new CRM_Core_DAO_UFJoin();
1487
1488 if ($ufGroupId) {
1489 $dao->uf_group_id = $ufGroupId;
1490 }
1491
1492 $dao->find();
1493 $ufJoin = array();
1494
1495 while ($dao->fetch()) {
1496 if (!$displayName) {
1497 $ufJoin[$dao->id] = $dao->module;
1498 }
1499 else {
1500 if (isset($UFGroupType[$dao->module])) {
1501 // skip the default modules
1502 if (!$status) {
1503 $ufJoin[$dao->id] = $UFGroupType[$dao->module];
1504 }
1505 // added for CRM-1475
1506 }
1507 elseif (!CRM_Utils_Array::key($dao->module, $ufJoin)) {
1508 $ufJoin[$dao->id] = $dao->module;
1509 }
1510 }
1511 }
1512 return $ufJoin;
1513 }
1514
1515 /**
1516 * Function takes an associative array and creates a ufjoin record for ufgroup
1517 *
1518 * @param array $params (reference) an assoc array of name/value pairs
1519 *
1520 * @return object CRM_Core_BAO_UFJoin object
1521 * @access public
1522 * @static
1523 */
1524 static function addUFJoin(&$params) {
1525 $ufJoin = new CRM_Core_DAO_UFJoin();
1526 $ufJoin->copyValues($params);
1527 $ufJoin->save();
1528 return $ufJoin;
1529 }
1530
1531 /**
1532 * Function to delete the uf join record for an uf group
1533 *
1534 * @param array $params (reference) an assoc array of name/value pairs
1535 *
1536 * @return void
1537 * @access public
1538 * @static
1539 */
1540 static function delUFJoin(&$params) {
1541 $ufJoin = new CRM_Core_DAO_UFJoin();
1542 $ufJoin->copyValues($params);
1543 $ufJoin->delete();
1544 }
1545
1546 /**
1547 * Function to get the weight for ufjoin record
1548 *
1549 * @param int $ufGroupId if $ufGroupId get update weight or add weight
1550 *
1551 * @return int weight of the UFGroup
1552 * @access public
1553 * @static
1554 */
1555 static function getWeight($ufGroupId = NULL) {
1556 //calculate the weight
1557 $p = array();
1558 if (!$ufGroupId) {
1559 $queryString = "SELECT ( MAX(civicrm_uf_join.weight)+1) as new_weight
1560 FROM civicrm_uf_join
1561 WHERE module = 'User Registration' OR module = 'User Account' OR module = 'Profile'";
1562 }
1563 else {
1564 $queryString = "SELECT MAX(civicrm_uf_join.weight) as new_weight
1565 FROM civicrm_uf_join
1566 WHERE civicrm_uf_join.uf_group_id = %1
1567 AND ( entity_id IS NULL OR entity_id <= 0 )";
1568 $p[1] = array($ufGroupId, 'Integer');
1569 }
1570
1571 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1572 $dao->fetch();
1573 return ($dao->new_weight) ? $dao->new_weight : 1;
1574 }
1575
1576 /**
1577 * Function to get the uf group for a module
1578 *
1579 * @param string $moduleName module name
2141efbf
TO
1580 * @param int $count no to increment the weight
1581 * @param bool $skipPermision - whether to add permission clause
1582 * @param int $op - which operation (view, edit, create, etc) to check permission for
1583 * @param array|NULL $returnFields list of UFGroup fields to return; NULL for default
6a488035
TO
1584 *
1585 * @return array $ufGroups array of ufgroups for a module
1586 * @access public
1587 * @static
1588 */
2141efbf
TO
1589 public static function getModuleUFGroup($moduleName = NULL, $count = 0, $skipPermission = TRUE, $op = CRM_Core_Permission::VIEW, $returnFields = NULL) {
1590 if ($returnFields === NULL) {
1591 $returnFields = array('id', 'title', 'created_id', 'description', 'is_active', 'is_reserved', 'group_type');
1592 }
1593 $queryString = 'SELECT civicrm_uf_group.' . implode(', civicrm_uf_group.', $returnFields) . '
6a488035
TO
1594 FROM civicrm_uf_group
1595 LEFT JOIN civicrm_uf_join ON (civicrm_uf_group.id = uf_group_id)';
1596 $p = array();
1597 if ($moduleName) {
1598 $queryString .= ' AND civicrm_uf_group.is_active = 1
1599 WHERE civicrm_uf_join.module = %2';
1600 $p[2] = array($moduleName, 'String');
1601 }
1602
1603
1604 // add permissioning for profiles only if not registration
1605 if (!$skipPermission) {
1606 $permissionClause = CRM_Core_Permission::ufGroupClause($op, 'civicrm_uf_group.');
1607 if (strpos($queryString, 'WHERE') !== FALSE) {
1608 $queryString .= " AND $permissionClause ";
1609 }
1610 else {
1611 $queryString .= " $permissionClause ";
1612 }
1613 }
1614
1615 $queryString .= ' ORDER BY civicrm_uf_join.weight, civicrm_uf_group.title';
1616 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
1617
1618 $ufGroups = array();
1619 while ($dao->fetch()) {
1620 //skip mix profiles in user Registration / User Account
1621 if (($moduleName == 'User Registration' || $moduleName == 'User Account') &&
1622 CRM_Core_BAO_UFField::checkProfileType($dao->id)
1623 ) {
1624 continue;
1625 }
1626 $ufGroups[$dao->id]['name'] = $dao->title;
1627 $ufGroups[$dao->id]['title'] = $dao->title;
bcbde5ca
AW
1628 $ufGroups[$dao->id]['created_id'] = $dao->created_id;
1629 $ufGroups[$dao->id]['description'] = $dao->description;
6a488035
TO
1630 $ufGroups[$dao->id]['is_active'] = $dao->is_active;
1631 $ufGroups[$dao->id]['group_type'] = $dao->group_type;
1632 $ufGroups[$dao->id]['is_reserved'] = $dao->is_reserved;
1633 }
1634
1635 // Allow other modules to alter/override the UFGroups.
1636 CRM_Utils_Hook::buildUFGroupsForModule($moduleName, $ufGroups);
1637
1638 return $ufGroups;
1639 }
1640
1641 /**
1642 * Function to filter ufgroups based on logged in user contact type
1643 *
1644 * @params int $ufGroupId uf group id (profile id)
1645 *
1646 * @return boolean true or false
1647 * @static
1648 * @access public
1649 */
1650 static function filterUFGroups($ufGroupId, $contactID = NULL) {
1651 if (!$contactID) {
1652 $session = CRM_Core_Session::singleton();
1653 $contactID = $session->get('userID');
1654 }
1655
1656 if ($contactID) {
1657 //get the contact type
1658 $contactType = CRM_Contact_BAO_Contact::getContactType($contactID);
1659
1660 //match if exixting contact type is same as profile contact type
1661 $profileType = CRM_Core_BAO_UFField::getProfileType($ufGroupId);
1662
1663 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1664 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
1665 }
1666
1667 //allow special mix profiles for Contribution and Participant
1668 $specialProfiles = array('Contribution', 'Participant', 'Membership');
1669
1670 if (in_array($profileType, $specialProfiles)) {
1671 return TRUE;
1672 }
1673
1674 if (($contactType == $profileType) || $profileType == 'Contact') {
1675 return TRUE;
1676 }
1677 }
1678
1679 return FALSE;
1680 }
1681
1682 /**
1683 * Function to build profile form
1684 *
1685 * @params object $form form object
1686 * @params array $field array field properties
1687 * @params int $mode profile mode
1688 * @params int $contactID contact id
1689 *
1690 * @return null
1691 * @static
1692 * @access public
1693 */
1694 static function buildProfile(
1695 &$form,
1696 &$field,
1697 $mode,
1698 $contactId = NULL,
1699 $online = FALSE,
1700 $onBehalf = FALSE,
1701 $rowNumber = NULL ,
1702 $prefix = ''
1703 ) {
1704 $defaultValues = array();
1705 $fieldName = $field['name'];
1706 $title = $field['title'];
1707 $attributes = $field['attributes'];
1708 $rule = $field['rule'];
1709 $view = $field['is_view'];
1710 $required = ($mode == CRM_Profile_Form::MODE_SEARCH) ? FALSE : $field['is_required'];
1711 $search = ($mode == CRM_Profile_Form::MODE_SEARCH) ? TRUE : FALSE;
1712 $isShared = CRM_Utils_Array::value('is_shared', $field, 0);
1713
1714 // do not display view fields in drupal registration form
1715 // CRM-4632
1716 if ($view && $mode == CRM_Profile_Form::MODE_REGISTER) {
1717 return;
1718 }
1719
1720 if ($onBehalf) {
1721 $name = "onbehalf[$fieldName]";
1722 }
1723 elseif ($contactId && !$online) {
1724 $name = "field[$contactId][$fieldName]";
1725 }
1726 elseif ($rowNumber) {
1727 $name = "field[$rowNumber][$fieldName]";
1728 }
1729 elseif (!empty($prefix)) {
1730 $name = $prefix ."[$fieldName]";
1731 }
1732 else {
1733 $name = $fieldName;
1734 }
1735
1736 if ($fieldName == 'image_URL' && $mode == CRM_Profile_Form::MODE_EDIT) {
1737 $deleteExtra = ts('Are you sure you want to delete contact image.');
1738 $deleteURL = array(
1739 CRM_Core_Action::DELETE =>
1740 array(
1741 'name' => ts('Delete Contact Image'),
1742 'url' => 'civicrm/contact/image',
1743 'qs' => 'reset=1&id=%%id%%&gid=%%gid%%&action=delete',
1744 'extra' =>
1745 'onclick = "if (confirm( \'' . $deleteExtra . '\' ) ) this.href+=\'&amp;confirmed=1\'; else return false;"',
1746 ),
1747 );
1748 $deleteURL = CRM_Core_Action::formLink($deleteURL,
1749 CRM_Core_Action::DELETE,
1750 array('id' => $form->get('id'),
1751 'gid' => $form->get('gid'),
1752 )
1753 );
1754 $form->assign('deleteURL', $deleteURL);
1755 }
1756 $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
1757 'address_options', TRUE, NULL, TRUE
1758 );
1759
1760 if (substr($fieldName, 0, 14) === 'state_province') {
1761 $form->add('select', $name, $title,
1762 array(
1763 '' => ts('- select -')) + CRM_Core_PseudoConstant::stateProvince(), $required
1764 );
1765 $config = CRM_Core_Config::singleton();
1766 if (!in_array($mode, array(
1767 CRM_Profile_Form::MODE_EDIT, CRM_Profile_Form::MODE_SEARCH)) &&
1768 $config->defaultContactStateProvince
1769 ) {
1770 $defaultValues[$name] = $config->defaultContactStateProvince;
1771 $form->setDefaults($defaultValues);
1772 }
1773 }
1774 elseif (substr($fieldName, 0, 7) === 'country') {
1775 $form->add('select', $name, $title,
1776 array(
1777 '' => ts('- select -')) + CRM_Core_PseudoConstant::country(), $required
1778 );
1779 $config = CRM_Core_Config::singleton();
1780 if (!in_array($mode, array(
1781 CRM_Profile_Form::MODE_EDIT, CRM_Profile_Form::MODE_SEARCH)) &&
1782 $config->defaultContactCountry
1783 ) {
1784 $defaultValues[$name] = $config->defaultContactCountry;
1785 $form->setDefaults($defaultValues);
1786 }
1787 }
1788 elseif (substr($fieldName, 0, 6) === 'county') {
1789 if ($addressOptions['county']) {
1790 $form->add('select', $name, $title,
1791 array(
1792 '' => ts('- select state -')), $required
1793 );
1794 }
1795 }
1796 elseif (substr($fieldName, 0, 9) === 'image_URL') {
1797 $form->add('file', $name, $title, $attributes, $required);
1798 $form->addUploadElement($name);
1799 }
1800 elseif (substr($fieldName, 0, 2) === 'im') {
1801 $form->add('text', $name, $title, $attributes, $required);
1802 if (!$contactId) {
1803 if ($onBehalf) {
1804 if (substr($name, -1) == ']') {
1805 $providerName = substr($name, 0, -1) . '-provider_id]';
1806 }
1807 $form->add('select', $providerName, NULL,
1808 array(
e7e657f0 1809 '' => ts('- select -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1810 );
1811 }
1812 else {
1813 $form->add('select', $name . '-provider_id', $title,
1814 array(
e7e657f0 1815 '' => ts('- select -')) + CRM_Core_PseudoConstant::get('CRM_Core_DAO_IM', 'provider_id'), $required
6a488035
TO
1816 );
1817 }
1818
1819 if ($view && $mode != CRM_Profile_Form::MODE_SEARCH) {
1820 $form->freeze($name . '-provider_id');
1821 }
1822 }
1823 }
1824 elseif (($fieldName === 'birth_date') || ($fieldName === 'deceased_date')) {
1825 $form->addDate($name, $title, $required, array('formatType' => 'birth'));
1826 }
1827 elseif (in_array($fieldName, array(
1828 'membership_start_date', 'membership_end_date', 'join_date'))) {
1829 $form->addDate($name, $title, $required, array('formatType' => 'custom'));
1830 }
1831 elseif (CRM_Utils_Array::value('name',$field) == 'membership_type') {
1832 list($orgInfo, $types) = CRM_Member_BAO_MembershipType::getMembershipTypeInfo();
1833 $sel = &$form->addElement('hierselect', $name, $title);
53cfc93c 1834 $select = array('' => ts('- select -') );
1835 if(count($orgInfo) == 1 && $field['is_required']) {
1836 // we only have one org - so we should default to it. Not sure about defaulting to first type
1837 // as it could be missed - so adding a select
1838 // however, possibly that is more similar to the membership form
1839 if(count($types[1]) > 1) {
1840 $types[1] = $select + $types[1];
1841 }
1842 }
1843 else {
1844 $orgInfo = $select + $orgInfo;
1845 }
1846 $sel->setOptions(array($orgInfo, $types));
6a488035
TO
1847 }
1848 elseif (CRM_Utils_Array::value('name',$field) == 'membership_status') {
1849 $form->add('select', $name, $title,
1850 array(
1851 '' => ts('- select -')) + CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'label'), $required
1852 );
1853 }
827659b2 1854 elseif ($fieldName === 'gender') {
6a488035 1855 $genderOptions = array();
26cf88b5 1856 $gender = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'gender_id');
6a488035
TO
1857 foreach ($gender as $key => $var) {
1858 $genderOptions[$key] = $form->createElement('radio', NULL, ts('Gender'), $var, $key);
1859 }
1860 $form->addGroup($genderOptions, $name, $title);
1861 if ($required) {
1862 $form->addRule($name, ts('%1 is a required field.', array(1 => $title)), 'required');
1863 }
1864 }
827659b2 1865 elseif ($fieldName === 'individual_prefix') {
6a488035
TO
1866 $form->add('select', $name, $title,
1867 array(
e6c4755b 1868 '' => ts('- select -')) + CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'prefix_id'), $required
6a488035
TO
1869 );
1870 }
827659b2 1871 elseif ($fieldName === 'individual_suffix') {
6a488035
TO
1872 $form->add('select', $name, $title,
1873 array(
e6c4755b 1874 '' => ts('- select -')) + CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'suffix_id'), $required
6a488035
TO
1875 );
1876 }
1877 elseif ($fieldName === 'contact_sub_type') {
1878 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
1879 if ($onBehalf) {
1880 $profileType = 'Organization';
1881 }
1882 else {
1883 $profileType = $gId ? CRM_Core_BAO_UFField::getProfileType($gId) : NULL;
1884 if ($profileType == 'Contact') {
1885 $profileType = 'Individual';
1886 }
1887 }
1888
1889 $setSubtype = FALSE;
1890 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1891 $setSubtype = $profileType;
1892 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
1893 }
1894
1895 $subtypes = $profileType ? CRM_Contact_BAO_ContactType::subTypePairs($profileType) : array();
1896
1897 if ($setSubtype) {
1898 $subtypeList = array();
1899 $subtypeList[$setSubtype] = $subtypes[$setSubtype];
1900 }
1901 else {
1902 $subtypeList = $subtypes;
1903 }
1904
1905 $sel = $form->add('select', $name, $title, $subtypeList, $required);
1906 $sel->setMultiple(TRUE);
1907 }
1908 elseif (in_array($fieldName, CRM_Contact_BAO_Contact::$_greetingTypes)) {
1909 //add email greeting, postal greeting, addressee, CRM-4575
1910 $gId = $form->get('gid') ? $form->get('gid') : CRM_Utils_Array::value('group_id', $field);
1911 $profileType = CRM_Core_BAO_UFField::getProfileType($gId, TRUE, FALSE, TRUE);
1912
1913 if (empty($profileType) || in_array($profileType, array(
1914 'Contact', 'Contribution', 'Participant', 'Membership'))) {
1915 $profileType = 'Individual';
1916 }
1917 if (CRM_Contact_BAO_ContactType::isaSubType($profileType)) {
1918 $profileType = CRM_Contact_BAO_ContactType::getBasicType($profileType);
1919 }
1920 $greeting = array(
1921 'contact_type' => $profileType,
1922 'greeting_type' => $fieldName,
1923 );
1924 $form->add('select', $name, $title,
1925 array(
1926 '' => ts('- select -')) + CRM_Core_PseudoConstant::greeting($greeting), $required
1927 );
1928 // add custom greeting element
1929 $form->add('text', $fieldName . '_custom', ts('Custom %1', array(1 => ucwords(str_replace('_', ' ', $fieldName)))),
1930 NULL, FALSE
1931 );
1932 }
1933 elseif ($fieldName === 'preferred_communication_method') {
e7e657f0 1934 $communicationFields = CRM_Core_PseudoConstant::get('CRM_Contact_DAO_Contact', 'preferred_communication_method');
6a488035
TO
1935 foreach ($communicationFields as $key => $var) {
1936 if ($key == '') {
1937 continue;
1938 }
1939 $communicationOptions[] = $form->createElement('checkbox', $key, NULL, $var);
1940 }
1941 $form->addGroup($communicationOptions, $name, $title, '<br/>');
1942 }
1943 elseif ($fieldName === 'preferred_mail_format') {
1944 $form->add('select', $name, $title, CRM_Core_SelectValues::pmf());
1945 }
1946 elseif ($fieldName === 'preferred_language') {
c0c9cd82 1947 $form->add('select', $name, $title, array('' => ts('- select -')) + CRM_Contact_BAO_Contact::buildOptions('preferred_language'));
6a488035
TO
1948 }
1949 elseif ($fieldName == 'external_identifier') {
1950 $form->add('text', $name, $title, $attributes, $required);
1951 $contID = $contactId;
1952 if (!$contID) {
1953 $contID = $form->get('id');
1954 }
1955 $form->addRule($name,
1956 ts('External ID already exists in Database.'),
1957 'objectExists',
1958 array('CRM_Contact_DAO_Contact', $contID, 'external_identifier')
1959 );
1960 }
1961 elseif ($fieldName === 'group') {
1962 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
1963 CRM_Contact_Form_Edit_TagsAndGroups::GROUP,
1964 TRUE, $required,
1965 $title, NULL, $name
1966 );
1967 }
1968 elseif ($fieldName === 'tag') {
1969 CRM_Contact_Form_Edit_TagsAndGroups::buildQuickForm($form, $contactId,
1970 CRM_Contact_Form_Edit_TagsAndGroups::TAG,
1971 FALSE, $required,
1972 NULL, $title, $name
1973 );
1974 }
1975 elseif (substr($fieldName, 0, 4) === 'url-') {
1976 $form->add('text', $name, $title,
1977 array_merge(CRM_Core_DAO::getAttribute('CRM_Core_DAO_Website', 'url'),
1978 array(
1979 'onfocus' => "if (!this.value) { this.value='http://';} else return false",
1980 'onblur' => "if ( this.value == 'http://') { this.value='';} else return false",
1981 )
1982 ), $required
1983 );
1984
1985 $form->addRule($name, ts('Enter a valid Website.'), 'url');
1986
1987 //Website type select
1988 if ($onBehalf) {
1989 if (substr($name, -1) == ']') {
1990 $websiteTypeName = substr($name, 0, -1) . '-website_type_id]';
1991 }
cbf48754 1992 $form->addElement('select', $websiteTypeName, NULL, CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id'));
6a488035
TO
1993 }
1994 else {
cbf48754 1995 $form->addElement('select', $name . '-website_type_id', NULL, CRM_Core_PseudoConstant::get('CRM_Core_DAO_Website', 'website_type_id'));
6a488035
TO
1996 }
1997 }
1998 // Note should be rendered as textarea
1999 elseif (substr($fieldName, -4) == 'note') {
2000 $form->add('textarea', $name, $title, $attributes, $required);
2001 }
2002 elseif (substr($fieldName, 0, 6) === 'custom') {
2003 $customFieldID = CRM_Core_BAO_CustomField::getKeyID($fieldName);
2004 if ($customFieldID) {
2005 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2006 }
2007 }
2008 elseif (substr($fieldName, 0, 14) === 'address_custom') {
2009 list($fName, $locTypeId) = CRM_Utils_System::explode('-', $fieldName, 2);
2010 $customFieldID = CRM_Core_BAO_CustomField::getKeyID(substr($fName, 8));
2011 if ($customFieldID) {
2012 CRM_Core_BAO_CustomField::addQuickFormElement($form, $name, $customFieldID, FALSE, $required, $search, $title);
2013 }
2014 }
2015 elseif (in_array($fieldName, array(
2016 'receive_date', 'receipt_date', 'thankyou_date', 'cancel_date'))) {
2017 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2018 }
2019 elseif ($fieldName == 'send_receipt') {
2020 $form->addElement('checkbox', $name, $title);
2021 }
2022 elseif ($fieldName == 'soft_credit') {
2023 CRM_Contact_Form_NewContact::buildQuickForm($form, $rowNumber, NULL, FALSE, 'soft_credit_');
5ee60152 2024 $form->addMoney("soft_credit_amount[{$rowNumber}]", ts('Amount'), FALSE, NULL, FALSE);
6a488035
TO
2025 }
2026 elseif ($fieldName == 'product_name') {
2027 list($products, $options) = CRM_Contribute_BAO_Premium::getPremiumProductInfo();
2028 $sel = &$form->addElement('hierselect', $name, $title);
2029 $products = array(
2030 '0' => ts('- select -')) + $products;
2031 $sel->setOptions(array($products, $options));
2032 }
2033 elseif ($fieldName == 'payment_instrument') {
2034 $form->add('select', $name, $title,
2035 array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant::paymentInstrument( ), $required );
2036 }
2037 else if ($fieldName == 'financial_type' ) {
2038 $form->add('select', $name, $title,
2039 array(
2040 '' => ts('- select -')) + CRM_Contribute_PseudoConstant::financialType(), $required
2041 );
2042 }
2043 elseif ($fieldName == 'contribution_status_id') {
aaf5ca44
DG
2044 $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus();
2045 $statusName = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
2046 foreach (array(
2047 'In Progress',
2048 'Overdue',
2049 'Refunded'
2050 ) as $suppress) {
2051 unset($contributionStatuses[CRM_Utils_Array::key($suppress, $statusName)]);
2052 }
6a73ef3f 2053
6a488035
TO
2054 $form->add('select', $name, $title,
2055 array(
aaf5ca44 2056 '' => ts('- select -')) + $contributionStatuses, $required
6a488035
TO
2057 );
2058 }
2059 elseif ($fieldName == 'currency') {
2060 $form->addCurrency($name, $title, $required);
2061 }
2062 elseif ($fieldName == 'contribution_page_id') {
2063 $form->add('select', $name, $title,
2064 array(
2065 '' => ts('- select -')) + CRM_Contribute_PseudoConstant::contributionPage(), $required, 'class="big"'
2066 );
2067 }
2068 elseif ($fieldName == 'participant_register_date') {
2069 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2070 }
2071 elseif ($fieldName == 'activity_status_id') {
2072 $form->add('select', $name, $title,
2073 array(
2074 '' => ts('- select -')) + CRM_Core_PseudoConstant::activityStatus(), $required
2075 );
2076 }
2077 elseif ($fieldName == 'activity_engagement_level') {
2078 $form->add('select', $name, $title,
2079 array(
2080 '' => ts('- select -')) + CRM_Campaign_PseudoConstant::engagementLevel(), $required
2081 );
2082 }
2083 elseif ($fieldName == 'activity_date_time') {
2084 $form->addDateTime($name, $title, $required, array('formatType' => 'activityDateTime'));
2085 }
2086 elseif ($fieldName == 'participant_status') {
2087 $cond = NULL;
2088 if ($online == TRUE) {
2089 $cond = 'visibility_id = 1';
2090 }
2091 $form->add('select', $name, $title,
2092 array(
2093 '' => ts('- select -')) + CRM_Event_PseudoConstant::participantStatus(NULL, $cond, 'label'), $required
2094 );
2095 }
2096 elseif ($fieldName == 'participant_role') {
2097 if (CRM_Utils_Array::value('is_multiple', $field)) {
2098 $form->addCheckBox($name, $title, CRM_Event_PseudoConstant::participantRole(), NULL, NULL, NULL, NULL, '&nbsp', TRUE);
2099 }
2100 else {
2101 $form->add('select', $name, $title,
2102 array(
2103 '' => ts('- select -')) + CRM_Event_PseudoConstant::participantRole(), $required
2104 );
2105 }
2106 }
2107 elseif ($fieldName == 'world_region') {
2108 $form->add('select', $name, $title,
2109 array(
2110 '' => ts('- select -')) + CRM_Core_PseudoConstant::worldRegion(), $required
2111 );
2112 }
2113 elseif ($fieldName == 'signature_html') {
2114 $form->addWysiwyg($name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
2115 }
2116 elseif ($fieldName == 'signature_text') {
2117 $form->add('textarea', $name, $title, CRM_Core_DAO::getAttribute('CRM_Core_DAO_Email', $fieldName));
2118 }
2119 elseif (substr($fieldName, -11) == 'campaign_id') {
2120 if (CRM_Campaign_BAO_Campaign::isCampaignEnable()) {
2121 $campaigns = CRM_Campaign_BAO_Campaign::getCampaigns(CRM_Utils_Array::value($contactId,
2122 $form->_componentCampaigns
2123 ));
2124 $form->add('select', $name, $title,
2125 array(
2126 '' => ts('- select -')) + $campaigns, $required, 'class="big"'
2127 );
2128 }
2129 }
2130 elseif ($fieldName == 'activity_details') {
2131 $form->addWysiwyg($fieldName, $title, array('rows' => 4, 'cols' => 60), $required);
2132 }
2133 elseif ($fieldName == 'activity_duration') {
2134 $form->add('text', $name, $title, $attributes, $required);
2135 $form->addRule($name, ts('Please enter the duration as number of minutes (integers only).'), 'positiveInteger');
2136 }
2137 else {
2138 if (substr($fieldName, 0, 3) === 'is_' or substr($fieldName, 0, 7) === 'do_not_') {
2139 $form->add('advcheckbox', $name, $title, $attributes, $required);
2140 }
2141 else {
2142 $form->add('text', $name, $title, $attributes, $required);
2143 }
2144 }
2145
2146 static $hiddenSubtype = FALSE;
2147 if (!$hiddenSubtype && CRM_Contact_BAO_ContactType::isaSubType($field['field_type'])) {
2148 // In registration mode params are submitted via POST and we don't have any clue
2149 // about profile-id or the profile-type (which could be a subtype)
2150 // To generalize the behavior and simplify the process,
2151 // lets always add the hidden
2152 //subtype value if there is any, and we won't have to
2153 // compute it while processing.
2154 if ($onBehalf) {
2155 $form->addElement('hidden', 'onbehalf[contact_sub_type]', $field['field_type']);
2156 }
2157 else {
2158 $form->addElement('hidden', 'contact_sub_type_hidden', $field['field_type']);
2159 }
2160 $hiddenSubtype = TRUE;
2161 }
2162
2163 if (($view && $mode != CRM_Profile_Form::MODE_SEARCH) || $isShared) {
2164 $form->freeze($name);
2165 }
2166
2167 //add the rules
2168 if (in_array($fieldName, array(
2169 'non_deductible_amount', 'total_amount', 'fee_amount', 'net_amount'))) {
2170 $form->addRule($name, ts('Please enter a valid amount.'), 'money');
2171 }
2172
2173 if ($rule) {
2174 if (!($rule == 'email' && $mode == CRM_Profile_Form::MODE_SEARCH)) {
2175 $form->addRule($name, ts('Please enter a valid %1', array(1 => $title)), $rule);
2176 }
2177 }
2178 }
2179
2180 /**
2181 * Function to set profile defaults
2182 *
2183 * @params int $contactId contact id
2184 * @params array $fields associative array of fields
2185 * @params array $defaults defaults array
2186 * @params boolean $singleProfile true for single profile else false(batch update)
2187 * @params int $componentId id for specific components like contribute, event etc
2188 *
2189 * @return null
2190 * @static
2191 * @access public
2192 */
2193 static function setProfileDefaults($contactId, &$fields, &$defaults,
2194 $singleProfile = TRUE, $componentId = NULL, $component = NULL
2195 ) {
2196 if (!$componentId) {
2197 //get the contact details
2198 list($contactDetails, $options) = CRM_Contact_BAO_Contact::getHierContactDetails($contactId, $fields);
2199 $details = CRM_Utils_Array::value($contactId, $contactDetails);
2200 $multipleFields = array('website' => 'url');
2201
2202 //start of code to set the default values
2203 foreach ($fields as $name => $field) {
2204 // skip pseudo fields
2205 if (substr($name, 0, 9) == 'phone_ext') {
2206 continue;
2207 }
2208
2209 //set the field name depending upon the profile mode(single/batch)
2210 if ($singleProfile) {
2211 $fldName = $name;
2212 }
2213 else {
2214 $fldName = "field[$contactId][$name]";
2215 }
2216
2217 if ($name == 'group') {
2218 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::GROUP, $fldName);
2219 }
2220 if ($name == 'tag') {
2221 CRM_Contact_Form_Edit_TagsAndGroups::setDefaults($contactId, $defaults, CRM_Contact_Form_Edit_TagsAndGroups::TAG, $fldName);
2222 }
2223
2224 if (CRM_Utils_Array::value($name, $details) || isset($details[$name])) {
2225 //to handle custom data (checkbox) to be written
58f00377 2226 // to handle birth/deceased date, greeting_type and few other fields
2227 if (($name == 'birth_date') || ($name == 'deceased_date')) {
6a488035
TO
2228 list($defaults[$fldName]) = CRM_Utils_Date::setDateDefaults($details[$name], 'birth');
2229 }
2230 elseif (in_array($name, CRM_Contact_BAO_Contact::$_greetingTypes)) {
2231 $defaults[$fldName] = $details[$name . '_id'];
2232 $defaults[$name . '_custom'] = $details[$name . '_custom'];
2233 }
2234 elseif ($name == 'preferred_communication_method') {
2235 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2236 foreach ($v as $item) {
2237 if ($item) {
2238 $defaults[$fldName . "[$item]"] = 1;
2239 }
2240 }
2241 }
2242 elseif ($name == 'world_region') {
2243 $defaults[$fldName] = $details['worldregion_id'];
2244 }
2245 elseif ($customFieldId = CRM_Core_BAO_CustomField::getKeyID($name)) {
2246 //fix for custom fields
2247 $customFields = CRM_Core_BAO_CustomField::getFields(CRM_Utils_Array::value('contact_type', $details));
2248
2249 // hack to add custom data for components
2250 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
2251 foreach ($components as $value) {
2252 $customFields = CRM_Utils_Array::crmArrayMerge($customFields,
2253 CRM_Core_BAO_CustomField::getFieldsForImport($value)
2254 );
2255 }
2256
2257 switch ($customFields[$customFieldId]['html_type']) {
2258 case 'Multi-Select State/Province':
2259 case 'Multi-Select Country':
2260 case 'AdvMulti-Select':
2261 case 'Multi-Select':
2262 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2263 foreach ($v as $item) {
2264 if ($item) {
2265 $defaults[$fldName][$item] = $item;
2266 }
2267 }
2268 break;
2269
2270 case 'CheckBox':
2271 $v = explode(CRM_Core_DAO::VALUE_SEPARATOR, $details[$name]);
2272 foreach ($v as $item) {
2273 if ($item) {
2274 $defaults[$fldName][$item] = 1;
2275 // seems like we need this for QF style checkboxes in profile where its multiindexed
2276 // CRM-2969
2277 $defaults["{$fldName}[{$item}]"] = 1;
2278 }
2279 }
2280 break;
2281
2282 case 'Autocomplete-Select':
2283 if ($customFields[$customFieldId]['data_type'] == 'ContactReference') {
2284 if (is_numeric($details[$name])) {
2285 $defaults[$fldName . '_id'] = $details[$name];
2286 $defaults[$fldName] = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $details[$name], 'sort_name');
2287 }
2288 }
2289 else {
2290 $label = CRM_Core_BAO_CustomOption::getOptionLabel($customFieldId, $details[$name]);
2291 $defaults[$fldName . '_id'] = $details[$name];
2292 $defaults[$fldName] = $label;
2293 }
2294 break;
2295
2296 case 'Select Date':
2297 // CRM-6681, set defult values according to date and time format (if any).
2298 $dateFormat = NULL;
fd933dc5
KJ
2299 if (CRM_Utils_Array::value('date_format', $customFields[$customFieldId])) {
2300 $dateFormat = $customFields[$customFieldId]['date_format'];
6a488035
TO
2301 }
2302
fd933dc5 2303 if (!CRM_Utils_Array::value('time_format', $customFields[$customFieldId])) {
6a488035
TO
2304 list($defaults[$fldName]) = CRM_Utils_Date::setDateDefaults($details[$name], NULL,
2305 $dateFormat
2306 );
2307 }
2308 else {
2309 $timeElement = $fldName . '_time';
2310 if (substr($fldName, -1) == ']') {
2311 $timeElement = substr($fldName, 0, -1) . '_time]';
2312 }
fd933dc5
KJ
2313 list($defaults[$fldName], $defaults[$timeElement]) = CRM_Utils_Date::setDateDefaults($details[$name],
2314 NULL, $dateFormat, $customFields[$customFieldId]['time_format']);
6a488035
TO
2315 }
2316 break;
2317
2318 default:
2319 $defaults[$fldName] = $details[$name];
2320 break;
2321 }
2322 }
2323 else {
2324 $defaults[$fldName] = $details[$name];
2325 }
2326 }
2327 else {
2328 $blocks = array('email', 'phone', 'im', 'openid');
2329 list($fieldName, $locTypeId, $phoneTypeId) = CRM_Utils_System::explode('-', $name, 3);
2330 if (!in_array($fieldName, $multipleFields)) {
2331 if (is_array($details)) {
2332 foreach ($details as $key => $value) {
2333 // when we fixed CRM-5319 - get primary loc
2334 // type as per loc field and removed below code.
2335 $primaryLocationType = FALSE;
2336 if ($locTypeId == 'Primary') {
2337 if (is_array($value) && array_key_exists($fieldName, $value)){
2338 $primaryLocationType = TRUE;
2339 if (in_array($fieldName, $blocks)){
2340 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, $fieldName);
2341 }
2342 else{
2343 $locTypeId = CRM_Contact_BAO_Contact::getPrimaryLocationType($contactId, FALSE, 'address');
2344 }
2345 }
2346 }
2347
2348 // fixed for CRM-665
2349 if (is_numeric($locTypeId)) {
2350 if ($primaryLocationType || $locTypeId == CRM_Utils_Array::value('location_type_id', $value)) {
2351 if (CRM_Utils_Array::value($fieldName, $value)) {
2352 //to handle stateprovince and country
2353 if ($fieldName == 'state_province') {
2354 $defaults[$fldName] = $value['state_province_id'];
2355 }
2356 elseif ($fieldName == 'county') {
2357 $defaults[$fldName] = $value['county_id'];
2358 }
2359 elseif ($fieldName == 'country') {
2360 $defaults[$fldName] = $value['country_id'];
2361 if (!isset($value['country_id']) || !$value['country_id']) {
2362 $config = CRM_Core_Config::singleton();
2363 if ($config->defaultContactCountry) {
2364 $defaults[$fldName] = $config->defaultContactCountry;
2365 }
2366 }
2367 }
2368 elseif ($fieldName == 'phone') {
2369 if ($phoneTypeId) {
2370 if (isset($value['phone'][$phoneTypeId])) {
2371 $defaults[$fldName] = $value['phone'][$phoneTypeId];
2372 }
2373 if (isset($value['phone_ext'][$phoneTypeId])) {
2374 $defaults[str_replace('phone', 'phone_ext', $fldName)] = $value['phone_ext'][$phoneTypeId];
2375 }
2376 }
2377 else {
2378 $phoneDefault = CRM_Utils_Array::value('phone', $value);
2379 // CRM-9216
2380 if (!is_array($phoneDefault)) {
2381 $defaults[$fldName] = $phoneDefault;
2382 }
2383 }
2384 }
2385 elseif ($fieldName == 'email') {
2386 //adding the first email (currently we don't support multiple emails of same location type)
2387 $defaults[$fldName] = $value['email'];
2388 }
2389 elseif ($fieldName == 'im') {
2390 //adding the first im (currently we don't support multiple ims of same location type)
2391 $defaults[$fldName] = $value['im'];
2392 $defaults[$fldName . '-provider_id'] = $value['im_provider_id'];
2393 }
2394 else {
2395 $defaults[$fldName] = $value[$fieldName];
2396 }
2397 }
2398 elseif (substr($fieldName, 0, 14) === 'address_custom' &&
2399 CRM_Utils_Array::value(substr($fieldName, 8), $value)
2400 ) {
2401 $defaults[$fldName] = $value[substr($fieldName, 8)];
2402 }
2403 }
2404 }
2405 }
2406 }
2407 }
2408 else {
2409 if (is_array($details)) {
2410 if ($fieldName === 'url') {
2411 if (!empty($details['website'])) {
2412 foreach ($details['website'] as $val) {
2413 $defaults[$fldName] = CRM_Utils_Array::value('url', $val);
2414 $defaults[$fldName . '-website_type_id'] = $val['website_type_id'];
2415 }
2416 }
2417 }
2418 }
2419 }
2420 }
2421 }
2422 }
2423
2424 //Handling Contribution Part of the batch profile
2425 if (CRM_Core_Permission::access('CiviContribute') && $component == 'Contribute') {
2426 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2427 }
2428
2429 //Handling Event Participation Part of the batch profile
2430 if (CRM_Core_Permission::access('CiviEvent') && $component == 'Event') {
2431 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2432 }
2433
2434 //Handling membership Part of the batch profile
2435 if (CRM_Core_Permission::access('CiviMember') && $component == 'Membership') {
2436 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2437 }
2438
2439 //Handling Activity Part of the batch profile
2440 if ($component == 'Activity') {
2441 self::setComponentDefaults($fields, $componentId, $component, $defaults);
2442 }
2443 }
2444
2445 /**
2446 * Function to get profiles by type eg: pure Individual etc
2447 *
2448 * @param array $types associative array of types eg: types('Individual')
2449 * @param boolean $onlyPure true if only pure profiles are required
2450 *
2451 * @return array $profiles associative array of profiles
2452 * @static
2453 * @access public
2454 */
2455 static function getProfiles($types, $onlyPure = FALSE) {
2456 $profiles = array();
ff4f7744 2457 $ufGroups = CRM_Core_PseudoConstant::get('CRM_Core_DAO_UFField', 'uf_group_id');
6a488035
TO
2458
2459 CRM_Utils_Hook::aclGroup(CRM_Core_Permission::ADMIN, NULL, 'civicrm_uf_group', $ufGroups, $ufGroups);
2460
2461 // Exclude Batch Data Entry profiles - CRM-10901
2462 $batchProfiles = CRM_Core_BAO_UFGroup::getBatchProfiles();
2463
2464 foreach ($ufGroups as $id => $title) {
2465 $ptype = CRM_Core_BAO_UFField::getProfileType($id, FALSE, $onlyPure);
2466 if (in_array($ptype, $types) && !array_key_exists($id, $batchProfiles)) {
2467 $profiles[$id] = $title;
2468 }
2469 }
2470 return $profiles;
2471 }
2472
2473 /**
2474 * Function to check whether a profile is valid combination of
2475 * required and/or optional profile types
2476 *
2477 * @param array $required array of types those are required
2478 * @param array $optional array of types those are optional
2479 *
2480 * @return array $profiles associative array of profiles
2481 * @static
2482 * @access public
2483 */
2484 static function getValidProfiles($required, $optional = NULL) {
2485 if (!is_array($required) || empty($required)) {
2486 return;
2487 }
2488
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 foreach ($ufGroups as $id => $title) {
2495 $type = CRM_Core_BAO_UFField::checkValidProfileType($id, $required, $optional);
2496 if ($type) {
2497 $profiles[$id] = $title;
2498 }
2499 }
2500
2501 return $profiles;
2502 }
2503
2504 /**
2505 * Function to check whether a profile is valid combination of
2506 * required profile fields
2507 *
2508 * @param array $ufId integer id of the profile
2509 * @param array $required array of fields those are required in the profile
2510 *
2511 * @return array $profiles associative array of profiles
2512 * @static
2513 * @access public
2514 */
2515 static function checkValidProfile($ufId, $required = NULL) {
2516 $validProfile = FALSE;
2517 if (!$ufId) {
2518 return $validProfile;
2519 }
2520
2521 if (!CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $ufId, 'is_active')) {
2522 return $validProfile;
2523 }
2524
2525 $profileFields = self::getFields($ufId, FALSE, CRM_Core_Action::VIEW, NULL,
2526 NULL, FALSE, NULL, FALSE, NULL,
2527 CRM_Core_Permission::CREATE, NULL
2528 );
2529
2530 $validProfile = array();
2531 if (!empty($profileFields)) {
2532 $fields = array_keys($profileFields);
2533 foreach ($fields as $val) {
2534 foreach ($required as $key => $field) {
2535 if (strpos($val, $field) === 0) {
2536 unset($required[$key]);
2537 }
2538 }
2539 }
2540
2541 $validProfile = (empty($required)) ? TRUE : FALSE;
2542 }
2543
2544 return $validProfile;
2545 }
2546
2547 /**
2548 * Function to get default value for Register.
2549 *
2550 * @return $defaults
2551 * @static
2552 * @access public
2553 */
2554 static function setRegisterDefaults(&$fields, &$defaults) {
b525f1cc 2555 $config = CRM_Core_Config::singleton();
6a488035
TO
2556 foreach ($fields as $name => $field) {
2557 if (substr($name, 0, 8) == 'country-') {
b525f1cc 2558 if (!empty($config->defaultContactCountry)) {
6a488035
TO
2559 $defaults[$name] = $config->defaultContactCountry;
2560 }
2561 }
2562 elseif (substr($name, 0, 15) == 'state_province-') {
b525f1cc 2563 if (!empty($config->defaultContactStateProvince)) {
6a488035
TO
2564 $defaults[$name] = $config->defaultContactStateProvince;
2565 }
2566 }
2567 }
2568 return $defaults;
2569 }
2570
2571 /**
2572 * This function is to make a copy of a profile, including
2573 * all the fields in the profile
2574 *
2575 * @param int $id the profile id to copy
2576 *
2577 * @return void
2578 * @access public
2579 */
2580 static function copy($id) {
2581 $fieldsFix = array('prefix' => array('title' => ts('Copy of ')));
2582 $copy = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFGroup',
2583 array('id' => $id),
2584 NULL,
2585 $fieldsFix
2586 );
2587
2588 if ($pos = strrpos($copy->name, "_{$id}")) {
2589 $copy->name = substr_replace($copy->name, '', $pos);
2590 }
2591 $copy->name = CRM_Utils_String::munge($copy->name, '_', 56) . "_{$copy->id}";
2592 $copy->save();
2593
2594 $copyUFJoin = &CRM_Core_DAO::copyGeneric('CRM_Core_DAO_UFJoin',
2595 array('uf_group_id' => $id),
2596 array('uf_group_id' => $copy->id),
2597 NULL,
2598 'entity_table'
2599 );
2600
2601 $copyUFField = &CRM_Core_DAO::copyGeneric('CRM_Core_BAO_UFField',
2602 array('uf_group_id' => $id),
2603 array('uf_group_id' => $copy->id)
2604 );
2605
2606 $maxWeight = CRM_Utils_Weight::getMax('CRM_Core_DAO_UFJoin', NULL, 'weight');
2607
2608 //update the weight
2609 $query = "
2610UPDATE civicrm_uf_join
2611SET weight = %1
2612WHERE uf_group_id = %2
2613AND ( entity_id IS NULL OR entity_id <= 0 )
2614";
2615 $p = array(1 => array($maxWeight + 1, 'Integer'),
2616 2 => array($copy->id, 'Integer'),
2617 );
2618 CRM_Core_DAO::executeQuery($query, $p);
2619 if ($copy->is_reserved) {
2620 $query = "UPDATE civicrm_uf_group SET is_reserved = 0 WHERE id = %1";
2621 $params = array(1 => array($copy->id, 'Integer'));
2622 CRM_Core_DAO::executeQuery($query, $params);
2623 }
2624 CRM_Utils_Hook::copy('UFGroup', $copy);
2625
2626 return $copy;
2627 }
2628
2629 /**
2630 * Process that send notification e-mails
2631 *
2632 * @params int $contactId contact id
2633 * @params array $values associative array of name/value pair
2634 *
2635 * @return void
2636 * @access public
2637 */
2638
2639 static function commonSendMail($contactID, &$values) {
2640 if (!$contactID || !$values) {
2641 return;
2642
2643 }
2644 $template = CRM_Core_Smarty::singleton();
2645
2646 $displayName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
2647 $contactID,
2648 'display_name'
2649 );
2650
2651 self::profileDisplay($values['id'], $values['values'], $template);
2652 $emailList = explode(',', $values['email']);
2653
2654 $contactLink = CRM_Utils_System::url('civicrm/contact/view',
2655 "reset=1&cid=$contactID",
2656 TRUE, NULL, FALSE, FALSE, TRUE
2657 );
2658
2659 //get the default domain email address.
2660 list($domainEmailName, $domainEmailAddress) = CRM_Core_BAO_Domain::getNameAndEmail();
2661
2662 if (!$domainEmailAddress || $domainEmailAddress == 'info@EXAMPLE.ORG') {
2663 $fixUrl = CRM_Utils_System::url('civicrm/admin/domain', 'action=update&reset=1');
2664 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)));
2665 }
2666
2667 foreach ($emailList as $emailTo) {
2668 // FIXME: take the below out of the foreach loop
c6327d7d 2669 CRM_Core_BAO_MessageTemplate::sendTemplate(
6a488035
TO
2670 array(
2671 'groupName' => 'msg_tpl_workflow_uf',
2672 'valueName' => 'uf_notify',
2673 'contactId' => $contactID,
2674 'tplParams' => array(
2675 'displayName' => $displayName,
2676 'currentDate' => date('r'),
2677 'contactLink' => $contactLink,
2678 ),
2679 'from' => "$domainEmailName <$domainEmailAddress>",
2680 'toEmail' => $emailTo,
2681 )
2682 );
2683 }
2684 }
2685
2686 /**
2687 * Given a contact id and a group id, returns the field values from the db
2688 * for this group and notify email only if group's notify field is
2689 * set and field values are not empty
2690 *
2691 * @params $gid group id
2692 * @params $cid contact id
2693 * @params $params associative array
2694 *
2695 * @return array
2696 * @access public
2697 */
2698 function checkFieldsEmptyValues($gid, $cid, $params, $skipCheck = FALSE) {
2699 if ($gid) {
2700 if (CRM_Core_BAO_UFGroup::filterUFGroups($gid, $cid) || $skipCheck) {
2701 $values = array();
2702 $fields = CRM_Core_BAO_UFGroup::getFields($gid, FALSE, CRM_Core_Action::VIEW);
2703 CRM_Core_BAO_UFGroup::getValues($cid, $fields, $values, FALSE, $params, TRUE);
2704
2705 $email = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'notify');
2706
2707 if (!empty($values) &&
2708 !empty($email)
2709 ) {
2710 $val = array(
2711 'id' => $gid,
2712 'values' => $values,
2713 'email' => $email,
2714 );
2715 return $val;
2716 }
2717 }
2718 }
2719 return NULL;
2720 }
2721
2722 /**
2723 * Function to assign uf fields to template
2724 *
2725 * @params int $gid group id
2726 * @params array $values associative array of fields
2727 *
2728 * @return void
2729 * @access public
2730 */
2731 function profileDisplay($gid, $values, $template) {
2732 $groupTitle = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'title');
2733 $template->assign('grouptitle', $groupTitle);
2734 if (count($values)) {
2735 $template->assign('values', $values);
2736 }
2737 }
2738
2739 /**
2740 * Format fields for dupe Contact Matching
2741 *
2742 * @param array $params associated array
2743 *
2744 * @return array $data assoicated formatted array
2745 * @access public
2746 * @static
2747 */
2748 static function formatFields($params, $contactId = NULL) {
2749 if ($contactId) {
2750 // get the primary location type id and email
2751 list($name, $primaryEmail, $primaryLocationType) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactId);
2752 }
2753 else {
2754 $defaultLocationType = CRM_Core_BAO_LocationType::getDefault();
2755 $primaryLocationType = $defaultLocationType->id;
2756 }
2757
2758 $data = array();
2759 $locationType = array();
2760 $count = 1;
2761 $primaryLocation = 0;
2762 foreach ($params as $key => $value) {
2763 list($fieldName, $locTypeId, $phoneTypeId) = explode('-', $key);
2764
2765 if ($locTypeId == 'Primary') {
2766 $locTypeId = $primaryLocationType;
2767 }
2768
2769 if (is_numeric($locTypeId)) {
2770 if (!in_array($locTypeId, $locationType)) {
2771 $locationType[$count] = $locTypeId;
2772 $count++;
2773 }
2774 $loc = CRM_Utils_Array::key($locTypeId, $locationType);
2775
2776 $data['location'][$loc]['location_type_id'] = $locTypeId;
2777
2778 // if we are getting in a new primary email, dont overwrite the new one
2779 if ($locTypeId == $primaryLocationType) {
2780 if (CRM_Utils_Array::value('email-' . $primaryLocationType, $params)) {
2781 $data['location'][$loc]['email'][$loc]['email'] = $fields['email-' . $primaryLocationType];
2782 }
2783 elseif (isset($primaryEmail)) {
2784 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2785 }
2786 $primaryLocation++;
2787 }
2788
2789 if ($loc == 1) {
2790 $data['location'][$loc]['is_primary'] = 1;
2791 }
2792 if ($fieldName == 'phone') {
2793 if ($phoneTypeId) {
2794 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = $phoneTypeId;
2795 }
2796 else {
2797 $data['location'][$loc]['phone'][$loc]['phone_type_id'] = '';
2798 }
2799 $data['location'][$loc]['phone'][$loc]['phone'] = $value;
2800 }
2801 elseif ($fieldName == 'email') {
2802 $data['location'][$loc]['email'][$loc]['email'] = $value;
2803 }
2804 elseif ($fieldName == 'im') {
2805 $data['location'][$loc]['im'][$loc]['name'] = $value;
2806 }
2807 else {
2808 if ($fieldName === 'state_province') {
2809 $data['location'][$loc]['address']['state_province_id'] = $value;
2810 }
2811 elseif ($fieldName === 'country') {
2812 $data['location'][$loc]['address']['country_id'] = $value;
2813 }
2814 else {
2815 $data['location'][$loc]['address'][$fieldName] = $value;
2816 }
2817 }
2818 }
2819 else {
2820 if ($key === 'individual_suffix') {
2821 $data['suffix_id'] = $value;
2822 }
2823 elseif ($key === 'individual_prefix') {
2824 $data['prefix_id'] = $value;
2825 }
2826 elseif ($key === 'gender') {
2827 $data['gender_id'] = $value;
2828 }
2829 elseif (substr($key, 0, 6) === 'custom') {
2830 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($key)) {
2831 //fix checkbox
2832 if ($customFields[$customFieldID]['html_type'] == 'CheckBox') {
2833 $value = implode(CRM_Core_DAO::VALUE_SEPARATOR, array_keys($value));
2834 }
2835 // fix the date field
2836 if ($customFields[$customFieldID]['data_type'] == 'Date') {
2837 $date = CRM_Utils_Date::format($value);
2838 if (!$date) {
2839 $date = '';
2840 }
2841 $value = $date;
2842 }
2843
2844 $data['custom'][$customFieldID] = array(
2845 'id' => $id,
2846 'value' => $value,
2847 'extends' => $customFields[$customFieldID]['extends'],
2848 'type' => $customFields[$customFieldID]['data_type'],
2849 'custom_field_id' => $customFieldID,
2850 );
2851 }
2852 }
2853 elseif ($key == 'edit') {
2854 continue;
2855 }
2856 else {
2857 $data[$key] = $value;
2858 }
2859 }
2860 }
2861
2862 if (!$primaryLocation) {
2863 $loc++;
2864 $data['location'][$loc]['email'][$loc]['email'] = $primaryEmail;
2865 }
2866
2867
2868 return $data;
2869 }
2870
2871 /**
2872 * calculate the profile type 'group_type' as per profile fields.
2873 *
2874 * @param int $gid profile id
2875 * @param int $ignoreFieldId ignore particular profile field
2876 *
2877 * @return array list of calculated group type
2878 */
2879 static function calculateGroupType($gId, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2880 //get the profile fields.
2881 $ufFields = self::getFields($gId, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE);
2882 return self::_calculateGroupType($ufFields, $includeTypeValues, $ignoreFieldId);
2883 }
2884
2885 /**
2886 * calculate the profile type 'group_type' as per profile fields.
2887 *
2888 * @param int $gid profile id
2889 * @param int $ignoreFieldId ignore perticular profile field
2890 *
2891 * @return array list of calculated group type
2892 */
2893 static function _calculateGroupType($ufFields, $includeTypeValues = FALSE, $ignoreFieldId = NULL) {
2894 $groupType = $groupTypeValues = $customFieldIds = array();
2895 if (!empty($ufFields)) {
2896 foreach ($ufFields as $fieldName => $fieldValue) {
2897 //ignore field from group type when provided.
2898 //in case of update profile field.
2899 if ($ignoreFieldId && ($ignoreFieldId == $fieldValue['field_id'])) {
2900 continue;
2901 }
2902 if (!in_array($fieldValue['field_type'], $groupType)) {
2903 $groupType[$fieldValue['field_type']] = $fieldValue['field_type'];
2904 }
2905
2906 if ($includeTypeValues && ($fldId = CRM_Core_BAO_CustomField::getKeyID($fieldName))) {
2907 $customFieldIds[$fldId] = $fldId;
2908 }
2909 }
2910 }
2911
2912 if (!empty($customFieldIds)) {
2913 $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) . ')';
2914
2915 $customGroups = CRM_Core_DAO::executeQuery($query);
2916 while ($customGroups->fetch()) {
2917 if (!$customGroups->extends_entity_column_value) {
2918 continue;
2919 }
2920
2921 $groupTypeName = "{$customGroups->extends}Type";
2922 if ($customGroups->extends == 'Participant' && $customGroups->extends_entity_column_id) {
2923 $groupTypeName = CRM_Core_OptionGroup::getValue('custom_data_type', $customGroups->extends_entity_column_id, 'value', 'String', 'name');
2924 }
2925
2926 foreach (explode(CRM_Core_DAO::VALUE_SEPARATOR, $customGroups->extends_entity_column_value) as $val) {
2927 if ($val) {
2928 $groupTypeValues[$groupTypeName][$val] = $val;
2929 }
2930 }
2931 }
2932
2933 if (!empty($groupTypeValues)) {
2934 $groupType = array_merge($groupType, $groupTypeValues);
2935 }
2936 }
2937
2938 return $groupType;
2939 }
2940
2941 /**
2942 * Update the profile type 'group_type' as per profile fields including group types and group subtype values.
2943 * Build and store string like: group_type1,group_type2[VALUE_SEPERATOR]group_type1Type:1:2:3,group_type2Type:1:2
2944 *
2945 * FIELDS GROUP_TYPE
2946 * BirthDate + Email Individual,Contact
2947 * BirthDate + Subject Individual,Activity
2948 * BirthDate + Subject + SurveyOnlyField Individual,Activity\0ActivityType:28
2949 * BirthDate + Subject + SurveyOnlyField + PhoneOnlyField (Not allowed)
2950 * BirthDate + SurveyOnlyField Individual,Activity\0ActivityType:28
2951 * BirthDate + Subject + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2952 * BirthDate + SurveyOrPhoneField Individual,Activity\0ActivityType:2:28
2953 * BirthDate + SurveyOrPhoneField + SurveyOnlyField Individual,Activity\0ActivityType:2:28
2954 * BirthDate + StudentField + Subject + SurveyOnlyField Individual,Activity,Student\0ActivityType:28
2955 *
2956 * @param Integer $gid profile id
2957 * @param Array $groupTypes With key having group type names
2958 *
2959 * @return Boolean
2960 */
2961 static function updateGroupTypes($gId, $groupTypes = array(
2962 )) {
2963 if (!is_array($groupTypes) || !$gId) {
2964 return FALSE;
2965 }
2966
2967 // If empty group types set group_type as 'null'
2968 if (empty($groupTypes)) {
2969 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', 'null');
2970 }
2971
2972 $componentGroupTypes = array('Contribution', 'Participant', 'Membership', 'Activity');
2973 $validGroupTypes = array_merge(array('Contact', 'Individual', 'Organization', 'Household'), $componentGroupTypes, CRM_Contact_BAO_ContactType::subTypes());
2974
2975 $gTypes = $gTypeValues = array();
2976
2977 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
2978 // Get valid group type and group subtypes
2979 foreach ($groupTypes as $groupType => $value) {
2980 if (in_array($groupType, $validGroupTypes) && !in_array($groupType, $gTypes)) {
2981 $gTypes[] = $groupType;
2982 }
2983
2984 $subTypesOf = NULL;
2985
2986 if (in_array($groupType, $participantExtends)) {
2987 $subTypesOf = $groupType;
2988 }
2989 elseif (strpos($groupType, 'Type') > 0) {
2990 $subTypesOf = substr($groupType, 0, strpos($groupType, 'Type'));
2991 }
2992 else {
2993 continue;
2994 }
2995
2996 if (!empty($value) &&
2997 (in_array($subTypesOf, $componentGroupTypes) ||
2998 in_array($subTypesOf, $participantExtends)
2999 )
3000 ) {
3001 $gTypeValues[$subTypesOf] = $groupType . ":" . implode(':', $value);
3002 }
3003 }
3004
3005 if (empty($gTypes)) {
3006 return FALSE;
3007 }
3008
3009 // Build String to store group types and group subtypes
3010 $groupTypeString = implode(',', $gTypes);
3011 if (!empty($gTypeValues)) {
3012 $groupTypeString .= CRM_Core_DAO::VALUE_SEPARATOR . implode(',', $gTypeValues);
3013 }
3014
3015 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFGroup', $gId, 'group_type', $groupTypeString);
3016 }
3017
3018 /**
3019 * Create a "group_type" string
3020 *
3021 * @param array $coreTypes e.g. array('Individual','Contact','Student')
3022 * @param array $subTypes e.g. array('ActivityType' => array(7, 11))
3023 * @param string $delim
3024 * @throws CRM_Core_Exception
3025 */
3026 static function encodeGroupType($coreTypes, $subTypes, $delim = CRM_Core_DAO::VALUE_SEPARATOR) {
3027 $groupTypeExpr = '';
3028 if ($coreTypes) {
3029 $groupTypeExpr .= implode(',', $coreTypes);
3030 }
3031 if ($subTypes) {
3032 if (count($subTypes) > 1) {
3033 throw new CRM_Core_Exception("Multiple subtype filtering is not currently supported by widget.");
3034 }
3035 foreach ($subTypes as $subType => $subTypeIds) {
3036 $groupTypeExpr .= $delim . $subType . ':' . implode(':', $subTypeIds);
3037 }
3038 }
3039 return $groupTypeExpr;
3040 }
3041
3042 /**
3043 * This function is used to setDefault componet specific profile fields.
3044 *
3045 * @param array $fields profile fields.
3046 * @param int $componentId componetID
3047 * @param string $component component name
3048 * @param array $defaults an array of default values.
3049 *
3050 * @return void.
3051 */
3052 function setComponentDefaults(&$fields, $componentId, $component, &$defaults, $isStandalone = FALSE) {
3053 if (!$componentId ||
3054 !in_array($component, array('Contribute', 'Membership', 'Event', 'Activity'))
3055 ) {
3056 return;
3057 }
3058
3059 $componentBAO = $componentSubType = NULL;
3060 switch ($component) {
3061 case 'Membership':
3062 $componentBAO = 'CRM_Member_BAO_Membership';
3063 $componentBAOName = 'Membership';
3064 $componentSubType = array('membership_type_id');
3065 break;
3066
3067 case 'Contribute':
3068 $componentBAO = 'CRM_Contribute_BAO_Contribution';
3069 $componentBAOName = 'Contribution';
3070 $componentSubType = array( 'financial_type_id' );
3071 break;
3072
3073 case 'Event':
3074 $componentBAO = 'CRM_Event_BAO_Participant';
3075 $componentBAOName = 'Participant';
3076 $componentSubType = array('role_id', 'event_id');
3077 break;
3078
3079 case 'Activity':
3080 $componentBAO = 'CRM_Activity_BAO_Activity';
3081 $componentBAOName = 'Activity';
3082 $componentSubType = array('activity_type_id');
3083 break;
3084 }
3085
3086 $values = array();
3087 $params = array('id' => $componentId);
3088
3089 //get the component values.
3090 CRM_Core_DAO::commonRetrieve($componentBAO, $params, $values);
3091
3092 $formattedGroupTree = array();
3093 $dateTimeFields = array('participant_register_date', 'activity_date_time', 'receive_date', 'receipt_date', 'cancel_date', 'thankyou_date', 'membership_start_date', 'membership_end_date', 'join_date');
3094 foreach ($fields as $name => $field) {
3095 $fldName = $isStandalone ? $name : "field[$componentId][$name]";
3096 if (in_array($name, $dateTimeFields)) {
3097 $timefldName = $isStandalone ? "{$name}_time" : "field[$componentId][{$name}_time]";
3098 if (CRM_Utils_Array::value($name, $values)) {
3099 list($defaults[$fldName], $defaults[$timefldName]) = CRM_Utils_Date::setDateDefaults($values[$name]);
3100 }
3101 }
3102 elseif (array_key_exists($name, $values)) {
3103 $defaults[$fldName] = $values[$name];
3104 }
3105 elseif ($name == 'participant_note') {
3106 $noteDetails = CRM_Core_BAO_Note::getNote($componentId, 'civicrm_participant');
3107 $defaults[$fldName] = array_pop($noteDetails);
3108 }
3109 elseif (in_array($name, array(
3110 'financial_type', 'payment_instrument', 'participant_status', 'participant_role'))) {
3111 $defaults[$fldName] = $values["{$name}_id"];
3112 }
3113 elseif ($name == 'membership_type') {
3114 // since membership_type field is a hierselect -
3115 $defaults[$fldName][0] =
3116 CRM_Core_DAO::getFieldValue('CRM_Member_DAO_MembershipType',$values['membership_type_id'],'member_of_contact_id','id');
3117 $defaults[$fldName][1] = $values['membership_type_id'];
3118 }
3119 elseif ($name == 'membership_status') {
3120 $defaults[$fldName] = $values['status_id'];
3121 }
3122 elseif ($customFieldInfo = CRM_Core_BAO_CustomField::getKeyID($name, TRUE)) {
3123 if (empty($formattedGroupTree)) {
3124 //get the groupTree as per subTypes.
3125 $groupTree = array();
3126 foreach ($componentSubType as $subType) {
3127 $subTree = CRM_Core_BAO_CustomGroup::getTree($componentBAOName, CRM_Core_DAO::$_nullObject,
3128 $componentId, 0, $values[$subType]
3129 );
3130 $groupTree = CRM_Utils_Array::crmArrayMerge($groupTree, $subTree);
3131 }
3132 $formattedGroupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree, 1, CRM_Core_DAO::$_nullObject);
3133 CRM_Core_BAO_CustomGroup::setDefaults($formattedGroupTree, $defaults);
3134 }
3135
3136 //FIX ME: We need to loop defaults, but once we move to custom_1_x convention this code can be simplified.
3137 foreach ($defaults as $customKey => $customValue) {
3138 if ($customFieldDetails = CRM_Core_BAO_CustomField::getKeyID($customKey, TRUE)) {
3139 if ($name == 'custom_' . $customFieldDetails[0]) {
3140
3141 //hack to set default for checkbox
3142 //basically this is for weired field name like field[33][custom_19]
3143 //we are converting this field name to array structure and assign value.
3144 $skipValue = FALSE;
3145
3146 foreach ($formattedGroupTree as $tree) {
3147 if ('CheckBox' == CRM_Utils_Array::value('html_type', $tree['fields'][$customFieldDetails[0]])) {
3148 $skipValue = TRUE;
3149 $defaults['field'][$componentId][$name] = $customValue;
3150 break;
3151 }
3152 elseif (CRM_Utils_Array::value('data_type', $tree['fields'][$customFieldDetails[0]]) == 'Date') {
3153 $skipValue = TRUE;
3154
3155 // CRM-6681, $default contains formatted date, time values.
3156 $defaults[$fldName] = $customValue;
3157 if (CRM_Utils_Array::value($customKey . '_time', $defaults)) {
3158 $defaults['field'][$componentId][$name . '_time'] = $defaults[$customKey . '_time'];
3159 }
3160 }
3161 }
3162
3163 if (!$skipValue || $isStandalone) {
3164 $defaults[$fldName] = $customValue;
3165 }
3166 unset($defaults[$customKey]);
3167 break;
3168 }
3169 }
3170 }
3171 }
3172 }
3173 }
3174
3175 /**
3176 * Function to retrieve reserved profiles
3177 *
3178 * @param string $name name if the reserve profile
3179 * @param array $extraProfiles associated array of profile id's that needs to merge
3180 *
3181 * @return array $reservedProfiles returns associated array
3182 * @static
3183 */
3184 static function getReservedProfiles($type = 'Contact', $extraProfiles = NULL) {
3185 $reservedProfiles = array();
3186 $profileNames = array();
3187 if ($type == 'Contact') {
3188 $whereClause = 'name IN ( "new_individual", "new_organization", "new_household" )';
3189 if (CRM_Contact_BAO_ContactType::isActive('Individual')) {
3190 $profileNames[] = '"new_individual"';
3191 }
3192 if (CRM_Contact_BAO_ContactType::isActive('Household')) {
3193 $profileNames[] = '"new_household"';
3194 }
3195 if (CRM_Contact_BAO_ContactType::isActive('Organization')) {
3196 $profileNames[] = '"new_organization"';
3197 }
3198 }
3199 if (!empty($profileNames)) {
3200 $whereClause = 'name IN ( ' . implode(',', $profileNames) . ' ) AND is_reserved = 1';
3201 }
3202 else {
3203 $whereClause = 'is_reserved = 1';
3204 }
3205
3206 $query = "SELECT id, title FROM civicrm_uf_group WHERE {$whereClause}";
3207
3208 $dao = CRM_Core_DAO::executeQuery($query);
3209 while ($dao->fetch()) {
3210 $key = $dao->id;
3211 if ($extraProfiles) {
3212 $key .= ',' . implode(',', $extraProfiles);
3213 }
3214 $reservedProfiles[$key] = $dao->title;
3215 }
3216 return $reservedProfiles;
3217 }
3218
3219 /**
3220 * Function to retrieve groups of profiles
3221 *
3222 * @param integer $profileID id of the profile
3223 *
3224 * @return array returns array
3225 * @static
3226 */
3227 static function profileGroups($profileID) {
3228 $groupTypes = array();
3229 $profileTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileID, 'group_type');
3230 if ($profileTypes) {
3231 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $profileTypes);
3232 $groupTypes = explode(',', $groupTypeParts[0]);
3233 }
3234 return $groupTypes;
3235 }
3236
3237 /**
3238 * Function to alter contact params by filtering existing subscribed groups and returns
3239 * unsubscribed groups array for subscription.
3240 *
3241 * @param array $params contact params
3242 * @param int $contactId user contact id
3243 *
3244 * @return array $subscribeGroupIds This contains array of groups for subscription
3245 */
3246 static function getDoubleOptInGroupIds(&$params, $contactId = NULL) {
3247 $config = CRM_Core_Config::singleton();
3248 $subscribeGroupIds = array();
3249
3250 // process further only if profileDoubleOptIn enabled and if groups exist
3251 if (!array_key_exists('group', $params) ||
3252 !self::isProfileDoubleOptin() ||
3253 CRM_Utils_System::isNull($params['group'])
3254 ) {
3255 return $subscribeGroupIds;
3256 }
3257
3258 //check if contact email exist.
3259 $hasEmails = FALSE;
3260 foreach ($params as $name => $value) {
3261 if (strpos($name, 'email-') !== FALSE) {
3262 $hasEmails = TRUE;
3263 break;
3264 }
3265 }
3266
3267 //Proceed furthur only if email present
3268 if (!$hasEmails) {
3269 return $subscribeGroupIds;
3270 }
3271
3272 //do check for already subscriptions.
3273 $contactGroups = array();
3274 if ($contactId) {
3275 $query = "
3276SELECT group_id
3277 FROM civicrm_group_contact
3278 WHERE status = 'Added'
3279 AND contact_id = %1";
3280
3281 $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($contactId, 'Integer')));
3282 while ($dao->fetch()) {
3283 $contactGroups[$dao->group_id] = $dao->group_id;
3284 }
3285 }
3286
3287 //since we don't have names, compare w/ label.
3288 $mailingListGroupType = array_search('Mailing List', CRM_Core_OptionGroup::values('group_type'));
3289
3290 //actual processing start.
3291 foreach ($params['group'] as $groupId => $isSelected) {
3292 //unset group those are not selected.
3293 if (!$isSelected) {
3294 unset($params['group'][$groupId]);
3295 continue;
3296 }
3297
3298 $groupTypes = explode(CRM_Core_DAO::VALUE_SEPARATOR,
3299 CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Group', $groupId, 'group_type', 'id')
3300 );
3301 //get only mailing type group and unset it from params
3302 if (in_array($mailingListGroupType, $groupTypes) && !in_array($groupId, $contactGroups)) {
3303 $subscribeGroupIds[$groupId] = $groupId;
3304 unset($params['group'][$groupId]);
3305 }
3306 }
3307
3308 return $subscribeGroupIds;
3309 }
3310
3311 /**
3312 * Function to check if we are rendering mixed profiles
3313 *
3314 * @param array $profileIds associated array of profile ids
3315 *
3316 * @return boolean $mixProfile true if profile is mixed
3317 * @static
3318 * @access public
3319 */
3320 static function checkForMixProfiles($profileIds) {
3321 $mixProfile = FALSE;
3322
3323 $contactTypes = array('Individual', 'Household', 'Organization');
3324 $subTypes = CRM_Contact_BAO_ContactType::subTypes();
3325
3326 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
3327
3328 $typeCount = array('ctype' => array(), 'subtype' => array());
3329 foreach ($profileIds as $gid) {
3330 $profileType = CRM_Core_BAO_UFField::getProfileType($gid);
3331 // ignore profile of type Contact
3332 if ($profileType == 'Contact') {
3333 continue;
3334 }
3335 if (in_array($profileType, $contactTypes)) {
3336 if (!isset($typeCount['ctype'][$profileType])) {
3337 $typeCount['ctype'][$profileType] = 1;
3338 }
3339
3340 // check if we are rendering profile of different contact types
3341 if (count($typeCount['ctype']) == 2) {
3342 $mixProfile = TRUE;
3343 break;
3344 }
3345 }
3346 elseif (in_array($profileType, $components)) {
3347 $mixProfile = TRUE;
3348 break;
3349 }
3350 else {
3351 if (!isset($typeCount['subtype'][$profileType])) {
3352 $typeCount['subtype'][$profileType] = 1;
3353 }
3354 // check if we are rendering profile of different contact sub types
3355 if (count($typeCount['subtype']) == 2) {
3356 $mixProfile = TRUE;
3357 break;
3358 }
3359 }
3360 }
3361 return $mixProfile;
3362 }
3363
3364 /**
3365 * Funtion to determine of we show overlay profile or not
3366 *
3367 * @return boolean true if profile should be shown else false
3368 * @static
3369 * @access public
3370 */
3371 static function showOverlayProfile() {
3372 $showOverlay = TRUE;
3373
3374 // get the id of overlay profile
3375 $overlayProfileId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', 'summary_overlay', 'id', 'name');
3376 $query = "SELECT count(id) FROM civicrm_uf_field WHERE uf_group_id = {$overlayProfileId} AND visibility IN ('Public Pages', 'Public Pages and Listings') ";
3377
3378 $count = CRM_Core_DAO::singleValueQuery($query);
3379
3380 //check if there are no public fields and use is anonymous
3381 $session = CRM_Core_Session::singleton();
3382 if (!$count && !$session->get('userID')) {
3383 $showOverlay = FALSE;
3384 }
3385
3386 return $showOverlay;
3387 }
3388
3389 /**
3390 * function to get group type values of the profile
3391 *
3392 * @params Integer $profileId Profile Id
3393 * @params String $groupType Group Type
3394 *
3395 * @return Array group type values
3396 * @static
3397 * @access public
3398 */
3399 static function groupTypeValues($profileId, $groupType = NULL) {
3400 $groupTypeValue = array();
3401 $groupTypes = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $profileId, 'group_type');
3402
3403 $groupTypeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $groupTypes);
3404 if (!CRM_Utils_Array::value(1, $groupTypeParts)) {
3405 return $groupTypeValue;
3406 }
3407 $participantExtends = array('ParticipantRole', 'ParticipantEventName', 'ParticipantEventType');
3408
3409 foreach (explode(',', $groupTypeParts[1]) as $groupTypeValues) {
3410 $values = array();
3411 $valueParts = explode(':', $groupTypeValues);
3412 if ($groupType &&
3413 ($valueParts[0] != "{$groupType}Type" ||
3414 ($groupType == 'Participant' &&
3415 !in_array($valueParts[0], $participantExtends)
3416 )
3417 )
3418 ) {
3419 continue;
3420 }
3421 foreach ($valueParts as $val) {
3422 if (CRM_Utils_Rule::integer($val)) {
3423 $values[$val] = $val;
3424 }
3425 }
3426 if (!empty($values)) {
3427 $typeName = substr($valueParts[0], 0, -4);
3428 if (in_array($valueParts[0], $participantExtends)) {
3429 $typeName = $valueParts[0];
3430 }
3431 $groupTypeValue[$typeName] = $values;
3432 }
3433 }
3434
3435 return $groupTypeValue;
3436 }
3437
3438 static function isProfileDoubleOptin() {
3439 // check for double optin
3440 $config = CRM_Core_Config::singleton();
3441 if (in_array('CiviMail', $config->enableComponents)) {
3442 return CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
3443 'profile_double_optin', NULL, FALSE
3444 );
3445 }
3446 return FALSE;
3447 }
3448
3449 static function isProfileAddToGroupDoubleOptin() {
3450 // check for add to group double optin
3451 $config = CRM_Core_Config::singleton();
3452 if (in_array('CiviMail', $config->enableComponents)) {
3453 return CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::MAILING_PREFERENCES_NAME,
3454 'profile_add_to_group_double_optin', NULL, FALSE
3455 );
3456 }
3457 return FALSE;
3458 }
3459
3460 /**
3461 * get profiles used for batch entry
3462 *
3463 * @return array profileIds profile ids
3464 * @static
3465 */
3466 static function getBatchProfiles() {
3467 $query = "SELECT id
3468 FROM civicrm_uf_group
3469 WHERE name IN ('contribution_batch_entry', 'membership_batch_entry')";
3470 $dao = CRM_Core_DAO::executeQuery( $query );
3471 $profileIds = array();
3472 while( $dao->fetch() ) {
3473 $profileIds[$dao->id] = $dao->id;
3474 }
3475 return $profileIds;
3476 }
3477
3478 static function shiftMultiRecordFields(&$source, &$destination, $returnMultiSummaryFields = FALSE) {
3479 $multiSummaryFields = $returnMultiSummaryFields ? array( ) : NULL;
3480 foreach ($source as $field => $properties) {
3481 if (!CRM_Core_BAO_CustomField::getKeyID($field)) {
3482 continue;
3483 }
3484 if (CRM_Core_BAO_CustomField::isMultiRecordField($field)) {
3485 $destination[$field] = $properties;
3486 if ($returnMultiSummaryFields) {
3487 if ($properties['is_multi_summary']) {
3488 $multiSummaryFields[$field] = $properties;
3489 }
3490 }
3491 unset($source[$field]);
3492 }
3493 }
3494 return $multiSummaryFields;
3495 }
3496
3497 /**
3498 * This is function is used to format pseudo fields
3499 *
3500 * @param array $fields associated array of profile fields
3501 *
3502 * @static
3503 */
3504 static function reformatProfileFields(&$fields) {
3505 //reformat fields array
3506 foreach ($fields as $name => $field) {
3507 //reformat phone and extension field
3508 if ( substr($field['name'], 0, 13) == 'phone_and_ext') {
3509 $fieldSuffix = str_replace('phone_and_ext-', '', $field['name']);
3510
3511 // retain existing element properties and just update and replace key
3512 CRM_Utils_Array::crmReplaceKey($fields, $name, "phone-{$fieldSuffix}");
3513 $fields["phone-{$fieldSuffix}"]['name'] = "phone-{$fieldSuffix}";
3514 $fields["phone-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone';
3515
3516 // add additional phone extension field
3517 $fields["phone_ext-{$fieldSuffix}"] = $field;
3518 $fields["phone_ext-{$fieldSuffix}"]['title'] = $field['title'] .' - '.ts('Ext.');
3519 $fields["phone_ext-{$fieldSuffix}"]['name'] = "phone_ext-{$fieldSuffix}";
3520 $fields["phone_ext-{$fieldSuffix}"]['where'] = 'civicrm_phone.phone_ext';
3521 $fields["phone_ext-{$fieldSuffix}"]['skipDisplay'] = 1;
3522 //ignore required for extension field
3523 $fields["phone_ext-{$fieldSuffix}"]['is_required'] = 0;
3524 }
3525 }
3526 }
3527}