Merge pull request #22974 from mattwire/activitytokens
[civicrm-core.git] / CRM / Report / Form / Campaign / SurveyDetails.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
5 | |
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
9 +--------------------------------------------------------------------+
10 */
11
12 /**
13 *
14 * @package CRM
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
16 */
17 class CRM_Report_Form_Campaign_SurveyDetails extends CRM_Report_Form {
18
19 protected $_emailField = FALSE;
20
21 protected $_phoneField = FALSE;
22
23 protected $_locationBasedPhoneField = FALSE;
24
25 protected $_summary = NULL;
26 protected $_customGroupGroupBy = FALSE;
27 protected $_customGroupExtends = array(
28 'Contact',
29 'Individual',
30 'Household',
31 'Organization',
32 'Activity',
33 );
34 public $_drilldownReport = array('contact/detail' => 'Link to Detail Report');
35
36 private static $_surveyRespondentStatus;
37
38 // Survey Question titles are overridden when in print or pdf mode to
39 /**
40 * say Q1, Q2 instead of the full title - to save space.
41 * @var array
42 */
43 private $_columnTitleOverrides = [];
44
45 /**
46 */
47
48 /**
49 */
50 public function __construct() {
51 //filter options for survey activity status.
52 $responseStatus = array('' => ts('- Any -'));
53 self::$_surveyRespondentStatus = [];
54 $activityStatus = CRM_Core_PseudoConstant::activityStatus('name');
55 if ($statusId = array_search('Scheduled', $activityStatus)) {
56 $responseStatus[$statusId] = ts('Reserved');
57 self::$_surveyRespondentStatus[$statusId] = 'Reserved';
58 }
59 if ($statusId = array_search('Completed', $activityStatus)) {
60 $responseStatus[$statusId] = ts('Interviewed');
61 self::$_surveyRespondentStatus[$statusId] = 'Interviewed';
62 }
63
64 $optionGroups = CRM_Campaign_BAO_Survey::getResultSets('name');
65 $resultOptions = [];
66 foreach ($optionGroups as $gid => $name) {
67 if ($name) {
68 $value = [];
69 $value = CRM_Core_OptionGroup::values($name);
70 if (!empty($value)) {
71 $value = array_combine($value, $value);
72 }
73 $resultOptions = $resultOptions + $value;
74 }
75 }
76 asort($resultOptions);
77
78 //get all interviewers.
79 $allSurveyInterviewers = CRM_Campaign_BAO_Survey::getInterviewers();
80
81 $this->_columns = array(
82 'civicrm_activity_contact' => array(
83 'dao' => 'CRM_Activity_DAO_ActivityContact',
84 'fields' => array('contact_id' => array('title' => ts('Interviewer Name'))),
85 'filters' => array(
86 'contact_id' => array(
87 'name' => 'contact_id',
88 'title' => ts('Interviewer Name'),
89 'type' => CRM_Utils_Type::T_INT,
90 'operatorType' => CRM_Report_Form::OP_SELECT,
91 'options' => array(
92 '' => ts('- any interviewer -'),
93 ) + $allSurveyInterviewers,
94 ),
95 ),
96 'grouping' => 'survey-interviewer-fields',
97 ),
98 'civicrm_contact' => array(
99 'dao' => 'CRM_Contact_DAO_Contact',
100 'fields' => array(
101 'id' => array(
102 'title' => ts('Contact ID'),
103 'no_display' => TRUE,
104 'required' => TRUE,
105 ),
106 'sort_name' => array(
107 'title' => ts('Respondent Name'),
108 'required' => TRUE,
109 'no_repeat' => TRUE,
110 ),
111 ),
112 'filters' => array(
113 'sort_name' => array(
114 'title' => ts('Respondent Name'),
115 'operator' => 'like',
116 ),
117 ),
118 'grouping' => 'contact-fields',
119 'order_bys' => array(
120 'sort_name' => array(
121 'title' => ts('Respondent Name'),
122 'required' => TRUE,
123 ),
124 ),
125 ),
126 'civicrm_phone' => array(
127 'dao' => 'CRM_Core_DAO_Phone',
128 'fields' => array(
129 'phone' => array(
130 'name' => 'phone',
131 'title' => ts('Phone'),
132 ),
133 ),
134 'grouping' => 'location-fields',
135 ),
136 'civicrm_email' => array(
137 'dao' => 'CRM_Core_DAO_Email',
138 'fields' => array(
139 'email' => array(
140 'name' => 'email',
141 'title' => ts('Email'),
142 ),
143 ),
144 'grouping' => 'location-fields',
145 ),
146 ) + $this->getAddressColumns() +
147 array(
148 'civicrm_activity' => array(
149 'dao' => 'CRM_Activity_DAO_Activity',
150 'alias' => 'survey_activity',
151 'fields' => array(
152 'survey_id' => array(
153 'name' => 'source_record_id',
154 'title' => ts('Survey'),
155 'type' => CRM_Utils_Type::T_INT,
156 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
157 'options' => CRM_Campaign_BAO_Survey::getSurveys(),
158 ),
159 'survey_response' => array(
160 'name' => 'survey_response',
161 'title' => ts('Survey Responses'),
162 ),
163 'details' => array(
164 'name' => 'details',
165 'title' => ts('Note'),
166 'type' => 1,
167 ),
168 'result' => array(
169 'name' => 'result',
170 'required' => TRUE,
171 'title' => ts('Survey Result'),
172 ),
173 'activity_date_time' => array(
174 'name' => 'activity_date_time',
175 'title' => ts('Date'),
176 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME,
177 ),
178 ),
179 'filters' => array(
180 'survey_id' => array(
181 'name' => 'source_record_id',
182 'title' => ts('Survey'),
183 'type' => CRM_Utils_Type::T_INT,
184 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
185 'options' => CRM_Campaign_BAO_Survey::getSurveys(),
186 ),
187 'status_id' => array(
188 'name' => 'status_id',
189 'title' => ts('Respondent Status'),
190 'type' => CRM_Utils_Type::T_INT,
191 'operatorType' => CRM_Report_Form::OP_SELECT,
192 'options' => $responseStatus,
193 ),
194 'result' => array(
195 'title' => ts('Survey Result'),
196 'type' => CRM_Utils_Type::T_STRING,
197 'operatorType' => CRM_Report_Form::OP_MULTISELECT,
198 'options' => $resultOptions,
199 ),
200 'activity_date_time' => array(
201 'title' => ts('Date'),
202 'type' => CRM_Utils_Type::T_DATE + CRM_Utils_Type::T_TIME,
203 'operatorType' => CRM_Report_Form::OP_DATE,
204 ),
205 ),
206 'grouping' => 'survey-activity-fields',
207 'order_bys' => array(
208 'activity_date_time' => array(
209 'title' => ts('Date'),
210 ),
211 ),
212 ),
213 );
214 parent::__construct();
215 }
216
217 public function preProcess() {
218 parent::preProcess();
219 }
220
221 public function select() {
222 $select = [];
223
224 //add the survey response fields.
225 $this->_addSurveyResponseColumns();
226
227 $this->_columnHeaders = [];
228 foreach ($this->_columns as $tableName => $table) {
229 if (!isset($table['fields'])) {
230 continue;
231 }
232 foreach ($table['fields'] as $fieldName => $field) {
233 if (!empty($field['required']) ||
234 !empty($this->_params['fields'][$fieldName]) ||
235 !empty($field['is_required'])
236 ) {
237
238 $fieldsName = CRM_Utils_Array::value(1, explode('_', $tableName));
239 if ($fieldsName) {
240 $this->{"_$fieldsName" . 'Field'} = TRUE;
241 }
242
243 //need to pickup custom data/survey response fields.
244 if ($fieldName == 'survey_response') {
245 continue;
246 }
247
248 $select[] = "{$field['dbAlias']} as {$tableName}_{$fieldName}";
249
250 // Set default title
251 $title = $field['title'] ?? NULL;
252 // Check for an override.
253 if (!empty($this->_columnTitleOverrides["{$tableName}_{$fieldName}"])) {
254 $title = $this->_columnTitleOverrides["{$tableName}_{$fieldName}"];
255 }
256 $this->_columnHeaders["{$tableName}_{$fieldName}"]['title'] = $title;
257
258 $this->_selectAliases[] = "{$tableName}_{$fieldName}";
259 }
260 }
261 }
262
263 $this->_select = "SELECT " . implode(",\n", $select) . " ";
264 }
265
266 public function from() {
267 $this->_from = " FROM civicrm_contact {$this->_aliases['civicrm_contact']} {$this->_aclFrom} ";
268 $activityContacts = CRM_Activity_BAO_ActivityContact::buildOptions('record_type_id', 'validate');
269 $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
270 $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
271
272 //get the activity table joins.
273 $this->_from .= " INNER JOIN civicrm_activity_contact civicrm_activity_target ON
274 ( {$this->_aliases['civicrm_contact']}.id = civicrm_activity_target.contact_id AND civicrm_activity_target.record_type_id = {$targetID}) \n";
275 $this->_from .= " INNER JOIN civicrm_activity {$this->_aliases['civicrm_activity']} ON
276 ( {$this->_aliases['civicrm_activity']}.id = civicrm_activity_target.activity_id )\n";
277 $this->_from .= " INNER JOIN civicrm_activity_contact activity_contact_civireport ON
278 ( {$this->_aliases['civicrm_activity']}.id = activity_contact_civireport.activity_id AND activity_contact_civireport.record_type_id = {$assigneeID} )\n";
279
280 $this->joinAddressFromContact();
281 $this->joinPhoneFromContact();
282 $this->joinEmailFromContact();
283
284 if ($this->_locationBasedPhoneField) {
285 foreach ($this->_surveyResponseFields as $key => $value) {
286 if (substr($key, 0, 5) == 'phone' && !empty($value['location_type_id'])
287 ) {
288 $fName = str_replace('-', '_', $key);
289 $this->_from .= "LEFT JOIN civicrm_phone " .
290 $this->_aliases["civicrm_phone_{$fName}"] .
291 " ON {$this->_aliases['civicrm_contact']}.id = " .
292 $this->_aliases["civicrm_phone_{$fName}"] . ".contact_id AND " .
293 $this->_aliases["civicrm_phone_{$fName}"] .
294 ".location_type_id = {$value['location_type_id']} AND " .
295 $this->_aliases["civicrm_phone_{$fName}"] .
296 ".phone_type_id = {$value['phone_type_id']}\n";
297 }
298 }
299 }
300 }
301
302 public function where() {
303 $clauses = [];
304 foreach ($this->_columns as $tableName => $table) {
305 if (array_key_exists('filters', $table)) {
306 foreach ($table['filters'] as $fieldName => $field) {
307 $clause = NULL;
308
309 if (CRM_Utils_Array::value('type', $field) & CRM_Utils_Type::T_DATE) {
310 $relative = $this->_params["{$fieldName}_relative"] ?? NULL;
311 $from = $this->_params["{$fieldName}_from"] ?? NULL;
312 $to = $this->_params["{$fieldName}_to"] ?? NULL;
313
314 $clause = $this->dateClause($field['name'], $relative, $from, $to, $field['type']);
315 }
316 else {
317 $op = $this->_params["{$fieldName}_op"] ?? NULL;
318 if ($op) {
319 $clause = $this->whereClause($field,
320 $op,
321 CRM_Utils_Array::value("{$fieldName}_value", $this->_params),
322 CRM_Utils_Array::value("{$fieldName}_min", $this->_params),
323 CRM_Utils_Array::value("{$fieldName}_max", $this->_params)
324 );
325 }
326 }
327
328 if (!empty($clause)) {
329 $clauses[] = $clause;
330 }
331 }
332 }
333 }
334
335 //apply survey activity types filter.
336 $surveyActivityTypes = CRM_Campaign_BAO_Survey::getSurveyActivityType();
337 if (!empty($surveyActivityTypes)) {
338 $clauses[] = "( {$this->_aliases['civicrm_activity']}.activity_type_id IN ( " .
339 implode(' , ', array_keys($surveyActivityTypes)) . ' ) )';
340 }
341
342 // always filter out deleted activities (so contacts that have been released
343 // don't show up in the report).
344 $clauses[] = "( {$this->_aliases['civicrm_activity']}.is_deleted = 0 )";
345
346 if (empty($clauses)) {
347 $this->_where = "WHERE ( 1 ) ";
348 }
349 else {
350 $this->_where = "WHERE " . implode(' AND ', $clauses);
351 }
352
353 if ($this->_aclWhere) {
354 $this->_where .= " AND {$this->_aclWhere} ";
355 }
356 }
357
358 public function compileContent() {
359 $coverSheet = $this->_surveyCoverSheet() .
360 "<div style=\"page-break-after: always\"></div>";
361 $templateFile = $this->getHookedTemplateFileName();
362 return $coverSheet .
363 CRM_Core_Form::$_template->fetch($templateFile) .
364 CRM_Utils_Array::value('report_footer', $this->_formValues);
365 }
366
367 /**
368 * @return bool|mixed|null|string
369 */
370 private function _surveyCoverSheet() {
371 $coverSheet = NULL;
372 $surveyIds = $this->_params['survey_id_value'] ?? NULL;
373 if (CRM_Utils_System::isNull($surveyIds)) {
374 return $coverSheet;
375 }
376
377 $fieldIds = [];
378
379 $surveyResponseFields = [];
380 foreach ($this->_columns as $tableName => $values) {
381 if (!is_array($values['fields'])) {
382 continue;
383 }
384 foreach ($values['fields'] as $name => $field) {
385 if (!empty($field['isSurveyResponseField'])) {
386 $fldId = substr($name, 7);
387 $fieldIds[$fldId] = $fldId;
388 $title = CRM_Utils_Array::value('label', $field, $field['title']);
389 $surveyResponseFields[$name] = array(
390 'id' => $fldId,
391 'title' => $title,
392 'name' => "{$tableName}_{$name}",
393 );
394 }
395 }
396 }
397
398 //now pickup all options.
399 if (!empty($fieldIds)) {
400 $query = '
401 SELECT field.id as id,
402 val.label as label,
403 val.value as value
404 FROM civicrm_custom_field field
405 INNER JOIN civicrm_option_value val ON ( val.option_group_id = field.option_group_id )
406 WHERE field.id IN (' . implode(' , ', $fieldIds) . ' )
407 Order By val.weight';
408 $field = CRM_Core_DAO::executeQuery($query);
409 $options = [];
410 while ($field->fetch()) {
411 $name = "custom_{$field->id}";
412 $surveyResponseFields[$name]['options'][$field->value] = $field->label;
413 }
414 }
415
416 //get the result values.
417 $query = '
418 SELECT survey.id as id,
419 survey.title as title,
420 val.label as label,
421 val.value as value
422 FROM civicrm_survey survey
423 INNER JOIN civicrm_option_value val ON ( val.option_group_id = survey.result_id )
424 WHERE survey.id IN ( ' . implode(' , ', array_values($surveyIds)) . ' )
425 Order By val.weight';
426 $resultSet = CRM_Core_DAO::executeQuery($query);
427 $surveyResultFields = [];
428 while ($resultSet->fetch()) {
429 $surveyResultFields[$resultSet->id]['title'] = $resultSet->title;
430 $surveyResultFields[$resultSet->id]['options'][$resultSet->value] = $resultSet->label;
431 }
432
433 $this->assign('surveyResultFields', $surveyResultFields);
434 $this->assign('surveyResponseFields', $surveyResponseFields);
435
436 $templateFile = 'CRM/Report/Form/Campaign/SurveyCoverSheet.tpl';
437 $coverSheet = CRM_Core_Form::$_template->fetch($templateFile);
438
439 return $coverSheet;
440 }
441
442 /**
443 * Alter display of rows.
444 *
445 * Iterate through the rows retrieved via SQL and make changes for display purposes,
446 * such as rendering contacts as links.
447 *
448 * @param array $rows
449 * Rows generated by SQL, with an array for each row.
450 */
451 public function alterDisplay(&$rows) {
452
453 $this->_formatSurveyResult($rows);
454 $this->_formatSurveyResponseData($rows);
455
456 $entryFound = FALSE;
457 foreach ($rows as $rowNum => $row) {
458 // convert display name to links
459 if (array_key_exists('civicrm_contact_sort_name', $row) &&
460 array_key_exists('civicrm_contact_id', $row)
461 ) {
462 $url = CRM_Report_Utils_Report::getNextUrl('contact/detail',
463 'reset=1&force=1&id_op=eq&id_value=' .
464 $row['civicrm_contact_id'],
465 $this->_absoluteUrl, $this->_id, $this->_drilldownReport
466 );
467 $rows[$rowNum]['civicrm_contact_sort_name_link'] = $url;
468 $entryFound = TRUE;
469 }
470
471 if (array_key_exists('civicrm_activity_contact_contact_id', $row)) {
472 $rows[$rowNum]['civicrm_activity_contact_contact_id'] = CRM_Utils_Array::value($row['civicrm_activity_contact_contact_id'],
473 CRM_Campaign_BAO_Survey::getInterviewers()
474 );
475 $entryFound = TRUE;
476 }
477
478 if (array_key_exists('civicrm_activity_survey_id', $row)) {
479 $rows[$rowNum]['civicrm_activity_survey_id'] = CRM_Utils_Array::value($row['civicrm_activity_survey_id'],
480 CRM_Campaign_BAO_Survey::getSurveys()
481 );
482 $entryFound = TRUE;
483 }
484
485 $entryFound = $this->alterDisplayAddressFields($row, $rows, $rowNum, NULL, NULL) ? TRUE : $entryFound;
486
487 // skip looking further in rows, if first row itself doesn't
488 // have the column we need
489 if (!$entryFound) {
490 break;
491 }
492 }
493 }
494
495 /**
496 * @param array $rows
497 */
498 private function _formatSurveyResult(&$rows) {
499 $surveyIds = $this->_params['survey_id_value'] ?? NULL;
500 if (CRM_Utils_System::isNull($surveyIds) ||
501 empty($this->_params['fields']['result']) ||
502 !in_array($this->_outputMode, array('print', 'pdf'))
503 ) {
504 return;
505 }
506
507 //swap the survey result label w/ value.
508 $query = '
509 SELECT survey.id as id,
510 val.label as label,
511 val.value as value
512 FROM civicrm_option_value val
513 INNER JOIN civicrm_option_group grp ON ( grp.id = val.option_group_id )
514 INNER JOIN civicrm_survey survey ON ( survey.result_id = grp.id )
515 WHERE survey.id IN (' . implode(' , ', array_values($surveyIds)) . ' )
516 Order By val.weight';
517
518 $result = CRM_Core_DAO::executeQuery($query);
519 $resultSet = [];
520 while ($result->fetch()) {
521 $resultSet[$result->id][$result->value] = $result->label;
522 }
523
524 $statusId = $this->_params['status_id_value'] ?? NULL;
525 $respondentStatus = self::$_surveyRespondentStatus[$statusId] ?? NULL;
526
527 $surveyId = $surveyIds[0] ?? NULL;
528 foreach ($rows as & $row) {
529 if (!empty($row['civicrm_activity_survey_id'])) {
530 $surveyId = $row['civicrm_activity_survey_id'];
531 }
532 $result = CRM_Utils_Array::value($surveyId, $resultSet, []);
533 $resultLabel = $row['civicrm_activity_result'] ?? NULL;
534 if ($respondentStatus == 'Reserved') {
535 $row['civicrm_activity_result'] = implode(' | ', array_keys($result));
536 }
537 elseif ($resultLabel) {
538 $resultValue = array_search($resultLabel, $result);
539 if ($resultValue) {
540 $row['civicrm_activity_result'] = $resultValue;
541 }
542 }
543 }
544 }
545
546 /**
547 * @param array $rows
548 */
549 private function _formatSurveyResponseData(&$rows) {
550 $surveyIds = $this->_params['survey_id_value'] ?? NULL;
551 if (CRM_Utils_System::isNull($surveyIds) ||
552 empty($this->_params['fields']['survey_response'])
553 ) {
554 return;
555 }
556
557 $surveyResponseFields = [];
558 $surveyResponseFieldIds = [];
559 foreach ($this->_columns as $tableName => $values) {
560 if (!is_array($values['fields'])) {
561 continue;
562 }
563 foreach ($values['fields'] as $name => $field) {
564 if (!empty($field['isSurveyResponseField'])) {
565 $fldId = substr($name, 7);
566 $surveyResponseFields[$name] = "{$tableName}_{$name}";
567 $surveyResponseFieldIds[$fldId] = $fldId;
568 }
569 }
570 }
571
572 if (empty($surveyResponseFieldIds)) {
573 return;
574 }
575
576 $hasResponseData = FALSE;
577 foreach ($surveyResponseFields as $fldName) {
578 foreach ($rows as $row) {
579 if (!empty($row[$fldName])) {
580 $hasResponseData = TRUE;
581 break;
582 }
583 }
584 }
585
586 //do check respondent status.
587 $statusId = $this->_params['status_id_value'] ?? NULL;
588 $respondentStatus = self::$_surveyRespondentStatus[$statusId] ?? NULL;
589
590 if (!$hasResponseData &&
591 ($respondentStatus != 'Reserved')
592 ) {
593 return;
594 }
595
596 //start response data formatting.
597 $query = '
598 SELECT cf.id,
599 cf.data_type,
600 cf.html_type,
601 cg.table_name,
602 cf.column_name,
603 ov.value, ov.label,
604 cf.option_group_id
605 FROM civicrm_custom_field cf
606 INNER JOIN civicrm_custom_group cg ON ( cg.id = cf.custom_group_id )
607 LEFT JOIN civicrm_option_value ov ON ( cf.option_group_id = ov.option_group_id )
608 WHERE cf.id IN ( ' . implode(' , ', $surveyResponseFieldIds) . ' )
609 Order By ov.weight';
610
611 $responseFields = [];
612 $fieldValueMap = [];
613 $properties = array(
614 'id',
615 'data_type',
616 'html_type',
617 'column_name',
618 'option_group_id',
619 );
620
621 $responseField = CRM_Core_DAO::executeQuery($query);
622 while ($responseField->fetch()) {
623 $reponseFldName = $responseField->table_name . '_custom_' .
624 $responseField->id;
625 foreach ($properties as $prop) {
626 $responseFields[$reponseFldName][$prop] = $responseField->$prop;
627 }
628 if ($responseField->option_group_id) {
629 //show value for print and pdf.
630 $value = $responseField->label;
631 if (in_array($this->_outputMode, array(
632 'print',
633 'pdf',
634 ))) {
635 $value = $responseField->value;
636 }
637 $fieldValueMap[$responseField->option_group_id][$responseField->value] = $value;
638 }
639 }
640
641 //actual data formatting.
642 $hasData = FALSE;
643 foreach ($rows as & $row) {
644 if (!is_array($row)) {
645 continue;
646 }
647
648 foreach ($row as $name => & $value) {
649 if (!array_key_exists($name, $responseFields)) {
650 continue;
651 }
652 $hasData = TRUE;
653 if ($respondentStatus == 'Reserved' &&
654 in_array($this->_outputMode, array('print', 'pdf'))
655 ) {
656 $optGrpId = $responseFields[$name]['option_group_id'] ?? NULL;
657 $options = CRM_Utils_Array::value($optGrpId, $fieldValueMap, []);
658 $value = implode(' | ', array_keys($options));
659 }
660 else {
661 $value = CRM_Core_BAO_CustomField::displayValue($value, $responseFields[$name]['id']);
662 }
663 }
664
665 if (!$hasData) {
666 break;
667 }
668 }
669 }
670
671 private function _addSurveyResponseColumns() {
672 $surveyIds = $this->_params['survey_id_value'] ?? NULL;
673 if (CRM_Utils_System::isNull($surveyIds) ||
674 empty($this->_params['fields']['survey_response'])
675 ) {
676 return;
677 }
678
679 $responseFields = [];
680 foreach ($surveyIds as $surveyId) {
681 $responseFields += CRM_Campaign_BAO_Survey::getSurveyResponseFields($surveyId);
682 $this->_surveyResponseFields = $responseFields;
683 }
684 foreach ($responseFields as $key => $value) {
685 if (substr($key, 0, 5) == 'phone' && !empty($value['location_type_id'])) {
686 $fName = str_replace('-', '_', $key);
687 $this->_columns["civicrm_{$fName}"] = array(
688 'dao' => 'CRM_Core_DAO_Phone',
689 'alias' => "phone_civireport_{$fName}",
690 'fields' => array(
691 $fName => array_merge($value, array(
692 'is_required' => '1',
693 'alias' => "phone_civireport_{$fName}",
694 'dbAlias' => "phone_civireport_{$fName}.phone",
695 'no_display' => TRUE,
696 )),
697 ),
698 );
699 $this->_aliases["civicrm_phone_{$fName}"] = $this->_columns["civicrm_{$fName}"]['alias'];
700 $this->_locationBasedPhoneField = TRUE;
701 }
702 }
703 $responseFieldIds = [];
704 foreach (array_keys($responseFields) as $key) {
705 $cfId = CRM_Core_BAO_CustomField::getKeyID($key);
706 if ($cfId) {
707 $responseFieldIds[$cfId] = $cfId;
708 }
709 }
710 if (empty($responseFieldIds)) {
711 return;
712 }
713
714 $query = '
715 SELECT cg.extends,
716 cf.data_type,
717 cf.html_type,
718 cg.table_name,
719 cf.column_name,
720 cf.time_format,
721 cf.id as cfId,
722 cf.option_group_id
723 FROM civicrm_custom_group cg
724 INNER JOIN civicrm_custom_field cf ON ( cg.id = cf.custom_group_id )
725 WHERE cf.id IN ( ' . implode(' , ', $responseFieldIds) .
726 ' ) ORDER BY cf.weight';
727 $response = CRM_Core_DAO::executeQuery($query);
728 $fieldCnt = 1;
729 while ($response->fetch()) {
730 $resTable = $response->table_name;
731 $fieldName = "custom_{$response->cfId}";
732
733 //need to check does these custom data already included.
734
735 if (!array_key_exists($resTable, $this->_columns)) {
736 $this->_columns[$resTable]['dao'] = 'CRM_Contact_DAO_Contact';
737 $this->_columns[$resTable]['extends'] = $response->extends;
738 }
739 if (empty($this->_columns[$resTable]['alias'])) {
740 $this->_columns[$resTable]['alias'] = "{$resTable}_survey_response";
741 }
742 if (empty($this->_columns[$resTable]['fields'])) {
743 $this->_columns[$resTable]['fields'] = [];
744 }
745
746 if (in_array($this->_outputMode, ['print', 'pdf'])) {
747 $this->_columnTitleOverrides["{$resTable}_{$fieldName}"] = 'Q' . $fieldCnt;
748 $fieldCnt++;
749 }
750
751 if (array_key_exists($fieldName, $this->_columns[$resTable]['fields'])) {
752 $this->_columns[$resTable]['fields'][$fieldName]['required'] = TRUE;
753 $this->_columns[$resTable]['fields'][$fieldName]['isSurveyResponseField'] = TRUE;
754 continue;
755 }
756
757 $title = $responseFields[$fieldName]['title'];
758 $fldType = 'CRM_Utils_Type::T_STRING';
759 if ($response->time_format) {
760 $fldType = CRM_Utils_Type::T_TIMESTAMP;
761 }
762 $field = array(
763 'name' => $response->column_name,
764 'type' => $fldType,
765 'title' => $title,
766 'label' => $responseFields[$fieldName]['title'],
767 'dataType' => $response->data_type,
768 'htmlType' => $response->html_type,
769 'required' => TRUE,
770 'alias' => ($response->data_type == 'ContactReference') ? $this->_columns[$resTable]['alias'] .
771 '_contact' : $this->_columns[$resTable]['alias'],
772 'dbAlias' => $this->_columns[$resTable]['alias'] . '.' .
773 $response->column_name,
774 'no_display' => TRUE,
775 'isSurveyResponseField' => TRUE,
776 );
777
778 $this->_columns[$resTable]['fields'][$fieldName] = $field;
779 $this->_aliases[$resTable] = $this->_columns[$resTable]['alias'];
780 }
781 }
782
783 }