REF use addRadio function to add in the radio fields to these forms
[civicrm-core.git] / CRM / Campaign / Form / Survey / Results.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
18 /**
19 * This class generates form components for processing a survey.
20 */
21 class CRM_Campaign_Form_Survey_Results extends CRM_Campaign_Form_Survey {
22
23 protected $_reportId;
24
25 protected $_reportTitle;
26
27 /**
28 * values
29 *
30 * @var array
31 *
32 */
33
34 public $_values;
35
36 const NUM_OPTION = 11;
37
38 public function preProcess() {
39 parent::preProcess();
40
41 $this->_values = $this->get('values');
42 if (!is_array($this->_values)) {
43 $this->_values = [];
44 if ($this->_surveyId) {
45 $params = ['id' => $this->_surveyId];
46 CRM_Campaign_BAO_Survey::retrieve($params, $this->_values);
47 }
48 $this->set('values', $this->_values);
49 }
50
51 $query = "SELECT MAX(id) as id, title FROM civicrm_report_instance WHERE name = %1 GROUP BY id";
52 $params = [1 => ["survey_{$this->_surveyId}", 'String']];
53 $result = CRM_Core_DAO::executeQuery($query, $params);
54 if ($result->fetch()) {
55 $this->_reportId = $result->id;
56 $this->_reportTitle = $result->title;
57 }
58 }
59
60 /**
61 * Set default values for the form.
62 *
63 * Note that in edit/view mode the default values are retrieved from the database.
64 *
65 * @return array
66 * array of default values
67 */
68 public function setDefaultValues() {
69 $defaults = $this->_values;
70
71 // set defaults for weight.
72 for ($i = 1; $i <= self::NUM_OPTION; $i++) {
73 $defaults["option_weight[{$i}]"] = $i;
74 }
75
76 $defaults['create_report'] = 1;
77 if ($this->_reportId) {
78 $defaults['report_title'] = $this->_reportTitle;
79 }
80 return $defaults;
81 }
82
83 /**
84 * Build the form object.
85 */
86 public function buildQuickForm() {
87 $optionGroups = CRM_Campaign_BAO_Survey::getResultSets();
88
89 if (empty($optionGroups)) {
90 $optionTypes = ['1' => ts('Create new result set')];
91 }
92 else {
93 $optionTypes = [
94 '1' => ts('Create new result set'),
95 '2' => ts('Use existing result set'),
96 ];
97 $this->add('select',
98 'option_group_id',
99 ts('Select Result Set'),
100 [
101 '' => ts('- select -'),
102 ] + $optionGroups, FALSE,
103 ['onChange' => 'loadOptionGroup( )']
104 );
105 }
106
107 $element = &$this->addRadio('option_type',
108 ts('Survey Responses'),
109 $optionTypes,
110 [
111 'onclick' => "showOptionSelect();",
112 ], '<br/>', TRUE
113 );
114
115 if (empty($optionGroups) || empty($this->_values['result_id'])) {
116 $this->setdefaults(['option_type' => 1]);
117 }
118 elseif (!empty($this->_values['result_id'])) {
119 $this->setdefaults([
120 'option_type' => 2,
121 'option_group_id' => $this->_values['result_id'],
122 ]);
123 }
124
125 // form fields of Custom Option rows
126 $defaultOptionValues = [];
127 $_showHide = new CRM_Core_ShowHideBlocks('', '');
128
129 $optionAttributes = CRM_Core_DAO::getAttribute('CRM_Core_DAO_OptionValue');
130 $optionAttributes['label']['size'] = $optionAttributes['value']['size'] = 25;
131 for ($i = 1; $i <= self::NUM_OPTION; $i++) {
132 //the show hide blocks
133 $showBlocks = 'optionField_' . $i;
134 if ($i > 2) {
135 $_showHide->addHide($showBlocks);
136 if ($i == self::NUM_OPTION) {
137 $_showHide->addHide('additionalOption');
138 }
139 }
140 else {
141 $_showHide->addShow($showBlocks);
142 }
143
144 $this->add('text', 'option_label[' . $i . ']', ts('Label'),
145 $optionAttributes['label']
146 );
147
148 // value
149 $this->add('text', 'option_value[' . $i . ']', ts('Value'),
150 $optionAttributes['value']
151 );
152
153 // weight
154 $this->add('number', "option_weight[$i]", ts('Order'),
155 $optionAttributes['weight']
156 );
157
158 $this->add('text', 'option_interval[' . $i .
159 ']', ts('Recontact Interval'),
160 CRM_Core_DAO::getAttribute('CRM_Campaign_DAO_Survey', 'release_frequency')
161 );
162
163 $defaultOptionValues[$i] = NULL;
164 }
165
166 //default option selection
167 $this->addRadio('default_option', '', $defaultOptionValues);
168
169 $_showHide->addToTemplate();
170
171 $this->addElement('checkbox', 'create_report', ts('Create Report'));
172 $this->addElement('text', 'report_title', ts('Report Title'));
173
174 if ($this->_reportId) {
175 $this->freeze('create_report');
176 $this->freeze('report_title');
177 }
178
179 $this->addFormRule([
180 'CRM_Campaign_Form_Survey_Results',
181 'formRule',
182 ], $this);
183
184 parent::buildQuickForm();
185 }
186
187 /**
188 * Global validation rules for the form.
189 *
190 * @param $fields
191 * @param $files
192 * @param $form
193 *
194 * @return array|bool
195 */
196 public static function formRule($fields, $files, $form) {
197 $errors = [];
198 if (!empty($fields['option_label']) && !empty($fields['option_value']) &&
199 (count(array_filter($fields['option_label'])) == 0) &&
200 (count(array_filter($fields['option_value'])) == 0)
201 ) {
202 $errors['option_label[1]'] = ts('Enter at least one result option.');
203 return $errors;
204 }
205 elseif (empty($fields['option_label']) && empty($fields['option_value'])) {
206 return $errors;
207 }
208
209 if (
210 $fields['option_type'] == 2 && empty($fields['option_group_id'])
211 ) {
212 $errors['option_group_id'] = ts("Please select a Survey Result Set.");
213 return $errors;
214 }
215
216 $_flagOption = $_rowError = 0;
217 $_showHide = new CRM_Core_ShowHideBlocks('', '');
218
219 //capture duplicate Custom option values
220 if (!empty($fields['option_value'])) {
221 $countValue = count($fields['option_value']);
222 $uniqueCount = count(array_unique($fields['option_value']));
223
224 if ($countValue > $uniqueCount) {
225 $start = 1;
226 while ($start < self::NUM_OPTION) {
227 $nextIndex = $start + 1;
228
229 while ($nextIndex <= self::NUM_OPTION) {
230 if ($fields['option_value'][$start] ==
231 $fields['option_value'][$nextIndex] &&
232 !empty($fields['option_value'][$nextIndex])
233 ) {
234
235 $errors['option_value[' . $start .
236 ']'] = ts('Duplicate Option values');
237 $errors['option_value[' . $nextIndex .
238 ']'] = ts('Duplicate Option values');
239 $_flagOption = 1;
240 }
241 $nextIndex++;
242 }
243 $start++;
244 }
245 }
246 }
247
248 //capture duplicate Custom Option label
249 if (!empty($fields['option_label'])) {
250 $countValue = count($fields['option_label']);
251 $uniqueCount = count(array_unique($fields['option_label']));
252
253 if ($countValue > $uniqueCount) {
254 $start = 1;
255 while ($start < self::NUM_OPTION) {
256 $nextIndex = $start + 1;
257
258 while ($nextIndex <= self::NUM_OPTION) {
259 if ($fields['option_label'][$start] ==
260 $fields['option_label'][$nextIndex] &&
261 !empty($fields['option_label'][$nextIndex])
262 ) {
263 $errors['option_label[' . $start .
264 ']'] = ts('Duplicate Option label');
265 $errors['option_label[' . $nextIndex .
266 ']'] = ts('Duplicate Option label');
267 $_flagOption = 1;
268 }
269 $nextIndex++;
270 }
271 $start++;
272 }
273 }
274 }
275
276 for ($i = 1; $i <= self::NUM_OPTION; $i++) {
277 if (!$fields['option_label'][$i]) {
278 if ($fields['option_value'][$i]) {
279 $errors['option_label[' . $i .
280 ']'] = ts('Option label cannot be empty');
281 $_flagOption = 1;
282 }
283 else {
284 $_emptyRow = 1;
285 }
286 }
287 elseif (!strlen(trim($fields['option_value'][$i]))) {
288 if (!$fields['option_value'][$i]) {
289 $errors['option_value[' . $i .
290 ']'] = ts('Option value cannot be empty');
291 $_flagOption = 1;
292 }
293 }
294
295 if (!empty($fields['option_interval'][$i]) &&
296 !CRM_Utils_Rule::integer($fields['option_interval'][$i])
297 ) {
298 $_flagOption = 1;
299 $errors['option_interval[' . $i .
300 ']'] = ts('Please enter a valid integer.');
301 }
302
303 $showBlocks = 'optionField_' . $i;
304 if ($_flagOption) {
305 $_showHide->addShow($showBlocks);
306 $_rowError = 1;
307 }
308
309 if (!empty($_emptyRow)) {
310 $_showHide->addHide($showBlocks);
311 }
312 else {
313 $_showHide->addShow($showBlocks);
314 }
315
316 if ($i == self::NUM_OPTION) {
317 $hideBlock = 'additionalOption';
318 $_showHide->addHide($hideBlock);
319 }
320
321 $_flagOption = $_emptyRow = 0;
322 }
323 $_showHide->addToTemplate();
324
325 return empty($errors) ? TRUE : $errors;
326 }
327
328 /**
329 * Process the form.
330 */
331 public function postProcess() {
332 // store the submitted values in an array
333 $status = '';
334 $params = $this->controller->exportValues($this->_name);
335 $params['id'] = $this->_surveyId;
336
337 $updateResultSet = FALSE;
338 $resultSetOptGrpId = NULL;
339 if ((CRM_Utils_Array::value('option_type', $params) == 2) &&
340 !empty($params['option_group_id'])
341 ) {
342 $updateResultSet = TRUE;
343 $resultSetOptGrpId = $params['option_group_id'];
344 }
345
346 $recontactInterval = [];
347 if ($updateResultSet) {
348 $optionValue = new CRM_Core_DAO_OptionValue();
349 $optionValue->option_group_id = $resultSetOptGrpId;
350 $optionValue->delete();
351
352 $params['result_id'] = $resultSetOptGrpId;
353 }
354 else {
355 $opGroupName = 'civicrm_survey_' . rand(10, 1000) . '_' . date('YmdHis');
356
357 $optionGroup = new CRM_Core_DAO_OptionGroup();
358 $optionGroup->name = $opGroupName;
359 $optionGroup->title = $this->_values['title'] . ' Result Set';
360 $optionGroup->is_active = 1;
361 $optionGroup->save();
362
363 $params['result_id'] = $optionGroup->id;
364 }
365
366 foreach ($params['option_value'] as $k => $v) {
367 if (strlen(trim($v))) {
368 $optionValue = new CRM_Core_DAO_OptionValue();
369 $optionValue->option_group_id = $params['result_id'];
370 $optionValue->label = $params['option_label'][$k];
371 $optionValue->name = CRM_Utils_String::titleToVar($params['option_label'][$k]);
372 $optionValue->value = trim($v);
373 $optionValue->weight = $params['option_weight'][$k];
374 $optionValue->is_active = 1;
375
376 if (!empty($params['default_option']) &&
377 $params['default_option'] == $k
378 ) {
379 $optionValue->is_default = 1;
380 }
381
382 $optionValue->save();
383
384 // using is_numeric since 0 is a valid value for option_interval
385 if (is_numeric($params['option_interval'][$k])) {
386 $recontactInterval[$optionValue->label] = $params['option_interval'][$k];
387 }
388 }
389 }
390
391 $params['recontact_interval'] = serialize($recontactInterval);
392 $survey = CRM_Campaign_BAO_Survey::create($params);
393
394 // create report if required.
395 if (!$this->_reportId && $survey->id && !empty($params['create_report'])) {
396 $activityStatus = CRM_Core_PseudoConstant::activityStatus('name');
397 $activityStatus = array_flip($activityStatus);
398 $this->_params = [
399 'name' => "survey_{$survey->id}",
400 'title' => $params['report_title'] ? $params['report_title'] : $this->_values['title'],
401 'status_id_op' => 'eq',
402 // reserved status
403 'status_id_value' => $activityStatus['Scheduled'],
404 'survey_id_value' => [$survey->id],
405 'description' => ts('Detailed report for canvassing, phone-banking, walk lists or other surveys.'),
406 ];
407 //Default value of order by
408 $this->_params['order_bys'] = [
409 1 => [
410 'column' => 'sort_name',
411 'order' => 'ASC',
412 ],
413 ];
414 // for WalkList or default
415 $displayFields = [
416 'id',
417 'sort_name',
418 'result',
419 'street_number',
420 'street_name',
421 'street_unit',
422 'survey_response',
423 ];
424 if (CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'WalkList') ==
425 $this->_values['activity_type_id']
426 ) {
427 $this->_params['order_bys'] = [
428 1 => [
429 'column' => 'street_name',
430 'order' => 'ASC',
431 ],
432 2 => [
433 'column' => 'street_number_odd_even',
434 'order' => 'ASC',
435 ],
436 3 => [
437 'column' => 'street_number',
438 'order' => 'ASC',
439 ],
440 4 => [
441 'column' => 'sort_name',
442 'order' => 'ASC',
443 ],
444 ];
445 }
446 elseif (CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'PhoneBank') ==
447 $this->_values['activity_type_id']
448 ) {
449 array_push($displayFields, 'phone');
450 }
451 elseif ((CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Survey') ==
452 $this->_values['activity_type_id']) ||
453 (CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Canvass') ==
454 $this->_values['activity_type_id'])
455 ) {
456 array_push($displayFields, 'phone', 'city', 'state_province_id', 'postal_code', 'email');
457 }
458 foreach ($displayFields as $key) {
459 $this->_params['fields'][$key] = 1;
460 }
461 $this->_createNew = TRUE;
462 $this->_id = CRM_Report_Utils_Report::getInstanceIDForValue('survey/detail');
463 CRM_Report_Form_Instance::setDefaultValues($this, $this->_defaults);
464 $this->_params = array_merge($this->_params, $this->_defaults);
465 CRM_Report_Form_Instance::postProcess($this, FALSE);
466
467 $query = "SELECT MAX(id) FROM civicrm_report_instance WHERE name = %1";
468 $reportID = CRM_Core_DAO::singleValueQuery($query, [
469 1 => [
470 "survey_{$survey->id}",
471 'String',
472 ],
473 ]);
474 if ($reportID) {
475 $url = CRM_Utils_System::url("civicrm/report/instance/{$reportID}", 'reset=1');
476 $status = ts("A Survey Detail Report <a href='%1'>%2</a> has been created.",
477 [1 => $url, 2 => $this->_params['title']]);
478 }
479 }
480
481 if ($status) {
482 // reset status as we don't want status set by Instance::postProcess
483 $session = CRM_Core_Session::singleton();
484 $session->getStatus(TRUE);
485 // set new status
486 CRM_Core_Session::setStatus($status, ts('Saved'), 'success');
487 }
488
489 parent::endPostProcess();
490 }
491
492 }