Skip to content

Commit

Permalink
Merge pull request #265 from dotkernel/issue-241
Browse files Browse the repository at this point in the history
Refactored handler
  • Loading branch information
arhimede authored Jul 25, 2024
2 parents 8eafd9b + bab6f37 commit a1bb87d
Show file tree
Hide file tree
Showing 18 changed files with 233 additions and 98 deletions.
2 changes: 0 additions & 2 deletions .laminas-ci/pre-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,4 @@ if [[ ${COMMAND} =~ phpunit ]];then
cp config/autoload/mail.local.php.dist config/autoload/mail.local.php
cp config/autoload/local.test.php.dist config/autoload/local.test.php

echo 'running if'

fi
10 changes: 10 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,14 @@
<code>iterable</code>
</LessSpecificImplementedReturnType>
</file>
<file src="src/Admin/src/Form/AdminForm.php">
<UndefinedInterfaceMethod>
<code>init</code>
</UndefinedInterfaceMethod>
</file>
<file src="src/Admin/src/Form/AdminDeleteForm.php">
<UndefinedInterfaceMethod>
<code>init</code>
</UndefinedInterfaceMethod>
</file>
</files>
2 changes: 1 addition & 1 deletion public/js/app.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/Admin/src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Frontend\Admin\Entity\Admin;
use Frontend\Admin\Entity\AdminInterface;
use Frontend\Admin\Factory\AuthenticationServiceFactory;
use Frontend\Admin\Form\AdminDeleteForm;
use Frontend\Admin\Form\AdminForm;
use Frontend\Admin\Form\ChangePasswordForm;
use Frontend\Admin\Form\LoginForm;
Expand Down Expand Up @@ -79,6 +80,7 @@ public function getForms(): array
'factories' => [
LoginForm::class => ElementFactory::class,
ChangePasswordForm::class => ElementFactory::class,
AdminDeleteForm::class => ElementFactory::class,
],
'aliases' => [],
'delegators' => [],
Expand Down
67 changes: 33 additions & 34 deletions src/Admin/src/Controller/AdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,26 @@

namespace Frontend\Admin\Controller;

use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\NonUniqueResultException;
use Dot\Controller\AbstractActionController;
use Dot\DependencyInjection\Attribute\Inject;
use Dot\FlashMessenger\FlashMessengerInterface;
use Exception;
use Fig\Http\Message\RequestMethodInterface;
use Fig\Http\Message\StatusCodeInterface;
use Frontend\Admin\Adapter\AuthenticationAdapter;
use Frontend\Admin\Entity\Admin;
use Frontend\Admin\Entity\AdminIdentity;
use Frontend\Admin\Entity\AdminLogin;
use Frontend\Admin\Form\AccountForm;
use Frontend\Admin\Form\AdminDeleteForm;
use Frontend\Admin\Form\AdminForm;
use Frontend\Admin\Form\ChangePasswordForm;
use Frontend\Admin\Form\LoginForm;
use Frontend\Admin\FormData\AdminFormData;
use Frontend\Admin\InputFilter\EditAdminInputFilter;
use Frontend\Admin\Service\AdminServiceInterface;
use Frontend\App\Common\ServerRequestAwareTrait;
use Frontend\App\Exception\IdentityException;
use Frontend\App\Message;
use Frontend\App\Plugin\FormsPlugin;
use Laminas\Authentication\AuthenticationServiceInterface;
Expand All @@ -37,8 +38,6 @@
use Psr\Http\Message\ResponseInterface;
use Throwable;

use function password_verify;

class AdminController extends AbstractActionController
{
use ServerRequestAwareTrait;
Expand Down Expand Up @@ -75,11 +74,11 @@ public function addAction(): ResponseInterface
try {
$this->adminService->createAdmin($result);
return new JsonResponse(['message' => Message::ADMIN_CREATED_SUCCESSFULLY]);
} catch (ORMException $e) {
} catch (IdentityException $e) {
$this->logErrors($e, Message::CREATE_ADMIN);
return new JsonResponse(
['message' => $e->getMessage()],
StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR
StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY
);
} catch (Throwable $e) {
$this->logErrors($e, Message::CREATE_ADMIN);
Expand All @@ -102,14 +101,12 @@ public function addAction(): ResponseInterface
[
'form' => $this->adminForm,
'formAction' => '/admin/add',
'method' => RequestMethodInterface::METHOD_POST,
]
),
]);
}

