/**
  * Handles creating or replacing the view for this survey
  *
  * @param \Gems_Tracker_Survey       $viewName
  * @param \MUtil_Model_ModelAbstract $answerModel
  */
 protected function replaceCreateView(\Gems_Tracker_Survey $survey, \MUtil_Model_ModelAbstract $answerModel)
 {
     $viewName = $this->getViewName($survey);
     $responseDb = $this->project->getResponseDatabase();
     $fieldSql = '';
     foreach ($answerModel->getItemsOrdered() as $name) {
         if (true === $answerModel->get($name, 'survey_question') && !in_array($name, array('submitdate', 'startdate', 'datestamp')) && !$answerModel->is($name, 'type', \MUtil_Model::TYPE_NOVALUE)) {
             // Only real answers
             $fieldSql .= ',MAX(IF(gdr_answer_id = ' . $responseDb->quote($name) . ', gdr_response, NULL)) AS ' . $responseDb->quoteIdentifier($name);
         }
     }
     if ($fieldSql > '') {
         $dbConfig = $this->db->getConfig();
         $tokenTable = $this->db->quoteIdentifier($dbConfig['dbname'] . '.gems__tokens');
         $createViewSql = 'CREATE OR REPLACE VIEW ' . $responseDb->quoteIdentifier($viewName) . ' AS SELECT gdr_id_token';
         $createViewSql .= $fieldSql;
         $createViewSql .= "FROM gemsdata__responses join " . $tokenTable . " on (gto_id_token=gdr_id_token and gto_id_survey=" . $survey->getSurveyId() . ") GROUP BY gdr_id_token;";
         try {
             $responseDb->query($createViewSql)->execute();
         } catch (Exception $exc) {
             $responseConfig = $responseDb->getConfig();
             $dbUser = $this->db->quoteIdentifier($responseConfig['username']) . '@' . $this->db->quoteIdentifier($responseConfig['host']);
             $statement = "GRANT SELECT ON  " . $tokenTable . " TO " . $dbUser;
             $this->getBatch()->addMessage(sprintf($this->_("Creating view failed, try adding rights using the following statement: %s"), $statement));
         }
     }
 }
 /**
  * Returns the data to show in the index action
  *
  * Allows to easily add or modifiy the information at project level
  *
  * @return array
  */
 protected function _getData()
 {
     $versions = $this->loader->getVersions();
     $data[$this->_('Project name')] = $this->project->getName();
     $data[$this->_('Project version')] = $versions->getProjectVersion();
     $data[$this->_('Gems version')] = $versions->getGemsVersion();
     $data[$this->_('Gems build')] = $versions->getBuild();
     $data[$this->_('Gems project')] = GEMS_PROJECT_NAME;
     $data[$this->_('Gems web directory')] = $this->getDirInfo(GEMS_WEB_DIR);
     $data[$this->_('Gems root directory')] = $this->getDirInfo(GEMS_ROOT_DIR);
     $data[$this->_('Gems code directory')] = $this->getDirInfo(GEMS_LIBRARY_DIR);
     $data[$this->_('Gems variable directory')] = $this->getDirInfo(GEMS_ROOT_DIR . '/var');
     $data[$this->_('MUtil version')] = \MUtil_Version::get();
     $data[$this->_('Zend version')] = \Zend_Version::VERSION;
     $data[$this->_('Application environment')] = APPLICATION_ENV;
     $data[$this->_('Application baseuri')] = $this->loader->getUtil()->getCurrentURI();
     $data[$this->_('Application directory')] = $this->getDirInfo(APPLICATION_PATH);
     $data[$this->_('Application encoding')] = APPLICATION_ENCODING;
     $data[$this->_('PHP version')] = phpversion();
     $data[$this->_('Server Hostname')] = php_uname('n');
     $data[$this->_('Server OS')] = php_uname('s');
     $data[$this->_('Time on server')] = date('r');
     $driveVars = array($this->_('Session directory') => \Zend_Session::getOptions('save_path'), $this->_('Temporary files directory') => realpath(getenv('TMP')));
     if ($system = getenv('SystemDrive')) {
         $driveVars[$this->_('System Drive')] = realpath($system);
     }
     foreach ($driveVars as $name => $drive) {
         $data[$name] = $this->getDirInfo($drive);
     }
     return $data;
 }
 /**
  * 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($trackId = null, $exportOrganizations = false)
 {
     $versions = $this->loader->getVersions();
     $data = array('gems_version' => $versions->getGemsVersion(), 'project' => $this->project->getName(), 'project_env' => APPLICATION_ENV, 'project_url' => $this->util->getCurrentURI(), 'project_version' => $versions->getProjectVersion());
     // Main version data
     $this->exportTypeHeader('version', false);
     $this->exportFieldHeaders($data);
     $this->exportFieldData($data);
     $this->exportFlush();
 }
 /**
  * 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($tableName = '', $idField = '', $passwordField = '', $methodField = '')
 {
     $passwords = $this->db->fetchPairs("SELECT {$idField}, {$passwordField} FROM {$tableName} WHERE {$passwordField} IS NOT NULL AND {$methodField} IS NULL");
     if ($passwords) {
         $values[$methodField] = 'default';
         foreach ($passwords as $key => $password) {
             $values[$passwordField] = $this->project->encrypt($password, $values[$methodField]);
             $this->db->update($tableName, $values, "{$idField} = '{$key}'");
         }
         $this->getBatch()->addMessage(sprintf($this->_('%d passwords encrypted for table %s.'), count($passwords), $tableName));
     } else {
         $this->getBatch()->addMessage(sprintf($this->_('No passwords found in table %s.'), $tableName));
     }
 }
 /**
  * Create the snippets content
  *
  * This is a stub function either override getHtmlOutput() or override render()
  *
  * @param \Zend_View_Abstract $view Just in case it is needed here
  * @return \MUtil_Html_HtmlInterface Something that can be rendered
  */
 public function getHtmlOutput(\Zend_View_Abstract $view)
 {
     $delay = $this->project->getAskDelay($this->request, $this->wasAnswered);
     $href = $this->getTokenHref($this->showToken);
     $html = $this->getHtmlSequence();
     $org = $this->showToken->getOrganization();
     $url = $href->render($this->view);
     switch ($delay) {
         case 0:
             // Redirect at once
             header('Location: ' . $url);
             exit;
         case -1:
             break;
         default:
             // Let the page load after stated interval
             $this->view->headMeta()->appendHttpEquiv('Refresh', $delay . '; url=' . $url);
     }
     $html->h3($this->_('Token'));
     if ($this->token->hasRelation()) {
         $p = $html->pInfo(sprintf($this->_('Welcome %s,'), $this->showToken->getRelation()->getName()));
         $html->pInfo(sprintf($this->_('We kindly ask you to answer a survey about %s.'), $this->showToken->getRespondent()->getName()));
     } else {
         $p = $html->pInfo(sprintf($this->_('Welcome %s,'), $this->showToken->getRespondentName()));
     }
     if ($this->wasAnswered) {
         $html->pInfo(sprintf($this->_('Thank you for answering the "%s" survey.'), $this->token->getSurveyName()));
         $html->pInfo($this->_('Please click the button below to answer the next survey.'));
     } else {
         if ($welcome = $org->getWelcome()) {
             $html->pInfo()->raw(\MUtil_Markup::render($this->_($welcome), 'Bbcode', 'Html'));
         }
         $html->pInfo(sprintf($this->_('Please click the button below to answer the survey for token %s.'), strtoupper($this->showToken->getTokenId())));
     }
     if ($delay > 0) {
         $html->pInfo(sprintf($this->plural('Wait one second to open the survey automatically or click on Cancel to stop.', 'Wait %d seconds to open the survey automatically or click on Cancel to stop.', $delay), $delay));
     }
     $buttonDiv = $html->buttonDiv(array('class' => 'centerAlign'));
     $buttonDiv->actionLink($href, $this->showToken->getSurveyName());
     if ($delay > 0) {
         $buttonDiv->actionLink(array('delay_cancelled' => 1), $this->_('Cancel'));
     }
     if ($next = $this->showToken->getTokenCountUnanswered()) {
         $html->pInfo(sprintf($this->plural('After this survey there is one other survey we would like you to answer.', 'After this survey there are another %d surveys we would like you to answer.', $next), $next));
     }
     if ($sig = $org->getSignature()) {
         $html->pInfo()->raw(\MUtil_Markup::render($this->_($sig), 'Bbcode', 'Html'));
     }
     return $html;
 }
 /**
  * Returns the data for a user object. It may be empty if the user is unknown.
  *
  * @param string $login_name
  * @param int $organization
  * @return array Of data to fill the user with.
  */
 public function getUserData($login_name, $organization)
 {
     $orgs = null;
     try {
         $orgs = $this->db->fetchPairs("SELECT gor_id_organization, gor_name FROM gems__organizations WHERE gor_active = 1 ORDER BY gor_name");
         natsort($orgs);
     } catch (\Zend_Db_Exception $zde) {
     }
     if (!$orgs) {
         // Table might not exist or be empty, so do something failsafe
         $orgs = array($organization => 'create db first');
     }
     return array('user_id' => \Gems_User_UserLoader::SYSTEM_USER_ID, 'user_login' => $login_name, 'user_name' => $login_name, 'user_group' => 800, 'user_role' => $this->project->getConsoleRole(), 'user_style' => 'gems', 'user_base_org_id' => $organization, 'user_allowed_ip_ranges' => null, 'user_blockable' => false, '__allowedOrgs' => $orgs);
 }
 /**
  * Returns the source choices in an array.
  *
  * @param boolean $validAfter True if it concerns _valid_after_ dates
  * @param boolean $firstRound List for first round
  * @param boolean $detailed   Return extended info
  * @return array source_name => label
  */
 protected function getSourceList($validAfter, $firstRound, $detailed = true)
 {
     if (!($validAfter || $this->project->isValidUntilRequired())) {
         $results[self::NO_TABLE] = array($this->_('Does not expire'));
     }
     if (!($validAfter && $firstRound)) {
         $results[self::ANSWER_TABLE] = array($this->_('Answers'), $this->_('Use an answer from a survey.'));
     }
     if ($this->_fieldsDefinition->hasAppointmentFields()) {
         $results[self::APPOINTMENT_TABLE] = array($this->_('Appointment'), $this->_('Use an appointment linked to this track.'));
     }
     if (!($validAfter && $firstRound)) {
         $results[self::TOKEN_TABLE] = array($this->_('Token'), $this->_('Use a standard token date.'));
     }
     $results[self::RESPONDENT_TRACK_TABLE] = array($this->_('Track'), $this->_('Use a track level date.'));
     if ($detailed) {
         foreach ($results as $key => $value) {
             if (is_array($value)) {
                 $results[$key] = \MUtil_Html::raw(sprintf('<strong>%s</strong> %s', reset($value), next($value)));
             }
         }
     } else {
         foreach ($results as $key => $value) {
             if (is_array($value)) {
                 $results[$key] = reset($value);
             }
         }
     }
     return $results;
 }
 /**
  * A ModelAbstract->setOnSave() function that returns the input
  * date as a valid date.
  *
  * @see \MUtil_Model_ModelAbstract
  *
  * @param mixed $value The value being saved
  * @param boolean $isNew True when a new item is being saved
  * @param string $name The name of the current field
  * @param array $context Optional, the other values being saved
  * @return \Zend_Date
  */
 public function saveValue($value, $isNew = false, $name = null, array $context = array())
 {
     if ($value) {
         // \MUtil_Echo::track($value);
         return $this->project->encrypt($value, 'default');
     }
 }
 /**
  * Load extra data not from the model into the form
  */
 protected function loadFormData()
 {
     parent::loadFormData();
     $this->loadMailer();
     if (isset($this->formData['gctt'])) {
         $multi = false;
         if (count($this->formData['gctt']) > 1) {
             $multi = true;
             $allLanguages = $this->util->getLocalized()->getLanguages();
         }
         $preview = $this->getPreview($this->formData['gctt']);
         $this->formData['preview_html'] = $preview['html'];
         $this->formData['preview_text'] = $preview['text'];
     }
     if (!isset($this->formData['to'])) {
         $organization = $this->mailer->getOrganization();
         $this->formData['to'] = $this->formData['from'] = null;
         if ($organization->getEmail()) {
             $this->formData['to'] = $this->formData['from'] = $organization->getEmail();
         } elseif ($this->project->getSiteEmail()) {
             $this->formData['to'] = $this->formData['from'] = $this->project->getSiteEmail();
         }
     }
     $this->formData['available_fields'] = $this->mailElements->displayMailFields($this->mailer->getMailFields());
 }
 /**
  * Called after the check that all required registry values
  * have been set correctly has run.
  *
  * @return void
  */
 public function afterRegistry()
 {
     parent::afterRegistry();
     if ($this->project instanceof \Gems_Project_ProjectSettings) {
         $this->useCsrf = $this->project->useCsrfCheck();
     }
 }
