/** * This function is called in addBrowseTableColumns() to filter the names displayed * by AnswerModelSnippetGeneric. * * @see \Gems_Tracker_Snippets_AnswerModelSnippetGeneric * * @param \MUtil_Model_Bridge_TableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @param array $currentNames The current names in use (allows chaining) * @return array Of the names of labels that should be shown */ public function filterAnswers(\MUtil_Model_Bridge_TableBridge $bridge, \MUtil_Model_ModelAbstract $model, array $currentNames) { $repeater = $model->loadRepeatable(); $table = $bridge->getTable(); $table->setRepeater($repeater); // Filter unless option 'fullanswers' is true, can be set as get or post var. $requestFullAnswers = \Zend_Controller_Front::getInstance()->getRequest()->getParam('fullanswers', false); if (!$repeater->__start()) { return $currentNames; } $keys = array(); if ($requestFullAnswers !== false) { // No filtering return $model->getItemsOrdered(); } else { foreach ($model->getItemNames() as $name) { $start = substr(strtolower($name), 0, $this->IncludeLength); if (in_array($start, $this->IncludeStarts)) { $keys[$name] = $name; } } } $answers = $this->token->getRawAnswers(); // Prevent errors when no answers present if (!empty($answers)) { $results = array_intersect($currentNames, array_keys($keys), array_keys($answers)); } else { $results = array_intersect($currentNames, array_keys($keys)); } $results = $this->restoreHeaderPositions($model, $results); if ($results) { return $results; } return $this->getHeaders($model, $currentNames); }
/** * Adds columns from the model to the bridge that creates the browse table. * * Overrule this function to add different columns to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_TableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @return void */ protected function addBrowseTableColumns(\MUtil_Model_Bridge_TableBridge $bridge, \MUtil_Model_ModelAbstract $model) { $model->set('gto_id_token', 'formatFunction', 'strtoupper'); $bridge->setDefaultRowClass(\MUtil_Html_TableElement::createAlternateRowClass('even', 'even', 'odd', 'odd')); $tr1 = $bridge->tr(); $tr1->appendAttrib('class', $bridge->row_class); $tr1->appendAttrib('title', $bridge->gto_comment); $bridge->addColumn($this->createShowTokenButton($bridge), ' ')->rowspan = 2; // Space needed because TableElement does not look at rowspans $bridge->addSortable('gto_valid_from'); $bridge->addSortable('gto_valid_until'); $bridge->addSortable('gto_id_token'); // $bridge->addSortable('gto_mail_sent_num', $this->_('Contact moments'))->rowspan = 2; $this->addRespondentCell($bridge, $model); $bridge->addMultiSort('ggp_name', array($this->createActionButtons($bridge))); $tr2 = $bridge->tr(); $tr2->appendAttrib('class', $bridge->row_class); $tr2->appendAttrib('title', $bridge->gto_comment); $bridge->addSortable('gto_mail_sent_date'); $bridge->addSortable('gto_completion_time'); $bridge->addSortable('gto_mail_sent_num', $this->_('Contact moments')); if ($this->multiTracks) { $model->set('gr2t_track_info', 'tableDisplay', 'smallData'); $model->set('gto_round_description', 'tableDisplay', 'smallData'); $bridge->addMultiSort('gtr_track_name', 'gr2t_track_info', array($bridge->gtr_track_name->if(\MUtil_Html::raw(' » ')), ' '), 'gsu_survey_name', 'gto_round_description'); } else { $bridge->addMultiSort('gto_round_description', \MUtil_Html::raw('; '), 'gsu_survey_name'); } $bridge->addSortable('assigned_by'); }
/** * Returns a text element for autosearch. Can be overruled. * * The form / html elements to search on. Elements can be grouped by inserting null's between them. * That creates a distinct group of elements * * @param array $data The $form field values (can be usefull, but no need to set them) * @return array Of \Zend_Form_Element's or static tekst to add to the html or null for group breaks. */ protected function getAutoSearchElements(array $data) { $elements = parent::getAutoSearchElements($data); $user = $this->loader->getCurrentUser(); if ($user->hasPrivilege('pr.respondent.select-on-track')) { $tracks = $this->searchData['__active_tracks']; $masks['show_all'] = $this->_('(all)'); $masks['show_without_track'] = $this->_('(no track)'); if (count($tracks) > 1) { $masks['show_with_track'] = $this->_('(with track)'); } if (count($tracks) > 1) { $elements[] = $this->_createSelectElement('gr2t_id_track', $masks + $tracks); } else { $element = $this->_createRadioElement('gr2t_id_track', $masks + $tracks); $element->setSeparator(' '); $elements[] = $element; } $lineBreak = true; } else { $lineBreak = false; } if ($user->hasPrivilege('pr.respondent.show-deleted')) { $elements[] = $this->_createCheckboxElement('grc_success', $this->_('Show active')); } if ($this->model->isMultiOrganization()) { $element = $this->_createSelectElement(\MUtil_Model::REQUEST_ID2, $user->getRespondentOrganizations(), $this->_('(all organizations)')); if ($lineBreak) { $element->setLabel($this->_('Organization'))->setAttrib('onchange', 'this.form.submit();'); $elements[] = \MUtil_Html::create('br'); } $elements[] = $element; } return $elements; }
/** * 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)); } } }
/** * Overrule to implement snippet specific filtering and sorting. * * @param \MUtil_Model_ModelAbstract $model */ protected function processFilterAndSort(\MUtil_Model_ModelAbstract $model) { $filter[] = $this->db->quoteInto("gr2t_id_respondent_track IN (\n SELECT gr2t2a_id_respondent_track\n FROM gems__respondent2track2appointment\n WHERE gr2t2a_id_appointment = ?)", $this->request->getParam(\Gems_Model::APPOINTMENT_ID)); // \MUtil_Model::$verbose = true; $model->setFilter($filter); $this->processSortOnly($model); }
/** * Adds elements from the model to the bridge that creates the form. * * Overrule this function to add different elements to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_FormBridgeInterface $bridge * @param \MUtil_Model_ModelAbstract $model */ protected function addFormElements(\MUtil_Model_Bridge_FormBridgeInterface $bridge, \MUtil_Model_ModelAbstract $model) { if (!$this->createData) { $bridge->addHidden('gtr_id_track'); } $bridge->addText('gtr_track_name'); // gtr_track_class if ($this->trackEngine) { $options = $model->get('gtr_track_class', 'multiOptions'); $alternatives = $this->trackEngine->getConversionTargets($options); if (count($alternatives) > 1) { $options = $alternatives; $bridge->addHidden($this->_oldClassName); if (!isset($this->formData[$this->_oldClassName])) { $this->formData[$this->_oldClassName] = $this->formData['gtr_track_class']; } $classEdit = true; } else { $classEdit = false; } } else { $tracker = $this->loader->getTracker(); $options = $tracker->getTrackEngineList(true, true); $classEdit = true; } $model->set('gtr_track_class', 'multiOptions', $options, 'escape', false); if ($classEdit) { $bridge->addRadio('gtr_track_class'); } else { $bridge->addExhibitor('gtr_track_class'); } $bridge->addDate('gtr_date_start'); $bridge->addDate('gtr_date_until'); if (!$this->createData) { $bridge->addCheckbox('gtr_active'); } if ($model->has('gtr_code')) { $bridge->addText('gtr_code'); } if ($model->has('gtr_calculation_event', 'label')) { $bridge->add('gtr_calculation_event'); } if ($model->has('gtr_completed_event', 'label')) { $bridge->add('gtr_completed_event'); } if ($model->has('gtr_beforefieldupdate_event', 'label')) { $bridge->add('gtr_beforefieldupdate_event'); } if ($model->has('gtr_fieldupdate_event', 'label')) { $bridge->add('gtr_fieldupdate_event'); } $bridge->add('gtr_organizations'); if (\MUtil_Bootstrap::enabled()) { $element = new \MUtil_Bootstrap_Form_Element_ToggleCheckboxes('toggleOrg', array('selector' => 'input[name^=gtr_organizations]')); } else { $element = new \Gems_JQuery_Form_Element_ToggleCheckboxes('toggleOrg', array('selector' => 'input[name^=gtr_organizations]')); } $element->setLabel($this->_('Toggle')); $bridge->addElement($element); }
/** * Creates the model * * @return \MUtil_Model_ModelAbstract */ protected function createModel() { if (!$this->model instanceof LogModel) { $this->model = $this->loader->getModels()->createLogModel(); $this->model->applyBrowseSettings(); } return $this->model; }
private function _addIf(array $names, \MUtil_Model_Bridge_VerticalTableBridge $bridge, \MUtil_Model_ModelAbstract $model) { foreach ($names as $name) { if ($model->has($name, 'label')) { $bridge->addItem($name); } } }
/** * Adds columns from the model to the bridge that creates the browse table. * * Overrule this function to add different columns to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_TableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @return void */ protected function addBrowseTableColumns(\MUtil_Model_Bridge_TableBridge $bridge, \MUtil_Model_ModelAbstract $model) { $bridge->gr2t_id_respondent_track; // Data needed for edit button $bridge->gr2o_id_organization; // Data needed for edit button $HTML = \MUtil_Html::create(); // Get the buttons $respMenu = $this->menu->findAllowedController('respondent', 'show'); if ($respMenu) { $respondentButton = $respMenu->toActionLink($this->request, $bridge, $this->_('Show respondent')); $respondentButton->appendAttrib('class', 'rightFloat'); } else { $respondentButton = null; } $trackMenu = $this->menu->findAllowedController('respondent', 'show-track'); if ($trackMenu) { $trackButton = $trackMenu->toActionLink($this->request, $bridge, $this->_('Show track')); $trackButton->appendAttrib('class', 'rightFloat'); } else { $trackButton = null; } // Row with dates and patient data $bridge->tr(array('onlyWhenChanged' => true, 'class' => 'even')); $bridge->addSortable('gr2o_patient_nr'); $bridge->addSortable('respondent_name')->colspan = 2; if ($this->multiTracks) { $bridge->addSortable('grs_birthday'); $bridge->addMultiSort('grs_city', array($respondentButton)); $model->set('gr2t_track_info', 'tableDisplay', 'smallData'); // Row with track info $bridge->tr(array('onlyWhenChanged' => true, 'class' => 'even')); $td = $bridge->addMultiSort('gtr_track_name', 'gr2t_track_info'); $td->class = 'indentLeft'; $td->colspan = 4; $td->renderWithoutContent = false; // Do not display this cell and thus this row if there is not content $td = $bridge->addMultiSort('progress', array($trackButton)); $td->renderWithoutContent = false; // Do not display this cell and thus this row if there is not content } else { $bridge->addSortable('grs_birthday'); $bridge->addMultiSort('progress', array($respondentButton)); } $bridge->tr(array('class' => array('odd', $bridge->row_class), 'title' => $bridge->gto_comment)); $bridge->addColumn($this->createShowTokenButton($bridge))->class = 'rightAlign'; $bridge->addSortable('gto_valid_from'); $bridge->addSortable('gto_valid_until'); $model->set('gto_round_description', 'tableDisplay', 'smallData'); $bridge->addMultiSort('gsu_survey_name', 'gto_round_description')->colspan = 2; $bridge->tr(array('class' => array('odd', $bridge->row_class), 'title' => $bridge->gto_comment)); $bridge->addColumn(); $bridge->addSortable('gto_mail_sent_date'); $bridge->addSortable('gto_completion_time'); $bridge->addSortable('gto_id_token'); $bridge->addMultiSort('ggp_name', array($this->createActionButtons($bridge))); }
/** * Overrule to implement snippet specific filtering and sorting. * * @param \MUtil_Model_ModelAbstract $model */ protected function processFilterAndSort(\MUtil_Model_ModelAbstract $model) { if ($this->request->getParam('log')) { $model->setFilter(array('gla_id'), $this->request->getParam('log')); parent::processSortOnly($model); } else { parent::processFilterAndSort($model); } }
/** * Appends the needed fields for this config to the $bridge * * @param \MUtil_Model_ModelAbstract $orgModel */ public function addConfigFields(\MUtil_Model_ModelAbstract $orgModel) { $configModel = $this->getConfigModel(true); $order = $orgModel->getOrder('gor_user_class') + 1; foreach ($configModel->getItemNames() as $name) { $orgModel->set($name, 'order', $order++, 'tab', 'access'); $orgModel->set($name, $configModel->get($name)); } }
/** * 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 * * @param array $row Row to save */ public function execute($row = null) { if ($row) { $batch = $this->getBatch(); $batch->addToCounter('imported'); // \MUtil_Echo::track($row); $this->targetModel->save($row); $batch->addToCounter('changed', $this->targetModel->getChanged()); } }
/** * Adds elements from the model to the bridge that creates the form. * * Overrule this function to add different elements to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_FormBridgeInterface $bridge * @param \MUtil_Model_ModelAbstract $model */ protected function addFormElements(\MUtil_Model_Bridge_FormBridgeInterface $bridge, \MUtil_Model_ModelAbstract $model) { $onOffFields = array('gr2t_track_info', 'gto_round_description', 'grc_description'); foreach ($onOffFields as $field) { if (!(isset($this->formData[$field]) && $this->formData[$field])) { $model->set($field, 'elementClass', 'None'); } } parent::addFormElements($bridge, $model); }
/** * Adds rows from the model to the bridge that creates the browse table. * * Overrule this function to add different columns to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_VerticalTableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @return void * / protected function addShowTableRows(\MUtil_Model_Bridge_VerticalTableBridge $bridge, \MUtil_Model_ModelAbstract $model) { parent::addShowTableRows($bridge, $model); } /** * Creates the model * * @return \MUtil_Model_ModelAbstract */ protected function createModel() { if (!$this->model instanceof \Gems_Model_AppointmentModel) { $this->model = $this->loader->getModels()->createAppointmentModel(); $this->model->applyDetailSettings(); } $this->model->set('gap_admission_time', 'formatFunction', array($this, 'displayDate')); $this->model->set('gap_discharge_time', 'formatFunction', array($this, 'displayDate')); return $this->model; }
/** * Construct the bridge while setting the model. * * Extra parameters can be added in subclasses, but the first parameter * must remain the model. * * @param \MUtil_Model_ModelAbstract $model * @param \Zend_Form $form Rquired */ public function __construct(\MUtil_Model_ModelAbstract $model, \Zend_Form $form = null) { $this->model = $model; $this->form = $form; if (!$form instanceof \Zend_Form) { throw new \MUtil_Model_ModelException("No form specified while create a form bridge for model " . $model->getName()); } if (!$form->getName()) { $form->setName($model->getName()); } }
/** * Set the surveys to be listed as valid for choices for this item and the way they are displayed (if at all) * * @param \MUtil_Model_ModelAbstract $model The round model * @param array $itemData The current items data * @param boolean True if the update changed values (usually by changed selection lists). */ protected function applySurveyListValidFor(\MUtil_Model_ModelAbstract $model, array &$itemData) { if (!(isset($itemData['gro_id_round']) && $itemData['gro_id_round'])) { $itemData['gro_id_round'] = ''; } // Fixed value $itemData['gro_valid_for_id'] = $itemData['gro_id_round']; // The options array $rounds[$itemData['gro_id_round']] = $this->_('This round'); $model->set('gro_valid_for_id', 'multiOptions', $rounds, 'elementClass', 'Exhibitor'); return false; }
/** * Creates the model * * @return \MUtil_Model_ModelAbstract */ protected function createModel() { // Replace two checkboxes with on radio button control $this->model->set('ggp_staff_members', 'elementClass', 'Hidden'); $this->model->setOnSave('ggp_staff_members', array($this, 'saveIsStaff')); $this->model->set('ggp_respondent_members', 'elementClass', 'Hidden'); $this->model->setOnSave('ggp_respondent_members', array($this, 'saveIsRespondent')); $options = array('1' => $this->model->get('ggp_staff_members', 'label'), '2' => $this->model->get('ggp_respondent_members', 'label')); $this->model->set('staff_respondent', 'label', $this->_('Can be assigned to'), 'elementClass', 'Radio', 'multiOptions', $options, 'order', $this->model->getOrder('ggp_staff_members') + 1); $this->model->setOnLoad('staff_respondent', array($this, 'loadStaffRespondent')); return $this->model; }
/** * Restores the header position of question before their corresponding question_sub * * When sub-questions with the same parent are shown continuous the parent is shown * once before them. When the sub-questions are displayed in seperate groups the * parent is shown once at their start. * * Stand alone headers without any corresponding value are removed. When they do have * a value of their own they are still shown, but their position may change according * to their sub-questions position. (NOTE: As in LimeSurvey their are no question * headers with values we leave it at this for the moment.) * * @param \MUtil_Model_ModelAbstract $model * @param array $currentNames The current names in use (allows chaining) * @return array Of the names of labels that should be shown */ protected function restoreHeaderPositions(\MUtil_Model_ModelAbstract $model, array $currentNames) { $lastParent = null; $results = array(); foreach ($currentNames as $name) { if ($model->is($name, 'type', \MUtil_Model::TYPE_NOVALUE)) { // Skip header types that contain no value continue; } if ($parent = $model->get($name, 'parent_question')) { // Check for change of parent if ($lastParent !== $parent) { if (isset($results[$parent])) { // Add another copy of the parent to the array $results[] = $parent; } else { // Insert parent header on name if it was not shown before $results[$parent] = $parent; } $lastParent = $parent; } } else { // Make sure a question (without parent) is picked up as parent too $lastParent = $name; } // If already set (as a $parent) this will not // redisplay the $parent as $result[$name] does // not change position $results[$name] = $name; } return $results; }
/** * 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() { $reqFilter = $this->request->getParam('filter'); switch ($reqFilter) { case 'todo': //Only actions valid now that are not already done $filter[] = 'gto_completion_time IS NULL'; $filter[] = 'gto_valid_from <= CURRENT_TIMESTAMP'; $filter[] = '(gto_valid_until IS NULL OR gto_valid_until >= CURRENT_TIMESTAMP)'; break; case 'done': //Only completed actions $filter[] = 'gto_completion_time IS NOT NULL'; break; case 'missed': //Only missed actions (not filled in, valid until < today) $filter[] = 'gto_completion_time IS NULL'; $filter[] = 'gto_valid_until < CURRENT_TIMESTAMP'; break; case 'all': $filter[] = 'gto_valid_from IS NOT NULL'; break; default: //2 weeks look ahead, valid from date is set $filter[] = 'gto_valid_from IS NOT NULL'; $filter[] = 'DATEDIFF(gto_valid_from, CURRENT_TIMESTAMP) < 15'; $filter[] = '(gto_valid_until IS NULL OR gto_valid_until >= CURRENT_TIMESTAMP)'; } $this->model->setMeta('tab_filter', $filter); return parent::hasHtmlOutput(); }
/** * Overrule to implement snippet specific filtering and sorting. * * @param \MUtil_Model_ModelAbstract $model */ protected function processFilterAndSort(\MUtil_Model_ModelAbstract $model) { $filter['gto_id_respondent'] = $this->respondent->getId(); if (is_array($this->forOtherOrgs)) { $filter['gto_id_organization'] = $this->forOtherOrgs; } elseif (true !== $this->forOtherOrgs) { $filter['gto_id_organization'] = $this->respondent->getOrganizationId(); } // Filter for valid track reception codes $filter[] = 'gr2t_reception_code IN (SELECT grc_id_reception_code FROM gems__reception_codes WHERE grc_success = 1)'; $filter['grc_success'] = 1; // Active round // or // no round // or // token is success and completed $filter[] = 'gro_active = 1 OR gro_active IS NULL OR (grc_success=1 AND gto_completion_time IS NOT NULL)'; $filter['gsu_active'] = 1; // NOTE! $this->model does not need to be the token model, but $model is a token model $tabFilter = $this->model->getMeta('tab_filter'); if ($tabFilter) { $model->addFilter($tabFilter); } $model->addFilter($filter); // \MUtil_Echo::track($model->getFilter()); $this->processSortOnly($model); }
/** * Creates the model * * @return \MUtil_Model_ModelAbstract */ protected function createModel() { if (!$this->model instanceof \Gems_Model_StaffModel) { $this->model = $this->loader->getModels()->getStaffModel(false); $this->model->applyOwnAccountEdit(); } return $this->model; }
/** * Use this function for a default application of this type to the model * * @param \MUtil_Model_ModelAbstract $model * @param string $valueField The field containing the value to be encrypted * #param string $methodField the field storing the method of encryption * @return \Gems_Model_Type_EncryptedField (continuation pattern) */ public function apply(\MUtil_Model_ModelAbstract $model, $valueField, $methodField) { $this->findValue[$methodField] = $valueField; $model->setSaveWhenNotNull($valueField); $model->setOnLoad($valueField, array($this, 'loadValue')); $model->setOnSave($valueField, array($this, 'saveValue')); // Only hidden to make sure onSave's are triggered $model->set($methodField, 'elementClass', 'hidden'); $model->setOnLoad($methodField, 'default'); // Yes you can set this to a constant $model->setSaveWhen($methodField, array($this, 'whenEncryption')); $model->setOnSave($methodField, array($this, 'saveEncryption')); if ($model instanceof \MUtil_Model_DatabaseModelAbstract) { $model->setOnTextFilter($valueField, false); $model->setOnTextFilter($methodField, false); } return $this; }
/** * The transform function performs the actual transformation of the data and is called after * the loading of the data in the source model. * * @param \MUtil_Model_ModelAbstract $model The parent model * @param array $data Nested array * @param boolean $new True when loading a new item * @param boolean $isPostData With post data, unselected multiOptions values are not set so should be added * @return array Nested array containing (optionally) transformed data */ public function transformLoad(\MUtil_Model_ModelAbstract $model, array $data, $new = false, $isPostData = false) { // get tokens $tokens = \MUtil_Ra::column('gto_id_token', $data); $answerRows = $this->source->getRawTokenAnswerRows(array('token' => $tokens), $this->survey->getSurveyId()); $resultRows = array(); $emptyRow = array_fill_keys($model->getItemNames(), null); foreach ($data as $row) { $tokenId = $row['gto_id_token']; if (isset($answerRows[$tokenId])) { $resultRows[$tokenId] = $row + $answerRows[$tokenId] + $emptyRow; } else { $resultRows[$tokenId] = $row + $emptyRow; } } //\MUtil_Echo::track($tokens); //\MUtil_Echo::track($resultRows); // No changes return $resultRows; }
/** * Adds columns from the model to the bridge that creates the browse table. * * Overrule this function to add different columns to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_TableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @return void */ protected function addBrowseTableColumns(\MUtil_Model_Bridge_TableBridge $bridge, \MUtil_Model_ModelAbstract $model) { // $bridge->getTable()->setAlternateRowClass('odd', 'odd', 'even', 'even'); // \MUtil_Model::$verbose = true; $bridge->add('gro_round_description', $bridge->createSortLink('gro_id_order', $model->get('gro_round_description', 'label'))); $bridge->addSortable('gsu_survey_name'); $bridge->th(array($bridge->createSortLink('answered'), 'colspan' => 2))->class = 'centerAlign'; $bridge->td($bridge->answered)->class = 'centerAlign'; $bridge->td($this->percentageLazy($bridge->answered, $bridge->total))->class = 'rightAlign'; $bridge->th(array($bridge->createSortLink('missed'), 'colspan' => 2))->class = 'centerAlign'; $bridge->td($bridge->missed)->class = 'centerAlign'; $bridge->td($this->percentageLazy($bridge->missed, $bridge->total))->class = 'rightAlign'; $bridge->th(array($bridge->createSortLink('open'), 'colspan' => 2))->class = 'centerAlign'; $bridge->td($bridge->open)->class = 'centerAlign'; $bridge->td($this->percentageLazy($bridge->open, $bridge->total))->class = 'rightAlign'; // $bridge->addSortable('answered'); // $bridge->addSortable('missed'); // $bridge->addSortable('open'); // $bridge->add('future'); // $bridge->add('unknown'); $bridge->addColumn(array('=', 'class' => 'centerAlign')); $bridge->addSortable('total'); $bridge->addSortable('gsu_id_primary_group'); // $bridge->tr(); // $bridge->add('gsu_survey_name')->colspan = 4; // $bridge->add('gsu_id_primary_group')->colspan = 2; // $bridge->addColumn(); /* $bridge->addColumn( array( $bridge->gsu_survey_name, \MUtil_Html::create('em', ' - ', $bridge->gsu_id_primary_group) ), array( $model->get('gsu_survey_name', 'label'), \MUtil_Html::create('em', ' - ', $model->get('gsu_id_primary_group', 'label')) ) )->colspan = 7; $bridge->add('removed'); // */ }
/** * Adds rows from the model to the bridge that creates the browse table. * * Overrule this function to add different columns to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_VerticalTableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @return void */ protected function addShowTableRows(\MUtil_Model_Bridge_VerticalTableBridge $bridge, \MUtil_Model_ModelAbstract $model) { $items = $model->getItemsOrdered(); foreach ($items as $name) { if ($model->get($name, 'type') === \MUtil_Model::TYPE_CHILD_MODEL) { $this->submodel = $model->get($name, 'model'); $subitems = $this->submodel->getItemsOrdered(); } } if (isset($subitems) && is_array($subitems)) { $items = array_diff($items, $subitems); } foreach ($items as $name) { if ($label = $model->get($name, 'label')) { $bridge->addItem($name, $label); } } /*if ($subitems) { $bridge->addItem('gctt', 'moo'); }*/ if ($model->has('row_class')) { // Make sure deactivated rounds are show as deleted foreach ($bridge->getTable()->tbody() as $tr) { foreach ($tr as $td) { if ('td' === $td->tagName) { $td->appendAttrib('class', $bridge->row_class); } } } } }
/** * Adds columns from the model to the bridge that creates the browse table. * * Overrule this function to add different columns to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_TableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @return void */ protected function addBrowseTableColumns(\MUtil_Model_Bridge_TableBridge $bridge, \MUtil_Model_ModelAbstract $model) { if ($model->has('row_class')) { $bridge->getTable()->tbody()->getFirst(true)->appendAttrib('class', $bridge->row_class); } if ($editMenuItem = $this->getEditMenuItem()) { $bridge->addItemLink($editMenuItem->toActionLinkLower($this->request, $bridge)); } // make sure search results are highlighted $this->applyTextMarker(); if ($this->columns) { foreach ($this->columns as $column) { call_user_func_array(array($bridge, 'addMultiSort'), $column); } } elseif ($this->sortableLinks) { foreach ($model->getItemsOrdered() as $name) { if ($label = $model->get($name, 'label')) { $bridge->addSortable($name, $label); } } } else { foreach ($model->getItemsOrdered() as $name) { if ($label = $model->get($name, 'label')) { $bridge->add($name, $label); } } } if ($deleteMenuItem = $this->findMenuItem($this->request->getControllerName(), 'delete')) { $bridge->addItemLink($deleteMenuItem->toActionLinkLower($this->request, $bridge)); } }
/** * Creates the model * * @return \MUtil_Model_ModelAbstract */ protected function createModel() { if (!$this->model instanceof \Gems_Tracker_Model_TrackModel) { $tracker = $this->loader->getTracker(); $this->model = $tracker->getRespondentTrackModel(); if (!$this->trackEngine instanceof \Gems_Tracker_Engine_TrackEngineInterface) { $this->trackEngine = $this->respondentTrack->getTrackEngine(); } $this->model->applyEditSettings($this->trackEngine); } $this->model->set('restore_tokens', 'label', $this->_('Restore tokens'), 'description', $this->_('Restores tokens with the same code as the track.'), 'elementClass', 'Checkbox'); return $this->model; }
/** * 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 * @param array $context * @return boolean * @throws \Zend_Validate_Exception If validation of $value is impossible */ public function isValid($value, $context = array()) { $this->_setValue($value); // Make sure the (optionally filtered) value is in the context $context[reset($this->_fields)] = $value; $filter = array(); foreach ($this->_fields as $name) { // Return valid when not all the fields to check for are in the context if (!isset($context[$name])) { return true; } $filter[$name] = $context[$name]; } $check = array(); $doGet = $this->_model->hasItemsUsed(); $keys = $this->_model->getKeys(); foreach ($keys as $id => $key) { if ($doGet) { // Make sure the item is used $this->_model->get($key); } if (isset($context[$id])) { $check[$key] = $context[$id]; } elseif (isset($context[$key])) { $check[$key] = $context[$key]; } else { // Not all keys are in => therefore this is a new item $check = false; break; } } $rows = $this->_model->load($filter); if (!$rows) { return true; } if (!$check) { // Rows where found while it is a new item $this->_error(self::ERROR_RECORD_FOUND); return false; } $count = count($check); foreach ($rows as $row) { // Check for return of the whole check if (count(array_intersect_assoc($check, $row)) !== $count) { // There exists a row with the same values but not the same keys $this->_error(self::ERROR_RECORD_FOUND); return false; } } return true; }
/** * 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() { $sql = "SELECT COALESCE(gto_round_description, '') AS label,\n SUM(\n CASE\n WHEN gto_completion_time IS NOT NULL\n THEN 1\n ELSE 0\n END\n ) AS completed,\n SUM(\n CASE\n WHEN gto_completion_time IS NULL AND\n gto_valid_from < CURRENT_TIMESTAMP AND\n (gto_valid_until > CURRENT_TIMESTAMP OR gto_valid_until IS NULL)\n THEN 1\n ELSE 0\n END\n ) AS waiting,\n COUNT(*) AS any\n FROM gems__tokens INNER JOIN\n gems__surveys ON gto_id_survey = gsu_id_survey INNER JOIN\n gems__rounds ON gto_id_round = gro_id_round INNER JOIN\n gems__respondent2track ON gto_id_respondent_track = gr2t_id_respondent_track INNER JOIN\n gems__reception_codes AS rcto ON gto_reception_code = rcto.grc_id_reception_code INNER JOIN\n gems__reception_codes AS rctr ON gr2t_reception_code = rctr.grc_id_reception_code\n WHERE gto_id_respondent = ? AND\n gro_active = 1 AND\n gsu_active = 1 AND\n rcto.grc_success = 1 AND\n rctr.grc_success = 1\n GROUP BY COALESCE(gto_round_description, '')\n ORDER BY MIN(COALESCE(gto_round_order, 100000)), gto_round_description"; // \MUtil_Echo::track($this->respondentId); $tabLabels = $this->db->fetchAll($sql, $this->respondentId); if ($tabLabels) { $default = null; $filters = array(); $noOpen = true; $tabs = array(); foreach ($tabLabels as $row) { $name = '_' . \MUtil_Form::normalizeName($row['label']); $label = $row['label'] ? $row['label'] : $this->_('empty'); if ($row['waiting']) { $label = sprintf($this->_('%s (%d open)'), $label, $row['waiting']); } else { $label = $label; } if (!$row['label']) { $label = \MUtil_Html::create('em', $label); } $filters[$name] = $row['label']; $tabs[$name] = $label; if ($noOpen && $row['completed'] > 0) { $default = $name; } if ($row['waiting'] > 0) { $default = $name; $noOpen = false; } } if (null === $default) { reset($filters); $default = key($filters); } // Set the model $reqFilter = $this->request->getParam($this->getParameterKey()); if (!isset($filters[$reqFilter])) { $reqFilter = $default; } if ('' === $filters[$reqFilter]) { $this->model->setMeta('tab_filter', array("(gto_round_description IS NULL OR gto_round_description = '')")); } else { $this->model->setMeta('tab_filter', array('gto_round_description' => $filters[$reqFilter])); } // \MUtil_Echo::track($tabs, $reqFilter, $default, $tabLabels); $this->defaultTab = $default; $this->_tabs = $tabs; } return $this->_tabs && parent::hasHtmlOutput(); }
/** * Adds columns from the model to the bridge that creates the browse table. * * Overrule this function to add different columns to the browse table, without * having to recode the core table building code. * * @param \MUtil_Model_Bridge_TableBridge $bridge * @param \MUtil_Model_ModelAbstract $model * @return void */ protected function addBrowseTableColumns(\MUtil_Model_Bridge_TableBridge $bridge, \MUtil_Model_ModelAbstract $model) { // Make sure these fields are loaded $model->get('gro_valid_after_field'); $model->get('gro_valid_after_id'); $model->get('gro_valid_after_length'); $model->get('gro_valid_after_source'); $model->get('gro_valid_after_unit'); $model->get('gro_valid_for_field'); $model->get('gro_valid_for_id'); $model->get('gro_valid_for_length'); $model->get('gro_valid_for_source'); $model->get('gro_valid_for_unit'); parent::addBrowseTableColumns($bridge, $model); }