diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:46:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 11:46:43 +0000 |
commit | 3e02d5aff85babc3ffbfcf52313f2108e313aa23 (patch) | |
tree | b01f3923360c20a6a504aff42d45670c58af3ec5 /application/forms/RepositoryForm.php | |
parent | Initial commit. (diff) | |
download | icingaweb2-3e02d5aff85babc3ffbfcf52313f2108e313aa23.tar.xz icingaweb2-3e02d5aff85babc3ffbfcf52313f2108e313aa23.zip |
Adding upstream version 2.12.1.upstream/2.12.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'application/forms/RepositoryForm.php')
-rw-r--r-- | application/forms/RepositoryForm.php | 453 |
1 files changed, 453 insertions, 0 deletions
diff --git a/application/forms/RepositoryForm.php b/application/forms/RepositoryForm.php new file mode 100644 index 0000000..8e4665d --- /dev/null +++ b/application/forms/RepositoryForm.php @@ -0,0 +1,453 @@ +<?php +/* Icinga Web 2 | (c) 2015 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Forms; + +use Exception; +use Icinga\Data\Filter\Filter; +use Icinga\Exception\NotFoundError; +use Icinga\Repository\Repository; +use Icinga\Web\Form; +use Icinga\Web\Notification; + +/** + * Form base-class providing standard functionality for extensible, updatable and reducible repositories + */ +abstract class RepositoryForm extends Form +{ + /** + * Insert mode + */ + const MODE_INSERT = 0; + + /** + * Update mode + */ + const MODE_UPDATE = 1; + + /** + * Delete mode + */ + const MODE_DELETE = 2; + + /** + * The repository being worked with + * + * @var Repository + */ + protected $repository; + + /** + * The target being worked with + * + * @var mixed + */ + protected $baseTable; + + /** + * How to interact with the repository + * + * @var int + */ + protected $mode; + + /** + * The name of the entry being handled when in mode update or delete + * + * @var string + */ + protected $identifier; + + /** + * The data of the entry to pre-populate the form with when in mode insert or update + * + * @var array + */ + protected $data; + + /** + * Set the repository to work with + * + * @param Repository $repository + * + * @return $this + */ + public function setRepository(Repository $repository) + { + $this->repository = $repository; + return $this; + } + + /** + * Return the target being worked with + * + * @return mixed + */ + protected function getBaseTable() + { + if ($this->baseTable === null) { + return $this->repository->getBaseTable(); + } + + return $this->baseTable; + } + + /** + * Return the name of the entry to handle + * + * @return string + */ + protected function getIdentifier() + { + return $this->identifier; + } + + /** + * Return the current data of the entry being handled + * + * @return array + */ + protected function getData() + { + return $this->data; + } + + /** + * Return whether an entry should be inserted + * + * @return bool + */ + public function shouldInsert() + { + return $this->mode === self::MODE_INSERT; + } + + /** + * Return whether an entry should be udpated + * + * @return bool + */ + public function shouldUpdate() + { + return $this->mode === self::MODE_UPDATE; + } + + /** + * Return whether an entry should be deleted + * + * @return bool + */ + public function shouldDelete() + { + return $this->mode === self::MODE_DELETE; + } + + /** + * Add a new entry + * + * @param array $data The defaults to use, if any + * + * @return $this + */ + public function add(array $data = null) + { + $this->mode = static::MODE_INSERT; + $this->data = $data; + return $this; + } + + /** + * Edit an entry + * + * @param string $name The entry's name + * @param array $data The entry's current data + * + * @return $this + */ + public function edit($name, array $data = null) + { + $this->mode = static::MODE_UPDATE; + $this->identifier = $name; + $this->data = $data; + return $this; + } + + /** + * Remove an entry + * + * @param string $name The entry's name + * + * @return $this + */ + public function remove($name) + { + $this->mode = static::MODE_DELETE; + $this->identifier = $name; + return $this; + } + + /** + * Fetch and return the entry to pre-populate the form with when in mode update + * + * @return false|object + */ + protected function fetchEntry() + { + return $this->repository + ->select() + ->from($this->getBaseTable()) + ->applyFilter($this->createFilter()) + ->fetchRow(); + } + + /** + * Return whether the entry supposed to be removed exists + * + * @return bool + */ + protected function entryExists() + { + $count = $this->repository + ->select() + ->from($this->getBaseTable()) + ->addFilter($this->createFilter()) + ->count(); + return $count > 0; + } + + /** + * Insert the new entry + */ + protected function insertEntry() + { + $this->repository->insert($this->getBaseTable(), $this->getValues()); + } + + /** + * Update the entry + */ + protected function updateEntry() + { + $this->repository->update($this->getBaseTable(), $this->getValues(), $this->createFilter()); + } + + /** + * Delete the entry + */ + protected function deleteEntry() + { + $this->repository->delete($this->getBaseTable(), $this->createFilter()); + } + + /** + * Create and add elements to this form + * + * @param array $formData The data sent by the user + */ + public function createElements(array $formData) + { + if ($this->shouldInsert()) { + $this->createInsertElements($formData); + } elseif ($this->shouldUpdate()) { + $this->createUpdateElements($formData); + } elseif ($this->shouldDelete()) { + $this->createDeleteElements($formData); + } + } + + /** + * Prepare the form for the requested mode + */ + public function onRequest() + { + if ($this->shouldInsert()) { + $this->onInsertRequest(); + } elseif ($this->shouldUpdate()) { + $this->onUpdateRequest(); + } elseif ($this->shouldDelete()) { + $this->onDeleteRequest(); + } + } + + /** + * Prepare the form for mode insert + * + * Populates the form with the data passed to add(). + */ + protected function onInsertRequest() + { + $data = $this->getData(); + if (! empty($data)) { + $this->setDefaults($data); + } + } + + /** + * Prepare the form for mode update + * + * Populates the form with either the data passed to edit() or tries to fetch it from the repository. + * + * @throws NotFoundError In case the entry to update cannot be found + */ + protected function onUpdateRequest() + { + $data = $this->getData(); + if ($data === null) { + $row = $this->fetchEntry(); + if ($row === false) { + throw new NotFoundError('Entry "%s" not found', $this->getIdentifier()); + } + + $data = get_object_vars($row); + } + + $this->setDefaults($data); + } + + /** + * Prepare the form for mode delete + * + * Verifies that the repository contains the entry to delete. + * + * @throws NotFoundError In case the entry to delete cannot be found + */ + protected function onDeleteRequest() + { + if (! $this->entryExists()) { + throw new NotFoundError('Entry "%s" not found', $this->getIdentifier()); + } + } + + /** + * Apply the requested mode on the repository + * + * @return ?bool + */ + public function onSuccess() + { + if ($this->shouldInsert()) { + return $this->onInsertSuccess(); + } elseif ($this->shouldUpdate()) { + return $this->onUpdateSuccess(); + } elseif ($this->shouldDelete()) { + return $this->onDeleteSuccess(); + } + } + + /** + * Apply mode insert on the repository + * + * @return bool + */ + protected function onInsertSuccess() + { + try { + $this->insertEntry(); + } catch (Exception $e) { + Notification::error($this->getInsertMessage(false)); + $this->error($e->getMessage()); + return false; + } + + Notification::success($this->getInsertMessage(true)); + return true; + } + + /** + * Apply mode update on the repository + * + * @return bool + */ + protected function onUpdateSuccess() + { + try { + $this->updateEntry(); + } catch (Exception $e) { + Notification::error($this->getUpdateMessage(false)); + $this->error($e->getMessage()); + return false; + } + + Notification::success($this->getUpdateMessage(true)); + return true; + } + + /** + * Apply mode delete on the repository + * + * @return bool + */ + protected function onDeleteSuccess() + { + try { + $this->deleteEntry(); + } catch (Exception $e) { + Notification::error($this->getDeleteMessage(false)); + $this->error($e->getMessage()); + return false; + } + + Notification::success($this->getDeleteMessage(true)); + return true; + } + + /** + * Create and add elements to this form to insert an entry + * + * @param array $formData The data sent by the user + */ + abstract protected function createInsertElements(array $formData); + + /** + * Create and add elements to this form to update an entry + * + * Calls createInsertElements() by default. Overwrite this to add different elements when in mode update. + * + * @param array $formData The data sent by the user + */ + protected function createUpdateElements(array $formData) + { + $this->createInsertElements($formData); + } + + /** + * Create and add elements to this form to delete an entry + * + * @param array $formData The data sent by the user + */ + abstract protected function createDeleteElements(array $formData); + + /** + * Create and return a filter to use when selecting, updating or deleting an entry + * + * @return Filter + */ + abstract protected function createFilter(); + + /** + * Return a notification message to use when inserting an entry + * + * @param bool $success true or false, whether the operation was successful + * + * @return string + */ + abstract protected function getInsertMessage($success); + + /** + * Return a notification message to use when updating an entry + * + * @param bool $success true or false, whether the operation was successful + * + * @return string + */ + abstract protected function getUpdateMessage($success); + + /** + * Return a notification message to use when deleting an entry + * + * @param bool $success true or false, whether the operation was successful + * + * @return string + */ + abstract protected function getDeleteMessage($success); +} |