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