예제 #11
0
 /**
  * Send an e-mail to this user
  *
  * @param string $subjectTemplate A subject template in which {fields} are replaced
  * @param string $bbBodyTemplate A BB Code body template in which {fields} are replaced
  * @param boolean $useResetFields When true get a reset key for this user
  * @param string $locale Optional locale
  * @return mixed String or array of warnings when something went wrong
  */
 public function sendMail($subjectTemplate, $bbBodyTemplate, $useResetFields = false, $locale = null)
 {
     if ($useResetFields && !$this->canResetPassword()) {
         return $this->_('Trying to send a password reset to a user that cannot be reset.');
     }
     $mail = $this->loader->getMail();
     $mail->setTemplateStyle($this->getBaseOrganization()->getStyle());
     $mail->setFrom($this->getFrom());
     $mail->addTo($this->getEmailAddress(), $this->getFullName(), $this->project->getEmailBounce());
     if ($bcc = $this->project->getEmailBcc()) {
         $mail->addBcc($bcc);
     }
     if ($useResetFields) {
         $fields = $this->getResetPasswordMailFields($locale);
     } else {
         $fields = $this->getMailFields($locale);
     }
     // \MUtil_Echo::track($fields, $bbBodyTemplate);
     $fields = \MUtil_Ra::braceKeys($fields, '{', '}');
     $mail->setSubject(strtr($subjectTemplate, $fields));
     $mail->setBodyBBCode(strtr($bbBodyTemplate, $fields));
     try {
         $mail->send();
         return null;
     } catch (\Exception $e) {
         return array($this->_('Unable to send e-mail.'), $e->getMessage());
     }
 }
 /**
  * Returns true if and only if $value meets the validation requirements
  *
  * If $value fails validation, then this method returns false, and
  * getMessages() will return an array of messages that explain why the
  * validation failed.
  *
  * @param  mixed $value
  * @return boolean
  * @throws \Zend_Valid_Exception If validation of $value is impossible
  */
 public function isValid($value)
 {
     if ($throttleSettings = $this->project->getAskThrottleSettings()) {
         // Prune the database for (very) old attempts
         $where = $this->db->quoteInto('gta_datetime < DATE_SUB(NOW(), INTERVAL ? second)', $throttleSettings['period'] * 20);
         $this->db->delete('gems__token_attempts', $where);
         // Retrieve the number of failed attempts that occurred within the specified window
         $select = $this->db->select();
         $select->from('gems__token_attempts', array(new \Zend_Db_Expr('COUNT(*) AS attempts'), new \Zend_Db_Expr('UNIX_TIMESTAMP(MAX(gta_datetime)) - UNIX_TIMESTAMP() AS last')))->where('gta_datetime > DATE_SUB(NOW(), INTERVAL ? second)', $throttleSettings['period']);
         $attemptData = $this->db->fetchRow($select);
         $remainingDelay = $attemptData['last'] + $throttleSettings['delay'];
         // \MUtil_Echo::track($throttleSettings, $attemptData, $remainingDelay);
         if ($attemptData['attempts'] > $throttleSettings['threshold'] && $remainingDelay > 0) {
             $this->logger->log("Possible token brute force attack, throttling for {$remainingDelay} seconds", \Zend_Log::ERR);
             $this->_messages = $this->translate->_('The server is currently busy, please wait a while and try again.');
             return false;
         }
     }
     // The pure token check
     if ($this->isValidToken($value)) {
         return true;
     }
     $max_length = $this->tracker->getTokenLibrary()->getLength();
     $this->db->insert('gems__token_attempts', array('gta_id_token' => substr($value, 0, $max_length), 'gta_ip_address' => $this->getRequest()->getClientIp()));
     return false;
 }
 /**
  * Get the db adapter for this source
  *
  * @return \Zend_Db_Adapter_Abstract
  */
 protected function getSourceDatabase()
 {
     if (!$this->_sourceDb) {
         if ($dbConfig['dbname'] = $this->_sourceData['gso_ls_database']) {
             // Default config values from gemsDb
             $gemsConfig = $this->_gemsDb->getConfig();
             $gemsName = $gemsConfig['dbname'];
             if ($dbConfig['dbname'] != $gemsName && ($adapter = $this->_sourceData['gso_ls_adapter'])) {
                 //If upgrade has run and we have a 'charset' use it
                 if (array_key_exists('gso_ls_charset', $this->_sourceData)) {
                     $dbConfig['charset'] = $this->_sourceData['gso_ls_charset'] ? $this->_sourceData['gso_ls_charset'] : $gemsConfig['charset'];
                 }
                 $dbConfig['host'] = $this->_sourceData['gso_ls_dbhost'] ? $this->_sourceData['gso_ls_dbhost'] : $gemsConfig['host'];
                 $dbConfig['username'] = $this->_sourceData['gso_ls_username'] ? $this->_sourceData['gso_ls_username'] : $gemsConfig['username'];
                 $dbConfig['password'] = $this->_sourceData['gso_ls_password'] ? $this->project->decrypt($this->_sourceData['gso_ls_password'], $this->_sourceData['gso_encryption']) : $gemsConfig['password'];
                 $this->_sourceDb = \Zend_Db::factory($adapter, $dbConfig);
             }
         }
         // In all other cases use $_gemsDb
         if (!$this->_sourceDb) {
             $this->_sourceDb = $this->_gemsDb;
         }
     }
     return $this->_sourceDb;
 }
