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