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