예제 #14
0
 /**
  *
  * @param boolean $detailed True when the current action is not in $summarizedActions.
  * @param string $action The current action.
  * @param int $defaultOrgId The default organization id or null if current organization
  * @return \Gems_Model_StaffModel
  */
 public function applySettings($detailed, $action, $defaultOrgId)
 {
     $this->resetOrder();
     $dbLookup = $this->util->getDbLookup();
     $editing = $action == 'edit' || $action == 'create';
     $translated = $this->util->getTranslated();
     $user = $this->loader->getCurrentUser();
     $yesNo = $translated->getYesNo();
     if ($editing) {
         $ucfirst = new \Zend_Filter_Callback('ucfirst');
         if ($this->project->isLoginShared()) {
             $this->set('gsf_login', 'validator', $this->createUniqueValidator('gsf_login', array('gsf_id_user')));
         } else {
             // per organization
             $this->set('gsf_login', 'validator', $this->createUniqueValidator(array('gsf_login', 'gsf_id_organization'), array('gsf_id_user')));
         }
     } else {
         $ucfirst = null;
     }
     $this->set('gsf_login', 'label', $this->_('Username'), 'minlength', 4, 'required', true, 'size', 15);
     if ($user->hasPrivilege('pr.staff.see.all') || !$editing) {
         // Select organization
         $options = $dbLookup->getOrganizations();
     } else {
         $options = $user->getAllowedOrganizations();
     }
     $this->set('gsf_id_organization', 'label', $this->_('Organization'), 'multiOptions', $options, 'required', true);
     if ($detailed) {
         $this->set('gsf_first_name', 'label', $this->_('First name'), 'filters[ucfirst]', $ucfirst);
         $this->set('gsf_surname_prefix', 'label', $this->_('Surname prefix'), 'description', $this->_('de, van der, \'t, etc...'));
         $this->set('gsf_last_name', 'label', $this->_('Last name'), 'required', true, 'filters[ucfirst]', $ucfirst);
     } else {
         $this->set('name', 'label', $this->_('Name'));
     }
     $this->set('gsf_gender', 'label', $this->_('Gender'), 'elementClass', 'Radio', 'multiOptions', $translated->getGenders(), 'separator', ' ');
     $this->set('gsf_email', 'label', $this->_('E-Mail'), 'itemDisplay', array('MUtil_Html_AElement', 'ifmail'), 'size', 30, 'validators[email]', 'SimpleEmail');
     $this->set('gsf_id_primary_group', 'label', $this->_('Primary function'), 'multiOptions', $editing ? $user->getAllowedStaffGroups() : $dbLookup->getStaffGroups());
     if ($detailed) {
         // Now try to load the current organization and find out if it has a default user definition
         // otherwise use the defaultStaffDefinition
         $organization = $this->loader->getOrganization($defaultOrgId ? $defaultOrgId : $user->getCurrentOrganizationId());
         $this->set('gsf_id_organization', 'default', $organization->getId());
         $this->set('gul_user_class', 'label', $this->_('User Definition'), 'default', $organization->get('gor_user_class', $this->defaultStaffDefinition), 'multiOptions', $this->loader->getUserLoader()->getAvailableStaffDefinitions());
         if ($editing) {
             $this->set('gul_user_class', 'order', 1, 'required', true);
         }
         $this->set('gsf_iso_lang', 'label', $this->_('Language'), 'default', $this->project->locale['default'], 'multiOptions', $this->util->getLocalized()->getLanguages());
         $this->set('gul_can_login', 'label', $this->_('Can login'), 'default', 1, 'description', $this->_('Users can only login when this box is checked.'), 'elementClass', 'Checkbox', 'multiOptions', $yesNo);
         $this->set('gsf_logout_on_survey', 'label', $this->_('Logout on survey'), 'description', $this->_('If checked the user will logoff when answering a survey.'), 'elementClass', 'Checkbox', 'multiOptions', $yesNo);
         $this->set('gsf_mail_watcher', 'label', $this->_('Check cron job mail'), 'description', $this->_('If checked the user will be mailed when the cron job does not run on time.'), 'elementClass', 'Checkbox', 'multiOptions', $yesNo);
     }
     $this->set('gsf_active', 'label', $this->_('Active'), 'elementClass', 'None', 'multiOptions', $yesNo);
     $this->setDeleteValues('gsf_active', 0, 'gul_can_login', 0);
     if (!$user->hasPrivilege('pr.staff.edit.all')) {
         $this->set('gsf_id_organization', 'elementClass', 'Exhibitor');
     }
     return $this;
 }
