Skip to content

Commit 9bef76d

Browse files
committed
added extra confirmation on deleting admin
Signed-off-by: MarioRadu <[email protected]>
1 parent a67871c commit 9bef76d

File tree

10 files changed

+180
-37
lines changed

10 files changed

+180
-37
lines changed

.laminas-ci/pre-run.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,4 @@ if [[ ${COMMAND} =~ phpunit ]];then
1212
cp config/autoload/mail.local.php.dist config/autoload/mail.local.php
1313
cp config/autoload/local.test.php.dist config/autoload/local.test.php
1414

15-
echo 'running if'
16-
1715
fi

psalm-baseline.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,9 @@
1616
<code>init</code>
1717
</UndefinedInterfaceMethod>
1818
</file>
19+
<file src="src/Admin/src/Form/AdminDeleteForm.php">
20+
<UndefinedInterfaceMethod>
21+
<code>init</code>
22+
</UndefinedInterfaceMethod>
23+
</file>
1924
</files>

public/js/app.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Admin/src/ConfigProvider.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Frontend\Admin\Entity\Admin;
1414
use Frontend\Admin\Entity\AdminInterface;
1515
use Frontend\Admin\Factory\AuthenticationServiceFactory;
16+
use Frontend\Admin\Form\AdminDeleteForm;
1617
use Frontend\Admin\Form\AdminForm;
1718
use Frontend\Admin\Form\ChangePasswordForm;
1819
use Frontend\Admin\Form\LoginForm;
@@ -79,6 +80,7 @@ public function getForms(): array
7980
'factories' => [
8081
LoginForm::class => ElementFactory::class,
8182
ChangePasswordForm::class => ElementFactory::class,
83+
AdminDeleteForm::class => ElementFactory::class,
8284
],
8385
'aliases' => [],
8486
'delegators' => [],

src/Admin/src/Controller/AdminController.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Frontend\Admin\Entity\AdminIdentity;
1616
use Frontend\Admin\Entity\AdminLogin;
1717
use Frontend\Admin\Form\AccountForm;
18+
use Frontend\Admin\Form\AdminDeleteForm;
1819
use Frontend\Admin\Form\AdminForm;
1920
use Frontend\Admin\Form\ChangePasswordForm;
2021
use Frontend\Admin\Form\LoginForm;
@@ -161,6 +162,13 @@ public function editAction(): ResponseInterface
161162

