classes/Gems/Menu/MenuAbstract.php
<?php
/**
*
* @package Gems
* @subpackage Menu
* @author Matijs de Jong <mjong@magnafacta.nl>
* @copyright Copyright (c) 2011 Erasmus MC
* @license New BSD License
*/
use MUtil\Translate\TranslateableTrait;
/**
* Base class for building a menu / button structure where the display of items is dependent
* on both privileges and the availability of parameter information,
* e.g. data to fill an 'id' parameter.
*
* @package Gems
* @subpackage Menu
* @copyright Copyright (c) 2011 Erasmus MC
* @license New BSD License
* @since Class available since version 1.0
*/
abstract class Gems_Menu_MenuAbstract extends \Gems_Loader_TargetLoaderAbstract
{
use TranslateableTrait;
/**
*
* @var \Gems_Menu_SubMenuItem[]
*/
protected $_subItems = array();
/**
*
* @var \MUtil_Acl
*/
public $acl;
/**
*
* @var \Gems_User_User
*/
protected $currentUser;
/**
* @var \GemsEscort
*/
public $escort;
/**
*
* @var \Gems_Loader
*
*/
public $loader;
/**
*
* @var \Gems_Project_ProjectSettings
*/
public $project;
public function __construct()
{
$this->escort = \GemsEscort::getInstance();
}
/**
* Adds privileges that are used in this menu item to the array
*
* @param array $privileges
*/
protected function _addUsedPrivileges(array &$privileges, $label)
{
foreach ($this->_subItems as $item) {
// Skip autofilter action, but include all others
if ($item->get('action') == 'autofilter') {
continue;
}
$_itemlabel = $label . ($item->get('label') ?: $item->get('privilege'));
$_privilege = $item->get('privilege');
// True is used to make a privilege always accessible, e.g. for ask/return and ask/forward
if ($_privilege && (true !== $_privilege)) {
if (isset($privileges[$_privilege])) {
$add = "<br/> + " . $_itemlabel;
if (! \MUtil_String::contains($privileges[$_privilege], $add)) {
$privileges[$_privilege] .= $add;
}
} else {
$privileges[$_privilege] = $_itemlabel;
}
}
$item->_addUsedPrivileges($privileges, $_itemlabel . '->');
}
}
/**
* Get tge request to use for menu building
*
* @return \Zend_Controller_Request_Abstract
*/
protected function _getOriginalRequest()
{
$request = \MUtil\Controller\Front::getRequest();
$handler = $request->getParam('error_handler');
if ($handler) {
return $handler->request;
}
return $request;
}
/**
* Returns a \Zend_Navigation creation array for this menu item, with
* sub menu items in 'pages'
*
* @param \Gems_Menu_ParameterCollector $source
* @return array
*/
protected function _toNavigationArray(\Gems_Menu_ParameterCollector $source)
{
$this->sortByOrder();
$lastParams = null;
$pageIdx = 0;
$pages = array();
foreach ($this->_subItems as $item) {
// Skip button_only items
if ($item->get('button_only')) {
continue;
}
$page = $item->_toNavigationArray($source);
if (($this instanceof \Gems_Menu_SubMenuItem) &&
(!$this->notSet('controller', 'action')) &&
isset($page['params'])) {
$params = $page['params'];
unset($params['reset']); // Ignore this setting
$class = [];
if (isset($page['class'])) {
$class[] = $page['class'];
}
if (empty($params)) {
$class[] = 'noParameters';
}
if ((null !== $lastParams) && ($lastParams !== $params)) {
$class[] = 'breakBefore';
}
if (!empty($class)) {
$page['class'] = join(' ', $class);
}
$lastParams = $params;
}
$pages[$pageIdx] = $page;
$pageIdx++;
}
return $pages;
}
/**
* Add a sub item to this item.
*
* The argumenets can be any of those used for \Zend_Navigation_Page as well as some Gems specials.<ul>
* <li>'action' The name of the action.</li>
* <li>'allowed' Is the user allowed to access this menu item. Is checked against ACL using 'privilige'.</li>
* <li>'button_only' Never in the menu, only shown as a button by the program.</li>
* <li>'class' Display class for the menu link.</li>
* <li>'controller' What controller to use.</li>
* <li>'icon' Icon to display with the label.</li>
* <li>'label' The label to display for the menu item.</li>
* <li>'privilege' The privilege needed to choose the item.</li>
* <li>'target' Optional target attribute for the link.</li>
* <li>'type' Optional content type for the link</li>
* <li>'visible' Is the item visible. Is checked against ACL using 'privilige'.</li>
* </ul>
*
* @see \Zend_Navigation_Page
*
* @param array $argsArray \MUtil_Ra::args array with defaults 'visible' and 'allowed' true.
* @return \Gems_Menu_SubMenuItem
*/
protected function add($argsArray)
{
// Process parameters.
$args = \MUtil_Ra::args(func_get_args(), 0,
array('visible' => true, // All menu items are initally visible unless stated otherwise
'allowed' => true, // Same as with visible, need this for _toNavigationArray()
));
if (! isset($args['label'])) {
$args['visible'] = false;
}
if (! isset($args['order'])) {
$args['order'] = 10 * (count($this->_subItems) + 1);
}
$page = new \Gems_Menu_SubMenuItem($this, $args);
$this->_subItems[] = $page;
return $page;
}
/**
* Add a agenda setup menu tree to the menu
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addAgendaSetupMenu($label)
{
$setup = $this->addContainer($label);
$setup->addAgendaSetupPage($this->_('Activities'), 'pr.agenda-activity', 'agenda-activity');
$setup->addAgendaSetupPage($this->_('Procedures'), 'pr.agenda-procedure', 'agenda-procedure');
$setup->addAgendaSetupPage($this->_('Diagnoses'), 'pr.agenda-diagnosis', 'agenda-diagnosis');
$setup->addAgendaSetupPage($this->_('Locations'), 'pr.locations', 'location');
$setup->addAgendaSetupPage($this->_('Healthcare staff'), 'pr.agenda-staff', 'agenda-staff');
$setup->addBrowsePage( $this->_('Appointment filters'), 'pr.agenda-filters', 'agenda-filter');
return $setup;
}
/**
* Add a browse / create / edit / show / / sleanup etc.. menu item
*
* @param string $label
* @param string $privilege
* @param string $controller
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addAgendaSetupPage($label, $privilege, $controller, array $other = array())
{
$page = $this->addPage($label, $privilege, $controller, 'index', $other);
$page->addAutofilterAction();
$page->addCreateAction();
$page->addExportAction();
$page->addImportAction();
$show = $page->addShowAction();
$show->addEditAction();
$show->addDeleteAction();
$show->addAction($this->_('Clean up'), $privilege . '.cleanup', 'cleanup')
->setModelParameters(1);
return $page;
}
/**
* Add a browse / ceate / edit / show / etc.. menu item
*
* @param string $label
* @param string $privilege
* @param string $controller
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addBrowsePage($label, $privilege, $controller, array $other = array())
{
$page = $this->addPage($label, $privilege, $controller, 'index', $other);
$page->addAutofilterAction();
$page->addCreateAction();
$page->addExportAction();
$page->addImportAction();
$show = $page->addShowAction();
$show->addEditAction();
$show->addDeleteAction();
return $page;
}
/**
* Add a menu item that is never added to the navigation tree and only shows up as a button.
*
* @param string $label
* @param string $privilege
* @param string $controller
* @param string $action
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addButtonOnly($label, $privilege, $controller, $action = 'index', array $other = array())
{
$other['button_only'] = true;
return $this->addPage($label, $privilege, $controller, $action, $other);
}
/**
* Add a calendar page to the menu
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addCalendarPage($label)
{
$page = $this->addPage($label, 'pr.calendar', 'calendar');
$page->addAutofilterAction();
$page->addExportAction();
$page->addImportAction();
$page->addAction(null, 'pr.calendar.simple-api', 'simple-api');
return $page;
}
/**
* Add a Mail menu tree to the menu
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addCommSetupMenu($label)
{
$setup = $this->addContainer($label);
// AUTOMATIC COMMUNICATION CONTROLLER
$page = $setup->addBrowsePage($this->_('Automatic messaging'), 'pr.comm.job', 'comm-job');
$page->addButtonOnly($this->_('Turn Automatic Messaging Jobs OFF'), 'pr.comm.job', 'cron', 'cron-lock');
$page->addButtonOnly($this->_('Monitor'), 'pr.comm.job', 'comm-job', 'monitor');
$page->addPage($this->_('Run all'), 'pr.cron.job', 'comm-job', 'execute-all');
$show = $page->findItem(array('controller' => 'comm-job', 'action' => 'show'));
$show->addPage($this->_('Preview'), 'pr.cron.job', 'comm-job', 'preview')
->setModelParameters(1);
$show->addPage($this->_('Run'), 'pr.cron.job', 'comm-job', 'execute')
->setModelParameters(1);
$ajaxPage = $this->addPage($this->_('Round Selection'), 'pr.comm.job', 'comm-job', 'roundselect', array('visible' => false));
$ajaxPage = $this->addPage($this->_('Sort jobs'), 'pr.comm.job.edit', 'comm-job', 'sort', array('visible' => false));
// MESSENGERS
$setup->addBrowsePage($this->_('Messengers'), 'pr.comm.messenger', 'comm-messengers');
// COMMUNICATION TEMPLATE CONTROLLER
$setup->addBrowsePage($this->_('Templates'), 'pr.comm.template', 'comm-template');
// MAIL SERVER CONTROLLER
$setup->addBrowsePage($this->_('Mail servers'), 'pr.mail.server', 'mail-server');
// COMMUNICATION ACTIVITY CONTROLLER
//$setup->addBrowsePage();
$page = $setup->addPage($this->_('Communication log'), 'pr.mail.log', 'mail-log');
$page->addAutofilterAction();
$page->addExportAction();
$showPage = $page->addShowAction();
$showPage->addButtonOnly($this->_('Resend mail'), 'pr.mail.log.resend', 'mail-log', 'resend')
->setModelParameters(1);
return $setup;
}
/**
*
* @param string $label
* @param string $privilege
* @param array $other
* @return \Gems_Menu_ContainerItem
*/
public function addContainer($label, $privilege = null, array $other = array())
{
$other['label'] = $label;
if ($privilege) {
$other['privilege'] = $privilege;
}
// Process parameters.
$defaults = array(
'visible' => (boolean) $label, // All menu containers are initally visible unless stated otherwise or specified without label
'allowed' => true, // Same as with visible, need this for t_oNavigationArray()
'order' => 10 * (count($this->_subItems) + 1),
);
foreach ($defaults as $key => $value) {
if (! isset($other[$key])) {
$other[$key] = $value;
}
}
$page = new \Gems_Menu_ContainerItem($this, $other);
$this->_subItems[] = $page;
return $page;
}
/**
* Shortcut function to create the export container.
*
* @param string $label Label for the container
* @return \Gems_Menu_MenuAbstract The new contact page
*/
public function addExportContainer($label)
{
$export = $this->addContainer($label);
// EXPORT
$surveyExport = $export->addPage($this->_('Single survey answers'), 'pr.export', 'export-survey', 'index');
$surveyExport->addAutofilterAction();
$surveyExport->addExportAction();
//$export->addButtonOnly('', 'pr.export', 'export', 'handle-export');
//$export->addButtonOnly('', 'pr.export', 'export', 'download');
$batchExport = $export->addPage(
$this->_('Multiple surveys answers'),
'pr.export',
'export-multi-surveys',
'index'
);
$batchExport->addAutofilterAction();
// EXPORT TO HTML
$export->addPage($this->_('Respondent archives'), 'pr.export-html', 'respondent-export', 'index');
$export->addPage($this->_('Survey codebooks'), 'pr.export.code-book-export', 'survey-code-book-multi-export', 'index');
return $export;
}
/**
* Add a file upload/download page to the menu
*
* @param string $label The label to display for the menu item, null for access without display
* @param string $privilege The privilege for the item, null is always, 'pr.islogin' must be logged in, 'pr.nologin' only when not logged in.
* @param string $controller What controller to use
* @param string $action The name of the action
* @param array $other Array of extra options for this item, e.g. 'visible', 'allowed', 'class', 'icon', 'target', 'type', 'button_only'
* @return \Gems_Menu_SubMenuItem
*/
public function addFilePage($label, $privilege, $controller, array $other = array())
{
$page = $this->addPage($label, $privilege, $controller, 'index', $other);
$page->addAutofilterAction();
$page->addAction($this->_('Create folder'), $privilege . '.createdir', 'create-folder');
$page->addAction($this->_('Upload'), $privilege . '.upload', 'upload');
// $page->addCreateAction();
$page = $page->addShowAction();
$page->addEditAction();
$onDelete = new \MUtil_Html_OnClickArrayAttribute();
$onDelete->addConfirm($this->_("Are you sure you want to delete this file?"));
$page->addButtonOnly($this->_('Delete'), $privilege . '.delete', $controller, 'delete', array(
'onclick' => $onDelete,
))->setModelParameters(1);
$page->addButtonOnly($this->_('Download'), $privilege . '.download', $controller, 'download')
->setModelParameters(1);
return $page;
}
/**
* Add a roles browse edit page to the menu,
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addGroupsPage($label, array $other = array())
{
$page = $this->addBrowsePage($label, 'pr.group', 'group', $other);
// $groups = array();
//
// if ($this->user instanceof \Gems_User_User) {
// if ($this->user->hasPrivilege('pr.group')) {
// $groups = $this->user->getAllowedStaffGroups();
// $rolesObj = \Gems_Roles::getInstance();
// $rolesRaw = $this->user->getAllowedRoles();
// $roleIds = $rolesObj->translateToRoleIds($rolesRaw);
// $roles = array_combine($roleIds, $roleIds) + $rolesRaw;
// }
// }
// \MUtil_Echo::track($roles, array_flip($rolesObj->translateToRoleIds($rolesRaw)), $rolesRaw);
// \Gems_Menu::$verbose = true;
// // Now limit changes to allowed roles
// foreach ($page->getChildren() as $showpage) {
// if ($showpage instanceof \Gems_Menu_SubMenuItem) {
// if ('show' === $showpage->get('action')) {
// foreach ($showpage->getChildren() as $subpage) {
// $subpage->addParameterFilter('ggp_role', $groups);
// }
// break;
// }
// }
// }
//
return $page;
}
/**
* Shortcut function to create the import container.
*
* @param string $label Label for the container
* @return \Gems_Menu_MenuAbstract The new contact page
*/
public function addImportContainer($label)
{
$import = $this->addContainer($label);
$page = $import->addPage($this->_('Answers'), 'pr.survey-maintenance.answer-import', 'file-import', 'answers-import');
$uplPage = $import->addFilePage($this->_('Importable'), 'pr.file-import', 'file-import');
// $page->addButtonOnly($this->_('Auto import'), 'pr.file-import.auto', 'file-import', 'auto');
$uplPage->addImportAction('pr.file-import.import', array('label' => $this->_('Import file')))
->setModelParameters(1);
$impPage = $import->addFilePage($this->_('Imported files'), 'pr.file-import', 'imported-files');
$impPage->addImportAction('pr.file-import.import', array('label' => $this->_('Reimport file')))
->setModelParameters(1);
$errPage = $import->addFilePage($this->_('Imported failures'), 'pr.file-import', 'imported-failures');
$errPage->addImportAction('pr.file-import.import', array('label' => $this->_('Retry import')))
->setModelParameters(1);
return $import;
}
/**
* Add the log menu items
*/
public function addLogControllers()
{
// LOG SETUP CONTROLLER
$this->addBrowsePage($this->_('Log Setup'), 'pr.log.maintenance', 'log-maintenance');
// LOG CONTROLLER
$page = $this->addPage($this->_('Log'), 'pr.log', 'log', 'index');
$page->addAutofilterAction();
$page->addExportAction();
$page->addShowAction()
->setNamedParameters(\Gems_Model::LOG_ITEM_ID, 'gla_id');
// LOG FILES CONTROLLER
$this->addFilePage($this->_('Log files'), 'pr.log.files', 'log-file');
}
/**
* Add a page to the menu
*
* @param string $label The label to display for the menu item, null for access without display
* @param string $privilege The privilege for the item, null is always, 'pr.islogin' must be logged in, 'pr.nologin' only when not logged in.
* @param string $controller What controller to use
* @param string $action The name of the action
* @param array $other Array of extra options for this item, e.g. 'visible', 'allowed', 'class', 'icon', 'target', 'type', 'button_only'
* @return \Gems_Menu_SubMenuItem
*/
public function addPage($label, $privilege, $controller, $action = 'index', array $other = array())
{
$other['label'] = $label;
$other['controller'] = $controller;
$other['action'] = $action;
if ($privilege) {
$other['privilege'] = $privilege;
}
return $this->add($other);
}
/**
* Add a list of report pages
*
* @param string $label The label to display for the menu item, null for access without display
* @return \Gems_Menu_SubMenuItem
*/
public function addPlanPage($label)
{
$infoPage = $this->addContainer($label);
$page = $infoPage->addPage($this->_('Track Summary'), 'pr.plan.summary', 'summary', 'index');
$page->addAutofilterAction();
$page->addExportAction();
$page = $infoPage->addPage($this->_('Track Compliance'), 'pr.plan.compliance', 'compliance', 'index');
$page->addAutofilterAction();
$page->addExportAction();
$page = $infoPage->addPage($this->_('Track Field Utilization'), 'pr.plan.fields', 'field-report', 'index');
$page->addAutofilterAction();
$page->addExportAction();
$page = $infoPage->addPage($this->_('Track Field Content'), 'pr.plan.fields', 'field-overview', 'index');
$page->addAutofilterAction();
$page->addExportAction();
$plans[] = $infoPage->addPage($this->_('By period'), 'pr.plan.overview', 'overview-plan', 'index');
$plans[] = $infoPage->addPage($this->_('By token'), 'pr.plan.token', 'token-plan', 'index');
$plans[] = $infoPage->addPage($this->_('By respondent'), 'pr.plan.respondent', 'respondent-plan', 'index');
foreach ($plans as $plan) {
$plan->addAutofilterAction();
$plan->addAction($this->_('Bulk mail'), 'pr.token.bulkmail', 'email', array('routeReset' => false));
$plan->addExportAction();
}
$page = $infoPage->addPage($this->_('Respondent status'), 'pr.plan.consent', 'consent-plan', 'index');
$page->addShowAction();
$page->addExportAction();
return $infoPage;
}
/**
* Add pages that show the user technical information about the installation
* in the project.
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addProjectInfoPage($label)
{
$page = $this->addPage($label, 'pr.project-information', 'project-information');
$page->addAction($this->_('Errors'), null, 'errors');
$page->addAction($this->_('PHP'), null, 'php');
$page->addAction($this->_('PHP Errors'), null, 'php-errors');
$page->addAction($this->_('Project'), null, 'project');
$page->addAction($this->_('Session'), null, 'session');
$page->addButtonOnly($this->_('Maintenance mode'), 'pr.maintenance.maintenance-mode', 'project-information', 'maintenance');
$page->addButtonOnly($this->_('Monitor'), 'pr.maintenance.maintenance-mode', 'project-information', 'monitor');
$page->addButtonOnly($this->_('Clean cache'), 'pr.maintenance.clean-cache', 'project-information', 'cacheclean');
// TEMPLATES CONTROLLER
$templates = $page->addPage($this->_('Templates'), 'pr.templates', 'template');
$templates->addAutofilterAction();
$edit = $templates->addEditAction();
$reset = $edit->addAction($this->_('Reset to default values'), 'pr.templates.reset', 'reset');
$reset->setModelParameters(1);
// UPGRADES CONTROLLER
$upage = $page->addPage($this->_('Upgrade'), 'pr.upgrade', 'upgrade', 'index');
$show = $upage->addAction($this->_('Show'), null, 'show')
->setNamedParameters('id','context');
$upage->addAction($this->_('Execute all'), 'pr.upgrade.all', 'execute-all')
->setModelParameters(1);
$show->addActionButton($this->_('Execute this'), 'pr.upgrade.one', 'execute-one')
->setModelParameters(1)
->addNamedParameters('from','from','to','to');
$show->addActionButton($this->_('Execute from here'), 'pr.upgrade.from', 'execute-from')
->setModelParameters(1)
->addNamedParameters('from','from');
$show->addActionButton($this->_('Execute to here'), 'pr.upgrade.to', 'execute-to')
->setModelParameters(1)
->addNamedParameters('to','to');
$show->addAction(null, 'pr.upgrade.to', 'execute-last');
$upage->addAction(
$this->_('Code compatibility report'),
'pr.upgrade',
'compatibility-report'
);
$upage->addPage(
sprintf($this->_('Changelog %s'), 'GemsTracker'),
'pr.upgrade',
'project-information',
'changelog-gems'
);
$upage->addPage(
sprintf($this->_('Changelog %s'), $this->project->getName()),
'pr.upgrade',
'project-information',
'changelog'
);
return $page;
}
/**
* Add pages that show the user an overview of the tracks / surveys used
* in the project.
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addProjectPage($label)
{
if ($this->escort instanceof \Gems_Project_Tracks_SingleTrackInterface) {
if ($trackId = $this->escort->getTrackId()) {
$infoPage = $this->addPage($label, 'pr.project', 'project-tracks', 'show')
->addHiddenParameter(\MUtil_Model::REQUEST_ID, $trackId);
$trackSurveys = $infoPage;
} else {
$infoPage = $this->addPage($label, 'pr.project', 'project-tracks');
$trackSurveys = $infoPage->addShowAction('pr.project');
}
$trackSurveys->addAction($this->_('Preview'), 'pr.project.questions', 'questions')
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gro_id_track', \Gems_Model::SURVEY_ID, 'gsu_id_survey');
$infoPage->addAutofilterAction();
// \MUtil_Echo::track($infoPage->_toNavigationArray(array($this->_getOriginalRequest())));
} else {
$infoPage = $this->addContainer($label);
$tracksPage = $infoPage->addPage($this->_('Tracks'), 'pr.project', 'project-tracks');
$tracksPage->addAutofilterAction();
$trackSurveys = $tracksPage->addShowAction('pr.project');
$trackSurveys->addAction($this->_('Preview'), 'pr.project.questions', 'questions')
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gro_id_track', \Gems_Model::SURVEY_ID, 'gsu_id_survey');
$surveysPage = $infoPage->addPage($this->_('Surveys'), 'pr.project', 'project-surveys');
$surveysPage->addAutofilterAction();
$surveysPage->addShowAction('pr.project');
}
return $infoPage;
}
/**
* Add a staff browse edit page to the menu,
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addStaffPage($label, array $other = array())
{
if ($this->currentUser->hasPrivilege('pr.staff.edit.all')) {
$filter = array_keys($this->loader->getUtil()->getDbLookup()->getOrganizations());
} else {
$filter = array_keys($this->currentUser->getAllowedOrganizations());
}
$page = $this->addPage($label, 'pr.staff', 'staff', 'index', $other);
$page->addAutofilterAction();
$createPage = $page->addCreateAction();
$showPage = $page->addShowAction();
$pages[] = $showPage->addEditAction();
$pages[] = $showPage->addAction($this->_('Reset password'), 'pr.staff.edit', 'reset')
->setModelParameters(1)
->addParameterFilter('gsf_active', 1);
$pages[] = $showPage->addAction($this->_('Reset 2FA'), 'pr.staff.edit', 'reset2fa')
->setModelParameters(1)
->addParameterFilter('gsf_active', 1, 'has_2factor', 2);
$showPage->addAction($this->_('Send Mail'), 'pr.staff.edit', 'mail')
->setModelParameters(1)
->addParameterFilter('can_mail', 1, 'gsf_active', 1, 'gsf_id_organization', $filter);
$pages = $pages + $showPage->addDeReactivateAction('gsf_active', 1, 0);
$pages[] = $showPage->addAction($this->_('Make system user'), 'pr.staff.switch-user', 'switch-user')
->setModelParameters(1)
->addParameterFilter('gsf_active', 1, 'gsf_id_organization', $filter);
// LOG CONTROLLER
$logPage = $showPage->addPage($this->_('Activity overview'), 'pr.staff-log', 'staff-log', 'index')
->setModelParameters(1)
->addParameterFilter('gsf_id_organization', $filter);
$logPage->addAutofilterAction();
$logPage->addShowAction()->setModelParameters(1)->addNamedParameters('log', 'gla_id');
$page->addExportAction();
$page->addImportAction();
if (! $this->currentUser->hasPrivilege('pr.staff.edit.all')) {
foreach ($pages as $subPage) {
$subPage->addParameterFilter('gsf_id_organization', $filter, 'accessible_role', 1);
}
}
return $page;
}
/**
* Add a staff browse edit page to the menu,
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addSystemUserPage($label, array $other = array())
{
if ($this->currentUser->hasPrivilege('pr.staff.edit.all')) {
$filter = array_keys($this->loader->getUtil()->getDbLookup()->getOrganizations());
} else {
$filter = array_keys($this->currentUser->getAllowedOrganizations());
}
$page = $this->addPage($label, 'pr.systemuser', 'system-user', 'index', $other);
$page->addAutofilterAction();
$createPage = $page->addCreateAction();
$showPage = $page->addShowAction();
$pages[] = $showPage->addEditAction();
$pages = $pages + $showPage->addDeReactivateAction('gsf_active', 1, 0);
$pages[] = $showPage->addAction($this->_('Make staff'), 'pr.staff.switch-user', 'switch-user')
->setModelParameters(1)
->addParameterFilter('gsf_active', 1, 'gsf_id_organization', $filter);
// LOG CONTROLLER
// $logPage = $showPage->addPage($this->_('Activity overview'), 'pr.staff-log', 'staff-log', 'index')
// ->setModelParameters(1);
// $logPage->addAutofilterAction();
// $logPage->addShowAction()->setModelParameters(1)->addNamedParameters('log', 'gla_id');
$page->addExportAction();
$page->addImportAction();
return $page;
}
/**
* Add a Trackbuilder menu tree to the menu
*
* @param string $label
* @param array $other
* @return \Gems_Menu_SubMenuItem
*/
public function addTrackBuilderMenu($label, array $other = array())
{
$setup = $this->addContainer($label);
// SURVEY SOURCES CONTROLLER
$page = $setup->addPage($this->_('Survey Sources'), 'pr.source', 'source');
$page->addAutofilterAction();
$page->addCreateAction();
$page->addExportAction();
$page->addImportAction();
$show = $page->addShowAction();
$show->addEditAction();
$show->addDeleteAction();
$show->addAction($this->_('Check status'), null, 'ping')
->addParameters(\MUtil_Model::REQUEST_ID);
$show->addAction($this->_('Synchronize surveys'), 'pr.source.synchronize', 'synchronize')
->addParameters(\MUtil_Model::REQUEST_ID);
$show->addAction($this->_('Check is answered'), 'pr.source.check-answers', 'check')
->addParameters(\MUtil_Model::REQUEST_ID);
$show->addAction($this->_('Check attributes'), 'pr.source.check-attributes', 'attributes')
->addParameters(\MUtil_Model::REQUEST_ID);
$page->addAction($this->_('Synchronize all surveys'), 'pr.source.synchronize-all', 'synchronize-all');
$page->addAction($this->_('Check all is answered'), 'pr.source.check-answers-all', 'check-all');
$page->addAction($this->_('Check all attributes'), 'pr.source.check-attributes-all', 'attributes-all');
// ADD CHART SETUP CONTROLLER
$setup->addBrowsePage($this->_('Charts setup'), 'pr.chartsetup', 'chartconfig');
// ADD CONDITIONS CONTROLLER - do not include import/export as this is handled by track import/export
$conditions = $setup->addPage($this->_('Conditions'), 'pr.conditions', 'condition');
$conditions->addAutofilterAction();
$conditions->addCreateAction();
$show = $conditions->addShowAction();
$show->addEditAction();
$show->addDeleteAction();
// SURVEY MAINTENANCE CONTROLLER
$page = $setup->addPage($this->_('Surveys'), 'pr.survey-maintenance', 'survey-maintenance');
$page->addAutofilterAction();
$page->addExportAction();
$showPage = $page->addShowAction();
$showPage->addEditAction();
$showPage->addAction($this->_('Check is answered'), 'pr.survey-maintenance.check', 'check')
->addParameters(\MUtil_Model::REQUEST_ID)
->setParameterFilter('gsu_active', 1);
$showPage->addAction($this->_('Import answers'), 'pr.survey-maintenance.answer-import', 'answer-import')
->addParameters(\MUtil_Model::REQUEST_ID)
->setParameterFilter('gsu_active', 1);
$showPage->addPdfButton($this->_('PDF'), 'pr.survey-maintenance')
->addParameters(\MUtil_Model::REQUEST_ID)
->setParameterFilter('gsu_has_pdf', 1);
$codePage = $showPage->addPage($this->_('Export codebook'), 'pr.survey-maintenance.code-book-export', 'survey-code-book-export', 'export')
->addParameters(\MUtil_Model::REQUEST_ID)
->setParameterFilter('gsu_active', 1);
$this->addHiddenPrivilege('pr.survey-maintenance.answer-groups', $this->_(
'Grant right to set answer access to surveys.'
));
// Multi survey
$page->addAction($this->_('Check all is answered'), 'pr.survey-maintenance.check-all', 'check-all');
$page->addAction($this->_('Import answers'), 'pr.survey-maintenance.answer-import', 'answer-imports');
$page->addPage($this->_('Update to new survey'), 'pr.track-maintenance.edit', 'update-survey', 'run');
// TRACK MAINTENANCE CONTROLLER
$page = $setup->addPage($this->_('Tracks'), 'pr.track-maintenance', 'track-maintenance', 'index');
$page->addAutofilterAction();
$page->addCreateAction();
//$page->addExportAction();
$page->addImportAction();
$showPage = $page->addShowAction();
$showPage->addEditAction();
$showPage->addDeleteAction();
/*$showPage->addButtonOnly($this->_('Copy'), 'pr.track-maintenance.copy', 'track-maintenance', 'copy')
->setModelParameters(1);*/
$showPage->addAction($this->_('Export'), 'pr.track-maintenance.export', 'export')
->addParameters(\MUtil_Model::REQUEST_ID);
$showPage->addAction($this->_('Check rounds'), 'pr.track-maintenance.check', 'check-track')
->addParameters(\MUtil_Model::REQUEST_ID)
->setParameterFilter('gtr_active', 1);
$showPage->addAction($this->_('Recalculate fields'), 'pr.track-maintenance.check', 'recalc-fields')
->addParameters(\MUtil_Model::REQUEST_ID)
->setParameterFilter('gtr_active', 1);
// Fields
$fpage = $showPage->addPage($this->_('Fields'), 'pr.track-maintenance', 'track-fields')
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gtf_id_track');
$fpage->addAutofilterAction();
$fpage->addCreateAction('pr.track-maintenance.create')
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gtf_id_track');
$fpage = $fpage->addShowAction()
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gtf_id_track', \Gems_Model::FIELD_ID, 'gtf_id_field', 'sub', 'sub');
$fpage->addEditAction('pr.track-maintenance.edit')
->addNamedParameters(\Gems_Model::FIELD_ID, 'gtf_id_field', \MUtil_Model::REQUEST_ID, 'gtf_id_track', 'sub', 'sub');
$fpage->addDeleteAction('pr.track-maintenance.delete')
->addNamedParameters(\Gems_Model::FIELD_ID, 'gtf_id_field', \MUtil_Model::REQUEST_ID, 'gtf_id_track', 'sub', 'sub');
// Rounds
$rpage = $showPage->addPage($this->_('Rounds'), 'pr.track-maintenance', 'track-rounds')
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gro_id_track');
$rpage->addAutofilterAction();
$rpage->addCreateAction('pr.track-maintenance.create')
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gro_id_track');
$spage = $rpage->addShowAction()
->addNamedParameters(\MUtil_Model::REQUEST_ID, 'gro_id_track', \Gems_Model::ROUND_ID, 'gro_id_round');
$spage->addEditAction('pr.track-maintenance.edit')
->addNamedParameters(\Gems_Model::ROUND_ID, 'gro_id_round', \MUtil_Model::REQUEST_ID, 'gro_id_track');
$spage->addDeleteAction('pr.track-maintenance.delete')
->addNamedParameters(\Gems_Model::ROUND_ID, 'gro_id_round', \MUtil_Model::REQUEST_ID, 'gro_id_track');
$ajaxPage = $this->addPage($this->_('Sort rounds'), 'pr.track-maintenance.edit', 'track-rounds', 'sort', array('visible' => false));
$overviewPage = $page->addPage($this->_('Tracks per org'), 'pr.track-maintenance.trackperorg', 'track-overview', 'index');
$overviewPage->addExportAction();
$overviewPage->addAutofilterAction();
$page->addAction($this->_('Check all rounds'), 'pr.track-maintenance.check-all', 'check-all');
$page->addAction($this->_('Recalculate all fields'), 'pr.track-maintenance.check-all', 'recalc-all-fields');
return $setup;
}
public function afterRegistry()
{
$this->initTranslateable();
parent::afterRegistry();
}
/**
* Set the visibility of the menu item and any sub items in accordance
* with the specified user role.
*
* @param \Zend_Acl $acl
* @param string $userRole
* @return \Gems_Menu_MenuAbstract (continuation pattern)
*/
protected function applyAcl(\MUtil_Acl $acl, $userRole)
{
foreach ($this->_subItems as $item) {
$allowed = $item->get('allowed', true);
if ($allowed && ($privilege = $item->get('privilege'))) {
if (true !== $privilege) {
$allowed = $acl->isAllowed($userRole, null, $privilege);
}
}
if ($allowed) {
$item->applyAcl($acl, $userRole);
} else {
// As an item can be invisible but allowed,
// but not disallowed but visible we need to
// set both.
$item->set('allowed', false);
$item->set('visible', false);
$item->setForChildren('allowed', false);
$item->setForChildren('visible', false);
}
}
return $this;
}
/**
*
* @param <type> $options
* @param <type> $findDeep
* @return \Gems_Menu_SubMenuItem|null
*/
protected function findItem($options, $findDeep = true)
{
foreach ($this->_subItems as $item) {
if ($result = $item->findItem($options, $findDeep)) {
return $result;
}
}
return null;
}
protected function findItemPath($options)
{
foreach ($this->_subItems as $item) {
if ($path = $item->findItemPath($options)) {
return $path;
}
}
return array();
}
protected function findItems($options, array &$results)
{
foreach ($this->_subItems as $item) {
$item->findItems($options, $results);
}
}
/**
*
* @return \Gems_Menu_SubMenuItem[]
*/
public function getChildren()
{
$this->sortByOrder();
return $this->_subItems;
}
public function hasChildren()
{
return (boolean) $this->_subItems;
}
abstract public function isTopLevel();
abstract public function isVisible();
/**
* Make sure only the active branch is visible
*
* @param array $activeBranch Of \Gems_Menu_Menu Abstract items
* @return \Gems_Menu_MenuAbstract (continuation pattern)
*/
protected function setBranchVisible(array $activeBranch)
{
$current = array_pop($activeBranch);
foreach ($this->_subItems as $item) {
if ($item->isVisible()) {
if ($item === $current) {
$item->set('active', true);
$item->setBranchVisible($activeBranch);
} else {
$item->setForChildren('visible', false);
}
}
}
return $this;
}
protected function setForChildren($key, $value)
{
foreach ($this->_subItems as $item) {
$item->set($key, $value);
if ($item->_subItems) {
$item->setForChildren($key, $value);
}
}
return $this;
}
/**
* Sorts the childeren on their order attribute (instead of the order the were added)
*
* @return \Gems_Menu_MenuAbstract (continuation pattern)
*/
public function sortByOrder()
{
uasort($this->_subItems, array(__CLASS__, 'sortOrder'));
return $this;
}
/**
* uasort() function for sortByOrder()
*
* @see sortByOrder();
*
* @param self $aItem
* @param self $bItem
* @return int
*/
public static function sortOrder($aItem, $bItem)
{
$a = $aItem->get('order');
$b = $bItem->get('order');
if ($a == $b) {
return 0;
}
return $a > $b ? 1 : -1;
}
}