예제 #15
0
 /**
  * Returns the current 'base site' url, optionally with a subpath.
  *
  * @staticvar string $uri
  * @param string $subpath Optional string
  * @return string The Url + basePath plus the optional subpath
  */
 public function getCurrentURI($subpath = '')
 {
     static $uri;
     if (!$uri) {
         $uri = \MUtil_Https::on() || $this->project->isHttpsRequired() ? 'https' : 'http';
         $uri .= '://';
         $uri .= isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : $this->project->getConsoleUrl();
         $uri .= $this->basepath->getBasePath();
     }
     if ($subpath && $subpath[0] != '/') {
         $subpath = '/' . $subpath;
     }
     return $uri . $subpath;
 }
 /**
  * Check for password weakness.
  *
  * @param \Gems_User_User $user
  * @param string $password Or null when you want a report on all the rules for this password.
  * @param array  $codes An array of code names that identify rules that should be used only for those codes.
  * @return mixed String or array of strings containing warning messages
  */
 public function reportPasswordWeakness(\Gems_User_User $user, $password, array $codes)
 {
     $this->user = $user;
     $this->_errors = array();
     $rules = $this->project->getPasswordRules($codes);
     // \MUtil_Echo::track($rules);
     foreach ($rules as $rule => $parameter) {
         if (method_exists($this, $rule)) {
             $this->{$rule}($parameter, $password);
         }
     }
     // \MUtil_Echo::track($this->_errors);
     return $this->_errors;
 }
 /**
  * Set those values needed for editing
  *
  * @return \Gems_Model_OrganizationModel
  */
 public function applyEditSettings()
 {
     $this->applyDetailSettings();
     $this->resetOrder();
     // GENERAL TAB
     $this->set('general', 'tab', 'general', 'elementClass', 'Tab', 'value', $this->_('General'));
     $this->set('gor_name', 'tab', 'general', 'size', 25, 'validator', $this->createUniqueValidator('gor_name'));
     $this->set('gor_location', 'tab', 'general', 'size', 50, 'maxlength', 255);
     $this->set('gor_task', 'tab', 'general', 'size', 25);
     $this->set('gor_url', 'tab', 'general', 'size', 50);
     $this->setIfExists('gor_url_base', 'tab', 'general', 'size', 50, 'filter', 'TrailingSlash');
     $this->setIfExists('gor_code', 'tab', 'general', 'size', 10);
     $this->set('gor_provider_id', 'tab', 'general');
     $this->setIfExists('gor_active', 'tab', 'general', 'elementClass', 'Checkbox');
     // EMAIL TAB
     $this->set('email', 'tab', 'email', 'elementClass', 'Tab', 'order', $this->getOrder('gor_active') + 1000, 'value', $this->_('Email') . ' & ' . $this->_('Token'));
     $this->set('gor_contact_name', 'tab', 'email', 'size', 25);
     $this->set('gor_contact_email', 'tab', 'email', 'size', 50, 'validator', 'SimpleEmail');
     $this->set('gor_welcome', 'tab', 'email', 'elementClass', 'Textarea', 'rows', 5);
     $this->set('gor_signature', 'tab', 'email', 'elementClass', 'Textarea', 'rows', 5);
     $this->set('gor_create_account_template', 'tab', 'email');
     $this->set('gor_reset_pass_template', 'tab', 'email');
     // ACCESS TAB
     $this->set('access', 'tab', 'access', 'elementClass', 'Tab', 'order', $this->getOrder('gor_reset_pass_template') + 1000, 'value', $this->_('Access'));
     $this->set('gor_has_login', 'tab', 'access', 'elementClass', 'CheckBox');
     $this->set('gor_add_respondents', 'tab', 'access', 'elementClass', 'CheckBox');
     $this->set('gor_has_respondents', 'tab', 'access', 'elementClass', 'Exhibitor');
     $this->set('gor_respondent_group', 'tab', 'access');
     $this->set('gor_accessible_by', 'tab', 'access', 'elementClass', 'MultiCheckbox');
     $this->set('allowed', 'tab', 'access', 'label', $this->_('Can access'), 'elementClass', 'Html');
     $this->setIfExists('gor_allowed_ip_ranges', 'tab', 'access', 'size', 50, 'validator', new \Gems_Validate_IPRanges(), 'maxlength', 500);
     $this->setIfExists('gor_user_class', 'tab', 'access');
     $definitions = $this->get('gor_user_class', 'multiOptions');
     if ($definitions && count($definitions) > 1) {
         reset($definitions);
         $this->setIfExists('gor_user_class', 'default', key($definitions), 'required', true);
     }
     // OTHER TAB
     $this->set('other', 'tab', 'other', 'elementClass', 'Tab', 'order', $this->getOrder('gor_user_class') + 1000, 'value', $this->_('Other'));
     $this->setIfExists('gor_iso_lang', 'tab', 'other', 'default', $this->project->getLocaleDefault());
     if ($this->_styles) {
         $this->setIfExists('gor_style', 'tab', 'other');
     }
     return $this;
 }
