diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
new file mode 100644
index 00000000..8fa0c48a
--- /dev/null
+++ b/.github/workflows/static-analysis.yml
@@ -0,0 +1,46 @@
+on:
+ # - pull_request
+ - push
+
+name: static analysis
+
+jobs:
+ mutation:
+ name: PHP ${{ matrix.php }}-${{ matrix.os }}
+
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ matrix:
+ os:
+ - ubuntu-latest
+
+ php:
+ - "7.4"
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2.3.4
+
+ - name: Install PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: "${{ matrix.php }}"
+ tools: composer:v2, cs2pr
+ coverage: none
+
+ - name: Determine composer cache directory
+ run: echo "COMPOSER_CACHE_DIR=$(composer config cache-dir)" >> $GITHUB_ENV
+
+ - name: Cache dependencies installed with composer
+ uses: actions/cache@v2
+ with:
+ path: ${{ env.COMPOSER_CACHE_DIR }}
+ key: php${{ matrix.php }}-composer-${{ hashFiles('**/composer.json') }}
+ restore-keys: |
+ php${{ matrix.php }}-composer-
+ - name: Install dependencies with composer
+ run: composer update --prefer-dist --no-interaction --no-progress --optimize-autoloader --ansi
+
+ - name: Static analysis
+ run: vendor/bin/psalm --no-cache --output-format=github --show-info=false --threads=4
diff --git a/bin/doctrine b/bin/doctrine
index e67edec7..33b919c9 100644
--- a/bin/doctrine
+++ b/bin/doctrine
@@ -1,3 +1,4 @@
+#!/usr/bin/env php
addSql('CREATE TABLE contact_message (uuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', email VARCHAR(150) NOT NULL, name VARCHAR(150) NOT NULL, subject LONGTEXT NOT NULL, message LONGTEXT NOT NULL, platform LONGTEXT NOT NULL, created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE user (uuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', identity VARCHAR(191) NOT NULL, password VARCHAR(191) NOT NULL, status ENUM(\'pending\', \'active\'), isDeleted TINYINT(1) NOT NULL, hash VARCHAR(64) NOT NULL, created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', UNIQUE INDEX UNIQ_8D93D6496A95E9C4 (identity), UNIQUE INDEX UNIQ_8D93D649D1B862B8 (hash), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE user_roles (userUuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', roleUuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', INDEX IDX_54FCD59FD73087E9 (userUuid), INDEX IDX_54FCD59F88446210 (roleUuid), PRIMARY KEY(userUuid, roleUuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE user_avatar (uuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', name VARCHAR(191) NOT NULL, created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', userUuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', UNIQUE INDEX UNIQ_73256912D73087E9 (userUuid), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE user_detail (uuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', firstName VARCHAR(191) DEFAULT NULL, lastName VARCHAR(191) DEFAULT NULL, created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', userUuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', UNIQUE INDEX UNIQ_4B5464AED73087E9 (userUuid), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE user_remember_me (uuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', rememberMeToken VARCHAR(100) NOT NULL, userAgent VARCHAR(100) NOT NULL, expireDate DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', userUuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', UNIQUE INDEX UNIQ_D3E96EBD1BBB86A0 (rememberMeToken), UNIQUE INDEX UNIQ_D3E96EBDD73087E9 (userUuid), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE user_reset_password (uuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', expires DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', hash VARCHAR(64) NOT NULL, status VARCHAR(20) NOT NULL, created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', userUuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', UNIQUE INDEX UNIQ_D21DE3BCD1B862B8 (hash), INDEX IDX_D21DE3BCD73087E9 (userUuid), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('CREATE TABLE user_role (uuid BINARY(16) NOT NULL COMMENT \'(DC2Type:uuid_binary_ordered_time)\', name VARCHAR(30) NOT NULL, created DATETIME NOT NULL COMMENT \'(DC2Type:datetime_immutable)\', updated DATETIME DEFAULT NULL COMMENT \'(DC2Type:datetime_immutable)\', UNIQUE INDEX UNIQ_2DE8C6A35E237E06 (name), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
+ $this->addSql('ALTER TABLE user_roles ADD CONSTRAINT FK_54FCD59FD73087E9 FOREIGN KEY (userUuid) REFERENCES user (uuid)');
+ $this->addSql('ALTER TABLE user_roles ADD CONSTRAINT FK_54FCD59F88446210 FOREIGN KEY (roleUuid) REFERENCES user_role (uuid)');
+ $this->addSql('ALTER TABLE user_avatar ADD CONSTRAINT FK_73256912D73087E9 FOREIGN KEY (userUuid) REFERENCES user (uuid)');
+ $this->addSql('ALTER TABLE user_detail ADD CONSTRAINT FK_4B5464AED73087E9 FOREIGN KEY (userUuid) REFERENCES user (uuid)');
+ $this->addSql('ALTER TABLE user_remember_me ADD CONSTRAINT FK_D3E96EBDD73087E9 FOREIGN KEY (userUuid) REFERENCES user (uuid)');
+ $this->addSql('ALTER TABLE user_reset_password ADD CONSTRAINT FK_D21DE3BCD73087E9 FOREIGN KEY (userUuid) REFERENCES user (uuid)');
+ }
+
+ public function down(Schema $schema): void
+ {
+ // this down() migration is auto-generated, please modify it to your needs
+ $this->addSql('ALTER TABLE user_roles DROP FOREIGN KEY FK_54FCD59FD73087E9');
+ $this->addSql('ALTER TABLE user_roles DROP FOREIGN KEY FK_54FCD59F88446210');
+ $this->addSql('ALTER TABLE user_avatar DROP FOREIGN KEY FK_73256912D73087E9');
+ $this->addSql('ALTER TABLE user_detail DROP FOREIGN KEY FK_4B5464AED73087E9');
+ $this->addSql('ALTER TABLE user_remember_me DROP FOREIGN KEY FK_D3E96EBDD73087E9');
+ $this->addSql('ALTER TABLE user_reset_password DROP FOREIGN KEY FK_D21DE3BCD73087E9');
+ $this->addSql('DROP TABLE contact_message');
+ $this->addSql('DROP TABLE user');
+ $this->addSql('DROP TABLE user_roles');
+ $this->addSql('DROP TABLE user_avatar');
+ $this->addSql('DROP TABLE user_detail');
+ $this->addSql('DROP TABLE user_remember_me');
+ $this->addSql('DROP TABLE user_reset_password');
+ $this->addSql('DROP TABLE user_role');
+ }
+}
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 00000000..3e4e3d08
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/App/src/Common/Pagination.php b/src/App/src/Common/Pagination.php
index 9df396b9..7b2843f2 100644
--- a/src/App/src/Common/Pagination.php
+++ b/src/App/src/Common/Pagination.php
@@ -30,8 +30,8 @@ public static function getOffsetAndLimit(array $filters = [])
}
return [
- 'offset' => (int)$offset,
- 'limit' => (int)$limit
+ 'offset' => $offset,
+ 'limit' => $limit
];
}
}
diff --git a/src/App/src/Common/UuidOrderedTimeGenerator.php b/src/App/src/Common/UuidOrderedTimeGenerator.php
index f58728af..780f6fa5 100644
--- a/src/App/src/Common/UuidOrderedTimeGenerator.php
+++ b/src/App/src/Common/UuidOrderedTimeGenerator.php
@@ -4,11 +4,11 @@
namespace Frontend\App\Common;
-use Exception;
use Ramsey\Uuid\Codec\OrderedTimeCodec;
-use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidFactory;
+use Ramsey\Uuid\UuidFactoryInterface;
use Ramsey\Uuid\UuidInterface;
+use Ramsey\Uuid\Uuid;
/**
* Class UuidOrderedTimeGenerator
@@ -16,35 +16,19 @@
*/
final class UuidOrderedTimeGenerator
{
- /** @var UuidFactory $factory */
- private static $factory;
+ private static UuidFactoryInterface $factory;
- /**
- * @return UuidInterface
- */
public static function generateUuid(): UuidInterface
{
- try {
- return self::getFactory()->uuid1();
- } catch (Exception $exception) {
- return null;
- }
+ return self::getFactory()->uuid1();
}
- /**
- * @return UuidFactory
- */
- private static function getFactory(): UuidFactory
+ /** @psalm-suppress UndefinedInterfaceMethod */
+ private static function getFactory(): UuidFactoryInterface
{
- if (!self::$factory) {
- self::$factory = clone Uuid::getFactory();
-
- $codec = new OrderedTimeCodec(
- self::$factory->getUuidBuilder()
- );
-
- self::$factory->setCodec($codec);
- }
+ self::$factory = clone Uuid::getFactory();
+ $codec = new OrderedTimeCodec(self::$factory->getUuidBuilder());
+ self::$factory->setCodec($codec);
return self::$factory;
}
diff --git a/src/App/src/Middleware/RememberMeMiddleware.php b/src/App/src/Middleware/RememberMeMiddleware.php
index 4709eb52..389bc18b 100644
--- a/src/App/src/Middleware/RememberMeMiddleware.php
+++ b/src/App/src/Middleware/RememberMeMiddleware.php
@@ -87,6 +87,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
$user->getDetail()->getArrayCopy(),
);
+ /** @psalm-suppress UndefinedInterfaceMethod */
$this->authenticationService->getStorage()->write($identity);
}
}
diff --git a/src/App/src/Resolver/EntityListenerResolver.php b/src/App/src/Resolver/EntityListenerResolver.php
index d4a30f04..c45413ea 100644
--- a/src/App/src/Resolver/EntityListenerResolver.php
+++ b/src/App/src/Resolver/EntityListenerResolver.php
@@ -5,7 +5,9 @@
namespace Frontend\App\Resolver;
use Doctrine\ORM\Mapping\DefaultEntityListenerResolver;
+use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
+use Psr\Container\NotFoundExceptionInterface;
/**
* Class EntityListenerResolver
@@ -14,7 +16,7 @@
class EntityListenerResolver extends DefaultEntityListenerResolver
{
/** @var ContainerInterface $container */
- protected $container;
+ protected ContainerInterface $container;
/**
* EntityListenerResolver constructor.
@@ -26,10 +28,12 @@ public function __construct(ContainerInterface $container)
}
/**
- * @param $className
- * @return mixed
+ * @param string $className
+ * @return object
+ * @throws ContainerExceptionInterface
+ * @throws NotFoundExceptionInterface
*/
- public function resolve($className)
+ public function resolve($className): object
{
return $this->container->get($className);
}
diff --git a/src/App/src/Service/RecaptchaService.php b/src/App/src/Service/RecaptchaService.php
index 868c68e8..cae6905b 100644
--- a/src/App/src/Service/RecaptchaService.php
+++ b/src/App/src/Service/RecaptchaService.php
@@ -46,7 +46,7 @@ public function setResponse(string $response): self
*/
public function isValid(): bool
{
- if (! isset($this->response)) {
+ if (empty($this->response)) {
throw new InvalidArgumentException('Recaptcha response not initialized.');
}
@@ -64,6 +64,8 @@ public function isValid(): bool
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
$response = curl_exec($curl);
+
+ /** @psalm-suppress InvalidScalarArgument */
$response = json_decode($response, true);
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
diff --git a/src/Contact/src/Form/ContactForm.php b/src/Contact/src/Form/ContactForm.php
index 3d267c64..058e3f33 100644
--- a/src/Contact/src/Form/ContactForm.php
+++ b/src/Contact/src/Form/ContactForm.php
@@ -9,7 +9,7 @@
use Laminas\Form\Element\Text;
use Laminas\Form\Element\Textarea;
use Laminas\Form\Form;
-use Laminas\InputFilter\InputFilter;
+use Laminas\InputFilter\InputFilterInterface;
/**
* Class ContactForm
@@ -17,8 +17,8 @@
*/
class ContactForm extends Form
{
- /** @var InputFilter $inputFilter */
- protected $inputFilter;
+ /** @var InputFilterInterface $inputFilter */
+ protected InputFilterInterface $inputFilter;
/**
* ContactForm constructor.
@@ -84,21 +84,12 @@ public function init()
],
'type' => Textarea::class,
]);
-
-// $this->add([
-// 'name' => 'submit',
-// 'type' => 'submit',
-// 'attributes' => [
-// 'type' => 'submit',
-// 'value' => 'Send message'
-// ]
-// ], ['priority' => -105]);
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/Plugin/src/ConfigProvider.php b/src/Plugin/src/ConfigProvider.php
index fad952a0..5ebad757 100644
--- a/src/Plugin/src/ConfigProvider.php
+++ b/src/Plugin/src/ConfigProvider.php
@@ -4,7 +4,6 @@
namespace Frontend\Plugin;
-use Frontend\Plugin\Factory\FlashMessengerPluginFactory;
use Frontend\Plugin\Factory\FormsPluginFactory;
use Frontend\Plugin\Factory\PluginManagerAwareInitializer;
use Frontend\Plugin\Factory\PluginManagerFactory;
@@ -26,7 +25,6 @@ public function __invoke(): array
'dot_controller' => [
'plugin_manager' => [
'factories' => [
- 'messenger' => FlashMessengerPluginFactory::class,
'forms' => FormsPluginFactory::class,
],
],
diff --git a/src/Plugin/src/FormsPlugin.php b/src/Plugin/src/FormsPlugin.php
index 05e1e7fa..f279d716 100644
--- a/src/Plugin/src/FormsPlugin.php
+++ b/src/Plugin/src/FormsPlugin.php
@@ -14,9 +14,11 @@
use Dot\FlashMessenger\FlashMessengerInterface;
use Dot\Form\Factory\FormAbstractServiceFactory;
use Dot\Form\FormElementManager;
+use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Laminas\Form\Form;
use Laminas\Form\FormInterface;
+use Psr\Container\NotFoundExceptionInterface;
/**
* Class FormsPlugin
@@ -24,14 +26,14 @@
*/
class FormsPlugin implements PluginInterface
{
- /** @var FormElementManager */
- protected $formElementManager;
+ /** @var FormElementManager $formElementManager */
+ protected FormElementManager $formElementManager;
- /** @var ContainerInterface */
- protected $container;
+ /** @var ContainerInterface $container */
+ protected ContainerInterface $container;
- /** @var FlashMessengerInterface */
- protected $flashMessenger;
+ /** @var FlashMessengerInterface|null $flashMessenger*/
+ protected ?FlashMessengerInterface $flashMessenger;
/**
* FormsPlugin constructor.
@@ -50,8 +52,10 @@ public function __construct(
}
/**
- * @param string $name
- * @return object
+ * @param string|null $name
+ * @return mixed
+ * @throws ContainerExceptionInterface
+ * @throws NotFoundExceptionInterface
*/
public function __invoke(string $name = null)
{
@@ -85,7 +89,7 @@ public function __invoke(string $name = null)
/**
* @param Form $form
*/
- public function restoreState(Form $form)
+ public function restoreState(Form $form): void
{
if ($this->flashMessenger) {
$dataKey = $form->getName() . '_data';
@@ -159,6 +163,7 @@ public function getErrors(Form $form): array
/**
* @param array $formMessages
+ * @psalm-suppress InvalidArrayOffset
* @return array
*/
protected function processFormErrors(array $formMessages): array
@@ -167,7 +172,7 @@ protected function processFormErrors(array $formMessages): array
foreach ($formMessages as $key => $message) {
if (is_array($message)) {
if (!isset($errors[$key])) {
- $errors[$key] = array();
+ $errors[$key] = [];
}
foreach ($message as $k => $m) {
diff --git a/src/Plugin/src/TemplatePlugin.php b/src/Plugin/src/TemplatePlugin.php
index 3aebfe00..1d82cd7e 100644
--- a/src/Plugin/src/TemplatePlugin.php
+++ b/src/Plugin/src/TemplatePlugin.php
@@ -18,8 +18,8 @@
*/
class TemplatePlugin implements PluginInterface
{
- /** @var TemplateRendererInterface */
- protected $template;
+ /** @var TemplateRendererInterface $template */
+ protected TemplateRendererInterface $template;
/**
* TemplatePlugin constructor.
@@ -32,8 +32,8 @@ public function __construct(TemplateRendererInterface $template)
/**
* @param string|null $templateName
- * @param array|null $params
- * @return mixed
+ * @param array $params
+ * @return self|string
*/
public function __invoke(string $templateName = null, array $params = [])
{
diff --git a/src/Slug/src/SlugCollector.php b/src/Slug/src/SlugCollector.php
index 370ffd7f..4d2ec300 100644
--- a/src/Slug/src/SlugCollector.php
+++ b/src/Slug/src/SlugCollector.php
@@ -282,6 +282,7 @@ public function generateUri(Slug $slug, RouteResult $routeResult, $matchParams =
if ($part[0] !== self::REMOVABLE_PART) {
// Check substitute value with regex
+ /** @psalm-suppress UndefinedVariable */
if (!empty($addOns)) {
$substitutions[$part[0]] = $addOns[$p];
}
diff --git a/src/User/src/Authentication/AuthenticationAdapter.php b/src/User/src/Authentication/AuthenticationAdapter.php
index e5480d3e..73353f31 100644
--- a/src/User/src/Authentication/AuthenticationAdapter.php
+++ b/src/User/src/Authentication/AuthenticationAdapter.php
@@ -6,20 +6,21 @@
use Frontend\User\Entity\User;
use Frontend\User\Entity\UserIdentity;
use Frontend\User\Entity\UserRole;
+use Laminas\Authentication\Adapter\AbstractAdapter;
use Laminas\Authentication\Adapter\AdapterInterface;
use Exception;
use Laminas\Authentication\Result;
-class AuthenticationAdapter implements AdapterInterface
+class AuthenticationAdapter extends AbstractAdapter implements AdapterInterface
{
private const METHOD_NOT_EXISTS = "Method %s not found in %s .";
private const OPTION_VALUE_NOT_PROVIDED = "Option '%s' not provided for '%s' option.";
/** @var string $identity */
- private string $identity;
+ protected $identity;
/** @var string $credential */
- private string $credential;
+ protected $credential;
/** @var EntityManager $entityManager */
private EntityManager $entityManager;
@@ -38,42 +39,6 @@ public function __construct($entityManager, array $config)
$this->config = $config;
}
- /**
- * @param string $identity
- * @return $this
- */
- public function setIdentity(string $identity): self
- {
- $this->identity = $identity;
- return $this;
- }
-
- /**
- * @param string $credential
- * @return $this
- */
- public function setCredential(string $credential): self
- {
- $this->credential = $credential;
- return $this;
- }
-
- /**
- * @return string
- */
- private function getIdentity(): string
- {
- return $this->identity;
- }
-
- /**
- * @return string
- */
- private function getCredential(): string
- {
- return $this->credential;
- }
-
/**
* @return Result
* @throws Exception
@@ -99,7 +64,6 @@ public function authenticate(): Result
);
}
- /** @var callable $getCredential */
$getCredential = "get" . ucfirst($this->config['orm_default']['credential_property']);
/** Check if get credential method exist in the provided identity class */
@@ -117,7 +81,6 @@ public function authenticate(): Result
/** Check for extra validation options */
if (! empty($this->config['orm_default']['options'])) {
foreach ($this->config['orm_default']['options'] as $property => $option) {
- /** @var callable $methodName */
$methodName = "get" . ucfirst($property);
/** Check if the method exists in the provided identity class */
diff --git a/src/User/src/Authentication/AuthenticationAdapterFactory.php b/src/User/src/Authentication/AuthenticationAdapterFactory.php
index 74a4f7f7..ae2f5be3 100644
--- a/src/User/src/Authentication/AuthenticationAdapterFactory.php
+++ b/src/User/src/Authentication/AuthenticationAdapterFactory.php
@@ -15,6 +15,7 @@ class AuthenticationAdapterFactory
*/
public function __invoke(ContainerInterface $container): AuthenticationAdapter
{
+ // TODO Refactor this to use the specific entity repository, not the entity manager
if (! $container->has(EntityManager::class)) {
throw new Exception('EntityManager not found.');
}
diff --git a/src/User/src/Controller/AccountController.php b/src/User/src/Controller/AccountController.php
index 50ed92e9..9ab8c4e1 100644
--- a/src/User/src/Controller/AccountController.php
+++ b/src/User/src/Controller/AccountController.php
@@ -11,7 +11,6 @@
use Frontend\Plugin\FormsPlugin;
use Frontend\User\Entity\User;
use Frontend\User\Entity\UserIdentity;
-use Frontend\User\Entity\UserInterface;
use Frontend\User\Entity\UserResetPassword;
use Frontend\User\Form\ProfileDeleteForm;
use Frontend\User\Form\ProfileDetailsForm;
@@ -23,13 +22,11 @@
use Laminas\Authentication\AuthenticationService;
use Laminas\Authentication\AuthenticationServiceInterface;
use Laminas\Diactoros\Response\HtmlResponse;
-use Laminas\Diactoros\Response\JsonResponse;
use Laminas\Diactoros\Response\RedirectResponse;
use Mezzio\Router\RouterInterface;
use Mezzio\Template\TemplateRendererInterface;
use Dot\AnnotatedServices\Annotation\Inject;
use Psr\Http\Message\ResponseInterface;
-use Psr\Http\Message\UploadedFileInterface;
use Exception;
class AccountController extends AbstractActionController
@@ -314,7 +311,6 @@ public function avatarAction(): ResponseInterface
$this->template->render('user::profile', [
'action' => 'avatar',
'content' => $this->template->render('profile::avatar', [
- 'userUploadsBaseUrl' => 'http://localhost:8080/uploads/user/',
'user' => $user,
'form' => $form
]),
diff --git a/src/User/src/Controller/UserController.php b/src/User/src/Controller/UserController.php
index 2711707a..15b7a42e 100644
--- a/src/User/src/Controller/UserController.php
+++ b/src/User/src/Controller/UserController.php
@@ -2,16 +2,19 @@
namespace Frontend\User\Controller;
+use Doctrine\ORM\NonUniqueResultException;
+use Doctrine\ORM\OptimisticLockException;
+use Doctrine\ORM\ORMException;
use Dot\Controller\AbstractActionController;
use Dot\FlashMessenger\FlashMessenger;
use Fig\Http\Message\RequestMethodInterface;
use Frontend\Plugin\FormsPlugin;
+use Frontend\User\Authentication\AuthenticationAdapter;
use Frontend\User\Entity\User;
use Frontend\User\Form\LoginForm;
use Frontend\User\Form\RegisterForm;
use Frontend\User\Service\UserService;
use Laminas\Authentication\AuthenticationService;
-use Laminas\Authentication\AuthenticationServiceInterface;
use Laminas\Diactoros\Response\HtmlResponse;
use Laminas\Diactoros\Response\RedirectResponse;
use Mezzio\Router\RouterInterface;
@@ -31,8 +34,8 @@ class UserController extends AbstractActionController
/** @var UserService $userService */
protected UserService $userService;
- /** @var AuthenticationServiceInterface $authenticationService */
- protected AuthenticationServiceInterface $authenticationService;
+ /** @var AuthenticationService $authenticationService */
+ protected AuthenticationService $authenticationService;
/** @var FlashMessenger $messenger */
protected FlashMessenger $messenger;
@@ -81,14 +84,17 @@ public function __construct(
}
/**
- * @throws \Doctrine\ORM\NonUniqueResultException
+ * @return ResponseInterface
+ * @throws NonUniqueResultException
+ * @throws ORMException
+ * @throws OptimisticLockException
*/
public function loginAction(): ResponseInterface
{
if ($this->authenticationService->hasIdentity()) {
return new RedirectResponse($this->router->generateUri("page"));
}
- /** @var LoginForm $form */
+
$form = new LoginForm();
$shouldRebind = $this->messenger->getData('shouldRebind') ?? true;
@@ -99,6 +105,7 @@ public function loginAction(): ResponseInterface
if (RequestMethodInterface::METHOD_POST === $this->getRequest()->getMethod()) {
$form->setData($this->getRequest()->getParsedBody());
if ($form->isValid()) {
+ /** @var AuthenticationAdapter $adapter */
$adapter = $this->authenticationService->getAdapter();
$data = $form->getData();
$adapter->setIdentity($data['identity'])->setCredential($data['password']);
diff --git a/src/User/src/Entity/User.php b/src/User/src/Entity/User.php
index 78ccbddf..8961cfe7 100644
--- a/src/User/src/Entity/User.php
+++ b/src/User/src/Entity/User.php
@@ -5,12 +5,13 @@
namespace Frontend\User\Entity;
use Doctrine\Common\Collections\ArrayCollection;
-use Doctrine\ORM\Mapping as ORM;
+use Doctrine\Common\Collections\Collection;
+use Dot\Authorization\Role\RoleInterface;
use Frontend\App\Common\AbstractEntity;
use Frontend\App\Common\UuidOrderedTimeGenerator;
+use Doctrine\ORM\Mapping as ORM;
use Exception;
-use function array_map;
use function bin2hex;
use function random_bytes;
@@ -40,45 +41,38 @@ class User extends AbstractEntity implements UserInterface
/**
* @ORM\OneToOne(targetEntity="Frontend\User\Entity\UserDetail", cascade={"persist", "remove"}, mappedBy="user")
- * @var UserDetail $detail
*/
- protected $detail;
+ protected UserDetail $detail;
/**
* @ORM\OneToOne(targetEntity="Frontend\User\Entity\UserAvatar", cascade={"persist", "remove"}, mappedBy="user")
- * @var UserAvatar $avatar
*/
- protected $avatar;
+ protected ?UserAvatar $avatar;
/**
* @ORM\Column(name="identity", type="string", length=191, nullable=false, unique=true)
- * @var string $identity
*/
- protected $identity;
+ protected string $identity;
/**
* @ORM\Column(name="password", type="string", length=191, nullable=false)
- * @var string $password
*/
- protected $password;
+ protected string $password;
/**
* @ORM\Column(name="status", type="string", length=20, columnDefinition="ENUM('pending', 'active')")
- * @var string $status
*/
- protected $status = self::STATUS_PENDING;
+ protected string $status = self::STATUS_PENDING;
/**
* @ORM\Column(name="isDeleted", type="boolean")
- * @var bool $isDeleted
*/
- protected $isDeleted = self::IS_DELETED_NO;
+ protected bool $isDeleted = self::IS_DELETED_NO;
/**
* @ORM\Column(name="hash", type="string", length=64, nullable=false, unique=true)
- * @var string $hash
*/
- protected $hash;
+ protected string $hash;
/**
* @ORM\ManyToMany(targetEntity="Frontend\User\Entity\UserRole")
@@ -87,16 +81,14 @@ class User extends AbstractEntity implements UserInterface
* joinColumns={@ORM\JoinColumn(name="userUuid", referencedColumnName="uuid")},
* inverseJoinColumns={@ORM\JoinColumn(name="roleUuid", referencedColumnName="uuid")}
* )
- * @var ArrayCollection $roles
*/
- protected $roles = [];
+ protected Collection $roles;
/**
* @ORM\OneToMany(targetEntity="UserResetPassword",
* cascade={"persist", "remove"}, mappedBy="user", fetch="EXTRA_LAZY")
- * @var UserResetPassword[] $resetPassword
*/
- protected $resetPasswords;
+ protected Collection $resetPasswords;
/**
* User constructor.
@@ -120,9 +112,9 @@ public function getDetail(): ?UserDetail
/**
* @param UserDetail $detail
- * @return UserInterface
+ * @return self
*/
- public function setDetail(UserDetail $detail): UserInterface
+ public function setDetail(UserDetail $detail): self
{
$this->detail = $detail;
@@ -139,9 +131,9 @@ public function getAvatar(): ?UserAvatar
/**
* @param UserAvatar $avatar
- * @return UserInterface
+ * @return self
*/
- public function setAvatar(UserAvatar $avatar): UserInterface
+ public function setAvatar(UserAvatar $avatar): self
{
$this->avatar = $avatar;
@@ -160,9 +152,9 @@ public function getIdentity(): string
/**
* @param string $identity
- * @return UserInterface
+ * @return self
*/
- public function setIdentity(string $identity): UserInterface
+ public function setIdentity(string $identity): self
{
$this->identity = $identity;
@@ -178,10 +170,10 @@ public function getPassword(): string
}
/**
- * @param string|null $password
- * @return UserInterface
+ * @param string $password
+ * @return self
*/
- public function setPassword(?string $password): UserInterface
+ public function setPassword(string $password): self
{
$this->password = $password;
@@ -198,9 +190,9 @@ public function getStatus(): string
/**
* @param string $status
- * @return UserInterface
+ * @return self
*/
- public function setStatus(string $status): UserInterface
+ public function setStatus(string $status): self
{
$this->status = $status;
@@ -217,9 +209,9 @@ public function getIsDeleted(): bool
/**
* @param bool $isDeleted
- * @return $this
+ * @return self
*/
- public function setIsDeleted(bool $isDeleted)
+ public function setIsDeleted(bool $isDeleted): self
{
$this->isDeleted = $isDeleted;
@@ -235,10 +227,10 @@ public function getHash(): string
}
/**
- * @param string|null $hash
- * @return $this
+ * @param string $hash
+ * @return self
*/
- public function setHash(string $hash = null)
+ public function setHash(string $hash): self
{
$this->hash = $hash;
@@ -254,10 +246,10 @@ public function getRoles()
}
/**
- * @param UserRole $role
- * @return UserInterface
+ * @param RoleInterface $role
+ * @return self
*/
- public function addRole(UserRole $role): UserInterface
+ public function addRole(RoleInterface $role): self
{
if (!$this->roles->contains($role)) {
$this->roles->add($role);
@@ -267,10 +259,10 @@ public function addRole(UserRole $role): UserInterface
}
/**
- * @param UserRole $role
- * @return UserInterface
+ * @param RoleInterface $role
+ * @return self
*/
- public function removeRole(UserRole $role): UserInterface
+ public function removeRole(RoleInterface $role): self
{
if (!$this->roles->contains($role)) {
$this->roles->removeElement($role);
@@ -280,10 +272,9 @@ public function removeRole(UserRole $role): UserInterface
}
/**
- * @return $this
- * @throws Exception
+ * @return self
*/
- public function renewHash()
+ public function renewHash(): self
{
$this->hash = self::generateHash();
@@ -292,7 +283,6 @@ public function renewHash()
/**
* @return string
- * @throws Exception
*/
public static function generateHash(): string
{
@@ -308,15 +298,15 @@ public static function generateHash(): string
/**
* @return bool
*/
- public function isActive()
+ public function isActive(): bool
{
return $this->status === self::STATUS_ACTIVE;
}
/**
- * @return $this
+ * @return self
*/
- public function markAsDeleted()
+ public function markAsDeleted(): self
{
$this->isDeleted = self::IS_DELETED_YES;
@@ -326,38 +316,37 @@ public function markAsDeleted()
/**
* @return string
*/
- public function getName()
+ public function getName(): string
{
return $this->getDetail()->getFirstName() . ' ' . $this->getDetail()->getLastName();
}
/**
- * @return User
+ * @return self
*/
- public function activate()
+ public function activate(): self
{
return $this->setStatus(self::STATUS_ACTIVE);
}
/**
- * @return $this
- * @throws Exception
+ * @return self
*/
- public function resetRoles()
+ public function resetRoles(): self
{
- foreach ($this->roles->getIterator()->getArrayCopy() as $role) {
+ $this->roles->map(function (RoleInterface $role) {
$this->removeRole($role);
- }
+ });
+
$this->roles = new ArrayCollection();
return $this;
}
/**
- * @return $this
- * @throws Exception
+ * @return self
*/
- public function createResetPassword()
+ public function createResetPassword(): self
{
$resetPassword = new UserResetPassword();
$resetPassword->setHash(self::generateHash());
@@ -370,16 +359,19 @@ public function createResetPassword()
/**
* @param UserResetPassword $resetPassword
+ * @return self
*/
- public function addResetPassword(UserResetPassword $resetPassword)
+ public function addResetPassword(UserResetPassword $resetPassword): self
{
$this->resetPasswords->add($resetPassword);
+
+ return $this;
}
/**
* @return ArrayCollection
*/
- public function getResetPasswords()
+ public function getResetPasswords(): ArrayCollection
{
return $this->resetPasswords;
}
@@ -388,16 +380,16 @@ public function getResetPasswords()
* @param UserResetPassword $resetPassword
* @return bool
*/
- public function hasResetPassword(UserResetPassword $resetPassword)
+ public function hasResetPassword(UserResetPassword $resetPassword): bool
{
return $this->resetPasswords->contains($resetPassword);
}
/**
* @param UserResetPassword $resetPassword
- * @return $this
+ * @return self
*/
- public function removeResetPassword(UserResetPassword $resetPassword)
+ public function removeResetPassword(UserResetPassword $resetPassword): self
{
$this->resetPasswords->removeElement($resetPassword);
@@ -406,9 +398,9 @@ public function removeResetPassword(UserResetPassword $resetPassword)
/**
* @param array $resetPasswords
- * @return $this
+ * @return self
*/
- public function setResetPasswords(array $resetPasswords)
+ public function setResetPasswords(array $resetPasswords): self
{
foreach ($resetPasswords as $resetPassword) {
$this->resetPasswords->add($resetPassword);
diff --git a/src/User/src/Entity/UserAvatar.php b/src/User/src/Entity/UserAvatar.php
index 069d6c6d..eeb5ffbe 100644
--- a/src/User/src/Entity/UserAvatar.php
+++ b/src/User/src/Entity/UserAvatar.php
@@ -20,20 +20,18 @@ class UserAvatar extends AbstractEntity
/**
* @ORM\OneToOne(targetEntity="Frontend\User\Entity\User", inversedBy="avatar")
* @ORM\JoinColumn(name="userUuid", referencedColumnName="uuid", nullable=false)
- * @var UserInterface $user
*/
- protected $user;
+ protected UserInterface $user;
/**
* @ORM\Column(name="name", type="string", length=191)
- * @var $name
*/
- protected $name;
+ protected string $name;
/**
* @var string $url
*/
- protected $url;
+ protected string $url;
/**
* UserAvatar constructor.
@@ -53,7 +51,7 @@ public function getUser(): UserInterface
/**
* @param UserInterface $user
- * @return UserAvatar
+ * @return self
*/
public function setUser(UserInterface $user): self
{
@@ -63,16 +61,16 @@ public function setUser(UserInterface $user): self
}
/**
- * @return mixed
+ * @return string
*/
- public function getName()
+ public function getName(): string
{
return $this->name;
}
/**
* @param $name
- * @return UserAvatar
+ * @return self
*/
public function setName($name): self
{
@@ -91,6 +89,7 @@ public function getUrl(): string
/**
* @param string $url
+ * @return void
*/
public function setUrl(string $url): void
{
diff --git a/src/User/src/Entity/UserDetail.php b/src/User/src/Entity/UserDetail.php
index 7adf3e62..a40b94f0 100644
--- a/src/User/src/Entity/UserDetail.php
+++ b/src/User/src/Entity/UserDetail.php
@@ -19,21 +19,18 @@ class UserDetail extends AbstractEntity
/**
* @ORM\OneToOne(targetEntity="Frontend\User\Entity\User", inversedBy="detail")
* @ORM\JoinColumn(name="userUuid", referencedColumnName="uuid", nullable=false)
- * @var UserInterface $user
*/
- protected $user;
+ protected UserInterface $user;
/**
* @ORM\Column(name="firstName", type="string", length=191, nullable=true)
- * @var $firstName
*/
- protected $firstName;
+ protected string $firstName;
/**
* @ORM\Column(name="lastName", type="string", length=191, nullable=true)
- * @var $lastName
*/
- protected $lastName;
+ protected string $lastName;
/**
* UserDetail constructor.
@@ -44,7 +41,7 @@ public function __construct()
}
/**
- * @return User
+ * @return UserInterface
*/
public function getUser(): UserInterface
{
@@ -53,9 +50,9 @@ public function getUser(): UserInterface
/**
* @param User $user
- * @return $this
+ * @return self
*/
- public function setUser(User $user)
+ public function setUser(User $user): self
{
$this->user = $user;
@@ -63,16 +60,16 @@ public function setUser(User $user)
}
/**
- * @return mixed
+ * @return string|null
*/
- public function getFirstName()
+ public function getFirstName(): ?string
{
return $this->firstName;
}
/**
* @param $firstName
- * @return UserDetail
+ * @return self
*/
public function setFirstName($firstName): self
{
@@ -82,16 +79,16 @@ public function setFirstName($firstName): self
}
/**
- * @return mixed
+ * @return string|null
*/
- public function getLastName()
+ public function getLastName(): ?string
{
return $this->lastName;
}
/**
* @param $lastName
- * @return UserDetail
+ * @return self
*/
public function setLastName($lastName): self
{
diff --git a/src/User/src/Entity/UserIdentity.php b/src/User/src/Entity/UserIdentity.php
index 53341c67..c0e14ac0 100644
--- a/src/User/src/Entity/UserIdentity.php
+++ b/src/User/src/Entity/UserIdentity.php
@@ -13,16 +13,16 @@
class UserIdentity implements UserInterface
{
/** @var string $identity */
- protected $identity;
+ protected string $identity;
/** @var array $roles */
- protected $roles;
+ protected array $roles;
/** @var array $details */
- protected $details;
+ protected array $details;
/** @var string $uuid */
- protected $uuid;
+ protected string $uuid;
/**
* UserIdentity constructor.
@@ -44,15 +44,25 @@ public function __construct(
}
/**
- * Get the unique user identity (id, username, email address or ...)
+ * @return string
+ */
+ public function getUuid(): string
+ {
+ return $this->uuid;
+ }
+
+ /**
+ * @return string
*/
public function getIdentity(): string
{
return $this->identity;
}
+
/**
* @return iterable
+ * @psalm-suppress LessSpecificImplementedReturnType
*/
public function getRoles(): iterable
{
@@ -61,8 +71,8 @@ public function getRoles(): iterable
/**
* @param string $name
- * @param null $default
- * @return mixed|null
+ * @param null|mixed $default
+ * @return mixed
*/
public function getDetail(string $name, $default = null)
{
@@ -71,17 +81,10 @@ public function getDetail(string $name, $default = null)
/**
* @return array
+ * @psalm-return array
*/
public function getDetails(): array
{
return $this->details;
}
-
- /**
- * @return User
- */
- public function getUuid(): string
- {
- return $this->uuid;
- }
}
diff --git a/src/User/src/Entity/UserInterface.php b/src/User/src/Entity/UserInterface.php
index c9a80279..873f64d3 100644
--- a/src/User/src/Entity/UserInterface.php
+++ b/src/User/src/Entity/UserInterface.php
@@ -4,12 +4,19 @@
namespace Frontend\User\Entity;
+use Ramsey\Uuid\UuidInterface;
+
/**
* Interface UserInterface
* @package Frontend\User\Entity
*/
interface UserInterface
{
+ /**
+ * @return UuidInterface
+ */
+ public function getUuid(): UuidInterface;
+
/**
* @return UserDetail|null
*/
diff --git a/src/User/src/Entity/UserResetPassword.php b/src/User/src/Entity/UserResetPassword.php
index 55d34036..654a0c9b 100644
--- a/src/User/src/Entity/UserResetPassword.php
+++ b/src/User/src/Entity/UserResetPassword.php
@@ -30,27 +30,23 @@ class UserResetPassword extends AbstractEntity
/**
* @ORM\ManyToOne(targetEntity="User", cascade={"persist", "remove"}, inversedBy="resetPasswords")
* @ORM\JoinColumn(name="userUuid", referencedColumnName="uuid", nullable=false)
- * @var User $user
*/
- protected $user;
+ protected User $user;
/**
* @ORM\Column(name="expires", type="datetime_immutable", nullable=false)
- * @var DateTimeImmutable
*/
- protected $expires;
+ protected DateTimeImmutable $expires;
/**
* @ORM\Column(name="hash", type="string", length=64, nullable=false, unique=true)
- * @var $hash
*/
- protected $hash;
+ protected string $hash;
/**
* @ORM\Column(name="status", type="string", length=20, nullable=false)
- * @var string $status
*/
- protected $status = self::STATUS_REQUESTED;
+ protected string $status = self::STATUS_REQUESTED;
/**
* UserResetPassword constructor.
@@ -74,9 +70,9 @@ public function getUser(): User
/**
* @param User $user
- * @return $this
+ * @return self
*/
- public function setUser(User $user)
+ public function setUser(User $user): self
{
$this->user = $user;
@@ -93,9 +89,9 @@ public function getExpires(): DateTimeImmutable
/**
* @param DateTimeImmutable $expires
- * @return $this
+ * @return self
*/
- public function setExpires(DateTimeImmutable $expires)
+ public function setExpires(DateTimeImmutable $expires): self
{
$this->expires = $expires;
@@ -103,18 +99,18 @@ public function setExpires(DateTimeImmutable $expires)
}
/**
- * @return mixed
+ * @return string
*/
- public function getHash()
+ public function getHash(): string
{
return $this->hash;
}
/**
* @param $hash
- * @return $this
+ * @return self
*/
- public function setHash($hash)
+ public function setHash($hash): self
{
$this->hash = $hash;
@@ -131,9 +127,9 @@ public function getStatus(): string
/**
* @param string $status
- * @return $this
+ * @return self
*/
- public function setStatus(string $status)
+ public function setStatus(string $status): self
{
$this->status = $status;
@@ -147,7 +143,7 @@ public function setStatus(string $status)
/**
* @return bool
*/
- public function isCompleted()
+ public function isCompleted(): bool
{
return $this->getStatus() === self::STATUS_COMPLETED;
}
@@ -166,9 +162,9 @@ public function isValid(): bool
}
/**
- * @return $this
+ * @return self
*/
- public function markAsCompleted()
+ public function markAsCompleted(): self
{
$this->status = self::STATUS_COMPLETED;
diff --git a/src/User/src/Entity/UserRole.php b/src/User/src/Entity/UserRole.php
index 79d34f7d..0f92b454 100644
--- a/src/User/src/Entity/UserRole.php
+++ b/src/User/src/Entity/UserRole.php
@@ -5,6 +5,7 @@
namespace Frontend\User\Entity;
use Doctrine\ORM\Mapping as ORM;
+use Dot\Authorization\Role\RoleInterface;
use Frontend\App\Common\AbstractEntity;
/**
@@ -14,7 +15,7 @@
* @ORM\HasLifecycleCallbacks()
* @package Frontend\User\Entity
*/
-class UserRole extends AbstractEntity
+class UserRole extends AbstractEntity implements RoleInterface
{
public const ROLE_ADMIN = 'admin';
public const ROLE_USER = 'user';
@@ -27,9 +28,8 @@ class UserRole extends AbstractEntity
/**
* @ORM\Column(name="name", type="string", length=30, nullable=false, unique=true)
- * @var string $name
*/
- protected $name;
+ protected string $name;
/**
* UserRole constructor.
diff --git a/src/User/src/EventListener/UserAvatarEventListener.php b/src/User/src/EventListener/UserAvatarEventListener.php
index 7bf6e835..01e20e09 100644
--- a/src/User/src/EventListener/UserAvatarEventListener.php
+++ b/src/User/src/EventListener/UserAvatarEventListener.php
@@ -16,8 +16,7 @@
*/
class UserAvatarEventListener
{
- /** @var array $config */
- protected $config;
+ protected array $config;
/**
* UserAvatarEventListener constructor.
diff --git a/src/User/src/Form/LoginForm.php b/src/User/src/Form/LoginForm.php
index 3b1ac0b0..bab69be2 100644
--- a/src/User/src/Form/LoginForm.php
+++ b/src/User/src/Form/LoginForm.php
@@ -9,7 +9,7 @@
use Laminas\Form\Element\Password;
use Laminas\Form\Element\Submit;
use Laminas\Form\Form;
-use Laminas\InputFilter\InputFilter;
+use Laminas\InputFilter\InputFilterInterface;
/**
* Class LoginForm
@@ -17,7 +17,7 @@
*/
class LoginForm extends Form
{
- /** @var InputFilter $inputFilter */
+ /** @var InputFilterInterface $inputFilter */
protected $inputFilter;
/**
@@ -82,9 +82,9 @@ public function init()
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/User/src/Form/ProfileDeleteForm.php b/src/User/src/Form/ProfileDeleteForm.php
index 62ec2b3a..a75c8132 100644
--- a/src/User/src/Form/ProfileDeleteForm.php
+++ b/src/User/src/Form/ProfileDeleteForm.php
@@ -9,6 +9,7 @@
use Laminas\Form\Element\Submit;
use Laminas\Form\Form;
use Laminas\InputFilter\InputFilter;
+use Laminas\InputFilter\InputFilterInterface;
/**
* Class ProfileDeleteForm
@@ -16,7 +17,7 @@
*/
class ProfileDeleteForm extends Form
{
- /** @var InputFilter $inputFilter */
+ /** @var InputFilterInterface $inputFilter */
protected $inputFilter;
/**
@@ -65,9 +66,9 @@ public function init()
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/User/src/Form/ProfileDetailsForm.php b/src/User/src/Form/ProfileDetailsForm.php
index 8b068fdb..e10095f0 100644
--- a/src/User/src/Form/ProfileDetailsForm.php
+++ b/src/User/src/Form/ProfileDetailsForm.php
@@ -5,15 +5,11 @@
namespace Frontend\User\Form;
use Frontend\User\Fieldset\UserDetailFieldset;
-use Frontend\User\InputFilter\RegisterInputFilter;
use Frontend\User\InputFilter\UserDetailInputFilter;
-use Laminas\Form\Element\Collection;
-use Laminas\Form\Element\Email;
-use Laminas\Form\Element\Password;
use Laminas\Form\Element\Submit;
-use Laminas\Form\Element\Text;
use Laminas\Form\Form;
use Laminas\InputFilter\InputFilter;
+use Laminas\InputFilter\InputFilterInterface;
/**
* Class ProfileDetailsForm
@@ -21,8 +17,8 @@
*/
class ProfileDetailsForm extends Form
{
- /** @var InputFilter $inputFilter */
- protected $inputFilter;
+ /** @var InputFilterInterface $inputFilter */
+ protected InputFilterInterface $inputFilter;
/**
* ProfileDetailsForm constructor.
@@ -60,9 +56,9 @@ public function init()
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/User/src/Form/ProfilePasswordForm.php b/src/User/src/Form/ProfilePasswordForm.php
index 3d6c72bf..9e872f57 100644
--- a/src/User/src/Form/ProfilePasswordForm.php
+++ b/src/User/src/Form/ProfilePasswordForm.php
@@ -7,8 +7,8 @@
use Frontend\User\InputFilter\ProfilePasswordInputFilter;
use Laminas\Form\Element\Password;
use Laminas\Form\Element\Submit;
+use Laminas\InputFilter\InputFilterInterface;
use Laminas\Form\Form;
-use Laminas\InputFilter\InputFilter;
/**
* Class ProfilePasswordForm
@@ -16,8 +16,8 @@
*/
class ProfilePasswordForm extends Form
{
- /** @var InputFilter $inputFilter */
- protected $inputFilter;
+ /** @var InputFilterInterface $inputFilter */
+ protected InputFilterInterface $inputFilter;
/**
* ProfilePasswordForm constructor.
@@ -71,9 +71,9 @@ public function init()
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/User/src/Form/RegisterForm.php b/src/User/src/Form/RegisterForm.php
index 0599d798..48074e39 100644
--- a/src/User/src/Form/RegisterForm.php
+++ b/src/User/src/Form/RegisterForm.php
@@ -7,13 +7,11 @@
use Frontend\User\Fieldset\UserDetailFieldset;
use Frontend\User\InputFilter\RegisterInputFilter;
use Frontend\User\InputFilter\UserDetailInputFilter;
-use Laminas\Form\Element\Collection;
use Laminas\Form\Element\Email;
use Laminas\Form\Element\Password;
use Laminas\Form\Element\Submit;
-use Laminas\Form\Element\Text;
+use Laminas\InputFilter\InputFilterInterface;
use Laminas\Form\Form;
-use Laminas\InputFilter\InputFilter;
/**
* Class RegisterForm
@@ -21,8 +19,8 @@
*/
class RegisterForm extends Form
{
- /** @var InputFilter $inputFilter */
- protected $inputFilter;
+ /** @var InputFilterInterface $inputFilter */
+ protected InputFilterInterface $inputFilter;
/**
* RegisterForm constructor.
@@ -94,9 +92,9 @@ public function init()
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/User/src/Form/RequestResetPasswordForm.php b/src/User/src/Form/RequestResetPasswordForm.php
index 5a94e088..6d597afa 100644
--- a/src/User/src/Form/RequestResetPasswordForm.php
+++ b/src/User/src/Form/RequestResetPasswordForm.php
@@ -9,6 +9,7 @@
use Laminas\Form\Element\Submit;
use Laminas\Form\Form;
use Laminas\InputFilter\InputFilter;
+use Laminas\InputFilter\InputFilterInterface;
/**
* Class RequestResetPasswordForm
@@ -16,11 +17,11 @@
*/
class RequestResetPasswordForm extends Form
{
- /** @var InputFilter $inputFilter */
+ /** @var InputFilterInterface $inputFilter */
protected $inputFilter;
/**
- * LoginForm constructor.
+ * RequestResetPasswordForm constructor.
* @param null $name
* @param array $options
*/
@@ -60,9 +61,9 @@ public function init()
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/User/src/Form/ResetPasswordForm.php b/src/User/src/Form/ResetPasswordForm.php
index 37b427a6..ca491813 100644
--- a/src/User/src/Form/ResetPasswordForm.php
+++ b/src/User/src/Form/ResetPasswordForm.php
@@ -4,17 +4,11 @@
namespace Frontend\User\Form;
-use Frontend\User\Fieldset\UserDetailFieldset;
-use Frontend\User\InputFilter\RegisterInputFilter;
use Frontend\User\InputFilter\ResetPasswordInputFilter;
-use Frontend\User\InputFilter\UserDetailInputFilter;
-use Laminas\Form\Element\Collection;
-use Laminas\Form\Element\Email;
use Laminas\Form\Element\Password;
use Laminas\Form\Element\Submit;
-use Laminas\Form\Element\Text;
use Laminas\Form\Form;
-use Laminas\InputFilter\InputFilter;
+use Laminas\InputFilter\InputFilterInterface;
/**
* Class ResetPasswordForm
@@ -22,7 +16,7 @@
*/
class ResetPasswordForm extends Form
{
- /** @var InputFilter $inputFilter */
+ /** @var InputFilterInterface $inputFilter */
protected $inputFilter;
/**
@@ -77,9 +71,9 @@ public function init()
}
/**
- * @return null|InputFilter|\Laminas\InputFilter\InputFilterInterface
+ * @return InputFilterInterface
*/
- public function getInputFilter(): \Laminas\InputFilter\InputFilterInterface
+ public function getInputFilter(): InputFilterInterface
{
return $this->inputFilter;
}
diff --git a/src/User/src/Repository/UserRepository.php b/src/User/src/Repository/UserRepository.php
index da20ed74..e688692e 100644
--- a/src/User/src/Repository/UserRepository.php
+++ b/src/User/src/Repository/UserRepository.php
@@ -12,6 +12,7 @@
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\OptimisticLockException;
+use DateTimeImmutable;
use Exception;
/**
@@ -57,8 +58,6 @@ public function findByIdentity(string $identity): UserInterface
/**
* @param User $user
- * @throws ORMException
- * @throws OptimisticLockException
*/
public function saveUser(User $user)
{
@@ -90,20 +89,6 @@ public function exists(string $email = '', ?string $uuid = '')
}
}
- /**
- * @param string $email
- * @return mixed
- * @throws NonUniqueResultException
- */
- public function getUserByEmail(string $email)
- {
- $qb = $this->getEntityManager()->createQueryBuilder();
- $qb->select('user')
- ->from(User::class, 'user')
- ->where('user.identity = :identity')->setParameter('identity', $email);
- return $qb->getQuery()->useQueryCache(true)->getOneOrNullResult();
- }
-
/**
* @param string $hash
* @return User|null
@@ -125,10 +110,8 @@ public function findByResetPasswordHash(string $hash): ?User
/**
* @param UserRememberMe $rememberUser
* @return void
- * @throws ORMException
- * @throws OptimisticLockException
*/
- public function saveRememberUser(UserRememberMe $rememberUser)
+ public function saveRememberUser(UserRememberMe $rememberUser): void
{
$em = $this->getEntityManager();
$rememberUser->touch();
@@ -156,7 +139,7 @@ public function getRememberUser($token): ?UserRememberMe
/**
* @param User $user
* @param string $userAgent
- * @return int|mixed|string|null
+ * @return mixed
* @throws NonUniqueResultException
*/
public function findRememberMeUser(User $user, string $userAgent)
@@ -174,10 +157,10 @@ public function findRememberMeUser(User $user, string $userAgent)
}
/**
- * @param \DateTimeImmutable $currentDate
- * @return void
+ * @param DateTimeImmutable $currentDate
+ * @return mixed
*/
- public function deleteExpiredCookies(\DateTimeImmutable $currentDate)
+ public function deleteExpiredCookies(DateTimeImmutable $currentDate)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->delete(UserRememberMe::class, 'user_remember_me')
@@ -190,10 +173,8 @@ public function deleteExpiredCookies(\DateTimeImmutable $currentDate)
/**
* @param UserRememberMe $userRememberMe
* @return void
- * @throws ORMException
- * @throws OptimisticLockException
*/
- public function removeUserRememberMe(UserRememberMe $userRememberMe)
+ public function removeUserRememberMe(UserRememberMe $userRememberMe): void
{
$this->getEntityManager()->remove($userRememberMe);
$this->getEntityManager()->flush();
diff --git a/src/User/src/Service/UserService.php b/src/User/src/Service/UserService.php
index 688fa9e9..fb0d3c47 100644
--- a/src/User/src/Service/UserService.php
+++ b/src/User/src/Service/UserService.php
@@ -5,14 +5,16 @@
namespace Frontend\User\Service;
use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\NonUniqueResultException;
+use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Dot\AnnotatedServices\Annotation\Inject;
use Dot\AnnotatedServices\Annotation\Service;
use Dot\Mail\Exception\MailException;
use Dot\Mail\Service\MailService;
+use Exception;
use Frontend\App\Common\Message;
use Frontend\App\Common\UuidOrderedTimeGenerator;
-use Frontend\Contact\Repository\MessageRepository;
use Frontend\User\Entity\UserRememberMe;
use Frontend\User\Entity\User;
use Frontend\User\Entity\UserAvatar;
@@ -100,7 +102,7 @@ public function __construct(
/**
* @param string $uuid
* @return User|null
- * @throws \Doctrine\ORM\NonUniqueResultException
+ * @throws NonUniqueResultException
*/
public function findByUuid(string $uuid)
{
@@ -110,7 +112,7 @@ public function findByUuid(string $uuid)
/**
* @param string $identity
* @return UserInterface
- * @throws \Doctrine\ORM\NonUniqueResultException
+ * @throws NonUniqueResultException
*/
public function findByIdentity(string $identity): UserInterface
{
@@ -120,9 +122,8 @@ public function findByIdentity(string $identity): UserInterface
/**
* @param array $data
* @return UserInterface
- * @throws \Exception
- * @throws \Doctrine\ORM\ORMException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws Exception
+ * @throws ORMException
*/
public function createUser(array $data): UserInterface
{
@@ -146,7 +147,7 @@ public function createUser(array $data): UserInterface
foreach ($data['roles'] as $roleName) {
$role = $this->userRoleRepository->findByName($roleName);
if (!$role instanceof UserRole) {
- throw new \Exception('Role not found: ' . $roleName);
+ throw new Exception('Role not found: ' . $roleName);
}
$user->addRole($role);
}
@@ -158,7 +159,7 @@ public function createUser(array $data): UserInterface
}
if (empty($user->getRoles())) {
- throw new \Exception(Message::RESTRICTION_ROLES);
+ throw new Exception(Message::RESTRICTION_ROLES);
}
$this->userRepository->saveUser($user);
@@ -170,13 +171,10 @@ public function createUser(array $data): UserInterface
/**
* @param User $user
* @param array $data
- * @return User
+ * @return UserInterface
* @throws ORMException
- * @throws \Doctrine\ORM\NoResultException
- * @throws \Doctrine\ORM\NonUniqueResultException
- * @throws \Doctrine\ORM\OptimisticLockException
*/
- public function updateUser(User $user, array $data = [])
+ public function updateUser(User $user, array $data = []): UserInterface
{
if (isset($data['email']) && !is_null($data['email'])) {
if ($this->exists($data['email'], $user->getUuid()->toString())) {
@@ -235,7 +233,7 @@ public function updateUser(User $user, array $data = [])
}
}
if (empty($user->getRoles())) {
- throw new \Exception(Message::RESTRICTION_ROLES);
+ throw new Exception(Message::RESTRICTION_ROLES);
}
$this->userRepository->saveUser($user);
@@ -248,7 +246,7 @@ public function updateUser(User $user, array $data = [])
* @param UploadedFile $uploadedFile
* @return UserAvatar
*/
- protected function createAvatar(User $user, UploadedFile $uploadedFile)
+ protected function createAvatar(User $user, UploadedFile $uploadedFile): UserAvatar
{
$path = $this->config['uploads']['user']['path'] . DIRECTORY_SEPARATOR;
$path .= $user->getUuid()->toString() . DIRECTORY_SEPARATOR;
@@ -265,7 +263,7 @@ protected function createAvatar(User $user, UploadedFile $uploadedFile)
}
$fileName = sprintf(
'avatar-%s.%s',
- UuidOrderedTimeGenerator::generateUuid(),
+ UuidOrderedTimeGenerator::generateUuid()->toString(),
self::EXTENSIONS[$uploadedFile->getClientMediaType()]
);
$avatar->setName($fileName);
@@ -284,7 +282,7 @@ protected function createAvatar(User $user, UploadedFile $uploadedFile)
* @param string $path
* @return bool
*/
- public function deleteAvatarFile(string $path)
+ public function deleteAvatarFile(string $path): bool
{
if (empty($path)) {
return false;
@@ -301,10 +299,8 @@ public function deleteAvatarFile(string $path)
* @param string $email
* @param string|null $uuid
* @return bool
- * @throws \Doctrine\ORM\NoResultException
- * @throws \Doctrine\ORM\NonUniqueResultException
*/
- public function exists(string $email = '', ?string $uuid = '')
+ public function exists(string $email = '', ?string $uuid = ''): bool
{
return !is_null(
$this->userRepository->exists($email, $uuid)
@@ -324,7 +320,7 @@ public function getUsers(): array
* @return bool
* @throws MailException
*/
- public function sendActivationMail(User $user)
+ public function sendActivationMail(User $user): bool
{
if ($user->isActive()) {
return false;
@@ -362,44 +358,22 @@ public function findOneBy(array $params = []): ?User
/**
* @param User $user
* @return User
- * @throws \Doctrine\ORM\ORMException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws ORMException
+ * @throws OptimisticLockException
*/
- public function activateUser(User $user)
+ public function activateUser(User $user): User
{
$this->userRepository->saveUser($user->activate());
return $user;
}
- /**
- * @param string $email
- * @return array
- * @throws \Doctrine\ORM\NonUniqueResultException
- */
- public function getRoleNamesByEmail(string $email)
- {
- $roleList = [];
-
- /** @var User $user */
- $user = $this->userRepository->getUserByEmail($email);
-
- if (!empty($user)) {
- /** @var UserRole $role */
- foreach ($user->getRoles() as $role) {
- $roleList[] = $role->getName();
- }
- }
-
- return $roleList;
- }
-
/**
* @param User $user
* @return bool
* @throws MailException
*/
- public function sendResetPasswordRequestedMail(User $user)
+ public function sendResetPasswordRequestedMail(User $user): bool
{
$this->mailService->setBody(
$this->templateRenderer->render('user::reset-password-requested', [
@@ -419,7 +393,7 @@ public function sendResetPasswordRequestedMail(User $user)
* @param string|null $hash
* @return User|null
* @throws \Doctrine\ORM\NoResultException
- * @throws \Doctrine\ORM\NonUniqueResultException
+ * @throws NonUniqueResultException
*/
public function findByResetPasswordHash(?string $hash): ?User
{
@@ -464,8 +438,8 @@ public function getRepository(): UserRepository
* @param string $userAgent
* @return void
* @throws ORMException
- * @throws \Doctrine\ORM\NonUniqueResultException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws NonUniqueResultException
+ * @throws OptimisticLockException
*/
public function addRememberMeToken(User $user, string $userAgent)
{
@@ -508,8 +482,8 @@ public function addRememberMeToken(User $user, string $userAgent)
* @return void
* @throws ORMException
* @throws \Doctrine\ORM\NoResultException
- * @throws \Doctrine\ORM\NonUniqueResultException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws NonUniqueResultException
+ * @throws OptimisticLockException
*/
public function deleteRememberMeCookie()
{
diff --git a/src/User/src/Service/UserServiceInterface.php b/src/User/src/Service/UserServiceInterface.php
index a40bedd1..46c1f12f 100644
--- a/src/User/src/Service/UserServiceInterface.php
+++ b/src/User/src/Service/UserServiceInterface.php
@@ -2,6 +2,7 @@
namespace Frontend\User\Service;
+use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Dot\Mail\Exception\MailException;
use Frontend\User\Entity\User;
@@ -14,12 +15,13 @@
*/
interface UserServiceInterface
{
+ // TODO refactor this interface, it should only have CRUD methods.
/**
* @param array $data
* @return UserInterface
* @throws \Exception
- * @throws \Doctrine\ORM\ORMException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws ORMException
+ * @throws OptimisticLockException
*/
public function createUser(array $data): UserInterface;
@@ -28,7 +30,7 @@ public function createUser(array $data): UserInterface;
* @return bool
* @throws MailException
*/
- public function sendActivationMail(User $user);
+ public function sendActivationMail(User $user): bool;
/**
* @param array $params
@@ -39,18 +41,11 @@ public function findOneBy(array $params = []): ?User;
/**
* @param User $user
* @return User
- * @throws \Doctrine\ORM\ORMException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws ORMException
+ * @throws OptimisticLockException
*/
public function activateUser(User $user);
- /**
- * @param string $email
- * @return array
- * @throws \Doctrine\ORM\NonUniqueResultException
- */
- public function getRoleNamesByEmail(string $email);
-
/**
* @param string $uuid
* @return User|null
@@ -68,7 +63,7 @@ public function getRepository(): UserRepository;
* @return void
* @throws ORMException
* @throws \Doctrine\ORM\NonUniqueResultException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws OptimisticLockException
*/
public function addRememberMeToken(User $user, string $userAgent);
@@ -77,7 +72,7 @@ public function addRememberMeToken(User $user, string $userAgent);
* @throws ORMException
* @throws \Doctrine\ORM\NoResultException
* @throws \Doctrine\ORM\NonUniqueResultException
- * @throws \Doctrine\ORM\OptimisticLockException
+ * @throws OptimisticLockException
*/
public function deleteRememberMeCookie();
}