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