예제 #18
0
 /**
  * Add the token to every page of a pdf
  *
  * @param \Zend_Pdf $pdf
  * @param string $tokenId
  * @param int $surveyId
  */
 protected function addTokenToDocument(\Zend_Pdf $pdf, $tokenId, $surveyId)
 {
     $token = strtoupper($tokenId);
     foreach (array('Title', 'Subject', 'Keywords') as $name) {
         if (isset($pdf->properties[$name])) {
             $value = rtrim($pdf->properties[$name]) . ' ' . $token;
         } else {
             $value = $token;
         }
         $pdf->properties[$name] = $value;
     }
     // Acrobat defined date format D:YYYYMMDDHHmmSSOHH'mm
     $pdf->properties['ModDate'] = 'D:' . str_replace(':', "'", date('YmdHisP')) . "'";
     $pdf->properties['Producer'] = $this->project->getName();
     // Avoid warning on Word with a (R) symbol
     $pdf->properties['Creator'] = $this->project->getName();
     // Avoid warning on Word with a (R) symbol
 }
예제 #19
0
 /**
  * Start the cron mail monitor
  *
  * @return boolean True when the job was started
  */
 public function startCronMailMonitor()
 {
     $to = $this->_getMailTo('cronmail', 'gsf_mail_watcher = 1');
     if (!$to) {
         return false;
     }
     $job = $this->getCronMailMonitor();
     switch ($this->project->getLocaleDefault()) {
         case 'nl':
             $subject = "{name} opdracht draait al meer dan {periodHours} uur niet";
             $messageBbText = "L.S.,\n\nDe [b]{name}[/b] opdracht heeft op {setTime} voor het laatst gedraait en zou voor {firstCheck} opnieuw gedraait moeten hebben.\n\nDit is waarschuwing nummer [b]{mailCount}[/b]. Controleer s.v.p. wat verkeerd gegaan is.\n\nDit is een automatische waarschuwing.";
             break;
         default:
             $subject = "{name} job has not run for over {periodHours} hours";
             $messageBbText = "L.S.,\n\nThe [b]{name}[/b] job ran at {setTime} for the last time and should have run again before {firstCheck}.\n\nThis is notice number {mailCount}. Please check what went wrong.\n\nThis messages was send automatically.";
             break;
     }
     $job->setFrom($this->project->getMonitorFrom('cronmail'))->setMessage($messageBbText)->setPeriod($this->project->getMonitorPeriod('cronmail'))->setSubject($subject)->setTo($to)->start();
     return true;
 }
 /**
  * Add form elements when a responseDatabase is present
  * @param  \Gems_Form $form existing form type
  * @param  array data existing options set in the form
  * @return array of form elements
  */
 protected function addResponseDatabaseForm($form, &$data, &$elements)
 {
     if (isset($data['tid']) && !empty($data['tid'])) {
         // If we have a responsedatabase and a track id, try something cool ;-)
         $responseDb = $this->project->getResponseDatabase();
         if ($this->db === $responseDb) {
             // We are in the same database, now put that to use by allowing to filter respondents based on an answer in any survey
             $empty = $this->util->getTranslated()->getEmptyDropdownArray();
             $allSurveys = $empty + $this->util->getDbLookup()->getSurveysForExport();
             $element = new \Zend_Form_Element_Select('filter_sid');
             $element->setLabel($this->_('Survey'))->setMultiOptions($allSurveys);
             $groupElements = array($element);
             if (isset($data['filter_sid']) && !empty($data['filter_sid'])) {
                 $filterSurvey = $this->loader->getTracker()->getSurvey($data['filter_sid']);
                 $filterQuestions = $empty + $filterSurvey->getQuestionList($this->locale->getLanguage());
                 $element = new \Zend_Form_Element_Select('filter_answer');
                 $element->setLabel($this->_('Question'))->setMultiOptions($filterQuestions);
                 $groupElements[] = $element;
             }
             if (isset($filterSurvey) && isset($data['filter_answer']) && !empty($data['filter_answer'])) {
                 $questionInfo = $filterSurvey->getQuestionInformation($this->locale->getLanguage());
                 if (array_key_exists($data['filter_answer'], $questionInfo)) {
                     $questionInfo = $questionInfo[$data['filter_answer']];
                 } else {
                     $questionInfo = array();
                 }
                 if (array_key_exists('answers', $questionInfo) && is_array($questionInfo['answers']) && count($questionInfo['answers']) > 1) {
                     $element = new \Zend_Form_Element_Multiselect('filter_value');
                     $element->setMultiOptions($empty + $questionInfo['answers']);
                     $element->setAttrib('size', count($questionInfo['answers']) + 1);
                 } else {
                     $element = new \Zend_Form_Element_Text('filter_value');
                 }
                 $element->setLabel($this->_('Value'));
                 $groupElements[] = $element;
             }
             $form->addDisplayGroup($groupElements, 'filter', array('showLabels' => true, 'Description' => $this->_('Filter')));
             array_shift($elements);
         }
     }
 }
 /**
  * A specific report on the escort class
  */
 protected function addEscortReport()
 {
     $this->html->h2('Project and escort class report');
     $escortClass = get_class($this->escort);
     $foundNone = true;
     $projectName = $this->project->getName();
     $oldInterfaces = array('Gems_Project_Log_LogRespondentAccessInterface', 'Gems_Project_Organization_MultiOrganizationInterface', 'Gems_Project_Organization_SingleOrganizationInterface', 'Gems_Project_Tracks_FixedTracksInterface', 'Gems_Project_Tracks_StandAloneSurveysInterface', 'Gems_Project_Tracks_TracksOnlyInterface');
     foreach ($oldInterfaces as $interface) {
         if ($this->escort instanceof $interface) {
             $foundNone = false;
             $this->html->pInfo(sprintf('%s implements the deprecated %s interface. Remove this interface.', $escortClass, $interface));
         }
     }
     $snippetsDir = APPLICATION_PATH . '\\snippets';
     if (file_exists($snippetsDir)) {
         $foundNone = false;
         $this->html->pInfo(sprintf('%s still uses the deprecated %s directory for snippets. This directory is deprecated and will be removed in 1.7.2.', $projectName, $snippetsDir));
     }
     if ($foundNone) {
         $this->html->pInfo(sprintf('%s and %s are up to date.', $projectName, $escortClass));
     }
 }
 /**
  * The place to check if the data set in the snippet is valid
  * to generate the snippet.
  *
  * When invalid data should result in an error, you can throw it
  * here but you can also perform the check in the
  * checkRegistryRequestsAnswers() function from the
  * {@see \MUtil_Registry_TargetInterface}.
  *
  * @return boolean
  */
 public function hasHtmlOutput()
 {
     if ($this->menu) {
         $default = $this->project->getDefaultTrackId();
         if ($default) {
             if ($this->respondent->getReceptionCode()->isSuccess()) {
                 $track = $this->loader->getTracker()->getTrackEngine($default);
                 if ($track->isUserCreatable()) {
                     $list = $this->menu->getMenuList()->addByController('track', 'create', sprintf($this->_('Add %s track to this respondent'), $track->getTrackName()))->addParameterSources(array(\Gems_Model::TRACK_ID => $default, 'gtr_id_track' => $default, 'track_can_be_created' => 1), $this->request);
                     $this->onEmpty = $list->getActionLink('track', 'create');
                 }
             }
         }
         if (!$this->onEmpty) {
             if ($this->respondent->getReceptionCode()->isSuccess()) {
                 $list = $this->menu->getMenuList()->addByController('track', 'show-track', $this->_('Add a track to this respondent'))->addParameterSources($this->request);
                 $this->onEmpty = $list->getActionLink('track', 'show-track');
             } else {
                 $this->onEmpty = \MUtil_Html::create('em', $this->_('No valid tokens found'));
             }
         }
     }
     return parent::hasHtmlOutput();
 }