162163
public function deleteAction(): ResponseInterface
163164
{
165+
if (! $this->isPost()) {
166+
return new JsonResponse(
167+
['message' => Message::METHOD_NOT_ALLOWED],
168+
StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED
169+
);
170+
}
171+
164172
$uuid = $this->getAttribute('uuid');
165173
if (empty($uuid)) {
166174
return new JsonResponse(
@@ -169,9 +177,17 @@ public function deleteAction(): ResponseInterface
169177
);
170178
}
171179

180+
$form = new AdminDeleteForm();
181+
$form->setData($this->getPostParams());
182+
if (! $form->isValid()) {
183+
return new JsonResponse(
184+
['message' => $this->forms->getMessages($form)],
185+
StatusCodeInterface::STATUS_BAD_REQUEST
186+
);
187+
}
188+
172189
/** @var Admin $admin */
173190
$admin = $this->adminService->getAdminRepository()->findOneBy(['uuid' => $uuid]);
174-
175191
try {
176192
$this->adminService->getAdminRepository()->deleteAdmin($admin);
177193
return new JsonResponse(['message' => Message::ADMIN_DELETED_SUCCESSFULLY]);
@@ -200,7 +216,9 @@ public function listAction(): ResponseInterface
200216
public function manageAction(): ResponseInterface
201217
{
202218
return new HtmlResponse(
203-
$this->template->render('admin::list')
219+
$this->template->render('admin::list', [
220+
'form' => new AdminDeleteForm(),
221+
])
204222
);
205223
}
206224

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Frontend\Admin\Form;
6+
7+
use Frontend\Admin\InputFilter\AdminDeleteInputFilter;
8+
use Laminas\Form\Form;
9+
use Laminas\Form\FormInterface;
10+
use Laminas\InputFilter\InputFilterInterface;
11+
12+
/** @template-extends Form<FormInterface> */
13+
class AdminDeleteForm extends Form
14+
{
15+
protected InputFilterInterface $inputFilter;
16+
17+
public function __construct(?string $name = null, array $options = [])
18+
{
19+
parent::__construct($name, $options);
20+
21+
$this->init();
22+
23+
$this->inputFilter = new AdminDeleteInputFilter();
24+
$this->inputFilter->init();
25+
}
26+
27+
public function init(): void
28+
{
29+
$this->add([
30+
'name' => 'confirmation',
31+
'type' => 'checkbox',
32+
'options' => [
33+
'label' => 'Confirmation',
34+
'checked_value' => 'yes',
35+
'unchecked_value' => 'no',
36+
],
37+
'attributes' => [
38+
'value' => 'no',
39+
'id' => 'confirmation',
40+
'class' => 'form-check-input',
41+
],
42+
]);
43+
44+
$this->add([
45+
'name' => 'close',
46+
'type' => 'button',
47+
'options' => [
48+
'label' => 'Close',
49+
],
50+
'attributes' => [
51+
'class' => 'btn btn-default',
52+
'data-bs-dismiss' => 'modal',
53+
'role' => 'button',
54+
],
55+
]);
56+
57+
$this->add([
58+
'name' => 'submit',
59+
'type' => 'submit',
60+
'attributes' => [
61+
'class' => 'btn btn-danger',
62+
'id' => 'modalDeleteBtn',
63+
'value' => 'Delete',
64+
],
65+
]);
66+
}
67+
68+
public function getInputFilter(): InputFilterInterface
69+
{
70+
return $this->inputFilter;
71+
}
72+
73+
public function setInputFilter(InputFilterInterface $inputFilter): void
74+
{
75+
$this->inputFilter = $inputFilter;
76+
$this->inputFilter->init();
77+
}
78+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Frontend\Admin\InputFilter;
6+
7+
use Laminas\InputFilter\Input;
8+
use Laminas\InputFilter\InputFilter;
9+
use Laminas\Validator\InArray;
10+
use Laminas\Validator\NotEmpty;
11+
12+
/** @extends InputFilter<object> */
13+
class AdminDeleteInputFilter extends InputFilter
14+
{
15+
public function init(): void
16+
{
17+
$confirmation = new Input('confirmation');
18+
$confirmation->setRequired(true);
19+
$confirmation->getValidatorChain()->attachByName(NotEmpty::class, [
20+
'break_chain_on_failure' => true,
21+
'message' => 'Please confirm admin deletion.',
22+
]);
23+
24+
$confirmation->getValidatorChain()->attachByName(InArray::class, [
25+
'haystack' => [
26+
'yes',
27+
],
28+
'break_chain_on_failure' => true,
29+
'message' => 'Please confirm the admin deletion.',
30+
]);
31+
32+
$this->add($confirmation);
33+
}
34+
}

src/Admin/templates/admin/list.html.twig

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,33 @@
6868
<div class="modal fade" tabindex="-1" role="dialog" id="deleteFormModal" aria-labelledby="deleteFormModal">
6969
<div class="modal-dialog" role="document">
7070
<div class="modal-content">
71+
{% set dummy = form.prepare() %}
72+
{% set dummy = form.setAttribute('id', 'deleteAdminForm') %}
73+
{{ form().openTag(form) | raw }}
7174
<div class="modal-header">
7275
<h4 class="modal-title" id="deleteFormModalTitle">Confirm Delete</h4>
7376
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
7477
</button>
7578
</div>
7679
<div class="modal-body">
77-
<div class="modal-form"></div>
78-
<div class="modal-messages"></div>
80+
<div class="modal-form">
81+
<p>Are you sure you want to delete <span id="adminIdentity"></span>?</p>
82+
<div class="form-check">
83+
{% set element = form.get('confirmation') %}
84+
{{ formElement(element) }}
85+
<label class="form-check-label" for="confirmation">Yes</label>
86+
</div>
87+
</div>
88+
<div class="modal-messages"></div>
7989
</div>
8090
<div class="modal-footer">
81-
<button type="button" class="btn btn-default" data-bs-dismiss="modal">Close</button>
82-
<button type="button" class="btn btn-danger" id="modalDeleteBtn">Delete</button>
91+
{% set element = form.get('close') %}
92+
{{ formElement(element) }}
93+
94+
{% set element = form.get('submit') %}
95+
{{ formElement(element) }}
8396
</div>
97+
{{ form().closeTag() | raw }}
8498
</div>
8599
</div>
86100
</div>

src/App/assets/js/components/_admin.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ $(document).ready(() => {
5454
});
5555
});
5656

57-
5857
$(document).on('click', '#adminEditBtn', () => {
5958
const selections = $("#bsTable").bootstrapTable('getSelections');
6059
if (selections.length !== 1) {
@@ -77,16 +76,18 @@ $(document).ready(() => {
7776
return;
7877
}
7978

80-
adminDeleteModal.find('.modal-form').html(`Are you sure you want to delete <b>${selections[0].identity}?</b>`);
79+
adminDeleteModal.find('#adminIdentity').html(`<b>${selections[0].identity}</b>`);
8180
adminDeleteModal.modal('show');
8281
});
8382

84-
$(document).on('click', '#modalDeleteBtn', () => {
83+
$("#deleteAdminForm").on('submit', (e) => {
84+
e.preventDefault();
8585
const selections = $("#bsTable").bootstrapTable('getSelections');
86-
const messages = adminDeleteModal.find('.modal-messages');
87-
request('GET', `/admin/delete/${selections[0].uuid}`)
86+
const form = $('#deleteAdminForm');
87+
const messages = $(form).find('.modal-messages');
88+
messages.html('');
89+
request('POST', `/admin/delete/${selections[0].uuid}`, new FormData(form.get(0)))
8890
.then(data => {
89-
messages.html('');
9091
messages.append(
9192
$('<div>').prop({
9293
innerHTML: data.message,
@@ -97,17 +98,22 @@ $(document).ready(() => {
9798
bsTable.bootstrapTable('refresh');
9899
setTimeout(function () {
99100
adminDeleteModal.modal('hide');
101+
messages.html('');
100102
},1500);
101103
}).catch(error => {
102-
messages.append(
103-
$('<div>').prop({
104-
innerHTML: error.cause,
105-
className: 'alert alert-danger',
106-
role: "alert"
107-
})
108-
);
109-
}).finally(() => {
110-
adminDeleteModal.modal('show');
111-
});
104+
messages.append(
105+
$('<div>').prop({
106+
innerHTML: error.cause,
107+
className: 'alert alert-danger',
108+
role: "alert"
109+
})
110+
);
111+
}).finally(() => {
112+
adminDeleteModal.modal('show');
113+
});
114+
});
115+
116+
adminDeleteModal.on('show.bs.modal', 'hidden.bs.modal', function () {
117+
adminDeleteModal.find('#confirmation').prop('checked', false);
112118
});
113119
});

src/Setting/src/Controller/SettingController.php

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,6 @@ public function __construct(
4242

4343
public function storeSettingAction(): JsonResponse
4444
{
45-
$this->denyRequest(
46-
! $this->isPost(),
47-
Message::METHOD_NOT_ALLOWED,
48-
StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED
49-
);
50-
5145
$data = json_decode($this->getRequest()->getBody()->getContents(), true);
5246
$identifier = $this->getRequest()->getAttribute('identifier');
5347
$value = $data['value'] ?? null;
@@ -96,12 +90,6 @@ public function storeSettingAction(): JsonResponse
9690

9791
public function getSettingAction(): JsonResponse
9892
{
99-
$this->denyRequest(
100-
! $this->isGet(),
101-
Message::METHOD_NOT_ALLOWED,
102-
StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED
103-
);
104-
10593
$identifier = $this->getRequest()->getAttribute('identifier');
10694
$inputFilter = new SettingInputFilter();
10795
$inputFilter->setData([

0 commit comments

Comments
 (0)