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