예제 #23
0
 /**
  * Returns \Zend_Mail_Transport_Abstract when something else than the default mail protocol should be used.
  *
  * @staticvar array $mailServers
  * @param email address $from
  * @return \Zend_Mail_Transport_Abstract or null
  */
 public function checkTransport($from)
 {
     if (!array_key_exists($from, self::$mailServers)) {
         $sql = 'SELECT * FROM gems__mail_servers WHERE ? LIKE gms_from ORDER BY LENGTH(gms_from) DESC LIMIT 1';
         // Always set cache, se we know when not to check for this row.
         $serverData = $this->escort->db->fetchRow($sql, $from);
         // \MUtil_Echo::track($serverData);
         if (isset($serverData['gms_server'])) {
             $options = array();
             if (isset($serverData['gms_user'], $serverData['gms_password'])) {
                 $options['auth'] = 'login';
                 $options['username'] = $serverData['gms_user'];
                 $options['password'] = $this->project->decrypt($serverData['gms_password'], $serverData['gms_encryption']);
             }
             if (isset($serverData['gms_port'])) {
                 $options['port'] = $serverData['gms_port'];
             }
             if (isset($serverData['gms_ssl'])) {
                 switch ($serverData['gms_ssl']) {
                     case self::MAIL_SSL:
                         $options['ssl'] = 'ssl';
                         break;
                     case self::MAIL_TLS:
                         $options['ssl'] = 'tls';
                         break;
                     default:
                         // intentional fall through
                 }
             }
             self::$mailServers[$from] = new \Zend_Mail_Transport_Smtp($serverData['gms_server'], $options);
         } else {
             self::$mailServers[$from] = $this->getDefaultTransport();
         }
     }
     return self::$mailServers[$from];
 }
 /**
  * Shows a support page
  */
 public function supportAction()
 {
     $this->initHtml();
     $this->html->h3($this->_('Support'));
     $this->html->pInfo()->sprintf($this->_('There is more than one way to get support for %s.'), $this->project->getName());
     if ($url = $this->project->getDocumentationUrl()) {
         $this->html->h4($this->_('Documentation'));
         $this->html->pInfo()->sprintf($this->_('All available documentation is gathered at: %s'))->a($url, array('rel' => 'external', 'target' => 'documentation'));
     }
     if ($url = $this->project->getManualUrl()) {
         $this->html->h4($this->_('Manual'));
         $this->html->pInfo()->sprintf($this->_('The manual is available here: %s'))->a($url, array('rel' => 'external', 'target' => 'manual'));
     }
     if ($url = $this->project->getForumUrl()) {
         $this->html->h4($this->_('The forum'));
         $this->html->pInfo()->sprintf($this->_('You will find questions asked by other users and ask new questions at our forum site: %s'))->a($url, array('rel' => 'external', 'target' => 'forum'));
     }
     if ($url = $this->project->getSupportUrl()) {
         $this->html->h4($this->_('Support site'));
         $this->html->pInfo()->sprintf($this->_('Check our support site at %s.'))->a($url, array('rel' => 'external', 'target' => 'support'));
     }
     $this->html->h4($this->_('Or contact'));
     $this->html->append($this->_getOrganizationsList());
 }
