Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example of implementation of select from database with delegators #400

Draft
wants to merge 2 commits into
base: 4.0
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions data/doctrine/fixtures/DepartmentLoader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Frontend\Fixtures;

use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Frontend\Contact\Entity\Department;

class DepartmentLoader implements FixtureInterface
{
public function load(ObjectManager $manager): void
{
$support = new Department();
$support->setName('Support');

$financial = new Department();
$financial->setName('Financial');

$hr = new Department();
$hr->setName('Human Resource');

$manager->persist($support);
$manager->persist($financial);
$manager->persist($hr);

$manager->flush();
}
}
1 change: 0 additions & 1 deletion data/doctrine/fixtures/RoleLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,3 @@ public function load(ObjectManager $manager): void
$manager->flush();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,23 @@
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20220817121035 extends AbstractMigration
final class Version20230905041559 extends AbstractMigration
{
public function getDescription(): string
{
return 'Create and seed the database structure.';
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->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 department (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)\', 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 TEXT 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), INDEX IDX_D3E96EBDD73087E9 (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 LONGTEXT 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), INDEX IDX_D3E96EBDD73087E9 (userUuid), PRIMARY KEY(uuid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LONGTEXT can store the maximum characters up to 4,294,967,295 characters

TEXT (or even a VARCHAR) should suffice - let's revert this change.

$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)');
Expand All @@ -46,6 +47,7 @@ public function down(Schema $schema): void
$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 department');
$this->addSql('DROP TABLE user');
$this->addSql('DROP TABLE user_roles');
$this->addSql('DROP TABLE user_avatar');
Expand All @@ -55,4 +57,3 @@ public function down(Schema $schema): void
$this->addSql('DROP TABLE user_role');
}
}

10 changes: 9 additions & 1 deletion src/Contact/src/ConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Dot\AnnotatedServices\Factory\AnnotatedServiceFactory;
use Frontend\Contact\Controller\ContactController;
use Frontend\Contact\Delegator\ContactFormDelegator;
use Frontend\Contact\Form\ContactForm;
use Frontend\Contact\Service\MessageService;
use Frontend\Contact\Service\MessageServiceInterface;
Expand Down Expand Up @@ -42,10 +43,14 @@ public function getDependencies(): array
Application::class => [
RoutesDelegator::class,
],
ContactForm::class => [
ContactFormDelegator::class
]
],
'factories' => [
ContactController::class => AnnotatedServiceFactory::class,
MessageService::class => AnnotatedServiceFactory::class,
ContactForm::class => ElementFactory::class
],
'aliases' => [
MessageServiceInterface::class => MessageService::class,
Expand Down Expand Up @@ -73,10 +78,13 @@ public function getForms(): array
return [
'form_manager' => [
'factories' => [
ContactForm::class => ElementFactory::class,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

],
'aliases' => [
],
'delegators' => [

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

],
],
];
}
Expand Down
19 changes: 13 additions & 6 deletions src/Contact/src/Controller/ContactController.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ContactController extends AbstractActionController
protected AuthenticationServiceInterface $authenticationService;
protected FlashMessenger $messenger;
protected FormsPlugin $forms;
protected ContactForm $contactForm;
protected DebugBar $debugBar;
protected array $config;

