/**
  * Process the respondent and return true when data has changed.
  *
  * The event has to handle the actual storage of the changes.
  *
  * @param \Gems_Tracker_Respondent $respondent
  * @param int $userId The current user
  * @return boolean True when something changed
  */
 public function processChangedRespondent(\Gems_Tracker_Respondent $respondent)
 {
     $changes = 0;
     $tracker = $this->loader->getTracker();
     $respTracks = $tracker->getRespondentTracks($respondent->getId(), $respondent->getOrganizationId());
     $userId = $this->currentUser->getUserId();
     foreach ($respTracks as $respondentTrack) {
         if ($respondentTrack instanceof \Gems_Tracker_RespondentTrack) {
             $changes += $respondentTrack->checkTrackTokens($userId);
         }
     }
     // \MUtil_Echo::track('Hi there! ' . $changes);
     return (bool) $changes;
 }
 /**
  * Default overview action
  */
 public function indexAction()
 {
     if ($this->checkForAnswersOnLoad) {
         $this->loader->getTracker()->processCompletedTokens(null, $this->currentUser->getUserId(), $this->currentUser->getCurrentOrganizationId(), true);
     }
     parent::indexAction();
 }
 /**
  * Perform automatic job mail
  */
 public function commJob()
 {
     $batch = $this->loader->getTaskRunnerBatch('cron');
     $batch->minimalStepDurationMs = 3000;
     // 3 seconds max before sending feedback
     $batch->autoStart = true;
     if (!$batch->isLoaded()) {
         // Check for unprocessed tokens
         $tracker = $this->loader->getTracker();
         $tracker->processCompletedTokens(null, $this->currentUser->getUserId());
         $batch->addTask('Mail\\AddAllMailJobsTask');
     }
     $title = $this->_('Executing cron jobs');
     $this->_helper->BatchRunner($batch, $title, $this->accesslog);
     $this->html->br();
 }
 public function showAction()
 {
     $orgId = $this->_getParam(\MUtil_Model::REQUEST_ID2);
     $patientNr = $this->_getParam(\MUtil_Model::REQUEST_ID1);
     $respId = $this->util->getDbLookup()->getRespondentId($patientNr, $orgId);
     $userId = $this->currentUser->getUserId();
     // Updated gr20_opened
     $this->openedRespondent($patientNr, $orgId, $respId);
     // Check for completed tokens
     $this->loader->getTracker()->processCompletedTokens($respId, $userId, $orgId);
     $model = $this->getModel();
     $model->applyRequest($this->getRequest(), true);
     $data = $model->loadFirst();
     if (!isset($data['grs_id_user'])) {
         $this->addMessage(sprintf($this->_('Unknown %s requested'), $this->getTopic()));
         $this->_reroute(array('action' => 'index'));
         return;
     }
     $params['model'] = $model;
     $params['baseUrl'] = array(\MUtil_Model::REQUEST_ID1 => $this->_getParam(\MUtil_Model::REQUEST_ID1), \MUtil_Model::REQUEST_ID2 => $this->_getParam(\MUtil_Model::REQUEST_ID2));
     $params['buttons'] = $this->createMenuLinks();
     $params['onclick'] = $this->findAllowedMenuItem('edit');
     if ($params['onclick']) {
         $params['onclick'] = $params['onclick']->toHRefAttribute($this->getRequest());
     }
     $params['respondentData'] = $data;
     $this->addSnippets($this->showSnippets, $params);
 }
 /**
  * Overrule this function for any activities you want to take place
  * after the form has successfully been validated, but before any
  * buttons are processed.
  *
  * @param int $step The current step
  */
 protected function afterFormValidationFor($step)
 {
     if (3 == $step) {
         $import = $this->loadImportData();
         $model = $this->getModel();
         $saves = array();
         foreach ($model->getCol('exportCode') as $name => $exportCode) {
             if (isset($this->formData[$name]) && $this->formData[$name]) {
                 $saves[] = array('gsu_id_survey' => $this->formData[$name], 'gsu_export_code' => $exportCode);
                 $import['surveyCodes'][$exportCode] = $this->formData[$name];
             }
         }
         if ($saves) {
             $sModel = new \MUtil_Model_TableModel('gems__surveys');
             \Gems_Model::setChangeFieldsByPrefix($sModel, 'gus', $this->currentUser->getUserId());
             $sModel->saveAll($saves);
             $count = $sModel->getChanged();
             if ($count == 0) {
                 $this->addMessage($this->_('No export code changed'));
             } else {
                 $this->cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, array('surveys'));
                 $this->addMessage(sprintf($this->plural('%d export code changed', '%d export codes changed', $count), $count));
             }
         }
     }
 }
 /**
  * Go directly to url
  */
 public function toSurveyAction()
 {
     if (!$this->_initToken()) {
         // Default option
         $this->_forward('index');
         return;
     }
     $language = $this->locale->getLanguage();
     try {
         $url = $this->token->getUrl($language, $this->currentUser->getUserId() ? $this->currentUser->getUserId() : $this->token->getRespondentId());
         /************************
          * Optional user logout *
          ************************/
         if ($this->currentUser->isLogoutOnSurvey()) {
             $this->currentUser->unsetAsCurrentUser();
         }
         // Redirect at once
         header('Location: ' . $url);
         exit;
     } catch (\Gems_Tracker_Source_SurveyNotFoundException $e) {
         $this->addMessage(sprintf($this->_('The survey for token %s is no longer active.'), strtoupper($this->tokenId)));
         // Default option
         $this->_forward('index');
     }
 }
 /**
  * Hook containing the actual save code.
  *
  * Call's afterSave() for user interaction.
  *
  * @see afterSave()
  */
 protected function saveData()
 {
     $model = $this->getModel();
     $userId = $this->currentUser->getUserId();
     $tokenData = array();
     $copyFields = array('gto_id_round', 'gto_valid_from', 'gto_valid_from_manual', 'gto_valid_until', 'gto_valid_until_manual', 'gto_comment', 'gto_id_relationfield');
     foreach ($copyFields as $name) {
         if (array_key_exists($name, $this->formData)) {
             if ($model->hasOnSave($name)) {
                 $tokenData[$name] = $model->getOnSave($this->formData[$name], $this->createData, $name, $this->formData);
             } elseif ('' === $this->formData[$name]) {
                 $tokenData[$name] = null;
             } else {
                 $tokenData[$name] = $this->formData[$name];
             }
         } else {
             $tokenData[$name] = null;
         }
     }
     $rounds = $model->get('gto_round_order', 'multiOptions');
     $tokenData['gto_id_round'] = '0';
     $tokenData['gto_round_order'] = $this->formData['gto_round_order'];
     $tokenData['gto_round_description'] = $rounds[$this->formData['gto_round_order']];
     $surveyId = $this->formData['gto_id_survey'];
     $this->token = $this->respondentTrack->addSurveyToTrack($surveyId, $tokenData, $userId);
     $changed = 1;
     // Communicate with the user
     $this->afterSave($changed);
 }
 /**
  * Check the tokens for all surveys
  */
 public function checkAllAction()
 {
     $batch = $this->loader->getTracker()->recalculateTokens('surveyCheckAll', $this->currentUser->getUserId());
     $title = $this->_('Checking for all surveys for answers .');
     $this->_helper->BatchRunner($batch, $title, $this->accesslog);
     $this->addSnippet('Survey\\CheckAnswersInformation', 'itemDescription', $this->_('This task checks all tokens for all surveys for answers.'));
 }
 /**
  * Creates a model for getModel(). Called only for each new $action.
  *
  * The parameters allow you to easily adapt the model to the current action. The $detailed
  * parameter was added, because the most common use of action is a split between detailed
  * and summarized actions.
  *
  * @param boolean $detailed True when the current action is not in $summarizedActions.
  * @param string $action The current action.
  * @return \MUtil_Model_ModelAbstract
  */
 protected function createModel($detailed, $action)
 {
     $dbLookup = $this->util->getDbLookup();
     $dbTracks = $this->util->getTrackData();
     $translated = $this->util->getTranslated();
     $empty = $translated->getEmptyDropdownArray();
     $unselected = array('' => '');
     $model = new \MUtil_Model_TableModel('gems__comm_jobs');
     \Gems_Model::setChangeFieldsByPrefix($model, 'gcj');
     $model->set('gcj_id_message', 'label', $this->_('Template'), 'multiOptions', $unselected + $dbLookup->getCommTemplates('token'));
     $model->set('gcj_id_user_as', 'label', $this->_('By staff member'), 'multiOptions', $unselected + $dbLookup->getActiveStaff(), 'default', $this->currentUser->getUserId(), 'description', $this->_('Used for logging and possibly from address.'));
     $model->set('gcj_active', 'label', $this->_('Active'), 'multiOptions', $translated->getYesNo(), 'elementClass', 'Checkbox', 'required', true, 'description', $this->_('Job is only run when active.'));
     $fromMethods = $unselected + $this->getBulkMailFromOptions();
     $model->set('gcj_from_method', 'label', $this->_('From address used'), 'multiOptions', $fromMethods);
     if ($detailed) {
         $model->set('gcj_from_fixed', 'label', $this->_('From other'), 'description', sprintf($this->_("Only when '%s' is '%s'."), $model->get('gcj_from_method', 'label'), end($fromMethods)));
     }
     $model->set('gcj_process_method', 'label', $this->_('Processing Method'), 'default', 'O', 'multiOptions', $translated->getBulkMailProcessOptions());
     $model->set('gcj_filter_mode', 'label', $this->_('Filter for'), 'multiOptions', $unselected + $this->getBulkMailFilterOptions());
     // If you really want to see this information in the overview, uncomment for the shorter labels
     // $model->set('gcj_filter_days_between', 'label', $this->_('Interval'), 'validators[]', 'Digits');
     // $model->set('gcj_filter_max_reminders','label', $this->_('Max'), 'validators[]', 'Digits');
     $model->set('gcj_id_track', 'label', $this->_('Track'), 'multiOptions', $empty + $dbTracks->getAllTracks());
     $defaultRounds = $empty + $this->db->fetchPairs('SELECT gro_round_description, gro_round_description FROM gems__rounds WHERE gro_round_description IS NOT NULL AND gro_round_description != "" GROUP BY gro_round_description');
     $model->set('gcj_round_description', 'label', $this->_('Round'), 'multiOptions', $defaultRounds, 'variableSelect', array('source' => 'gcj_id_track', 'baseQuery' => $this->roundDescriptionQuery, 'ajax' => array('controller' => 'comm-job', 'action' => 'roundselect'), 'firstValue' => $empty, 'defaultValues' => $defaultRounds));
     $model->set('gcj_id_survey', 'label', $this->_('Survey'), 'multiOptions', $empty + $dbTracks->getAllSurveys());
     if ($detailed) {
         $model->set('gcj_filter_days_between', 'label', $this->_('Days between reminders'), 'description', $this->_('1 day means the reminder is send the next day'), 'validators[]', 'Digits');
         $model->set('gcj_filter_max_reminders', 'label', $this->_('Maximum reminders'), 'description', $this->_('1 means only one reminder will be send'), 'validators[]', 'Digits');
         $model->set('gcj_id_organization', 'label', $this->_('Organization'), 'multiOptions', $empty + $dbLookup->getOrganizations());
     }
     return $model;
 }
 /**
  * If the current user is the system user, present a message and don't allow to edit
  *
  * @return boolean
  */
 public function hasHtmlOutput()
 {
     if ($this->currentUser->getUserId() == \Gems_User_UserLoader::SYSTEM_USER_ID) {
         $this->addMessage($this->getNotAllowedMessage());
         return false;
     }
     return parent::hasHtmlOutput();
 }
 /**
  * Overrule this function for any activities you want to take place
  * after the form has successfully been validated, but before any
  * buttons are processed.
  *
  * @param int $step The current step
  */
 protected function afterFormValidationFor($step)
 {
     parent::afterFormValidationFor($step);
     if ($this->trackEngine) {
         if (4 == $step) {
             $import = $this->loadImportData();
             $model = $this->getModel();
             $saves = array();
             $import['deactivateRounds'] = array();
             foreach ($model->getCol('roundId') as $name => $roundId) {
                 $round = $this->trackEngine->getRound($roundId);
                 if (isset($this->formData[$name]) && $this->formData[$name] && $round instanceof Round) {
                     switch ($this->formData[$name]) {
                         case self::ROUND_DEACTIVATE:
                             $import['deactivateRounds'][$roundId] = $round->getFullDescription();
                             break;
                         case self::ROUND_LEAVE:
                             if (isset($import['roundOrderToLine'][$round->getRoundOrder()])) {
                                 $lineNr = $import['roundOrderToLine'][$round->getRoundOrder()];
                                 unset($import['rounds'][$lineNr]);
                             }
                             $import['roundOrders'][$round->getRoundOrder()] = $roundId;
                             break;
                         default:
                             if (isset($import['roundOrderToLine'][$this->formData[$name]])) {
                                 $lineNr = $import['roundOrderToLine'][$this->formData[$name]];
                                 $import['rounds'][$lineNr]['gro_id_round'] = $roundId;
                             }
                             $import['roundOrders'][$this->formData[$name]] = $roundId;
                             break;
                     }
                 }
             }
         }
     } elseif (3 == $step) {
         $import = $this->loadImportData();
         $model = $this->getModel();
         $saves = array();
         foreach ($model->getCol('exportCode') as $name => $exportCode) {
             if (isset($this->formData[$name]) && $this->formData[$name]) {
                 $saves[] = array('gsu_id_survey' => $this->formData[$name], 'gsu_export_code' => $exportCode);
                 $import['surveyCodes'][$exportCode] = $this->formData[$name];
             }
         }
         if ($saves) {
             $sModel = new \MUtil_Model_TableModel('gems__surveys');
             \Gems_Model::setChangeFieldsByPrefix($sModel, 'gus', $this->currentUser->getUserId());
             $sModel->saveAll($saves);
             $count = $sModel->getChanged();
             if ($count == 0) {
                 $this->addMessage($this->_('No export code changed'));
             } else {
                 $this->cache->clean(\Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, array('surveys'));
                 $this->addMessage(sprintf($this->plural('%d export code changed', '%d export codes changed', $count), $count));
             }
         }
     }
 }
 /**
  * Synchronize survey status for the surveys in all sources
  */
 public function synchronizeAllAction()
 {
     $batch = $this->loader->getTracker()->synchronizeSources(null, $this->currentUser->getUserId());
     $batch->minimalStepDurationMs = 3000;
     $title = $this->_('Synchronize all sources.');
     $this->_helper->batchRunner($batch, $title, $this->accesslog);
     $this->html->actionLink(array('action' => 'index'), $this->_('Cancel'), array('class' => 'btn-danger'));
     $this->addSynchronizationInformation();
 }
 /**
  * Action for checking all assigned rounds for a single track using a batch
  */
 public function checkTrackAction()
 {
     $id = $this->_getIdParam();
     $track = $this->getTrackEngine();
     $where = $this->db->quoteInto('gr2t_id_track = ?', $id);
     $batch = $this->loader->getTracker()->checkTrackRounds('trackCheckRounds' . $id, $this->currentUser->getUserId(), $where);
     $title = sprintf($this->_("Checking round assignments for track '%s'."), $track->getTrackName());
     $this->_helper->BatchRunner($batch, $title, $this->accesslog);
     $this->addSnippet('Track\\CheckRoundsInformation');
 }
 /**
  * Action for checking all assigned rounds for a single track using a batch
  */
 public function recalcFieldsAction()
 {
     $id = $this->_getIdParam();
     $track = $this->getTrackEngine();
     $where = $this->db->quoteInto('gr2t_id_track = ?', $id);
     $batch = $this->loader->getTracker()->recalcTrackFields('trackRecalcFields' . $id, $this->currentUser->getUserId(), $where);
     $title = sprintf($this->_("Recalculating fields for track '%s'."), $track->getTrackName(), $this->accesslog);
     $this->_helper->BatchRunner($batch, $title, $this->accesslog);
     $this->addRecalcInformation();
 }
 /**
  * Execute all mail jobs
  */
 public function executeAllAction()
 {
     $batch = $this->loader->getTaskRunnerBatch('commjob-execute-all');
     $batch->minimalStepDurationMs = 3000;
     // 3 seconds max before sending feedback
     if (!$batch->isLoaded()) {
         // Check for unprocessed tokens
         $tracker = $this->loader->getTracker();
         $tracker->processCompletedTokens(null, $this->currentUser->getUserId());
         $batch->addTask('Mail\\AddAllMailJobsTask');
     }
     $this->_helper->BatchRunner($batch, $this->_('Execute all mail jobs'), $this->accesslog);
 }
 /**
  *
  * @return \Gems_Default_RespondentNewAction
  */
 protected function openedRespondent()
 {
     $orgId = $this->_getParam(\MUtil_Model::REQUEST_ID2);
     $patientNr = $this->_getParam(\MUtil_Model::REQUEST_ID1);
     if ($patientNr && $orgId) {
         $where['gr2o_patient_nr = ?'] = $patientNr;
         $where['gr2o_id_organization = ?'] = $orgId;
         $values['gr2o_opened'] = new \MUtil_Db_Expr_CurrentTimestamp();
         $values['gr2o_opened_by'] = $this->currentUser->getUserId();
         $this->db->update('gems__respondent2org', $values, $where);
     }
     return $this;
 }
 /**
  * Update one or more values for this track's fields.
  *
  * Return the complete set of fielddata
  *
  * @param array $newFieldData The new field values, may be partial, field set by code overwrite field set by key
  * @return array
  */
 public function setFieldData($newFieldData)
 {
     $trackEngine = $this->getTrackEngine();
     if (!$trackEngine) {
         return $newFieldData;
     }
     $this->_fieldData = $this->processFieldsBeforeSave($newFieldData);
     $changes = $this->saveFields(array());
     if ($changes) {
         $info = $trackEngine->getFieldsDefinition()->calculateFieldsInfo($this->_fieldData);
         if ($info != $this->_respTrackData['gr2t_track_info']) {
             $this->_updateTrack(array('gr2t_track_info' => $info), $this->currentUser->getUserId());
         }
     }
     return $this->_fieldData;
 }
 /**
  * Restores tracks for a respondent, when the reception code matches the given $oldCode
  *
  * Used when restoring a respondent, and the restore tracks box is checked. This will
  * also restore all tokens in the tracks that have the same codes.
  *
  * @param \Gems_Util_ReceptionCode $oldCode The old reception code
  * @param \Gems_Util_ReceptionCode $newCode the new reception code
  * @return int  The number of restored tracks
  */
 public function restoreTracks(\Gems_Util_ReceptionCode $oldCode, \Gems_Util_ReceptionCode $newCode)
 {
     $count = 0;
     if (!$oldCode->isSuccess() && $newCode->isSuccess()) {
         $respTracks = $this->loader->getTracker()->getRespondentTracks($this->getId(), $this->getOrganizationId());
         foreach ($respTracks as $respTrack) {
             if ($respTrack instanceof \Gems_Tracker_RespondentTrack) {
                 if ($oldCode->getCode() === $respTrack->getReceptionCode()->getCode()) {
                     $respTrack->setReceptionCode($newCode, null, $this->currentUser->getUserId());
                     $respTrack->restoreTokens($oldCode, $newCode);
                     $count++;
                 }
             }
         }
     }
     return $count;
 }
 /**
  * Perform automatic job mail
  */
 public function commJob()
 {
     /*
             \Zend_Mail::setDefaultTransport(new \Zend_Mail_Transport_File(array(
                 'callback' => function ($transport) {
                     // throw new \Zend_Mail_Transport_Exception('Invalid e-mail address');
                     return $transport->recipients . '_' . time() . '_' . mt_rand() . '.tmp';
                 },
                 'path'     => GEMS_ROOT_DIR . '/var/sentmails'
             )));
             // */
     $dbLookup = $this->util->getDbLookup();
     $mailLoader = $this->loader->getMailLoader();
     $tracker = $this->loader->getTracker();
     $model = $tracker->getTokenModel();
     // Fix for #680: token with the valid from the longest in the past should be the
     // used as first token and when multiple rounds start at the same date the
     // lowest round order should be used.
     $model->setSort(array('gto_valid_from' => SORT_ASC, 'gto_round_order' => SORT_ASC));
     // Check for unprocessed tokens
     $tracker->processCompletedTokens(null, $this->currentUser->getUserId());
     $sql = "SELECT *\r\n            FROM gems__comm_jobs INNER JOIN\r\n                gems__comm_templates ON gcj_id_message = gct_id_template\r\n            WHERE gcj_active = 1\r\n            ORDER BY CASE WHEN gcj_id_survey IS NULL THEN 1 ELSE 0 END,\r\n                CASE WHEN gcj_round_description IS NULL THEN 1 ELSE 0 END,\r\n                CASE WHEN gcj_id_track IS NULL THEN 1 ELSE 0 END,\r\n                CASE WHEN gcj_id_organization IS NULL THEN 1 ELSE 0 END";
     $jobs = $this->db->fetchAll($sql);
     $mailed = false;
     if ($jobs) {
         foreach ($jobs as $job) {
             $sendByMail = $this->getUserEmail($job['gcj_id_user_as']);
             $filter = $dbLookup->getFilterForMailJob($job);
             $multipleTokensData = $model->load($filter);
             if (count($multipleTokensData)) {
                 $errors = 0;
                 $mails = 0;
                 $updates = 0;
                 $sentMailAddresses = array();
                 foreach ($multipleTokensData as $tokenData) {
                     $mailer = $mailLoader->getMailer('token', $tokenData);
                     /* @var $mailer \Gems_Mail_TokenMailer */
                     $token = $mailer->getToken();
                     $email = $token->getEmail();
                     $respondentId = $token->getRespondent()->getId();
                     if (!empty($email)) {
                         if ($job['gcj_from_method'] == 'O') {
                             $organization = $mailer->getOrganization();
                             $from = $organization->getEmail();
                             //$organization->getName() . ' <' . $organization->getEmail() . '>';
                             $mailer->setFrom($from);
                         } elseif ($job['gcj_from_method'] == 'U') {
                             $from = $sendByMail;
                             $mailer->setFrom($from);
                         } elseif ($job['gcj_from_method'] == 'F') {
                             $mailer->setFrom($job['gcj_from_fixed']);
                         }
                         $mailer->setBy($sendByMail);
                         try {
                             if ($job['gcj_process_method'] == 'M') {
                                 $mailer->setTemplate($job['gcj_id_message']);
                                 $mailer->send();
                                 $mailed = true;
                                 $mails++;
                                 $updates++;
                             } elseif (!isset($sentMailAddresses[$respondentId][$email])) {
                                 $mailer->setTemplate($job['gcj_id_message']);
                                 $mailer->send();
                                 $mailed = true;
                                 $mails++;
                                 $updates++;
                                 $sentMailAddresses[$respondentId][$email] = true;
                             } elseif ($job['gcj_process_method'] == 'O') {
                                 $mailer->updateToken();
                                 $updates++;
                             }
                         } catch (\Zend_Mail_Exception $exception) {
                             $fields = $mailer->getMailFields(false);
                             $info = sprintf("Error mailing to %s respondent %s with email address %s.", $fields['organization'], $fields['full_name'], $fields['email']);
                             // Use a gems exception to pass extra information to the log
                             $gemsException = new \Gems_Exception($info, 0, $exception);
                             \Gems_Log::getLogger()->logError($gemsException);
                             $errors++;
                         }
                     }
                 }
                 $this->addMessage(sprintf($this->_('Sent %d e-mails with template %s, updated %d tokens.'), $mails, $job['gct_name'], $updates));
                 if ($errors) {
                     $this->addMessage(sprintf($this->_('%d error(s) occurred while creating mails for template %s. Check error log for details.'), $errors, $job['gct_name']));
                 }
             }
             $tokensData = null;
         }
     }
     if (!$mailed) {
         $this->addMessage($this->_('No mails sent.'));
     }
 }
 /**
  * Replaces a null or empty userId with that of the current user
  *
  * @param int $userId
  * @return int
  */
 private function _checkUserId($userId = null)
 {
     if (empty($userId)) {
         $userId = $this->currentUser->getUserId();
         if (0 === $userId) {
             $userId = null;
         }
     }
     return $userId;
 }
 /**
  * Sets the user up as a new staff user
  *
  * @param \Gems_User_User $user
  * @param string $password
  */
 protected function makeNewStaffUser(\Gems_User_User $user, $password)
 {
     $staff_id = $user->getUserId();
     $sql = 'SELECT gul_id_user FROM gems__user_logins WHERE gul_can_login = 1 AND gul_login = ? AND gul_id_organization = ?';
     try {
         $user_id = $this->db->fetchOne($sql, array($user->getLoginName(), $user->getBaseOrganizationId()));
         $currentTimestamp = new \MUtil_Db_Expr_CurrentTimestamp();
         // Move to USER_STAFF
         $values['gup_id_user'] = $user_id;
         $values['gup_password'] = $this->hashNewPassword($password);
         $values['gup_reset_key'] = null;
         $values['gup_reset_requested'] = null;
         $values['gup_reset_required'] = 0;
         $values['gup_changed'] = $currentTimestamp;
         $values['gup_changed_by'] = $staff_id;
         $values['gup_created'] = $currentTimestamp;
         $values['gup_created_by'] = $staff_id;
         $this->db->insert('gems__user_passwords', $values);
         // Update user class
         $values = array();
         $values['gul_user_class'] = \Gems_User_UserLoader::USER_STAFF;
         $values['gul_changed'] = $currentTimestamp;
         $values['gul_changed_by'] = $staff_id;
         $this->db->update('gems__user_logins', $values, $this->db->quoteInto('gul_id_user = ?', $user_id));
         // Remove old password
         $values = array();
         $values['gsf_password'] = null;
         $values['gsf_changed'] = $currentTimestamp;
         $values['gsf_changed_by'] = $user_id;
         $this->db->update('gems__staff', $values, $this->db->quoteInto('gsf_id_user = ?', $staff_id));
         $user->refresh(\Gems_User_UserLoader::USER_STAFF);
     } catch (\Zend_Db_Exception $e) {
         \GemsEscort::getInstance()->logger->log($e->getMessage(), \Zend_Log::ERR);
         // Fall through as this does not work if the database upgrade did not run
         // \MUtil_Echo::r($e);
     }
 }
 /**
  * Set the password, if allowed for this user type.
  *
  * @param \Gems_User_User $user The user whose password to change
  * @param string $password
  * @return \Gems_User_UserDefinitionInterface (continuation pattern)
  */
 public function setPassword(\Gems_User_User $user, $password)
 {
     $data['gup_id_user'] = $user->getUserLoginId();
     $data['gup_reset_key'] = null;
     $data['gup_reset_requested'] = null;
     $data['gup_reset_required'] = 0;
     if (null === $password) {
         // Passwords may be emptied.
         $data['gup_password'] = null;
     } else {
         $data['gup_password'] = $this->hashPassword($password);
     }
     $data['gup_last_pwd_change'] = new \Zend_Db_Expr('CURRENT_TIMESTAMP');
     $model = new \MUtil_Model_TableModel('gems__user_passwords');
     \Gems_Model::setChangeFieldsByPrefix($model, 'gup', $user->getUserId());
     $model->save($data);
     return $this;
 }
 /**
  * Check the tokens for a single track
  */
 public function checkTrackAnswersAction()
 {
     $respondent = $this->getRespondent();
     $respTrackId = $this->getRespondentTrackId();
     $trackEngine = $this->getTrackEngine();
     $where = $this->db->quoteInto('gto_id_respondent_track = ?', $respTrackId);
     $batch = $this->loader->getTracker()->recalculateTokens('answersCheckAllFor__' . $respTrackId, $this->currentUser->getUserId(), $where);
     $title = sprintf($this->_("Checking the surveys in track '%s' of respondent %s, %s for answers."), $trackEngine->getTrackName(), $respondent->getPatientNumber(), $respondent->getFullName());
     $this->_helper->BatchRunner($batch, $title, $this->accesslog);
     $this->addSnippet('Survey\\CheckAnswersInformation', 'itemDescription', $this->_('This task checks all tokens for this track for this respondent for answers.'));
 }
 /**
  * Check the tokens for all surveys
  */
 public function checkAllAction()
 {
     $batch = $this->loader->getTracker()->recalculateTokens('surveyCheckAll', $this->currentUser->getUserId());
     $title = $this->_('Checking survey results for all surveys.');
     $this->_helper->BatchRunner($batch, $title, $this->accesslog);
     \Gems_Default_SourceAction::addCheckInformation($this->html, $this->translate, $this->_('This task checks all tokens for all surveys.'));
 }
 /**
  * Recalculate all tracks that use this appointment
  *
  * @return int The number of tokens changed by this code
  */
 public function updateTracks()
 {
     $tokenChanges = 0;
     $tracker = $this->loader->getTracker();
     $userId = $this->currentUser->getUserId();
     // Find all the fields that use this agenda item
     $select = $this->db->select();
     $select->from('gems__respondent2track2appointment', array('gr2t2a_id_respondent_track'))->joinInner('gems__respondent2track', 'gr2t_id_respondent_track = gr2t2a_id_respondent_track', array('gr2t_id_track'))->where('gr2t2a_id_appointment = ?', $this->_appointmentId)->distinct();
     // AND find the filters for any new fields to fill
     $filters = $this->agenda->matchFilters($this);
     if ($filters) {
         $ids = array_map(function ($value) {
             return $value->getTrackId();
         }, $filters);
         // \MUtil_Echo::track(array_keys($filters), $ids);
         $respId = $this->getRespondentId();
         $orgId = $this->getOrganizationId();
         $select->orWhere("gr2t_id_user = {$respId} AND gr2t_id_organization = {$orgId} AND gr2t_id_track IN (" . implode(', ', $ids) . ")");
         // \MUtil_Echo::track($this->getId(), implode(', ', $ids));
     }
     // \MUtil_Echo::track($select->__toString());
     // Now find all the existing tracks that should be checked
     $respTracks = $this->db->fetchPairs($select);
     // \MUtil_Echo::track($respTracks);
     if ($respTracks) {
         foreach ($respTracks as $respTrackId => $trackId) {
             $respTrack = $tracker->getRespondentTrack($respTrackId);
             // Recalculate this track
             $fieldsChanged = false;
             $tokenChanges += $respTrack->recalculateFields($fieldsChanged);
             // Store the track for creation checking
             $existingTracks[$trackId][] = $respTrack;
         }
     } else {
         $existingTracks = array();
         $respTracks = array();
     }
     // \MUtil_Echo::track($tokenChanges);
     // Never create tracks for inactive appointments and for appointments in the past
     if (!$this->isActive() || $this->getAdmissionTime()->isEarlierOrEqual(new \MUtil_Date())) {
         return $tokenChanges;
     }
     // \MUtil_Echo::track(count($filters));
     // Check for tracks that should be created
     foreach ($filters as $filter) {
         if ($filter instanceof AppointmentFilterInterface && $filter->isCreator()) {
             $createTrack = true;
             $trackId = $filter->getTrackId();
             if (isset($existingTracks[$trackId])) {
                 foreach ($existingTracks[$trackId] as $respTrack) {
                     if ($respTrack instanceof \Gems_Tracker_RespondentTrack) {
                         if ($respTrack->hasSuccesCode()) {
                             // \MUtil_Echo::track($trackId, $respTrack->isOpen());
                             // An open track of this type exists: do not create a new one
                             if ($respTrack->isOpen()) {
                                 $createTrack = false;
                                 break;
                             }
                             // A closed tracks exist.
                             // Is there one that ended less than wait days ago
                             $curr = $this->getAdmissionTime();
                             $end = $respTrack->getEndDate();
                             $wait = $filter->getWaitDays();
                             if ($wait === null || !$curr || !$end || $curr->diffDays($end) <= $wait) {
                                 // \MUtil_Echo::track($trackId, $curr->diffDays($end), $wait);
                                 $createTrack = false;
                                 break;
                             }
                             // \MUtil_Echo::track($trackId, $curr->diffDays($end), $wait);
                             // Track has already been assigned
                             $data = $respTrack->getFieldData();
                             if (isset($data[$filter->getFieldId()]) && $this->getId() == $data[$filter->getFieldId()]) {
                                 // \MUtil_Echo::track($data[$filter->getFieldId()]);
                                 $createTrack = false;
                                 break;
                             }
                         }
                     }
                 }
             }
             // \MUtil_Echo::track($trackId, $createTrack, $filter->getName(), $filter->getSqlWhere(), $filter->getFilterId());
             if ($createTrack) {
                 $trackData = array('gr2t_comment' => sprintf($this->_('Track created by %s filter'), $filter->getName()));
                 $fields = array($filter->getFieldId() => $this->getId());
                 $respTrack = $tracker->createRespondentTrack($this->getRespondentId(), $this->getOrganizationId(), $trackId, $userId, $trackData, $fields);
                 $existingTracks[$trackId][] = $respTrack;
                 $tokenChanges += $respTrack->getCount();
             }
         }
     }
     return $tokenChanges;
 }
 /**
  * Get a filter for the show log snippet
  */
 public function getShowLogOverviewFilter()
 {
     return array('gla_by' => $this->currentUser->getUserId());
 }