summaryrefslogtreecommitdiffstats
path: root/application/forms/Jobs/ScheduleForm.php
diff options
context:
space:
mode:
Diffstat (limited to 'application/forms/Jobs/ScheduleForm.php')
-rw-r--r--application/forms/Jobs/ScheduleForm.php201
1 files changed, 201 insertions, 0 deletions
diff --git a/application/forms/Jobs/ScheduleForm.php b/application/forms/Jobs/ScheduleForm.php
new file mode 100644
index 0000000..ae47e58
--- /dev/null
+++ b/application/forms/Jobs/ScheduleForm.php
@@ -0,0 +1,201 @@
+<?php
+
+/* Icinga Web 2 X.509 Module | (c) 2023 Icinga GmbH | GPLv2 */
+
+namespace Icinga\Module\X509\Forms\Jobs;
+
+use DateTime;
+use Exception;
+use Icinga\Application\Icinga;
+use Icinga\Application\Web;
+use Icinga\Authentication\Auth;
+use Icinga\Module\X509\Common\Database;
+use Icinga\Module\X509\Model\X509Schedule;
+use Icinga\User;
+use Icinga\Util\Json;
+use Icinga\Web\Notification;
+use ipl\Html\BaseHtmlElement;
+use ipl\Html\Contract\FormSubmitElement;
+use ipl\Html\HtmlDocument;
+use ipl\Html\HtmlElement;
+use ipl\Validator\CallbackValidator;
+use ipl\Web\Compat\CompatForm;
+use ipl\Web\FormElement\ScheduleElement;
+use Psr\Http\Message\RequestInterface;
+
+use function ipl\Stdlib\get_php_type;
+
+class ScheduleForm extends CompatForm
+{
+ /** @var int */
+ protected $jobId;
+
+ /** @var ?X509Schedule */
+ protected $schedule;
+
+ /** @var ScheduleElement */
+ protected $scheduleElement;
+
+ public function __construct(X509Schedule $schedule = null)
+ {
+ $this->schedule = $schedule;
+ $this->scheduleElement = new ScheduleElement('schedule_element');
+
+ /** @var Web $app */
+ $app = Icinga::app();
+ $this->scheduleElement->setIdProtector([$app->getRequest(), 'protectId']);
+ }
+
+ protected function isUpdating(): bool
+ {
+ return $this->schedule !== null;
+ }
+
+ public function setJobId(int $jobId): self
+ {
+ $this->jobId = $jobId;
+
+ return $this;
+ }
+
+ /**
+ * Get multipart updates
+ *
+ * @return array<int, BaseHtmlElement>
+ */
+ public function getPartUpdates(): array
+ {
+ /** @var RequestInterface $request */
+ $request = $this->getRequest();
+
+ return $this->scheduleElement->prepareMultipartUpdate($request);
+ }
+
+ public function hasBeenSubmitted(): bool
+ {
+ if (! $this->hasBeenSent()) {
+ return false;
+ }
+
+ $button = $this->getPressedSubmitElement();
+
+ return $button && ($button->getName() === 'submit' || $button->getName() === 'btn_remove');
+ }
+
+ protected function assemble(): void
+ {
+ $this->addElement('text', 'name', [
+ 'required' => true,
+ 'label' => $this->translate('Name'),
+ 'description' => $this->translate('Schedule name'),
+ ]);
+
+ $this->addElement('checkbox', 'full_scan', [
+ 'required' => false,
+ 'class' => 'autosubmit',
+ 'label' => $this->translate('Full Scan'),
+ 'description' => $this->translate(
+ 'Scan all known and unknown targets of this job. (Defaults to only scan unknown targets)'
+ )
+ ]);
+
+ if ($this->getPopulatedValue('full_scan', 'n') === 'n') {
+ $this->addElement('checkbox', 'rescan', [
+ 'required' => false,
+ 'class' => 'autosubmit',
+ 'label' => $this->translate('Rescan'),
+ 'description' => $this->translate('Rescan only targets that have been scanned before')
+ ]);
+
+ $this->addElement('text', 'since_last_scan', [
+ 'required' => false,
+ 'label' => $this->translate('Since Last Scan'),
+ 'placeholder' => '-24 hours',
+ 'description' => $this->translate(
+ 'Scan targets whose last scan is older than the specified date/time, which can also be an'
+ . ' English textual datetime description like "2 days". If you want to scan only unknown targets'
+ . ' you can set this to "null".'
+ ),
+ 'validators' => [
+ new CallbackValidator(function ($value, CallbackValidator $validator) {
+ if ($value !== null && $value !== 'null') {
+ try {
+ new DateTime($value);
+ } catch (Exception $_) {
+ $validator->addMessage($this->translate('Invalid textual date time'));
+
+ return false;
+ }
+ }
+
+ return true;
+ })
+ ]
+ ]);
+ }
+
+ $this->addHtml(HtmlElement::create('div', ['class' => 'schedule-element-separator']));
+ $this->addElement($this->scheduleElement);
+
+ $this->addElement('submit', 'submit', [
+ 'label' => $this->isUpdating() ? $this->translate('Update') : $this->translate('Schedule')
+ ]);
+
+ if ($this->isUpdating()) {
+ $removeButton = $this->createElement('submit', 'btn_remove', [
+ 'class' => 'btn-remove',
+ 'label' => $this->translate('Remove Schedule'),
+ ]);
+ $this->registerElement($removeButton);
+
+ /** @var HtmlDocument $wrapper */
+ $wrapper = $this->getElement('submit')->getWrapper();
+ $wrapper->prepend($removeButton);
+ }
+ }
+
+ protected function onSuccess(): void
+ {
+ /** @var X509Schedule $schedule */
+ $schedule = $this->schedule;
+ $conn = Database::get();
+ /** @var FormSubmitElement $submitElement */
+ $submitElement = $this->getPressedSubmitElement();
+ if ($submitElement->getName() === 'btn_remove') {
+ $conn->delete('x509_schedule', ['id = ?' => $schedule->id]);
+
+ Notification::success($this->translate('Deleted schedule successfully'));
+ } else {
+ $config = $this->getValues();
+ unset($config['name']);
+ unset($config['schedule_element']);
+
+ $frequency = $this->scheduleElement->getValue();
+ $config['type'] = get_php_type($frequency);
+ $config['frequency'] = Json::encode($frequency);
+
+ /** @var User $user */
+ $user = Auth::getInstance()->getUser();
+ if (! $this->isUpdating()) {
+ $conn->insert('x509_schedule', [
+ 'job_id' => $this->schedule ? $this->schedule->job_id : $this->jobId,
+ 'name' => $this->getValue('name'),
+ 'author' => $user->getUsername(),
+ 'config' => Json::encode($config),
+ 'ctime' => (new DateTime())->getTimestamp() * 1000.0,
+ 'mtime' => (new DateTime())->getTimestamp() * 1000.0
+ ]);
+ $message = $this->translate('Created schedule successfully');
+ } else {
+ $conn->update('x509_schedule', [
+ 'name' => $this->getValue('name'),
+ 'config' => Json::encode($config),
+ 'mtime' => (new DateTime())->getTimestamp() * 1000.0
+ ], ['id = ?' => $schedule->id]);
+ $message = $this->translate('Updated schedule successfully');
+ }
+
+ Notification::success($message);
+ }
+ }
+}