Expand All @@ -46,6 +47,7 @@ class ContactController extends AbstractActionController
* @param AuthenticationService $authenticationService
* @param FlashMessenger $messenger
* @param FormsPlugin $forms
* @param ContactForm $contactForm
* @param DebugBar $debugBar
* @param array $config
* @Inject({
Expand All @@ -57,6 +59,7 @@ class ContactController extends AbstractActionController
* FlashMessenger::class,
* FormsPlugin::class,
* DebugBar::class,
* ContactForm::class,
* "config"
* })
*/
Expand All @@ -69,6 +72,7 @@ public function __construct(
FlashMessenger $messenger,
FormsPlugin $forms,
DebugBar $debugBar,
ContactForm $contactForm,
array $config = []
) {
$this->messageService = $messageService;
Expand All @@ -78,16 +82,19 @@ public function __construct(
$this->authenticationService = $authenticationService;
$this->messenger = $messenger;
$this->forms = $forms;
$this->contactForm = $contactForm;
$this->debugBar = $debugBar;
$this->config = $config;

}

/**
* @return ResponseInterface
*/
public function formAction(): ResponseInterface
{
$form = new ContactForm();
// $form = new ContactForm();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// $form = new ContactForm();

// $form = $this->forms(ContactForm::class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// $form = $this->forms(ContactForm::class);

$request = $this->getRequest();

if ($request->getMethod() === RequestMethodInterface::METHOD_POST) {
Expand All @@ -105,9 +112,9 @@ public function formAction(): ResponseInterface
}

$data['subject'] = $data['subject'] ?: $this->config['application']['name'] . ' Contact';
$form->setData($data);
if ($form->isValid()) {
$dataForm = $form->getData();
$this->contactForm->setData($data);
if ($this->contactForm->isValid()) {
$dataForm = $this->contactForm->getData();
$result = $this->messageService->processMessage($dataForm);

if ($result) {
Expand All @@ -118,13 +125,13 @@ public function formAction(): ResponseInterface
return new RedirectResponse($request->getUri(), 303);
}
} else {
$this->messenger->addError($this->forms->getMessages($form));
$this->messenger->addError($this->forms->getMessages($this->contactForm));
return new RedirectResponse($request->getUri(), 303);
}
}

return new HtmlResponse($this->template->render('contact::contact-form', [
'form' => $form,
'form' => $this->contactForm,
'recaptchaSiteKey' => $this->config['recaptcha']['siteKey']
]));
}
Expand Down
55 changes: 55 additions & 0 deletions src/Contact/src/Delegator/ContactFormDelegator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Frontend\Contact\Delegator;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Exception\NotSupported;
use Frontend\Contact\Entity\Department;
use Frontend\Contact\Form\ContactForm;
use Frontend\User\Entity\UserRole;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
use Frontend\User\Entity\UserRole;

use Laminas\ServiceManager\Factory\DelegatorFactoryInterface;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;

class ContactFormDelegator implements DelegatorFactoryInterface
{
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws NotSupported
*/
public function __invoke(
ContainerInterface $container,
$name,
callable $callback,
?array $options = null
): ContactForm {

/** @var ContactForm $contactForm */
$contactForm = $callback();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
$contactForm = $callback();
$contactForm = $name();

No need to use the callback here, $name parameter containes the requested service name.


/** @var EntityManager $entityManager */
$entityManager = $container->get(EntityManager::class);

$departments = $entityManager->getRepository(Department::class)
->findAll();

$options = [];

/** @var Department $department */
foreach ($departments as $department){
$data = [
'value' => $department->getUuid()->toString(),
'label' => $department->getName(),
'selected' => $department->getName() === 'Support' // here you can add your option which one to be default selected
];

$options[] = $data;
}

$contactForm->setDepartment($options);

return $contactForm;
}
}
32 changes: 32 additions & 0 deletions src/Contact/src/Entity/Department.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Frontend\Contact\Entity;

use Frontend\App\Common\AbstractEntity;
use Doctrine\ORM\Mapping as ORM;


/**
* @ORM\Entity(repositoryClass="Frontend\Contact\Repository\DepartmentRepository")
* @ORM\Table(name="department")
* @ORM\HasLifecycleCallbacks
*/
class Department extends AbstractEntity
{
/**
* @ORM\Column(name="name", type="string", length=191)
*/
protected string $name = '';

public function getName(): string
{
return $this->name;
}

public function setName(string $name): void
{
$this->name = $name;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

}
15 changes: 15 additions & 0 deletions src/Contact/src/Form/ContactForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Frontend\Contact\InputFilter\ContactInputFilter;
use Laminas\Form\Element\Email;
use Laminas\Form\Element\Hidden;
use Laminas\Form\Element\Select;
use Laminas\Form\Element\Text;
use Laminas\Form\Element\Textarea;
use Laminas\Form\Form;
Expand All @@ -20,6 +21,8 @@ class ContactForm extends Form
{
protected InputFilterInterface $inputFilter;

private $roles = [];

/**
* ContactForm constructor.
* @param null $name
Expand All @@ -35,6 +38,18 @@ public function __construct($name = null, array $options = [])
$this->inputFilter->init();
}

public function setDepartment(array $countries)
{
$this->add([
'name' => 'department',
'options' => [
'label' => 'department',
'value_options' => $countries
],
'type' => Select::class,
]);
}

/**
* @return void
*/
Expand Down
10 changes: 10 additions & 0 deletions src/Contact/src/Repository/DepartmentRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Frontend\Contact\Repository;

use Doctrine\ORM\EntityRepository;

class DepartmentRepository extends EntityRepository
{

}
11 changes: 11 additions & 0 deletions src/Contact/templates/contact/contact-form.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@
</div>
</div>

<div class="row mb-2">
{% set department = form.get('department') %}
{% set dummy = department.setAttribute('class', 'form-control') %}
{% set dummy = department.setAttribute('id', 'subject') %}
{% set departmentTranslatePlaceholder = department.getAttribute('placeholder')|trans|raw %}
{% set dummy = department.setAttribute('placeholder', departmentTranslatePlaceholder) %}
<div class="col-md-12">
{{ formElement(department) }}
</div>
</div>

<div class="row">
{% set message = form.get('message') %}
{% set dummy = message.setAttribute('class', 'form-control') %}
Expand Down