/** * Should handle execution of the task, taking as much (optional) parameters as needed * * The parameters should be optional and failing to provide them should be handled by * the task */ public function execute($sourceId = null, $sourceSurveyId = null, $surveyId = null) { $batch = $this->getBatch(); if ($surveyId) { $survey = $this->loader->getTracker()->getSurvey($surveyId); } else { $survey = $this->loader->getTracker()->getSurveyBySourceId($sourceSurveyId, $sourceId); } if (!$survey->isActive()) { return; } // Now save the questions $answerModel = $survey->getAnswerModel('en'); foreach ($answerModel->getItemsOrdered() as $order => $name) { if (true === $answerModel->get($name, 'survey_question')) { $batch->addTask('Tracker_RefreshQuestion', $surveyId, $name, $order); } } // If we have a response database, create a view on the answers if ($this->project->hasResponseDatabase()) { $this->replaceCreateView($survey, $answerModel); } }
/** * Get form elements for the specific Export * @param \Gems_Form $form existing form type * @param array data existing options set in the form * @return array of form elements */ public function getFormElements(\Gems_Form $form, &$data) { $form->activateJQuery(); $dbLookup = $this->util->getDbLookup(); $translated = $this->util->getTranslated(); $noRound = array(self::NoRound => $this->_('No round description')); $empty = $translated->getEmptyDropdownArray(); $dateOptions = array(); \MUtil_Model_Bridge_FormBridge::applyFixedOptions('date', $dateOptions); $organizations = $this->currentUser->getRespondentOrganizations(); $tracks = $empty + $this->util->getTrackData()->getAllTracks(); $rounds = $empty + $noRound + $dbLookup->getRoundsForExport(isset($data['tid']) ? $data['tid'] : null); $surveys = $dbLookup->getSurveysForExport(isset($data['tid']) ? $data['tid'] : null, isset($data['rounds']) ? $data['rounds'] : null); $yesNo = $translated->getYesNo(); $elements = array(); $element = $form->createElement('textarea', 'ids'); $element->setLabel($this->_('Respondent id\'s'))->setAttrib('cols', 60)->setAttrib('rows', 4)->setDescription($this->_('Not respondent nr, but respondent id as exported here.')); $elements[] = $element; $element = $form->createElement('select', 'tid'); $element->setLabel($this->_('Tracks'))->setMultiOptions($tracks); $elements[] = $element; if (isset($data['tid']) && $data['tid']) { $element = $form->createElement('radio', 'tid_fields'); $element->setLabel($this->_('Export fields'))->setMultiOptions($yesNo); $elements[] = $element; if (!array_key_exists('tid_fields', $data)) { $data['tid_fields'] = 1; } } $element = $form->createElement('select', 'rounds'); $element->setLabel($this->_('Round description'))->setMultiOptions($rounds); $elements[] = $element; $element = $form->createElement('multiselect', 'sid'); $element->setLabel($this->_('Survey'))->setMultiOptions($surveys)->setDescription($this->_('Use CTRL or Shift to select more')); $elements[] = $element; $element = $form->createElement('multiCheckbox', 'oid'); $element->setLabel($this->_('Organization'))->setMultiOptions($organizations); $elements[] = $element; if (\MUtil_Bootstrap::enabled()) { $element = new \MUtil_Bootstrap_Form_Element_ToggleCheckboxes('toggleOrg', array('selector' => 'input[name^=oid]')); } else { $element = new \Gems_JQuery_Form_Element_ToggleCheckboxes('toggleOrg', array('selector' => 'input[name^=oid]')); } $element->setLabel($this->_('Toggle')); $elements[] = $element; $element = $form->createElement('datePicker', 'valid_from', $dateOptions); $element->setLabel($this->_('Valid from')); $elements[] = $element; $element = $form->createElement('datePicker', 'valid_until', $dateOptions); $element->setLabel($this->_('Valid until')); $elements[] = $element; if (\MUtil_Bootstrap::enabled()) { $element = new \MUtil_Bootstrap_Form_Element_ToggleCheckboxes('toggleOrg', array('selector' => 'input[name^=oid]')); } else { $element = new \Gems_JQuery_Form_Element_ToggleCheckboxes('toggleOrg', array('selector' => 'input[name^=oid]')); } $element = $form->createElement('checkbox', 'column_identifiers'); $element->setLabel($this->_('Column Identifiers')); $element->setDescription($this->_('Prefix the column labels with an identifier. (A) Answers, (TF) Trackfields, (D) Description')); $elements[] = $element; //unset($data['records']); if (!empty($data['sid'])) { $filters = $this->getFilters($data); foreach ($filters as $key => $filter) { unset($data['records_' . $key]); $model = $this->getModel($filter, $data); $survey = $this->loader->getTracker()->getSurvey(intval($filter['gto_id_survey'])); $recordCount = $model->loadPaginator($filter)->getTotalItemCount(); $element = $form->createElement('exhibitor', 'records_' . $key); $element->setValue($survey->getName() . ': ' . sprintf($this->_('%s records found.'), $recordCount)); //$element->setValue($survey->getName()); $elements[] = $element; } } if ($this->project->hasResponseDatabase()) { $this->addResponseDatabaseForm($form, $data, $elements); } return $elements; }
/** * Checks whether the survey for this token was completed and processes the result * * @param int $userId The id of the gems user * @return int self::COMPLETION_NOCHANGE || (self::COMPLETION_DATACHANGE | self::COMPLETION_EVENTCHANGE) */ public function checkTokenCompletion($userId) { $result = self::COMPLETION_NOCHANGE; // Some defaults $values['gto_completion_time'] = null; $values['gto_duration_in_sec'] = null; $values['gto_result'] = null; if ($this->inSource()) { $survey = $this->getSurvey(); $values['gto_in_source'] = 1; $startTime = $survey->getStartTime($this); if ($startTime instanceof \MUtil_Date) { // Value from source overrules any set date time $values['gto_start_time'] = $startTime->toString(\Gems_Tracker::DB_DATETIME_FORMAT); } else { // Otherwise use the time kept by Gems. $startTime = $this->getDateTime('gto_start_time'); //What if we have older tokens... where no gto_start_time was set?? if (is_null($startTime)) { $startTime = new \MUtil_Date(); } // No need to set $values['gto_start_time'], it does not change } // If there is a start date there can be a completion date if ($startTime instanceof \MUtil_Date) { if ($survey->isCompleted($this)) { $complTime = $survey->getCompletionTime($this); $setCompletionTime = true; if (!$complTime instanceof \MUtil_Date) { // Token is completed but the source cannot tell the time // // Try to see it was stored already $complTime = $this->getDateTime('gto_completion_time'); if ($complTime instanceof \MUtil_Date) { // Again no need to change a time that did not change unset($values['gto_completion_time']); $setCompletionTime = false; } else { // Well anyhow it was completed now or earlier. Get the current moment. $complTime = new \MUtil_Date(); } } //Set completion time for completion event if ($setCompletionTime) { $values['gto_completion_time'] = $complTime->toString(\Gems_Tracker::DB_DATETIME_FORMAT); //Save the old value $originalCompletionTime = $this->_gemsData['gto_completion_time']; $this->_gemsData['gto_completion_time'] = $values['gto_completion_time']; } // Process any Gems side survey dependent changes if ($changed = $this->handleAfterCompletion()) { // Communicate change $result += self::COMPLETION_EVENTCHANGE; if (\Gems_Tracker::$verbose) { \MUtil_Echo::r($changed, 'Source values for ' . $this->_tokenId . ' changed by event.'); } } if ($setCompletionTime) { //Reset to old value, so changes will be picked up $this->_gemsData['gto_completion_time'] = $originalCompletionTime; } $values['gto_duration_in_sec'] = max($complTime->diffSeconds($startTime), 0); //If the survey has a resultfield, store it if ($resultField = $survey->getResultField()) { $rawAnswers = $this->getRawAnswers(); if (isset($rawAnswers[$resultField])) { // Cast to string, because that is the way the result is stored in the db // not casting to strings means e.g. float results always result in // an update, even when they did not change. $values['gto_result'] = (string) $rawAnswers[$resultField]; // Chunk of text that is too long if ($len = $this->_getResultFieldLength()) { $values['gto_result'] = substr($values['gto_result'], 0, $len); } } } if ($this->project->hasResponseDatabase()) { $this->toResponseDatabase($userId); } } } } else { $values['gto_in_source'] = 0; $values['gto_start_time'] = null; } if ($this->_updateToken($values, $userId)) { // Communicate change $result += self::COMPLETION_DATACHANGE; } return $result; }
/** * Convert the submitted form-data to a filter to be used for retrieving the data to export * * Now only handles the organization ID and consent codes, but can be extended to * include track info or perform some checks * * @param array $data * @return array */ protected function _getFilter($data) { $filter = array(); if (isset($data['ids'])) { $idStrings = $data['ids']; $idArray = preg_split('/[\\s,;]+/', $idStrings, -1, PREG_SPLIT_NO_EMPTY); if ($idArray) { // Make sure output is OK // $idArray = array_map(array($this->db, 'quote'), $idArray); $filter['respondentid'] = $idArray; } } if ($this->project->hasResponseDatabase()) { $this->_getResponseDatabaseFilter($data, $filter); } if (isset($data['tid'])) { $select = $this->db->select(); $select->from('gems__respondent2track', array('gr2t_id_respondent_track'))->where('gr2t_id_track = ?', $data['tid']); if ($trackArray = $this->db->fetchCol($select)) { $filter['resptrackid'] = $trackArray; } } if (isset($data['oid'])) { $filter['organizationid'] = $data['oid']; } else { //Invalid id so when nothing selected... we get nothing // $filter['organizationid'] = '-1'; } // Consent codes $filter['consentcode'] = array_diff((array) $this->util->getConsentTypes(), (array) $this->util->getConsentRejected()); if (isset($data['rounds']) && !empty($data['rounds'])) { $select = $this->loader->getTracker()->getTokenSelect(array('gto_id_token')); // Only get positive receptioncodes $select->andReceptionCodes(array())->onlySucces(); // Apply track filter if (isset($data['tid']) && !empty($data['tid'])) { $select->forWhere('gto_id_track = ?', (int) $data['tid']); } // Apply survey filter if (isset($data['sid']) && !empty($data['sid'])) { $select->forSurveyId((int) $data['sid']); } // Apply organization filter if (isset($data['oid'])) { $select->forWhere('gto_id_organization in (?)', $data['oid']); } // Apply round description filter if ($data['rounds'] == self::NoRound) { $select->forWhere('gto_round_description IS NULL OR gto_round_description = ""'); } else { $select->forWhere('gto_round_description = ?', $data['rounds']); } $tokens = array(); $result = $select->getSelect()->query(); while ($row = $result->fetch(\Zend_Db::FETCH_NUM)) { $tokens[] = $row[0]; } if (empty($tokens)) { // Add invalid filter $filter['organizationid'] = -1; } $filter['token'] = $tokens; } // \Gems_Tracker::$verbose = true; return $filter; }