/** * Saves the page currently being edited */ public function saveAction() { try { $page = new PageModel(array('pageID' => $this->_getParam('id'), 'depth' => 'page')); $lock = $this->lockPage($page, 'edit'); $attachments = array(); $auth = Zend_Auth::getInstance(); $user = DbUserModel::findByUsername($auth->getIdentity()); $responses = array(); foreach ($this->_getAllParams() as $key => $value) { // if the element's name begins 'qXXX' where X is a digit if (preg_match('/^q(\\d+)(.*)$/', $key, $matches)) { $questionID = intval($matches[1]); $remainder = $matches[2]; // if the element name consists of *only* 'qXXX' or qXXX_mXXX for multiple select question types if ($remainder == '' || preg_match('/^_m(\\d+)$/', $remainder)) { $q = new QuestionModel(array('questionID' => $questionID)); $response = $q->getResponse(); if ($response->state == 2) { $this->flash('error', 'You cannot modify a response that has been approved'); $this->_redirector->gotoRouteAndExit(array('action' => 'view', 'id' => $page->pageID)); } if (strlen($value) > 0) { $responses[$questionID]['value'][] = $value; } } elseif ($remainder == "_addl_mod" && intval($this->_getParam("q{$questionID}_addl_mod"))) { $responses[$questionID]['addl'] = $this->_getParam("q{$questionID}_addl"); } elseif ($remainder == "_privateNote_mod" && intval($this->_getParam("q{$questionID}_privateNote_mod"))) { $responses[$questionID]['pNote'] = $this->_getParam("q{$questionID}_privateNote"); } elseif ($remainder == '_attachments') { $question = new QuestionModel(array('questionID' => $questionID)); foreach ($value as $file) { $fileModel = new FileModel($question); $properties = Spyc::YAMLLoad(PROJECT_PATH . '/tmp/.' . $file); $fileModel->storeFilename(PROJECT_PATH . '/tmp/' . $file, $properties); } } elseif (preg_match('/^_file(\\d+)_delete$/', $remainder, $matches) && $value === 'true') { $question = new QuestionModel(array('questionID' => $questionID)); $fileModel = new FileModel($question); $fileModel->delete(intval($matches[1])); } } } foreach ($responses as $questionID => $data) { $q = new QuestionModel(array('questionID' => $questionID)); $response = $q->getResponse(); if (isset($data['value'])) { $response->responseText = join(',', $data['value']); } if (isset($data['addl'])) { $response->additionalInfo = $data['addl']; } if (isset($data['pNote'])) { $response->privateNote = $data['pNote']; } $response->save($user); } /* If there are any file uploads that didn't auto-upload before the user saved */ foreach ($_FILES as $name => $file) { if ($file['size'] > 0) { $question = new QuestionModel(array('questionID' => intVal($name))); $fileModel = new FileModel($question); $properties = array('filename' => $file['name'], 'mime' => $file['type']); $fileModel->storeFilename($file['tmp_name'], $properties); } } $page = new PageModel(array('pageID' => $this->_getParam('id'), 'depth' => 'response')); $page->save(); $instance = new InstanceModel(array('instanceID' => $page->instanceID, 'depth' => 'page')); $instance->save(); } catch (Exception $e) { $this->view->error = $e->getMessage(); } $this->view->setRenderLayout(false); }
/** * Returns comparison information based on criteria arguments. Virtual questions always return an empty array. * * @param array See argument array below * @return array Following this structure: * array($criteria_term => array(array('question' => QuestionModel, * 'messages' => array(string) * ) * ) * ) */ public function compare($args = array()) { // Comparison criteria $args = array_merge(array('model_fail' => true, 'model_pass' => false, 'additional_information' => false), $args); if ($this->question->virtualQuestion) { return array(); } if ($this->compareInstance->depth !== 'response') { throw new Exception('Comparison not possible since compare instance depth not set to response'); } if ($this->depth !== 'response') { throw new Exception('Comparison not possible since depth not set to response'); } $modelPageRows = self::$pageTable->fetchRows('pageID', $this->question->pageID, null, $this->question->instanceID); $modelPageRow = $modelPageRows[0]; $pageGUID = $modelPageRow->pageGUID; $comparePageRows = self::$pageTable->fetchRows('pageGUID', $pageGUID, null, $this->compareInstance->instanceID); $comparePageRow = $comparePageRows[0]; $compareQuestionRows = self::$questionTable->fetchRows('questionGUID', $this->question->questionGUID, null, $comparePageRow->pageID); $compareQuestionRow = $compareQuestionRows[0]; $compareQuestion = new QuestionModel(array('questionID' => $compareQuestionRow->questionID, 'depth' => 'response')); $response = $compareQuestion->getResponse(); $result = array(); foreach ($args as $key => $value) { $result[$key] = array(); } if ($args['model_fail'] || $args['model_pass']) { $messages = array(); $remediationInfo = ''; $pass = null; while ($modelResponse = $this->nextModelResponse()) { switch ($modelResponse->type) { case "no preference": break; case "match": if ($modelResponse->target == $response->responseText) { $messages['pass'][] = "Matches " . $modelResponse->target; $pass = true; } else { $messages['fail'][] = "Does not match " . $modelResponse->target; $pass = false; break; } break; case "selected": if ($modelResponse->promptText() == $response->promptText()) { $messages['pass'][] = "Prompt selected: " . $modelResponse->promptText(); $pass = true; } else { $messages['fail'][] = "Prompt not selected: " . $modelResponse->promptText(); $pass = false; break; } break; case "not selected": if ($modelResponse->promptText() == $response->promptText()) { $messages['fail'][] = "Prompt selected: " . $modelResponse->promptText(); $pass = false; break; } else { $messages['pass'][] = "Prompt not selected: " . $modelResponse->promptText(); $pass = true; } break; case "or selected": if ($modelResponse->promptText() == $response->promptText()) { $messages['pass'][] = "Or prompt selected: " . $modelResponse->promptText(); $pass = true; } else { if ($pass !== TRUE) { $messages['fail'][] = "And prompt not selected: " . $modelResponse->promptText(); $pass = false; } } break; case "remediation info": $remediationInfo = $modelResponse->info; break; case "require attachment": $file = new FileModel($compareQuestion); if ($file->hasAttachment()) { $pass = true; $messages['pass'][] = 'Has attachment'; } else { $pass = false; $messages['fail'][] = 'No attachment'; } break; default: throw new Exception('Unknown model response type'); } } if ($pass === TRUE && $args['model_pass']) { $result['model_pass'][] = array('question' => $compareQuestion, 'messages' => $messages['pass'], 'remediation_info' => $remediationInfo); } if ($pass === FALSE && $args['model_fail']) { $result['model_fail'][] = array('question' => $compareQuestion, 'messages' => $messages['fail'], 'remediation_info' => $remediationInfo); } } if ($args['additional_information'] && (!$args['model_fail'] || count($result['model_fail']) === 0) && strlen($response->additionalInfo) > 0) { if ($args['model_pass'] === TRUE) { $result['model_pass'] = array(); } $result['additional_information'][] = array('question' => $compareQuestion); } return $result; }