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