/**
* @throws NonUniqueResultException
*/
public function editAction(): ResponseInterface
{
$uuid = $this->getAttribute('uuid');
Expand All @@ -121,18 +118,18 @@ public function editAction(): ResponseInterface

if ($this->isPost()) {
$this->adminForm->setData($this->getPostParams());
$this->adminForm->setDifferentInputFilter(new EditAdminInputFilter());
$this->adminForm->setInputFilter(new EditAdminInputFilter());
if ($this->adminForm->isValid()) {
/** @var array $result */
$result = $this->adminForm->getData();
try {
$this->adminService->updateAdmin($admin, $result);
return new JsonResponse(['message' => Message::ADMIN_UPDATED_SUCCESSFULLY]);
} catch (ORMException $e) {
} catch (IdentityException $e) {
$this->logErrors($e, Message::UPDATE_ADMIN);
return new JsonResponse(
['message' => $e->getMessage()],
StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR
StatusCodeInterface::STATUS_UNPROCESSABLE_ENTITY
);
} catch (Throwable $e) {
$this->logErrors($e, Message::UPDATE_ADMIN);
Expand All @@ -157,24 +154,19 @@ public function editAction(): ResponseInterface
[
'form' => $this->adminForm,
'formAction' => '/admin/edit/' . $uuid,
'method' => RequestMethodInterface::METHOD_POST,
]
),
]);
}

/**
* @throws NonUniqueResultException
*/
public function deleteAction(): ResponseInterface
{
if (! $this->isDelete()) {
return new JsonResponse([
'error' => [
'messages' => [
[Message::METHOD_NOT_ALLOWED],
],
],
], StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED);
if (! $this->isPost()) {
return new JsonResponse(
['message' => Message::METHOD_NOT_ALLOWED],
StatusCodeInterface::STATUS_METHOD_NOT_ALLOWED
);
}

$uuid = $this->getAttribute('uuid');
Expand All @@ -185,9 +177,17 @@ public function deleteAction(): ResponseInterface
);
}

$form = new AdminDeleteForm();
$form->setData($this->getPostParams());
if (! $form->isValid()) {
return new JsonResponse(
['message' => $this->forms->getMessages($form)],
StatusCodeInterface::STATUS_BAD_REQUEST
);
}

/** @var Admin $admin */
$admin = $this->adminService->getAdminRepository()->findOneBy(['uuid' => $uuid]);

try {
$this->adminService->getAdminRepository()->deleteAdmin($admin);
return new JsonResponse(['message' => Message::ADMIN_DELETED_SUCCESSFULLY]);
Expand All @@ -200,9 +200,6 @@ public function deleteAction(): ResponseInterface
}
}