예제 #25
0
 /**
  * Handle sending responses to the response database (if used)
  *
  * Triggered by checkTokenCompletion
  *
  * @param int $userId The id of the gems user
  */
 protected function toResponseDatabase($userId)
 {
     $db = $this->project->getResponseDatabase();
     // WHY EXPLANATION!!
     //
     // For some reason mysql prepared parameters do nothing with a \Zend_Db_Expr
     // object and that causes an error when using CURRENT_TIMESTAMP
     $current = \MUtil_Date::now()->toString(\Gems_Tracker::DB_DATETIME_FORMAT);
     $rValues = array('gdr_id_token' => $this->_tokenId, 'gdr_changed' => $current, 'gdr_changed_by' => $userId, 'gdr_created' => $current, 'gdr_created_by' => $userId);
     $responses = $this->getRawAnswers();
     unset($responses['token'], $responses['id'], $responses['lastpage'], $responses['startlanguage'], $responses['submitdate'], $responses['startdate'], $responses['datestamp']);
     // first read current responses to differentiate between insert and update
     $responseSelect = $db->select()->from('gemsdata__responses', array('gdr_answer_id', 'gdr_response'))->where('gdr_id_token = ?', $this->_tokenId);
     $currentResponses = $db->fetchPairs($responseSelect);
     if (!$currentResponses) {
         $currentResponses = array();
     }
     // \MUtil_Echo::track($currentResponses, $responses);
     // Prepare sql
     $sql = "UPDATE gemsdata__responses\n            SET `gdr_response` = ?, `gdr_changed` = ?, `gdr_changed_by` = ?\n            WHERE gdr_id_token = ? AND gdr_answer_id = ? AND gdr_answer_row = 1";
     $stmt = $db->prepare($sql);
     $inserts = array();
     foreach ($responses as $fieldName => $response) {
         $rValues['gdr_answer_id'] = $fieldName;
         if (is_array($response)) {
             $response = join('|', $response);
         }
         $rValues['gdr_response'] = $response;
         if (array_key_exists($fieldName, $currentResponses)) {
             // Already exists, do update
             // But only if value changed
             if ($currentResponses[$fieldName] != $response) {
                 try {
                     // \MUtil_Echo::track($sql, $rValues['gdr_id_token'], $fieldName, $response);
                     $stmt->execute(array($response, $rValues['gdr_changed'], $rValues['gdr_changed_by'], $rValues['gdr_id_token'], $fieldName));
                 } catch (\Zend_Db_Statement_Exception $e) {
                     error_log($e->getMessage());
                     \Gems_Log::getLogger()->logError($e);
                 }
             }
         } else {
             // We add the inserts together in the next prepared statement to improve speed
             $inserts[$fieldName] = $rValues;
         }
     }
     if (count($inserts) > 0) {
         // \MUtil_Echo::track($inserts);
         try {
             $fields = array_keys(reset($inserts));
             $fields = array_map(array($db, 'quoteIdentifier'), $fields);
             $sql = 'INSERT INTO gemsdata__responses (' . implode(', ', $fields) . ') VALUES (' . implode(', ', array_fill(1, count($fields), '?')) . ')';
             // \MUtil_Echo::track($sql);
             $stmt = $db->prepare($sql);
             foreach ($inserts as $insert) {
                 // \MUtil_Echo::track($insert);
                 $stmt->execute($insert);
             }
         } catch (\Zend_Db_Statement_Exception $e) {
             error_log($e->getMessage());
             \Gems_Log::getLogger()->logError($e);
         }
     }
 }
