commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / civicrm / CRM / Core / BAO / UFField.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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-2015
32 * $Id$
33 *
34 */
35
36 /**
37 * This class contains function for UFField
38 *
39 */
40 class CRM_Core_BAO_UFField extends CRM_Core_DAO_UFField {
41
42 /**
43 * Batch entry fields.
44 */
45 private static $_contriBatchEntryFields = NULL;
46 private static $_memberBatchEntryFields = NULL;
47
48
49 /**
50 * Fetch object based on array of properties.
51 *
52 * @param array $params
53 * (reference ) an assoc array of name/value pairs.
54 * @param array $defaults
55 * (reference ) an assoc array to hold the flattened values.
56 *
57 * @return CRM_Core_BAO_UFField
58 */
59 public static function retrieve(&$params, &$defaults) {
60 return CRM_Core_DAO::commonRetrieve('CRM_Core_DAO_UFField', $params, $defaults);
61 }
62
63 /**
64 * Get the form title.
65 *
66 * @param int $id
67 * Id of uf_form.
68 *
69 * @return string
70 * title
71 *
72 */
73 public static function getTitle($id) {
74 return CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFField', $groupId, 'title');
75 }
76
77 /**
78 * Update the is_active flag in the db.
79 *
80 * @param int $id
81 * Id of the database record.
82 * @param bool $is_active
83 * Value we want to set the is_active field.
84 *
85 * @return Object
86 * DAO object on sucess, null otherwise
87 */
88 public static function setIsActive($id, $is_active) {
89 //check if custom data profile field is disabled
90 if ($is_active) {
91 if (CRM_Core_BAO_UFField::checkUFStatus($id)) {
92 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFField', $id, 'is_active', $is_active);
93 }
94 else {
95 CRM_Core_Session::setStatus(ts('Cannot enable this UF field since the used custom field is disabled.'), ts('Check Custom Field'), 'error');
96 }
97 }
98 else {
99 return CRM_Core_DAO::setFieldValue('CRM_Core_DAO_UFField', $id, 'is_active', $is_active);
100 }
101 }
102
103 /**
104 * Delete the profile Field.
105 *
106 * @param int $id
107 * Field Id.
108 *
109 * @return bool
110 *
111 */
112 public static function del($id) {
113 //delete field field
114 $field = new CRM_Core_DAO_UFField();
115 $field->id = $id;
116 $field->delete();
117 return TRUE;
118 }
119
120 /**
121 * Check duplicate for duplicate field in a group.
122 *
123 * @param array $params
124 * An associative array with field and values.
125 * @param $ids
126 *
127 * @return mixed
128 * @ids array $ids array that containd ids
129 *
130 */
131 public static function duplicateField($params, $ids) {
132 $ufField = new CRM_Core_DAO_UFField();
133 $ufField->uf_group_id = CRM_Utils_Array::value('uf_group', $ids);
134 $ufField->field_type = $params['field_name'][0];
135 $ufField->field_name = $params['field_name'][1];
136 if ($params['field_name'][1] == 'url') {
137 $ufField->website_type_id = CRM_Utils_Array::value(2, $params['field_name'], NULL);
138 }
139 else {
140 $ufField->location_type_id = (CRM_Utils_Array::value(2, $params['field_name'])) ? $params['field_name'][2] : 'NULL';
141 }
142 $ufField->phone_type_id = CRM_Utils_Array::value(3, $params['field_name']);
143
144 if (!empty($ids['uf_field'])) {
145 $ufField->whereAdd("id <> " . CRM_Utils_Array::value('uf_field', $ids));
146 }
147
148 return $ufField->find(TRUE);
149 }
150
151 /**
152 * Does profile consists of a multi-record custom field
153 */
154 public static function checkMultiRecordFieldExists($gId) {
155 $queryString = "SELECT f.field_name
156 FROM civicrm_uf_field f, civicrm_uf_group g
157 WHERE f.uf_group_id = g.id
158 AND g.id = %1 AND f.field_name LIKE 'custom%'";
159 $p = array(1 => array($gId, 'Integer'));
160 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
161 $customFieldIds = array();
162 $isMultiRecordFieldPresent = FALSE;
163 while ($dao->fetch()) {
164 if ($customId = CRM_Core_BAO_CustomField::getKeyID($dao->field_name)) {
165 if (is_numeric($customId)) {
166 $customFieldIds[] = $customId;
167 }
168 }
169 }
170
171 if (!empty($customFieldIds) && count($customFieldIds) == 1) {
172 $customFieldId = array_pop($customFieldIds);
173 $isMultiRecordFieldPresent = CRM_Core_BAO_CustomField::isMultiRecordField($customFieldId);
174 }
175 elseif (count($customFieldIds) > 1) {
176 $customFieldIds = implode(", ", $customFieldIds);
177 $queryString = "
178 SELECT cg.id as cgId
179 FROM civicrm_custom_group cg
180 INNER JOIN civicrm_custom_field cf
181 ON cg.id = cf.custom_group_id
182 WHERE cf.id IN (" . $customFieldIds . ") AND is_multiple = 1 LIMIT 0,1";
183
184 $dao = CRM_Core_DAO::executeQuery($queryString);
185 if ($dao->fetch()) {
186 $isMultiRecordFieldPresent = ($dao->cgId) ? $dao->cgId : FALSE;
187 }
188 }
189
190 return $isMultiRecordFieldPresent;
191 }
192
193 /**
194 * Add the UF Field.
195 *
196 * @param array $params
197 * (reference) array containing the values submitted by the form.
198 * @param array $ids
199 * Array containing the id.
200 *
201 * @return CRM_Core_BAO_UFField
202 *
203 */
204 public static function add(&$params, $ids = array()) {
205 // set values for uf field properties and save
206 $ufField = new CRM_Core_DAO_UFField();
207 $ufField->field_type = $params['field_name'][0];
208 $ufField->field_name = $params['field_name'][1];
209
210 //should not set location type id for Primary
211 $locationTypeId = NULL;
212 if ($params['field_name'][1] == 'url') {
213 $ufField->website_type_id = CRM_Utils_Array::value(2, $params['field_name']);
214 }
215 else {
216 $locationTypeId = CRM_Utils_Array::value(2, $params['field_name']);
217 $ufField->website_type_id = NULL;
218 }
219 if ($locationTypeId) {
220 $ufField->location_type_id = $locationTypeId;
221 }
222 else {
223 $ufField->location_type_id = 'null';
224 }
225
226 $ufField->phone_type_id = CRM_Utils_Array::value(3, $params['field_name'], 'NULL');
227 $ufField->listings_title = CRM_Utils_Array::value('listings_title', $params);
228 $ufField->visibility = CRM_Utils_Array::value('visibility', $params);
229 $ufField->help_pre = CRM_Utils_Array::value('help_pre', $params);
230 $ufField->help_post = CRM_Utils_Array::value('help_post', $params);
231 $ufField->label = CRM_Utils_Array::value('label', $params);
232 $ufField->is_required = CRM_Utils_Array::value('is_required', $params, FALSE);
233 $ufField->is_active = CRM_Utils_Array::value('is_active', $params, FALSE);
234 $ufField->in_selector = CRM_Utils_Array::value('in_selector', $params, FALSE);
235 $ufField->is_view = CRM_Utils_Array::value('is_view', $params, FALSE);
236 $ufField->is_registration = CRM_Utils_Array::value('is_registration', $params, FALSE);
237 $ufField->is_match = CRM_Utils_Array::value('is_match', $params, FALSE);
238 $ufField->is_searchable = CRM_Utils_Array::value('is_searchable', $params, FALSE);
239 $ufField->is_multi_summary = CRM_Utils_Array::value('is_multi_summary', $params, FALSE);
240 $ufField->weight = CRM_Utils_Array::value('weight', $params, 0);
241
242 // need the FKEY - uf group id
243 $ufField->uf_group_id = CRM_Utils_Array::value('uf_group', $ids, FALSE);
244 $ufField->id = CRM_Utils_Array::value('uf_field', $ids, FALSE);
245
246 return $ufField->save();
247 }
248
249 /**
250 * Automatically determine one weight and modify others.
251 *
252 * @param array $params
253 * UFField record, e.g. with 'weight', 'uf_group_id', and 'field_id'.
254 * @return int
255 */
256 public static function autoWeight($params) {
257 // fix for CRM-316
258 $oldWeight = NULL;
259
260 if (!empty($params['field_id'])) {
261 $oldWeight = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFField', $params['field_id'], 'weight', 'id');
262 }
263 $fieldValues = array('uf_group_id' => $params['group_id']);
264 return CRM_Utils_Weight::updateOtherWeights('CRM_Core_DAO_UFField', $oldWeight, CRM_Utils_Array::value('weight', $params, 0), $fieldValues);
265 }
266
267 /**
268 * Enable/disable profile field given a custom field id
269 *
270 * @param int $customFieldId
271 * Custom field id.
272 * @param bool $is_active
273 * Set the is_active field.
274 *
275 * @return void
276 */
277 public static function setUFField($customFieldId, $is_active) {
278 //find the profile id given custom field
279 $ufField = new CRM_Core_DAO_UFField();
280 $ufField->field_name = "custom_" . $customFieldId;
281
282 $ufField->find();
283 while ($ufField->fetch()) {
284 //enable/ disable profile
285 CRM_Core_BAO_UFField::setIsActive($ufField->id, $is_active);
286 }
287 }
288
289 /**
290 * Copy existing profile fields to
291 * new profile from the already built profile
292 *
293 * @param int $old_id
294 * From which we need to copy.
295 * @param bool $new_id
296 * In which to copy.
297 *
298 * @return void
299 */
300 public static function copy($old_id, $new_id) {
301 $ufField = new CRM_Core_DAO_UFField();
302 $ufField->uf_group_id = $old_id;
303 $ufField->find();
304 while ($ufField->fetch()) {
305 //copy the field records as it is on new ufgroup id
306 $ufField->uf_group_id = $new_id;
307 $ufField->id = NULL;
308 $ufField->save();
309 }
310 }
311
312 /**
313 * Delete profile field given a custom field.
314 *
315 * @param int $customFieldId
316 * ID of the custom field to be deleted.
317 *
318 * @return void
319 *
320 */
321 public static function delUFField($customFieldId) {
322 //find the profile id given custom field id
323 $ufField = new CRM_Core_DAO_UFField();
324 $ufField->field_name = "custom_" . $customFieldId;
325
326 $ufField->find();
327 while ($ufField->fetch()) {
328 //enable/ disable profile
329 CRM_Core_BAO_UFField::del($ufField->id);
330 }
331 }
332
333 /**
334 * Enable/disable profile field given a custom group id
335 *
336 * @param int $customGroupId
337 * Custom group id.
338 * @param bool $is_active
339 * Value we want to set the is_active field.
340 *
341 * @return void
342 */
343 public static function setUFFieldStatus($customGroupId, $is_active) {
344 //find the profile id given custom group id
345 $queryString = "SELECT civicrm_custom_field.id as custom_field_id
346 FROM civicrm_custom_field, civicrm_custom_group
347 WHERE civicrm_custom_field.custom_group_id = civicrm_custom_group.id
348 AND civicrm_custom_group.id = %1";
349 $p = array(1 => array($customGroupId, 'Integer'));
350 $dao = CRM_Core_DAO::executeQuery($queryString, $p);
351
352 while ($dao->fetch()) {
353 //enable/ disable profile
354 CRM_Core_BAO_UFField::setUFField($dao->custom_field_id, $is_active);
355 }
356 }
357
358 /**
359 * Check the status of custom field used in uf fields.
360 *
361 * @param int $UFFieldId
362 *
363 * @return bool
364 * false if custom field are disabled else true
365 */
366 public static function checkUFStatus($UFFieldId) {
367 $fieldName = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFField', $UFFieldId, 'field_name');
368 // return if field is not a custom field
369 if (!$customFieldId = CRM_Core_BAO_CustomField::getKeyID($fieldName)) {
370 return TRUE;
371 }
372
373 $customField = new CRM_Core_DAO_CustomField();
374 $customField->id = $customFieldId;
375 // if uf field is custom field
376 if ($customField->find(TRUE)) {
377 if (!$customField->is_active) {
378 return FALSE;
379 }
380 else {
381 return TRUE;
382 }
383 }
384 }
385
386 /**
387 * Find out whether given profile group using Activity
388 * Profile fields with contact fields
389 */
390 public static function checkContactActivityProfileType($ufGroupId) {
391 $ufGroup = new CRM_Core_DAO_UFGroup();
392 $ufGroup->id = $ufGroupId;
393 $ufGroup->find(TRUE);
394
395 return self::checkContactActivityProfileTypeByGroupType($ufGroup->group_type);
396 }
397
398 /**
399 * FIXME say 10 ha
400 * @param $ufGroupType
401 * @return bool
402 */
403 public static function checkContactActivityProfileTypeByGroupType($ufGroupType) {
404 $profileTypes = array();
405 if ($ufGroupType) {
406 $typeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $ufGroupType);
407 $profileTypes = explode(',', $typeParts[0]);
408 }
409
410 if (empty($profileTypes)) {
411 return FALSE;
412 }
413 $components = array('Contribution', 'Participant', 'Membership');
414 if (!in_array('Activity', $profileTypes)) {
415 return FALSE;
416 }
417 elseif (count($profileTypes) == 1) {
418 return FALSE;
419 }
420
421 if ($index = array_search('Contact', $profileTypes)) {
422 unset($profileTypes[$index]);
423 if (count($profileTypes) == 1) {
424 return TRUE;
425 }
426 }
427
428 $contactTypes = array('Individual', 'Household', 'Organization');
429 $subTypes = CRM_Contact_BAO_ContactType::subTypes();
430
431 $profileTypeComponent = array_intersect($components, $profileTypes);
432 if (!empty($profileTypeComponent) ||
433 count(array_intersect($contactTypes, $profileTypes)) > 1 ||
434 count(array_intersect($subTypes, $profileTypes)) > 1
435 ) {
436 return FALSE;
437 }
438
439 return TRUE;
440 }
441
442 /**
443 * Find out whether given profile group uses $required
444 * and/or $optional profile types
445 *
446 * @param int $ufGroupId
447 * Profile id.
448 * @param array $required
449 * Array of types those are required.
450 * @param array $optional
451 * Array of types those are optional.
452 *
453 * @return bool
454 */
455 public static function checkValidProfileType($ufGroupId, $required, $optional = NULL) {
456 if (!is_array($required) || empty($required)) {
457 return FALSE;
458 }
459
460 $ufGroup = new CRM_Core_DAO_UFGroup();
461 $ufGroup->id = $ufGroupId;
462 $ufGroup->find(TRUE);
463
464 $profileTypes = array();
465 if ($ufGroup->group_type) {
466 $typeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $ufGroup->group_type);
467 $profileTypes = explode(',', $typeParts[0]);
468 }
469
470 if (empty($profileTypes)) {
471 return FALSE;
472 }
473
474 $valid = TRUE;
475 foreach ($required as $key => $val) {
476 if (!in_array($val, $profileTypes)) {
477 $valid = FALSE;
478 break;
479 }
480 }
481
482 if ($valid && is_array($optional)) {
483 foreach ($optional as $key => $val) {
484 if (in_array($val, $profileTypes)) {
485 $valid = TRUE;
486 break;
487 }
488 }
489 }
490
491 return $valid;
492 }
493
494 /**
495 * Check for mix profile fields (eg: individual + other contact types)
496 *
497 * @param int $ufGroupId
498 *
499 * @return bool
500 * true for mix profile else false
501 */
502 public static function checkProfileType($ufGroupId) {
503 $ufGroup = new CRM_Core_DAO_UFGroup();
504 $ufGroup->id = $ufGroupId;
505 $ufGroup->find(TRUE);
506
507 $profileTypes = array();
508 if ($ufGroup->group_type) {
509 $typeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $ufGroup->group_type);
510 $profileTypes = explode(',', $typeParts[0]);
511 }
512
513 //early return if new profile.
514 if (empty($profileTypes)) {
515 return FALSE;
516 }
517
518 //we need to unset Contact
519 if (count($profileTypes) > 1) {
520 $index = array_search('Contact', $profileTypes);
521 if ($index !== FALSE) {
522 unset($profileTypes[$index]);
523 }
524 }
525
526 // suppress any subtypes if present
527 CRM_Contact_BAO_ContactType::suppressSubTypes($profileTypes);
528
529 $contactTypes = array('Contact', 'Individual', 'Household', 'Organization');
530 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
531 $fields = array();
532
533 // check for mix profile condition
534 if (count($profileTypes) > 1) {
535 //check the there are any components include in profile
536 foreach ($components as $value) {
537 if (in_array($value, $profileTypes)) {
538 return TRUE;
539 }
540 }
541 //check if there are more than one contact types included in profile
542 if (count($profileTypes) > 1) {
543 return TRUE;
544 }
545 }
546 elseif (count($profileTypes) == 1) {
547 // note for subtype case count would be zero
548 $profileTypes = array_values($profileTypes);
549 if (!in_array($profileTypes[0], $contactTypes)) {
550 return TRUE;
551 }
552 }
553
554 return FALSE;
555 }
556
557 /**
558 * Get the profile type (eg: individual/organization/household)
559 *
560 * @param int $ufGroupId
561 * Uf group id.
562 * @param bool $returnMixType
563 * This is true, then field type of mix profile field is returned.
564 * @param bool $onlyPure
565 * True if only pure profiles are required.
566 *
567 * @param bool $skipComponentType
568 *
569 * @return string
570 * profile group_type
571 *
572 */
573 public static function getProfileType($ufGroupId, $returnMixType = TRUE, $onlyPure = FALSE, $skipComponentType = FALSE) {
574 $ufGroup = new CRM_Core_DAO_UFGroup();
575 $ufGroup->id = $ufGroupId;
576 $ufGroup->is_active = 1;
577
578 $ufGroup->find(TRUE);
579 return self::calculateProfileType($ufGroup->group_type, $returnMixType, $onlyPure, $skipComponentType);
580 }
581
582 /**
583 * Get the profile type (eg: individual/organization/household)
584 *
585 * @param string $ufGroupType
586 * @param bool $returnMixType
587 * This is true, then field type of mix profile field is returned.
588 * @param bool $onlyPure
589 * True if only pure profiles are required.
590 * @param bool $skipComponentType
591 *
592 * @return string profile group_type
593 *
594 */
595 public static function calculateProfileType($ufGroupType, $returnMixType = TRUE, $onlyPure = FALSE, $skipComponentType = FALSE) {
596 // profile types
597 $contactTypes = array('Contact', 'Individual', 'Household', 'Organization');
598 $subTypes = CRM_Contact_BAO_ContactType::subTypes();
599 $components = array('Contribution', 'Participant', 'Membership', 'Activity');
600
601 $profileTypes = array();
602 if ($ufGroupType) {
603 $typeParts = explode(CRM_Core_DAO::VALUE_SEPARATOR, $ufGroupType);
604 $profileTypes = explode(',', $typeParts[0]);
605 }
606
607 if ($onlyPure) {
608 if (count($profileTypes) == 1) {
609 return $profileTypes[0];
610 }
611 else {
612 return NULL;
613 }
614 }
615
616 //we need to unset Contact
617 if (count($profileTypes) > 1) {
618 $index = array_search('Contact', $profileTypes);
619 if ($index !== FALSE) {
620 unset($profileTypes[$index]);
621 }
622 }
623
624 $profileType = $mixProfileType = NULL;
625
626 // this case handles pure profile
627 if (count($profileTypes) == 1) {
628 $profileType = array_pop($profileTypes);
629 }
630 else {
631 //check the there are any components include in profile
632 $componentCount = array();
633 foreach ($components as $value) {
634 if (in_array($value, $profileTypes)) {
635 $componentCount[] = $value;
636 }
637 }
638
639 //check contact type included in profile
640 $contactTypeCount = array();
641 foreach ($contactTypes as $value) {
642 if (in_array($value, $profileTypes)) {
643 $contactTypeCount[] = $value;
644 }
645 }
646 // subtype counter
647 $subTypeCount = array();
648 foreach ($subTypes as $value) {
649 if (in_array($value, $profileTypes)) {
650 $subTypeCount[] = $value;
651 }
652 }
653 if (!$skipComponentType && count($componentCount) == 1) {
654 $profileType = $componentCount[0];
655 }
656 elseif (count($componentCount) > 1) {
657 $mixProfileType = $componentCount[1];
658 }
659 elseif (count($subTypeCount) == 1) {
660 $profileType = $subTypeCount[0];
661 }
662 elseif (count($contactTypeCount) == 1) {
663 $profileType = $contactTypeCount[0];
664 }
665 elseif (count($subTypeCount) > 1) {
666 // this is mix subtype profiles
667 $mixProfileType = $subTypeCount[1];
668 }
669 elseif (count($contactTypeCount) > 1) {
670 // this is mix contact profiles
671 $mixProfileType = $contactTypeCount[1];
672 }
673 }
674
675 if ($mixProfileType) {
676 if ($returnMixType) {
677 return $mixProfileType;
678 }
679 else {
680 return 'Mixed';
681 }
682 }
683 else {
684 return $profileType;
685 }
686 }
687
688 /**
689 * Check for mix profiles groups (eg: individual + other contact types)
690 *
691 * @param $ctype
692 *
693 * @return bool
694 * true for mix profile group else false
695 */
696 public static function checkProfileGroupType($ctype) {
697 $ufGroup = new CRM_Core_DAO_UFGroup();
698
699 $query = "
700 SELECT ufg.id as id
701 FROM civicrm_uf_group as ufg, civicrm_uf_join as ufj
702 WHERE ufg.id = ufj.uf_group_id
703 AND ufj.module = 'User Registration'
704 AND ufg.is_active = 1 ";
705
706 $ufGroup = CRM_Core_DAO::executeQuery($query);
707
708 $fields = array();
709 $validProfiles = array('Individual', 'Organization', 'Household', 'Contribution');
710 while ($ufGroup->fetch()) {
711 $profileType = self::getProfileType($ufGroup->id);
712 if (in_array($profileType, $validProfiles)) {
713 continue;
714 }
715 elseif ($profileType) {
716 return FALSE;
717 }
718 }
719
720 return TRUE;
721 }
722
723 /**
724 * Check for searchable or in selector field for given profile.
725 *
726 * @param int $profileID
727 *
728 * @return bool
729 */
730 public static function checkSearchableORInSelector($profileID) {
731 $result = FALSE;
732 if (!$profileID) {
733 return $result;
734 }
735
736 $query = "
737 SELECT id
738 From civicrm_uf_field
739 WHERE (in_selector = 1 OR is_searchable = 1)
740 AND uf_group_id = {$profileID}";
741
742 $ufFields = CRM_Core_DAO::executeQuery($query);
743 while ($ufFields->fetch()) {
744 $result = TRUE;
745 break;
746 }
747
748 return $result;
749 }
750
751 /**
752 * Reset In selector and is searchable values for given $profileID.
753 *
754 * @param int $profileID
755 *
756 * @return void
757 */
758 public function resetInSelectorANDSearchable($profileID) {
759 if (!$profileID) {
760 return;
761 }
762 $query = "UPDATE civicrm_uf_field SET in_selector = 0, is_searchable = 0 WHERE uf_group_id = {$profileID}";
763 CRM_Core_DAO::executeQuery($query);
764 }
765
766 /**
767 * Add fields to $profileAddressFields as appropriate.
768 * profileAddressFields is assigned to the template to tell it
769 * what fields are in the profile address
770 * that potentially should be copied to the Billing fields
771 * we want to give precedence to
772 * 1) Billing &
773 * 2) then Primary designated as 'Primary
774 * 3) location_type is primary
775 * 4) if none of these apply then it just uses the first one
776 *
777 * as this will be used to
778 * transfer profile address data to billing fields
779 * http://issues.civicrm.org/jira/browse/CRM-5869
780 *
781 * @param string $key
782 * Field key - e.g. street_address-Primary, first_name.
783 * @param array $profileAddressFields
784 * Array of profile fields that relate to address fields.
785 * @param array $profileFilter
786 * Filter to apply to profile fields - expected usage is to only fill based on.
787 * the bottom profile per CRM-13726
788 *
789 * @return bool
790 * Can the address block be hidden safe in the knowledge all fields are elsewhere collected (see CRM-15118)
791 */
792 public static function assignAddressField($key, &$profileAddressFields, $profileFilter) {
793 $billing_id = CRM_Core_BAO_LocationType::getBilling();
794 list($prefixName, $index) = CRM_Utils_System::explode('-', $key, 2);
795
796 $profileFields = civicrm_api3('uf_field', 'get', array_merge($profileFilter,
797 array(
798 'is_active' => 1,
799 'return' => 'field_name, is_required',
800 'options' => array(
801 'limit' => 0,
802 ),
803 )
804 ));
805 //check for valid fields ( fields that are present in billing block )
806 $validBillingFields = array(
807 'first_name',
808 'middle_name',
809 'last_name',
810 'street_address',
811 'supplemental_address_1',
812 'city',
813 'state_province',
814 'postal_code',
815 'country',
816 );
817 $requiredBillingFields = array_diff($validBillingFields, array('middle_name', 'supplemental_address_1'));
818 $validProfileFields = array();
819 $requiredProfileFields = array();
820
821 foreach ($profileFields['values'] as $field) {
822 if (in_array($field['field_name'], $validBillingFields)) {
823 $validProfileFields[] = $field['field_name'];
824 }
825 if ($field['is_required']) {
826 $requiredProfileFields[] = $field['field_name'];
827 }
828 }
829
830 if (!in_array($prefixName, $validProfileFields)) {
831 return FALSE;
832 }
833
834 if (!empty($index) && (
835 // it's empty so we set it OR
836 !CRM_Utils_array::value($prefixName, $profileAddressFields)
837 //we are dealing with billing id (precedence)
838 || $index == $billing_id
839 // we are dealing with primary & billing not set
840 || ($index == 'Primary' && $profileAddressFields[$prefixName] != $billing_id)
841 || ($index == CRM_Core_BAO_LocationType::getDefault()->id
842 && $profileAddressFields[$prefixName] != $billing_id
843 && $profileAddressFields[$prefixName] != 'Primary'
844 )
845 )
846 ) {
847 $profileAddressFields[$prefixName] = $index;
848 }
849
850 $potentiallyMissingRequiredFields = array_diff($requiredBillingFields, $requiredProfileFields);
851 CRM_Core_Resources::singleton()
852 ->addSetting(array('billing' => array('billingProfileIsHideable' => empty($potentiallyMissingRequiredFields))));
853 }
854
855 /**
856 * Get a list of fields which can be added to profiles.
857 *
858 * @param int $gid : UF group ID
859 * @param array $defaults : Form defaults
860 * @return array, multidimensional; e.g. $result['FieldGroup']['field_name']['label']
861 */
862 public static function getAvailableFields($gid = NULL, $defaults = array()) {
863 $fields = array(
864 'Contact' => array(),
865 'Individual' => CRM_Contact_BAO_Contact::importableFields('Individual', FALSE, FALSE, TRUE, TRUE, TRUE),
866 'Household' => CRM_Contact_BAO_Contact::importableFields('Household', FALSE, FALSE, TRUE, TRUE, TRUE),
867 'Organization' => CRM_Contact_BAO_Contact::importableFields('Organization', FALSE, FALSE, TRUE, TRUE, TRUE),
868 );
869
870 // include hook injected fields
871 $fields['Contact'] = array_merge($fields['Contact'], CRM_Contact_BAO_Query_Hook::singleton()->getFields());
872
873 // add current employer for individuals
874 $fields['Individual']['current_employer'] = array(
875 'name' => 'organization_name',
876 'title' => ts('Current Employer'),
877 );
878
879 $addressOptions = CRM_Core_BAO_Setting::valueOptions(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME,
880 'address_options', TRUE, NULL, TRUE
881 );
882
883 if (!$addressOptions['county']) {
884 unset($fields['Individual']['county'], $fields['Household']['county'], $fields['Organization']['county']);
885 }
886
887 // break out common contact fields array CRM-3037.
888 // from a UI perspective this makes very little sense
889 foreach ($fields['Individual'] as $key => $value) {
890 if (!empty($fields['Household'][$key]) && !empty($fields['Organization'][$key])) {
891 $fields['Contact'][$key] = $value;
892 unset($fields['Individual'][$key], $fields['Household'][$key], $fields['Organization'][$key]);
893 }
894 }
895
896 // Internal field not exposed to forms
897 unset($fields['Contact']['contact_type']);
898 unset($fields['Contact']['master_id']);
899
900 // convert phone extension in to psedo-field phone + phone extension
901 //unset extension
902 unset($fields['Contact']['phone_ext']);
903 //add psedo field
904 $fields['Contact']['phone_and_ext'] = array(
905 'name' => 'phone_and_ext',
906 'title' => ts('Phone and Extension'),
907 'hasLocationType' => 1,
908 );
909
910 // include Subtypes For Profile
911 $subTypes = CRM_Contact_BAO_ContactType::subTypeInfo();
912 foreach ($subTypes as $name => $val) {
913 //custom fields for sub type
914 $subTypeFields = CRM_Core_BAO_CustomField::getFieldsForImport($name, FALSE, FALSE, FALSE, TRUE, TRUE);
915 if (array_key_exists($val['parent'], $fields)) {
916 $fields[$name] = $fields[$val['parent']] + $subTypeFields;
917 }
918 else {
919 $fields[$name] = $subTypeFields;
920 }
921 }
922
923 if (CRM_Core_Permission::access('CiviContribute')) {
924 $contribFields = CRM_Contribute_BAO_Contribution::getContributionFields(FALSE);
925 if (!empty($contribFields)) {
926 unset($contribFields['is_test']);
927 unset($contribFields['is_pay_later']);
928 unset($contribFields['contribution_id']);
929 $contribFields['contribution_note'] = array(
930 'name' => 'contribution_note',
931 'title' => ts('Contribution Note'),
932 );
933 $fields['Contribution'] = array_merge($contribFields, self::getContribBatchEntryFields());
934 }
935 }
936
937 if (CRM_Core_Permission::access('CiviEvent')) {
938 $participantFields = CRM_Event_BAO_Query::getParticipantFields();
939 if ($participantFields) {
940 // Remove fields not supported by profiles
941 CRM_Utils_Array::remove($participantFields,
942 'external_identifier',
943 'event_id',
944 'participant_contact_id',
945 'participant_role_id',
946 'participant_status_id',
947 'participant_is_test',
948 'participant_fee_level',
949 'participant_id',
950 'participant_is_pay_later',
951 'participant_campaign'
952 );
953 if (isset($participantFields['participant_campaign_id'])) {
954 $participantFields['participant_campaign_id']['title'] = ts('Campaign');
955 }
956 $fields['Participant'] = $participantFields;
957 }
958 }
959
960 if (CRM_Core_Permission::access('CiviMember')) {
961 $membershipFields = CRM_Member_BAO_Membership::getMembershipFields();
962 // Remove fields not supported by profiles
963 CRM_Utils_Array::remove($membershipFields,
964 'membership_id',
965 'membership_type_id',
966 'member_is_test',
967 'is_override',
968 'status_id',
969 'member_is_pay_later'
970 );
971 if ($gid && CRM_Core_DAO::getFieldValue('CRM_Core_DAO_UFGroup', $gid, 'name') == 'membership_batch_entry') {
972 $fields['Membership'] = array_merge($membershipFields, self::getMemberBatchEntryFields());
973 }
974 else {
975 $fields['Membership'] = $membershipFields;
976 }
977 }
978
979 if (CRM_Core_Permission::access('CiviCase')) {
980 $caseFields = CRM_Case_BAO_Query::getFields(TRUE);
981 $caseFields = array_merge($caseFields, CRM_Core_BAO_CustomField::getFieldsForImport('Case'));
982 if ($caseFields) {
983 // Remove fields not supported by profiles
984 CRM_Utils_Array::remove($caseFields,
985 'case_id',
986 'case_type',
987 'case_start_date',
988 'case_end_date',
989 'case_role',
990 'case_status',
991 'case_deleted'
992 );
993 }
994 $fields['Case'] = $caseFields;
995 }
996
997 $activityFields = CRM_Activity_BAO_Activity::getProfileFields();
998 if ($activityFields) {
999 // campaign related fields.
1000 if (isset($activityFields['activity_campaign_id'])) {
1001 $activityFields['activity_campaign_id']['title'] = ts('Campaign');
1002 }
1003 $fields['Activity'] = $activityFields;
1004 }
1005
1006 $fields['Formatting']['format_free_html_' . rand(1000, 9999)] = array(
1007 'name' => 'free_html',
1008 'import' => FALSE,
1009 'export' => FALSE,
1010 'title' => 'Free HTML',
1011 );
1012
1013 // Sort by title
1014 foreach ($fields as &$values) {
1015 $values = CRM_Utils_Array::crmArraySortByField($values, 'title');
1016 }
1017
1018 //group selected and unwanted fields list
1019 $ufFields = $gid ? CRM_Core_BAO_UFGroup::getFields($gid, FALSE, NULL, NULL, NULL, TRUE, NULL, TRUE) : array();
1020 $groupFieldList = array_merge($ufFields, array(
1021 'note',
1022 'email_greeting_custom',
1023 'postal_greeting_custom',
1024 'addressee_custom',
1025 'id',
1026 ));
1027 //unset selected fields
1028 foreach ($groupFieldList as $key => $value) {
1029 if (is_int($key)) {
1030 unset($fields['Individual'][$value], $fields['Household'][$value], $fields['Organization'][$value]);
1031 continue;
1032 }
1033 if (!empty($defaults['field_name'])
1034 && $defaults['field_name']['0'] == $value['field_type']
1035 && $defaults['field_name']['1'] == $key
1036 ) {
1037 continue;
1038 }
1039 unset($fields[$value['field_type']][$key]);
1040 }
1041
1042 return $fields;
1043 }
1044
1045 /**
1046 * Get a list of fields which can be added to profiles.
1047 *
1048 * @param bool $force
1049 *
1050 * @return array, multidimensional; e.g. $result['field_name']['label']
1051 */
1052 public static function getAvailableFieldsFlat($force = FALSE) {
1053 // FIXME reset when data model changes
1054 static $result = NULL;
1055 if ($result === NULL || $force) {
1056 $fieldTree = self::getAvailableFields();
1057 $result = array();
1058 foreach ($fieldTree as $field_type => $fields) {
1059 foreach ($fields as $field_name => $field) {
1060 if (!isset($result[$field_name])) {
1061 $field['field_type'] = $field_type;
1062 $result[$field_name] = $field;
1063 }
1064 }
1065 }
1066 }
1067 return $result;
1068 }
1069
1070 /**
1071 * Determine whether the given field_name is valid.
1072 *
1073 * @param string $fieldName
1074 * @return bool
1075 */
1076 public static function isValidFieldName($fieldName) {
1077 $availableFields = CRM_Core_BAO_UFField::getAvailableFieldsFlat();
1078 return isset($availableFields[$fieldName]);
1079 }
1080
1081 /**
1082 * @return array|null
1083 */
1084 public static function getContribBatchEntryFields() {
1085 if (self::$_contriBatchEntryFields === NULL) {
1086 self::$_contriBatchEntryFields = array(
1087 'send_receipt' => array(
1088 'name' => 'send_receipt',
1089 'title' => ts('Send Receipt'),
1090 ),
1091 'soft_credit' => array(
1092 'name' => 'soft_credit',
1093 'title' => ts('Soft Credit'),
1094 ),
1095 'soft_credit_type' => array(
1096 'name' => 'soft_credit_type',
1097 'title' => ts('Soft Credit Type'),
1098 ),
1099 'product_name' => array(
1100 'name' => 'product_name',
1101 'title' => ts('Premiums'),
1102 ),
1103 'contribution_note' => array(
1104 'name' => 'contribution_note',
1105 'title' => ts('Contribution Note'),
1106 ),
1107 );
1108 }
1109 return self::$_contriBatchEntryFields;
1110 }
1111
1112 /**
1113 * @return array|null
1114 */
1115 public static function getMemberBatchEntryFields() {
1116 if (self::$_memberBatchEntryFields === NULL) {
1117 self::$_memberBatchEntryFields = array(
1118 'send_receipt' => array(
1119 'name' => 'send_receipt',
1120 'title' => ts('Send Receipt'),
1121 ),
1122 'soft_credit' => array(
1123 'name' => 'soft_credit',
1124 'title' => ts('Soft Credit'),
1125 ),
1126 'product_name' => array(
1127 'name' => 'product_name',
1128 'title' => ts('Premiums'),
1129 ),
1130 'financial_type' => array(
1131 'name' => 'financial_type',
1132 'title' => ts('Financial Type'),
1133 ),
1134 'total_amount' => array(
1135 'name' => 'total_amount',
1136 'title' => ts('Total Amount'),
1137 ),
1138 'receive_date' => array(
1139 'name' => 'receive_date',
1140 'title' => ts('Receive Date'),
1141 ),
1142 'payment_instrument' => array(
1143 'name' => 'payment_instrument',
1144 'title' => ts('Payment Instrument'),
1145 ),
1146 'contribution_status_id' => array(
1147 'name' => 'contribution_status_id',
1148 'title' => ts('Contribution Status'),
1149 ),
1150 );
1151 }
1152 return self::$_memberBatchEntryFields;
1153 }
1154
1155 }