/**
* @throws NonUniqueResultException
*/
public function listAction(): ResponseInterface
{
$result = $this->adminService->getAdmins(
Expand All @@ -219,7 +216,9 @@ public function listAction(): ResponseInterface
public function manageAction(): ResponseInterface
{
return new HtmlResponse(
$this->template->render('admin::list')
$this->template->render('admin::list', [
'form' => new AdminDeleteForm(),
])
);
}

Expand All @@ -233,8 +232,7 @@ public function loginAction(): ResponseInterface
return new RedirectResponse($this->router->generateUri("dashboard"));
}

$form = new LoginForm();

$form = new LoginForm();
$shouldRebind = $this->messenger->getData('shouldRebind') ?? true;
if ($shouldRebind) {
$this->forms->restoreState($form);
Expand Down Expand Up @@ -297,6 +295,7 @@ public function loginAction(): ResponseInterface
public function logoutAction(): ResponseInterface
{
$this->authenticationService->clearIdentity();

return new RedirectResponse(
$this->router->generateUri('admin', ['action' => 'login'])
);
Expand All @@ -317,7 +316,7 @@ public function accountAction(): ResponseInterface
try {
$this->adminService->updateAdmin($admin, $result);
$this->messenger->addSuccess(Message::ACCOUNT_UPDATE_SUCCESSFULLY);
} catch (ORMException $e) {
} catch (IdentityException $e) {
$this->logErrors($e, Message::UPDATE_ADMIN);
$this->messenger->addError($e->getMessage());
} catch (Throwable $e) {
Expand Down Expand Up @@ -354,11 +353,11 @@ public function changePasswordAction(): ResponseInterface
if ($changePasswordForm->isValid()) {
/** @var array $result */
$result = $changePasswordForm->getData();
if (password_verify($result['currentPassword'], $admin->getPassword())) {
if ($admin->verifyPassword($result['currentPassword'])) {
try {
$this->adminService->updateAdmin($admin, $result);
$this->messenger->addSuccess(Message::ACCOUNT_UPDATE_SUCCESSFULLY);
} catch (ORMException $e) {
} catch (IdentityException $e) {
$this->logErrors($e, Message::CHANGE_PASSWORD);
$this->messenger->addError($e->getMessage());
} catch (Throwable $e) {
Expand Down Expand Up @@ -398,7 +397,7 @@ public function listLoginsAction(): ResponseInterface
return new JsonResponse($result);
}

public function logErrors(Throwable|Exception $e, string $message): void
private function logErrors(Throwable $e, string $message): void
{
$this->logger->err($message, [
'error' => $e->getMessage(),
Expand Down
6 changes: 6 additions & 0 deletions src/Admin/src/Entity/Admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Frontend\Setting\Entity\Setting;

use function array_map;
use function password_verify;

#[ORM\Entity(repositoryClass: AdminRepository::class)]
#[ORM\Table(name: "admin")]
Expand Down Expand Up @@ -131,6 +132,11 @@ public function setPassword(string $password): self
return $this;
}

public function verifyPassword(string $password): bool
{
return password_verify($password, $this->getPassword());
}

public function getStatus(): string
{
return $this->status;
Expand Down
78 changes: 78 additions & 0 deletions src/Admin/src/Form/AdminDeleteForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

declare(strict_types=1);

namespace Frontend\Admin\Form;

use Frontend\Admin\InputFilter\AdminDeleteInputFilter;
use Laminas\Form\Form;
use Laminas\Form\FormInterface;
use Laminas\InputFilter\InputFilterInterface;

/** @template-extends Form<FormInterface> */
class AdminDeleteForm extends Form
{
protected InputFilterInterface $inputFilter;

public function __construct(?string $name = null, array $options = [])
{
parent::__construct($name, $options);

$this->init();

$this->inputFilter = new AdminDeleteInputFilter();
$this->inputFilter->init();
}

public function init(): void
{
$this->add([
'name' => 'confirmation',
'type' => 'checkbox',
'options' => [
'label' => 'Confirmation',
'checked_value' => 'yes',
'unchecked_value' => 'no',
],
'attributes' => [
'value' => 'no',
'id' => 'confirmation',
'class' => 'form-check-input',
],
]);

$this->add([
'name' => 'close',
'type' => 'button',
'options' => [
'label' => 'Close',
],
'attributes' => [
'class' => 'btn btn-default',
'data-bs-dismiss' => 'modal',
'role' => 'button',
],
]);

$this->add([
'name' => 'submit',
'type' => 'submit',
'attributes' => [
'class' => 'btn btn-danger',
'id' => 'modalDeleteBtn',
'value' => 'Delete',
],
]);
}

public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}

public function setInputFilter(InputFilterInterface $inputFilter): void
{
$this->inputFilter = $inputFilter;
$this->inputFilter->init();
}
}
3 changes: 1 addition & 2 deletions src/Admin/src/Form/AdminForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Frontend\Admin\InputFilter\AdminInputFilter;
use Laminas\Form\Form;
use Laminas\Form\FormInterface;
use Laminas\InputFilter\InputFilter;
use Laminas\InputFilter\InputFilterInterface;

/** @template-extends Form<FormInterface> */
Expand Down Expand Up @@ -119,7 +118,7 @@ public function getInputFilter(): InputFilterInterface
return $this->inputFilter;
}

public function setDifferentInputFilter(InputFilter $inputFilter): void
public function setInputFilter(InputFilterInterface $inputFilter): void
{
$this->inputFilter = $inputFilter;
$this->inputFilter->init();
Expand Down
34 changes: 34 additions & 0 deletions src/Admin/src/InputFilter/AdminDeleteInputFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Frontend\Admin\InputFilter;

use Laminas\InputFilter\Input;
use Laminas\InputFilter\InputFilter;
use Laminas\Validator\InArray;
use Laminas\Validator\NotEmpty;

/** @extends InputFilter<object> */
class AdminDeleteInputFilter extends InputFilter
{
public function init(): void
{
$confirmation = new Input('confirmation');
$confirmation->setRequired(true);
$confirmation->getValidatorChain()->attachByName(NotEmpty::class, [
'break_chain_on_failure' => true,
'message' => 'Please confirm admin deletion.',
]);

$confirmation->getValidatorChain()->attachByName(InArray::class, [
'haystack' => [
'yes',
],
'break_chain_on_failure' => true,
'message' => 'Please confirm the admin deletion.',
]);

$this->add($confirmation);
}
}
Loading

0 comments on commit a1bb87d

Please sign in to comment.