예제 #26
0
 /**
  * Check: is this user the super user defined
  * in project.ini?
  *
  * @param string $login_name
  * @return boolean
  */
 protected function isProjectUser($login_name)
 {
     return $this->project->getSuperAdminName() == $login_name;
 }
 /**
  * Return a hashed version of the input value.
  *
  * @param mixed $value The value being saved
  * @param boolean $isNew True when a new item is being saved
  * @param string $name The name of the current field
  * @param array $context Optional, the other values being saved
  * @return string The salted hash as a 32-character hexadecimal number.
  */
 public function saveSSN($value, $isNew = false, $name = null, array $context = array())
 {
     if ($value) {
         return $this->project->getValueHash($value, $this->hashAlgorithm);
     }
 }
 /**
  * Allow overruling of password hashing.
  *
  * @param string $password
  * @return string
  */
 protected function hashNewPassword($password)
 {
     return $this->project->getValueHash($password);
 }
 /**
  * Get the directory to use as the root for automatic import
  *
  * @return string
  */
 public function getFileImportRoot()
 {
     return $this->project->getFileImportRoot();
 }
 /**
  * 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();
     $survey = null;
     $translated = $this->util->getTranslated();
     $yesNo = $translated->getYesNo();
     if ($detailed) {
         $surveyId = $this->_getIdParam();
         if ($surveyId) {
             $survey = $this->loader->getTracker()->getSurvey($surveyId);
         }
     }
     $model = new \Gems_Model_JoinModel('surveys', 'gems__surveys', 'gus');
     $model->addTable('gems__sources', array('gsu_id_source' => 'gso_id_source'));
     $model->setCreate(false);
     $model->addColumn("CASE WHEN gsu_survey_pdf IS NULL OR CHAR_LENGTH(gsu_survey_pdf) = 0 THEN 0 ELSE 1 END", 'gsu_has_pdf');
     $model->addColumn(sprintf("CASE WHEN (gsu_status IS NULL OR gsu_status = '') THEN '%s' ELSE gsu_status END", $this->_('OK')), 'gsu_status_show', 'gsu_status');
     $model->addColumn("CASE WHEN gsu_surveyor_active THEN '' ELSE 'deleted' END", 'row_class');
     $model->resetOrder();
     $model->set('gsu_survey_name', 'label', $this->_('Name'), 'elementClass', 'Exhibitor');
     $model->set('gsu_survey_description', 'label', $this->_('Description'), 'elementClass', 'Exhibitor', 'formatFunction', array(__CLASS__, 'formatDescription'));
     $model->set('gso_source_name', 'label', $this->_('Source'), 'elementClass', 'Exhibitor');
     $model->set('gsu_surveyor_active', 'label', $this->_('Active in source'), 'elementClass', 'Exhibitor', 'multiOptions', $yesNo);
     $model->set('gsu_status_show', 'label', $this->_('Status in source'), 'elementClass', 'Exhibitor');
     $model->set('gsu_active', 'label', sprintf($this->_('Active in %s'), $this->project->getName()), 'elementClass', 'Checkbox', 'multiOptions', $yesNo);
     $model->set('gsu_id_primary_group', 'label', $this->_('Group'), 'description', $this->_('If empty, survey will never show up!'), 'multiOptions', $dbLookup->getGroups());
     if ($detailed) {
         $model->addDependency('CanEditDependency', 'gsu_surveyor_active', array('gsu_active'));
         $model->set('gsu_active', 'validators[group]', new \MUtil_Validate_Require($model->get('gsu_active', 'label'), 'gsu_id_primary_group', $model->get('gsu_id_primary_group', 'label')));
     }
     $model->set('gsu_insertable', 'label', $this->_('Insertable'), 'description', $this->_('Can this survey be manually inserted into a track?'), 'elementClass', 'Checkbox', 'multiOptions', $yesNo, 'onclick', 'this.form.submit()');
     if ($detailed) {
         $model->set('gsu_valid_for_length', 'label', $this->_('Add to inserted end date'), 'description', $this->_('Add to the start date to calculate the end date when inserting.'), 'filter', 'Int');
         $model->set('gsu_valid_for_unit', 'label', $this->_('Inserted end date unit'), 'description', $this->_('The unit used to calculate the end date when inserting the survey.'), 'multiOptions', $translated->getPeriodUnits());
         $model->set('gsu_insert_organizations', 'label', $this->_('Insert organizations'), 'description', $this->_('The organizations where the survey may be inserted.'), 'elementClass', 'MultiCheckbox', 'multiOptions', $dbLookup->getOrganizations(), 'required', true);
         $ct = new \MUtil_Model_Type_ConcatenatedRow('|', $this->_(', '));
         $ct->apply($model, 'gsu_insert_organizations');
         //            if ('edit' == $action) {
         //                $element = new \Gems_JQuery_Form_Element_ToggleCheckboxes('toggleOrg', array('selector'=>'input[name^=gtr_organizations]'));
         //                $element->setLabel($this->_('Toggle'));
         //                $model->set('toggleOrg', 'elementClass', $element);
         //            }
         $switches = array(0 => array('gsu_valid_for_length' => array('elementClass' => 'Hidden', 'label' => null), 'gsu_valid_for_unit' => array('elementClass' => 'Hidden', 'label' => null), 'gsu_insert_organizations' => array('elementClass' => 'Hidden', 'label' => null)));
         $model->addDependency(array('ValueSwitchDependency', $switches), 'gsu_insertable');
     }
     if ($detailed) {
         $model->set('track_usage', 'label', $this->_('Usage'), 'elementClass', 'Exhibitor', 'noSort', true, 'no_text_search', true);
         $model->setOnLoad('track_usage', array($this, 'calculateTrackUsage'));
         $model->set('calc_duration', 'label', $this->_('Duration calculated'), 'elementClass', 'Html');
         $model->setOnLoad('calc_duration', array($this, 'calculateDuration'));
         $model->set('gsu_duration', 'label', $this->_('Duration description'), 'description', $this->_('Text to inform the respondent, e.g. "20 seconds" or "1 minute".'));
         if ($survey instanceof \Gems_Tracker_Survey) {
             $surveyFields = $this->util->getTranslated()->getEmptyDropdownArray() + $survey->getQuestionList($this->locale->getLanguage());
             $model->set('gsu_result_field', 'label', $this->_('Result field'), 'multiOptions', $surveyFields);
             // $model->set('gsu_agenda_result',         'label', $this->_('Agenda field'));
         }
     } else {
         $model->set('track_count', 'label', ' ', 'elementClass', 'Exhibitor', 'noSort', true, 'no_text_search', true);
         $model->setOnLoad('track_count', array($this, 'calculateTrackCount'));
     }
     $model->set('gsu_code', 'label', $this->_('Survey code'), 'description', $this->_('Optional code name to link the survey to program code.'), 'size', 10);
     $model->set('gsu_export_code', 'label', $this->_('Survey export code'), 'description', $this->_('A unique code indentifying this survey during track import'), 'size', 20);
     if ($detailed) {
         $events = $this->loader->getEvents();
         $beforeOptions = $events->listSurveyBeforeAnsweringEvents();
         if (count($beforeOptions) > 1) {
             $model->set('gsu_beforeanswering_event', 'label', $this->_('Before answering'), 'multiOptions', $beforeOptions, 'elementClass', 'Select');
         }
         $completedOptions = $events->listSurveyCompletionEvents();
         if (count($completedOptions) > 1) {
             $model->set('gsu_completed_event', 'label', $this->_('After completion'), 'multiOptions', $completedOptions, 'elementClass', 'Select');
         }
         $displayOptions = $events->listSurveyDisplayEvents();
         if (count($displayOptions) > 1) {
             $model->set('gsu_display_event', 'label', $this->_('Answer display'), 'multiOptions', $displayOptions, 'elementClass', 'Select');
         }
         if ('show' !== $action || $survey->hasPdf()) {
             // Only the action changes from the current page
             // and the right to see the pdf is the same as
             // the right to see this page.
             $pdfLink = \MUtil_Html::create('a', array($this->getRequest()->getActionKey() => 'pdf'), array('class' => 'pdf', 'target' => '_blank', 'type' => 'application/pdf', 'onclick' => 'event.cancelBubble = true;'));
             $model->set('gsu_survey_pdf', 'label', 'Pdf', 'accept', 'application/pdf', 'destination', $this->loader->getPdf()->getUploadDir('survey_pdfs'), 'elementClass', 'File', 'extension', 'pdf', 'filename', $surveyId, 'required', false, 'itemDisplay', $pdfLink, 'validators[pdf]', new \MUtil_Validate_Pdf());
         }
     }
     return $model;
 }