Don't access Request except in controller & activate home/pane by a given name

This commit is contained in:
Yonas Habteab 2022-06-02 19:10:33 +02:00
parent 8560b2ec3f
commit c4112b40d5
7 changed files with 74 additions and 97 deletions

View File

@ -45,7 +45,8 @@ class DashboardsController extends CompatController
public function indexAction() public function indexAction()
{ {
$this->dashboard->load(DashboardHome::DEFAULT_HOME); $pane = $this->getParam('pane');
$this->dashboard->load(DashboardHome::DEFAULT_HOME, $pane);
$this->createTabs(); $this->createTabs();
@ -62,12 +63,8 @@ class DashboardsController extends CompatController
$this->content->getAttributes()->add('class', 'welcome-view'); $this->content->getAttributes()->add('class', 'welcome-view');
$this->dashboard->addHtml($welcomeForm); $this->dashboard->addHtml($welcomeForm);
} else { } else {
$pane = $this->getParam('pane'); $pane = $activeHome->getActivePane();
if (! $pane) { $this->dashboard->activate($pane->getName());
$pane = $activeHome->getActivePane($this->dashboard->getTabs())->getName();
}
$this->dashboard->activate($pane);
} }
$this->addContent($this->dashboard); $this->addContent($this->dashboard);
@ -91,12 +88,8 @@ class DashboardsController extends CompatController
$this->createTabs(); $this->createTabs();
if ($activeHome->hasEntries()) { if ($activeHome->hasEntries()) {
$pane = $this->getParam('pane'); $pane = $activeHome->getActivePane();
if (! $pane) { $this->dashboard->activate($pane->getName());
$pane = $activeHome->getActivePane($this->dashboard->getTabs())->getName();
}
$this->dashboard->activate($pane);
} }
$this->addContent($this->dashboard); $this->addContent($this->dashboard);
@ -154,7 +147,7 @@ class DashboardsController extends CompatController
{ {
$home = $this->params->getRequired('home'); $home = $this->params->getRequired('home');
$this->dashboard->load(); $this->dashboard->load($home, null, true);
$paneForm = (new PaneForm($this->dashboard)) $paneForm = (new PaneForm($this->dashboard))
->on(PaneForm::ON_SUCCESS, function () { ->on(PaneForm::ON_SUCCESS, function () {
@ -171,7 +164,7 @@ class DashboardsController extends CompatController
$home = $this->params->getRequired('home'); $home = $this->params->getRequired('home');
$pane = $this->params->getRequired('pane'); $pane = $this->params->getRequired('pane');
$this->dashboard->load(); $this->dashboard->load($home, $pane, true);
if (! $this->dashboard->getActiveHome()->hasEntry($pane)) { if (! $this->dashboard->getActiveHome()->hasEntry($pane)) {
$this->httpNotFound(t('Pane "%s" not found'), $pane); $this->httpNotFound(t('Pane "%s" not found'), $pane);
@ -194,7 +187,7 @@ class DashboardsController extends CompatController
$home = $this->params->getRequired('home'); $home = $this->params->getRequired('home');
$paneParam = $this->params->getRequired('pane'); $paneParam = $this->params->getRequired('pane');
$this->dashboard->load($home); $this->dashboard->load($home, $paneParam);
if (! $this->dashboard->getActiveHome()->hasEntry($paneParam)) { if (! $this->dashboard->getActiveHome()->hasEntry($paneParam)) {
$this->httpNotFound(t('Pane "%s" not found'), $paneParam); $this->httpNotFound(t('Pane "%s" not found'), $paneParam);
@ -214,7 +207,7 @@ class DashboardsController extends CompatController
{ {
$home = $this->params->getRequired('home'); $home = $this->params->getRequired('home');
$this->dashboard->load(); $this->dashboard->load($home, null, true);
$dashletForm = new DashletForm($this->dashboard); $dashletForm = new DashletForm($this->dashboard);
$dashletForm->populate($this->getRequest()->getPost()); $dashletForm->populate($this->getRequest()->getPost());
@ -479,7 +472,7 @@ class DashboardsController extends CompatController
$pane = $this->params->getRequired('pane'); $pane = $this->params->getRequired('pane');
$dashlet = $this->params->getRequired('dashlet'); $dashlet = $this->params->getRequired('dashlet');
$this->dashboard->load(); $this->dashboard->load($home, $pane, true);
if (! $this->dashboard->getActiveHome()->hasEntry($pane)) { if (! $this->dashboard->getActiveHome()->hasEntry($pane)) {
$this->httpNotFound(t('Pane "%s" not found'), $pane); $this->httpNotFound(t('Pane "%s" not found'), $pane);

View File

@ -12,7 +12,6 @@ use Icinga\Web\Dashboard\Dashboard;
use Icinga\Web\Dashboard\DashboardHome; use Icinga\Web\Dashboard\DashboardHome;
use Icinga\Util\DBUtils; use Icinga\Util\DBUtils;
use ipl\Stdlib\Filter; use ipl\Stdlib\Filter;
use ipl\Web\Url;
trait DashboardManager trait DashboardManager
{ {
@ -25,12 +24,13 @@ trait DashboardManager
* *
* @return void * @return void
*/ */
public function load(string $name = null) public function load(string $name = null, string $activePane = null, bool $loadAll = false)
{ {
$query = Model\Home::on(DBUtils::getConn()); $query = Model\Home::on(DBUtils::getConn());
$query->filter(Filter::equal('icingaweb_dashboard_owner.id', $this::getUser()->getAdditional('id'))); $query->filter(Filter::equal('icingaweb_dashboard_owner.id', $this::getUser()->getAdditional('id')));
if ($name !== null) { $this->setEntries([]);
if ($name !== null && ! $loadAll) {
$query->filter(Filter::equal('name', $name)); $query->filter(Filter::equal('name', $name));
/** @var Model\Home $row */ /** @var Model\Home $row */
@ -46,22 +46,25 @@ trait DashboardManager
} }
$this->activateHome($home); $this->activateHome($home);
$home->loadDashboardEntries(); $home->loadDashboardEntries($activePane);
} else { } else {
foreach ($query as $row) { foreach ($query as $row) {
$this->addEntry(DashboardHome::create($row)); $this->addEntry(DashboardHome::create($row));
} }
$homeParam = Url::fromRequest()->getParam('home'); if ($name !== null && $loadAll) {
if ($homeParam && $this->hasEntry($homeParam)) { if (! $this->hasEntry($name)) {
$firstHome = $this->getEntry($homeParam); throw new HttpNotFoundException(t('Home "%s" not found'), $name);
}
$firstHome = $this->getEntry($name);
} else { } else {
$firstHome = $this->rewindEntries(); $firstHome = $this->rewindEntries();
} }
if ($firstHome) { if ($firstHome) {
$this->activateHome($firstHome); $this->activateHome($firstHome);
$firstHome->loadDashboardEntries(); $firstHome->loadDashboardEntries($activePane);
} }
} }
@ -97,6 +100,10 @@ trait DashboardManager
*/ */
public function activateHome(DashboardHome $home): self public function activateHome(DashboardHome $home): self
{ {
if (! $this->hasEntry($home->getName())) {
throw new ProgrammingError('Trying to activate Dashboard Home "%s" that does not exist.', $home->getName());
}
$activeHome = $this->getActiveHome(); $activeHome = $this->getActiveHome();
if ($activeHome && $activeHome->getName() !== $home->getName()) { if ($activeHome && $activeHome->getName() !== $home->getName()) {
$activeHome->setActive(false); $activeHome->setActive(false);
@ -116,7 +123,7 @@ trait DashboardManager
{ {
/** @var DashboardHome $home */ /** @var DashboardHome $home */
foreach ($this->getEntries() as $home) { foreach ($this->getEntries() as $home) {
if ($home->getActive()) { if ($home->isActive()) {
return $home; return $home;
} }
} }

View File

@ -4,8 +4,6 @@
namespace Icinga\Web\Dashboard; namespace Icinga\Web\Dashboard;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Dashboard\Common\DashboardEntries; use Icinga\Web\Dashboard\Common\DashboardEntries;
use Icinga\Web\Dashboard\Common\DashboardEntry; use Icinga\Web\Dashboard\Common\DashboardEntry;
use Icinga\Web\Dashboard\Common\DashboardManager; use Icinga\Web\Dashboard\Common\DashboardManager;
@ -180,7 +178,7 @@ class Dashboard extends BaseHtmlElement implements DashboardEntry
} elseif (! $activeHome->hasEntries()) { } elseif (! $activeHome->hasEntries()) {
$this->addHtml(HtmlElement::create('h1', null, t('No dashboard added to this dashboard home.'))); $this->addHtml(HtmlElement::create('h1', null, t('No dashboard added to this dashboard home.')));
} else { } else {
$activePane = $activeHome->getActivePane($this->getTabs()); $activePane = $activeHome->getActivePane();
if (! $activePane->hasEntries()) { if (! $activePane->hasEntries()) {
$this->addHtml(HtmlElement::create('h1', null, t('No dashlet added to this pane.'))); $this->addHtml(HtmlElement::create('h1', null, t('No dashlet added to this pane.')));

View File

@ -5,6 +5,7 @@
namespace Icinga\Web\Dashboard; namespace Icinga\Web\Dashboard;
use Icinga\Exception\ConfigurationError; use Icinga\Exception\ConfigurationError;
use Icinga\Exception\Http\HttpNotFoundException;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
use Icinga\Model\Home; use Icinga\Model\Home;
use Icinga\Web\Dashboard\Common\BaseDashboard; use Icinga\Web\Dashboard\Common\BaseDashboard;
@ -13,9 +14,8 @@ use Icinga\Web\Dashboard\Common\Sortable;
use Icinga\Util\DBUtils; use Icinga\Util\DBUtils;
use Icinga\Web\Dashboard\Common\WidgetState; use Icinga\Web\Dashboard\Common\WidgetState;
use ipl\Stdlib\Filter; use ipl\Stdlib\Filter;
use ipl\Web\Url; use ipl\Web\Url;
use ipl\Web\Widget\Tabs;
use function ipl\Stdlib\get_php_type; use function ipl\Stdlib\get_php_type;
class DashboardHome extends BaseDashboard implements Sortable class DashboardHome extends BaseDashboard implements Sortable
@ -44,13 +44,6 @@ class DashboardHome extends BaseDashboard implements Sortable
*/ */
protected $type = Dashboard::SYSTEM; protected $type = Dashboard::SYSTEM;
/**
* A flag whether this home has been activated
*
* @var bool
*/
protected $active = false;
/** /**
* Create a new dashboard home from the given model * Create a new dashboard home from the given model
* *
@ -71,32 +64,6 @@ class DashboardHome extends BaseDashboard implements Sortable
return $self; return $self;
} }
/**
* Set whether this home is active
*
* DB dashboards will load only when this home has been activated
*
* @param bool $active
*
* @return $this
*/
public function setActive(bool $active = true): self
{
$this->active = $active;
return $this;
}
/**
* Get whether this home has been activated
*
* @return bool
*/
public function getActive(): bool
{
return $this->active;
}
/** /**
* Set the type of this dashboard home * Set the type of this dashboard home
* *
@ -122,46 +89,43 @@ class DashboardHome extends BaseDashboard implements Sortable
} }
/** /**
* @see determineActivePane() * Activate the given pane and deactivate all the others
*
* @param Pane $pane
*
* @return $this
*/ */
public function getActivePane(Tabs $tabs): Pane public function activatePane(Pane $pane): self
{ {
return $this->determineActivePane($tabs); if (! $this->hasEntry($pane->getName())) {
throw new ProgrammingError('Trying to activate Dashboard Pane "%s" that does not exist.', $pane->getName());
}
$active = $this->getActivePane();
if ($active && $active->getName() !== $pane->getName()) {
$active->setActive(false);
}
$pane->setActive(true);
return $this;
} }
/** /**
* Determine the active pane either by the selected tab or the current request * Determine the active pane currently being loaded
* *
* @param Tabs $tabs * @return ?Pane
*
* @return Pane
*/ */
public function determineActivePane(Tabs $tabs): Pane public function getActivePane()
{ {
$activeTab = $tabs->getActiveTab(); /** @var Pane $pane */
if ($activeTab) { foreach ($this->getEntries() as $pane) {
$pane = $activeTab->getName(); if ($pane->isActive()) {
} else { return $pane;
if (! ($pane = Url::fromRequest()->getParam('pane'))) {
if (($firstPane = $this->rewindEntries())) {
$tabs->activate($firstPane->getName());
$pane = $firstPane->getName();
}
} else {
if ($this->hasEntry($pane)) {
$tabs->activate($pane);
} else {
throw new ProgrammingError('Try to get an inexistent pane.');
}
} }
} }
if ($pane && $this->hasEntry($pane)) { return null;
return $this->getEntry($pane);
}
throw new ConfigurationError('Could not determine active pane');
} }
public function removeEntry($pane) public function removeEntry($pane)
@ -201,10 +165,23 @@ class DashboardHome extends BaseDashboard implements Sortable
->setTitle($pane->label) ->setTitle($pane->label)
->setPriority($pane->priority); ->setPriority($pane->priority);
$newPane->loadDashboardEntries($name);
$this->addEntry($newPane); $this->addEntry($newPane);
} }
if ($name !== null) {
if ($this->hasEntry($name)) {
$pane = $this->getEntry($name);
$this->activatePane($pane);
$pane->loadDashboardEntries();
} else {
throw new HttpNotFoundException(t('Pane "%s" not found'), $name);
}
} elseif (($firstPane = $this->rewindEntries())) {
$this->activatePane($firstPane);
$firstPane->loadDashboardEntries();
}
return $this; return $this;
} }

View File

@ -55,7 +55,7 @@ class DashboardHomeList extends ItemListControl
protected function shouldExpandByDefault(): bool protected function shouldExpandByDefault(): bool
{ {
return $this->home->getActive(); return $this->home->isActive();
} }
protected function getCollapsibleControlClass(): string protected function getCollapsibleControlClass(): string

View File

@ -37,7 +37,7 @@ class DashboardList extends ItemListControl
protected function shouldExpandByDefault(): bool protected function shouldExpandByDefault(): bool
{ {
return $this->pane->getHome()->getActive(); return $this->pane->isActive();
} }
protected function getCollapsibleControlClass(): string protected function getCollapsibleControlClass(): string

View File

@ -12,6 +12,7 @@ use Icinga\Model;
use Icinga\Web\Dashboard\Common\DashboardEntries; use Icinga\Web\Dashboard\Common\DashboardEntries;
use Icinga\Web\Dashboard\Common\Sortable; use Icinga\Web\Dashboard\Common\Sortable;
use Icinga\Util\DBUtils; use Icinga\Util\DBUtils;
use Icinga\Web\Dashboard\Common\WidgetState;
use ipl\Stdlib\Filter; use ipl\Stdlib\Filter;
use function ipl\Stdlib\get_php_type; use function ipl\Stdlib\get_php_type;
@ -22,6 +23,7 @@ use function ipl\Stdlib\get_php_type;
class Pane extends BaseDashboard implements Sortable class Pane extends BaseDashboard implements Sortable
{ {
use DashboardEntries; use DashboardEntries;
use WidgetState;
const TABLE = 'icingaweb_dashboard'; const TABLE = 'icingaweb_dashboard';