welcome back to dyb-tech
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<services>
|
||||
<defaults public="false" />
|
||||
|
||||
<service id="maker.maker.make_authenticator" class="Symfony\Bundle\MakerBundle\Maker\MakeAuthenticator">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument type="service" id="maker.security_config_updater" />
|
||||
<argument type="service" id="maker.generator" />
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
<argument type="service" id="maker.security_controller_builder" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_command" class="Symfony\Bundle\MakerBundle\Maker\MakeCommand">
|
||||
<argument type="service" id="maker.php_compat_util" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_twig_component" class="Symfony\Bundle\MakerBundle\Maker\MakeTwigComponent">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_controller" class="Symfony\Bundle\MakerBundle\Maker\MakeController">
|
||||
<argument type="service" id="maker.php_compat_util" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_crud" class="Symfony\Bundle\MakerBundle\Maker\MakeCrud">
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
<argument type="service" id="maker.renderer.form_type_renderer" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_docker_database" class="Symfony\Bundle\MakerBundle\Maker\MakeDockerDatabase">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_entity" class="Symfony\Bundle\MakerBundle\Maker\MakeEntity">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
<argument>null</argument>
|
||||
<argument type="service" id="maker.generator" />
|
||||
<argument type="service" id="maker.entity_class_generator" />
|
||||
<argument type="service" id="maker.php_compat_util" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_fixtures" class="Symfony\Bundle\MakerBundle\Maker\MakeFixtures">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_form" class="Symfony\Bundle\MakerBundle\Maker\MakeForm">
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
<argument type="service" id="maker.renderer.form_type_renderer" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_functional_test" class="Symfony\Bundle\MakerBundle\Maker\MakeFunctionalTest">
|
||||
<tag name="maker.command" />
|
||||
<deprecated package="symfony/maker-bundle" version="1.29">The "%service_id%" service is deprecated, use "maker.maker.make_test" instead.</deprecated>
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_listener" class="Symfony\Bundle\MakerBundle\Maker\MakeListener">
|
||||
<tag name="maker.command" />
|
||||
<argument type="service" id="maker.event_registry" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_message" class="Symfony\Bundle\MakerBundle\Maker\MakeMessage">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_messenger_middleware" class="Symfony\Bundle\MakerBundle\Maker\MakeMessengerMiddleware">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_registration_form" class="Symfony\Bundle\MakerBundle\Maker\MakeRegistrationForm">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument type="service" id="maker.renderer.form_type_renderer" />
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
<argument type="service" id="router" on-invalid="ignore" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_reset_password" class="Symfony\Bundle\MakerBundle\Maker\MakeResetPassword">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
<argument type="service" id="maker.entity_class_generator" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_serializer_encoder" class="Symfony\Bundle\MakerBundle\Maker\MakeSerializerEncoder">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_serializer_normalizer" class="Symfony\Bundle\MakerBundle\Maker\MakeSerializerNormalizer">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_subscriber" class="Symfony\Bundle\MakerBundle\Maker\MakeSubscriber">
|
||||
<tag name="maker.command" />
|
||||
<argument type="service" id="maker.event_registry" />
|
||||
<deprecated package="symfony/maker-bundle" version="1.51">The "%service_id%" service is deprecated, use "maker.maker.make_listener" instead.</deprecated>
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_twig_extension" class="Symfony\Bundle\MakerBundle\Maker\MakeTwigExtension">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_test" class="Symfony\Bundle\MakerBundle\Maker\MakeTest">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_unit_test" class="Symfony\Bundle\MakerBundle\Maker\MakeUnitTest">
|
||||
<tag name="maker.command" />
|
||||
<deprecated package="symfony/maker-bundle" version="1.29">The "%service_id%" service is deprecated, use "maker.maker.make_test" instead.</deprecated>
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_validator" class="Symfony\Bundle\MakerBundle\Maker\MakeValidator">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_voter" class="Symfony\Bundle\MakerBundle\Maker\MakeVoter">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_user" class="Symfony\Bundle\MakerBundle\Maker\MakeUser">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument type="service" id="maker.user_class_builder" />
|
||||
<argument type="service" id="maker.security_config_updater" />
|
||||
<argument type="service" id="maker.entity_class_generator" />
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_migration" class="Symfony\Bundle\MakerBundle\Maker\MakeMigration">
|
||||
<argument>%kernel.project_dir%</argument>
|
||||
<argument type="service" id="maker.file_link_formatter" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_stimulus_controller" class="Symfony\Bundle\MakerBundle\Maker\MakeStimulusController">
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
|
||||
<service id="maker.maker.make_form_login" class="Symfony\Bundle\MakerBundle\Maker\Security\MakeFormLogin">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument type="service" id="maker.security_config_updater" />
|
||||
<argument type="service" id="maker.security_controller_builder" />
|
||||
<tag name="maker.command" />
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony MakerBundle package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
->setRules([
|
||||
'@Symfony' => true,
|
||||
'@Symfony:risky' => true,
|
||||
'native_function_invocation' => false,
|
||||
'blank_line_before_statement' => ['statements' => ['break', 'case', 'continue', 'declare', 'default', 'do', 'exit', 'for', 'foreach', 'goto', 'if', 'include', 'include_once', 'phpdoc', 'require', 'require_once', 'return', 'switch', 'throw', 'try', 'while', 'yield', 'yield_from']],
|
||||
])
|
||||
->setRiskyAllowed(true)
|
||||
;
|
||||
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" ?>
|
||||
|
||||
<container xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<services>
|
||||
<defaults public="false" />
|
||||
|
||||
<service id="maker.file_manager" class="Symfony\Bundle\MakerBundle\FileManager">
|
||||
<argument type="service" id="filesystem" />
|
||||
<argument type="service" id="maker.autoloader_util" />
|
||||
<argument type="service" id="maker.file_link_formatter" />
|
||||
<argument>%kernel.project_dir%</argument>
|
||||
<argument>%twig.default_path%</argument>
|
||||
</service>
|
||||
|
||||
<service id="maker.autoloader_finder" class="Symfony\Bundle\MakerBundle\Util\ComposerAutoloaderFinder" >
|
||||
<argument /> <!-- root namespace -->
|
||||
</service>
|
||||
|
||||
<service id="maker.autoloader_util" class="Symfony\Bundle\MakerBundle\Util\AutoloaderUtil">
|
||||
<argument type="service" id="maker.autoloader_finder" />
|
||||
</service>
|
||||
|
||||
<service id="maker.file_link_formatter" class="Symfony\Bundle\MakerBundle\Util\MakerFileLinkFormatter" >
|
||||
<argument type="service" id="debug.file_link_formatter" on-invalid="ignore" />
|
||||
</service>
|
||||
|
||||
<service id="maker.event_registry" class="Symfony\Bundle\MakerBundle\EventRegistry">
|
||||
<argument type="service" id="event_dispatcher" />
|
||||
</service>
|
||||
|
||||
<service id="maker.console_error_listener" class="Symfony\Bundle\MakerBundle\Event\ConsoleErrorSubscriber">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
</service>
|
||||
|
||||
<service id="maker.doctrine_helper" class="Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper">
|
||||
<argument /> <!-- entity namespace -->
|
||||
<argument type="service" id="doctrine" on-invalid="ignore" />
|
||||
</service>
|
||||
|
||||
<service id="maker.template_linter" class="Symfony\Bundle\MakerBundle\Util\TemplateLinter">
|
||||
<argument>%env(default::string:MAKER_PHP_CS_FIXER_BINARY_PATH)%</argument>
|
||||
<argument>%env(default::string:MAKER_PHP_CS_FIXER_CONFIG_PATH)%</argument>
|
||||
</service>
|
||||
|
||||
<service id="maker.auto_command.abstract" class="Symfony\Bundle\MakerBundle\Command\MakerCommand" abstract="true">
|
||||
<argument /> <!-- maker -->
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument type="service" id="maker.generator" />
|
||||
<argument type="service" id="maker.template_linter" />
|
||||
</service>
|
||||
|
||||
<service id="maker.generator" class="Symfony\Bundle\MakerBundle\Generator">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
<argument /> <!-- root namespace -->
|
||||
<argument>null</argument> <!-- PhpCompatUtil -->
|
||||
<argument type="service" id="maker.template_component_generator" />
|
||||
</service>
|
||||
|
||||
<service id="maker.entity_class_generator" class="Symfony\Bundle\MakerBundle\Doctrine\EntityClassGenerator">
|
||||
<argument type="service" id="maker.generator" />
|
||||
<argument type="service" id="maker.doctrine_helper" />
|
||||
</service>
|
||||
|
||||
<service id="maker.user_class_builder" class="Symfony\Bundle\MakerBundle\Security\UserClassBuilder" />
|
||||
|
||||
<service id="maker.security_config_updater" class="Symfony\Bundle\MakerBundle\Security\SecurityConfigUpdater" />
|
||||
|
||||
<service id="maker.renderer.form_type_renderer" class="Symfony\Bundle\MakerBundle\Renderer\FormTypeRenderer">
|
||||
<argument type="service" id="maker.generator" />
|
||||
</service>
|
||||
|
||||
<service id="maker.security_controller_builder" class="Symfony\Bundle\MakerBundle\Security\SecurityControllerBuilder">
|
||||
</service>
|
||||
|
||||
<service id="maker.php_compat_util" class="Symfony\Bundle\MakerBundle\Util\PhpCompatUtil">
|
||||
<argument type="service" id="maker.file_manager" />
|
||||
</service>
|
||||
|
||||
<service id="maker.template_component_generator" class="Symfony\Bundle\MakerBundle\Util\TemplateComponentGenerator">
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
@@ -0,0 +1,108 @@
|
||||
The Symfony MakerBundle
|
||||
=======================
|
||||
|
||||
Symfony Maker helps you create empty commands, controllers, form classes,
|
||||
tests and more so you can forget about writing boilerplate code. This bundle
|
||||
assumes you're using a standard Symfony 5 directory structure, but many
|
||||
commands can generate code into any application.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Run this command to install and enable this bundle in your application:
|
||||
|
||||
.. code-block:: terminal
|
||||
|
||||
$ composer require --dev symfony/maker-bundle
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
This bundle provides several commands under the ``make:`` namespace. List them
|
||||
all executing this command:
|
||||
|
||||
.. code-block:: terminal
|
||||
|
||||
$ php bin/console list make
|
||||
|
||||
make:command Creates a new console command class
|
||||
make:controller Creates a new controller class
|
||||
make:entity Creates a new Doctrine entity class
|
||||
|
||||
[...]
|
||||
|
||||
make:validator Creates a new validator and constraint class
|
||||
make:voter Creates a new security voter class
|
||||
|
||||
The names of the commands are self-explanatory, but some of them include
|
||||
optional arguments and options. Check them out with the ``--help`` option:
|
||||
|
||||
.. code-block:: terminal
|
||||
|
||||
$ php bin/console make:controller --help
|
||||
|
||||
|
||||
Linting Generated Code
|
||||
______________________
|
||||
|
||||
MakerBundle uses php-cs-fixer to enforce coding standards when generating ``.php``
|
||||
files. When running a ``make`` command, MakerBundle will use a ``php-cs-fixer``
|
||||
version and configuration that is packaged with this bundle.
|
||||
|
||||
You can explicitly set a custom path to a php-cs-fixer binary and/or configuration
|
||||
file by their respective environment variables:
|
||||
|
||||
- ``MAKER_PHP_CS_FIXER_BINARY_PATH`` e.g. tools/vendor/bin/php-cs-fixer
|
||||
- ``MAKER_PHP_CS_FIXER_CONFIG_PATH`` e.g. .php-cs-fixer.config.php
|
||||
|
||||
|
||||
.. tip::
|
||||
|
||||
Is PHP-CS-Fixer installed globally? To avoid needing to set these in every
|
||||
project, you can instead set these on your operating system.
|
||||
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
This bundle doesn't require any configuration. But, you *can* configure
|
||||
the root namespace that is used to "guess" what classes you want to generate:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# config/packages/dev/maker.yaml
|
||||
# create this file if you need to configure anything
|
||||
maker:
|
||||
# tell MakerBundle that all of your classes live in an
|
||||
# Acme namespace, instead of the default App
|
||||
# (e.g. Acme\Entity\Article, Acme\Command\MyCommand, etc)
|
||||
root_namespace: 'Acme'
|
||||
|
||||
Creating your Own Makers
|
||||
------------------------
|
||||
|
||||
In case your applications need to generate custom boilerplate code, you can
|
||||
create your own ``make:...`` command reusing the tools provided by this bundle.
|
||||
To do that, you should create a class that extends
|
||||
`AbstractMaker`_ in your ``src/Maker/``
|
||||
directory. And this is really it!
|
||||
|
||||
For examples of how to complete your new maker command, see the `core maker commands`_.
|
||||
Make sure your class is registered as a service and tagged with ``maker.command``.
|
||||
If you're using the standard Symfony ``services.yaml`` configuration, this
|
||||
will be done automatically.
|
||||
|
||||
Overriding the Generated Code
|
||||
-----------------------------
|
||||
|
||||
Generated code can never be perfect for everyone. The MakerBundle tries to balance
|
||||
adding "extension points" with keeping the library simple so that existing commands
|
||||
can be improved and new commands can be added.
|
||||
|
||||
For that reason, in general, the generated code cannot be modified. In many cases,
|
||||
adding your *own* maker command is so easy, that we recommend that. However, if there
|
||||
is some extension point that you'd like, please open an issue so we can discuss!
|
||||
|
||||
.. _`SensioGeneratorBundle`: https://github.com/sensiolabs/SensioGeneratorBundle
|
||||
.. _`AbstractMaker`: https://github.com/symfony/maker-bundle/blob/main/src/Maker/AbstractMaker.php
|
||||
.. _`core maker commands`: https://github.com/symfony/maker-bundle/tree/main/src/Maker
|
||||
@@ -0,0 +1,8 @@
|
||||
The <info>%command.name%</info> command generates various authentication systems,
|
||||
by asking questions.
|
||||
|
||||
It can provide an empty authenticator, or a full login form authentication process.
|
||||
In both cases it also updates your <info>security.yaml</info>.
|
||||
For the login form, it also generates a controller and the twig template.
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new command:
|
||||
|
||||
<info>php %command.full_name% app:do-something</info>
|
||||
|
||||
If the argument is missing, the command will ask for the command name interactively.
|
||||
@@ -0,0 +1,9 @@
|
||||
The <info>%command.name%</info> command generates a new controller class.
|
||||
|
||||
<info>php %command.full_name% CoolStuffController</info>
|
||||
|
||||
If the argument is missing, the command will ask for the controller class name interactively.
|
||||
|
||||
You can also generate the controller alone, without template with this option:
|
||||
|
||||
<info>php %command.full_name% --no-template</info>
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates crud controller with templates for selected entity.
|
||||
|
||||
<info>php %command.full_name% BlogPost</info>
|
||||
|
||||
If the argument is missing, the command will ask for the entity class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates or updates databases services in compose.yaml
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
|
||||
Supports MySQL, MariaDB and PostgreSQL
|
||||
@@ -0,0 +1,24 @@
|
||||
The <info>%command.name%</info> command creates or updates an entity and repository class.
|
||||
|
||||
<info>php %command.full_name% BlogPost</info>
|
||||
|
||||
If the argument is missing, the command will ask for the entity class name interactively.
|
||||
|
||||
You can also mark this class as an API Platform resource. A hypermedia CRUD API will
|
||||
automatically be available for this entity class:
|
||||
|
||||
<info>php %command.full_name% --api-resource</info>
|
||||
|
||||
Symfony can also broadcast all changes made to the entity to the client using Symfony
|
||||
UX Turbo.
|
||||
|
||||
<info>php %command.full_name% --broadcast</info>
|
||||
|
||||
You can also generate all the getter/setter/adder/remover methods
|
||||
for the properties of existing entities:
|
||||
|
||||
<info>php %command.full_name% --regenerate</info>
|
||||
|
||||
You can also *overwrite* any existing methods:
|
||||
|
||||
<info>php %command.full_name% --regenerate --overwrite</info>
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new Doctrine fixtures class.
|
||||
|
||||
<info>php %command.full_name% AppFixtures</info>
|
||||
|
||||
If the argument is missing, the command will ask for a class interactively.
|
||||
@@ -0,0 +1,16 @@
|
||||
The <info>%command.name%</info> command generates a new form class.
|
||||
|
||||
<info>php %command.full_name% UserType</info>
|
||||
|
||||
If the argument is missing, the command will ask for the form class interactively.
|
||||
|
||||
You can optionally specify the bound class in a second argument.
|
||||
This can be the name of an entity like <info>User</info>
|
||||
|
||||
<info>php %command.full_name% UserType User</info>
|
||||
|
||||
You can also specify a fully qualified name to another class like <info>\App\Dto\UserData</info>.
|
||||
Slashes must be escaped in the argument.
|
||||
|
||||
<info>php %command.full_name% UserType \\App\\Dto\\UserData</info>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new functional test class.
|
||||
|
||||
<info>php %command.full_name% DefaultControllerTest</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new event subscriber class or a new event listener class.
|
||||
|
||||
<info>php %command.full_name% ExceptionListener</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new message class & handler.
|
||||
|
||||
<info>php %command.full_name% EmailMessage</info>
|
||||
|
||||
If the argument is missing, the command will ask for the message class interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new Middleware class.
|
||||
|
||||
<info>php %command.full_name% CustomMiddleware</info>
|
||||
|
||||
If the argument is missing, the command will ask for the message class interactively.
|
||||
@@ -0,0 +1,3 @@
|
||||
The <info>%command.name%</info> command generates a new migration:
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a complete registration form, controller & template.
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
|
||||
The command will ask for several pieces of information to build your form.
|
||||
@@ -0,0 +1,18 @@
|
||||
The <info>%command.name%</info> command generates all the files needed to implement
|
||||
a fully-functional & secure password reset system.
|
||||
|
||||
The SymfonycastsResetPasswordBundle is required and can be added using composer:
|
||||
<info>composer require symfonycasts/reset-password-bundle</info>
|
||||
|
||||
For more information on the <info>reset-password-bundle</info> check out:
|
||||
<href=https://github.com/symfonycasts/reset-password-bundle>https://github.com/symfonycasts/reset-password-bundle</>
|
||||
|
||||
<info>%command.name%</info> requires a user entity with an email property,
|
||||
email getter method, and a password setter method. Maker will ask for these
|
||||
interactively if they cannot be guessed.
|
||||
|
||||
Maker will also update your <info>reset-password.yaml</info> configuration file
|
||||
if one exists. If you have customized the configuration file, maker will attempt
|
||||
to modify it accordingly but preserve your customizations.
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new serializer encoder class.
|
||||
|
||||
<info>php %command.full_name% YamlEncoder</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new serializer normalizer class.
|
||||
|
||||
<info>php %command.full_name% UserNormalizer</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates new Stimulus Controller.
|
||||
|
||||
<info>php %command.full_name% hello</info>
|
||||
|
||||
If the argument is missing, the command will ask for the controller name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new event subscriber class.
|
||||
|
||||
<info>php %command.full_name% ExceptionSubscriber</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,7 @@
|
||||
The <info>%command.name%</info> command generates a new test class.
|
||||
|
||||
<info>php %command.full_name% TestCase BlogPostTest</info>
|
||||
|
||||
If the first argument is missing, the command will ask for the test type interactively.
|
||||
|
||||
If the second argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new twig extension with its runtime class.
|
||||
|
||||
<info>php %command.full_name% AppExtension</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new unit test class.
|
||||
|
||||
<info>php %command.full_name% UtilTest</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,7 @@
|
||||
The <info>%command.name%</info> command generates a new user class for security
|
||||
and updates your security.yaml file for it. It will also generate a user provider
|
||||
class if your situation needs a custom class.
|
||||
|
||||
<info>php %command.full_name% User</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new validation constraint.
|
||||
|
||||
<info>php %command.full_name% EnabledValidator</info>
|
||||
|
||||
If the argument is missing, the command will ask for the constraint class name interactively.
|
||||
@@ -0,0 +1,5 @@
|
||||
The <info>%command.name%</info> command generates a new security voter.
|
||||
|
||||
<info>php %command.full_name% BlogPostVoter</info>
|
||||
|
||||
If the argument is missing, the command will ask for the class name interactively.
|
||||
@@ -0,0 +1,9 @@
|
||||
The <info>%command.name%</info> command generates a controller and twig template
|
||||
to allow users to login using the form_login authenticator.
|
||||
|
||||
The controller name, and logout ability can be customized by answering the
|
||||
questions asked when running <info>%command.name%</info>.
|
||||
|
||||
This will also update your <info>security.yaml</info> for the new authenticator.
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
class <?= $class_name."\n" ?>
|
||||
{
|
||||
}
|
||||
Vendored
+39
@@ -0,0 +1,39 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> extends AbstractAuthenticator
|
||||
{
|
||||
public function supports(Request $request): ?bool
|
||||
{
|
||||
// TODO: Implement supports() method.
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport
|
||||
{
|
||||
// TODO: Implement authenticate() method.
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||
{
|
||||
// TODO: Implement onAuthenticationSuccess() method.
|
||||
}
|
||||
|
||||
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
|
||||
{
|
||||
// TODO: Implement onAuthenticationFailure() method.
|
||||
}
|
||||
|
||||
// public function start(Request $request, AuthenticationException $authException = null): Response
|
||||
// {
|
||||
// /*
|
||||
// * If you would like this class to control what happens when an anonymous user accesses a
|
||||
// * protected page (e.g. redirect to /login), uncomment this method and make this class
|
||||
// * implement Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface.
|
||||
// *
|
||||
// * For more details, see https://symfony.com/doc/current/security/experimental_authenticators.html#configuring-the-authentication-entry-point
|
||||
// */
|
||||
// }
|
||||
}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name; ?> extends AbstractController
|
||||
{
|
||||
}
|
||||
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name; ?> extends AbstractLoginFormAuthenticator
|
||||
{
|
||||
use TargetPathTrait;
|
||||
|
||||
public const LOGIN_ROUTE = 'app_login';
|
||||
|
||||
public function __construct(private UrlGeneratorInterface $urlGenerator)
|
||||
{
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport
|
||||
{
|
||||
$<?= $username_field_var ?> = $request->request->get('<?= $username_field ?>', '');
|
||||
|
||||
$request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME, $<?= $username_field_var ?>);
|
||||
|
||||
return new Passport(
|
||||
new UserBadge($<?= $username_field_var ?>),
|
||||
new PasswordCredentials($request->request->get('password', '')),
|
||||
[
|
||||
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),<?= $remember_me_badge ? "
|
||||
new RememberMeBadge(),\n" : "" ?>
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
|
||||
{
|
||||
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
|
||||
return new RedirectResponse($targetPath);
|
||||
}
|
||||
|
||||
// For example:
|
||||
// return new RedirectResponse($this->urlGenerator->generate('some_route'));
|
||||
throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
|
||||
}
|
||||
|
||||
protected function getLoginUrl(Request $request): string
|
||||
{
|
||||
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Log in!{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form method="post">
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
|
||||
{% endif %}
|
||||
|
||||
<?php if ($logout_setup): ?>
|
||||
{% if app.user %}
|
||||
<div class="mb-3">
|
||||
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
<?php endif; ?>
|
||||
|
||||
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
|
||||
<label for="input<?= ucfirst($username_field); ?>"><?= $username_label; ?></label>
|
||||
<input type="<?= $username_is_email ? 'email' : 'text'; ?>" value="{{ last_username }}" name="<?= $username_field; ?>" id="input<?= ucfirst($username_field); ?>" class="form-control" autocomplete="<?= $username_is_email ? 'email' : 'username'; ?>" required autofocus>
|
||||
<label for="inputPassword">Password</label>
|
||||
<input type="password" name="password" id="inputPassword" class="form-control" autocomplete="current-password" required>
|
||||
|
||||
<input type="hidden" name="_csrf_token"
|
||||
value="{{ csrf_token('authenticate') }}"
|
||||
>
|
||||
<?php if($support_remember_me && !$always_remember_me): ?>
|
||||
|
||||
<div class="checkbox mb-3">
|
||||
<label>
|
||||
<input type="checkbox" name="_remember_me"> Remember me
|
||||
</label>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<button class="btn btn-lg btn-primary" type="submit">
|
||||
Sign in
|
||||
</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?= "<?php\n"; ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
#[AsCommand(
|
||||
name: '<?= $command_name; ?>',
|
||||
description: 'Add a short description for your command',
|
||||
)]
|
||||
class <?= $class_name; ?> extends Command
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure(): void
|
||||
{
|
||||
$this
|
||||
<?= $set_description ? " ->setDescription(self::\$defaultDescription)\n" : '' ?>
|
||||
->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')
|
||||
->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
|
||||
;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$arg1 = $input->getArgument('arg1');
|
||||
|
||||
if ($arg1) {
|
||||
$io->note(sprintf('You passed an argument: %s', $arg1));
|
||||
}
|
||||
|
||||
if ($input->getOption('option1')) {
|
||||
// ...
|
||||
}
|
||||
|
||||
$io->success('You have a new command! Now make it your own! Pass --help to see your options.');
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name; ?> extends AbstractController
|
||||
{
|
||||
<?= $generator->generateRouteForControllerMethod($route_path, $route_name); ?>
|
||||
public function <?= $method_name ?>(): <?php if ($with_template) { ?>Response<?php } else { ?>JsonResponse<?php } ?>
|
||||
|
||||
{
|
||||
<?php if ($with_template) { ?>
|
||||
return $this->render('<?= $template_name ?>', [
|
||||
'controller_name' => '<?= $class_name ?>',
|
||||
]);
|
||||
<?php } else { ?>
|
||||
return $this->json([
|
||||
'message' => 'Welcome to your new controller!',
|
||||
'path' => '<?= $relative_path; ?>',
|
||||
]);
|
||||
<?php } ?>
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
<?= $helper->getHeadPrintCode("Hello $class_name!"); ?>
|
||||
|
||||
{% block body %}
|
||||
<style>
|
||||
.example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
|
||||
.example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
|
||||
</style>
|
||||
|
||||
<div class="example-wrapper">
|
||||
<h1>Hello {{ controller_name }}! ✅</h1>
|
||||
|
||||
This friendly message is coming from:
|
||||
<ul>
|
||||
<li>Your controller at <code><?= $root_directory ?>/<?= $controller_path ?></code></li>
|
||||
<li>Your template at <code><?= $root_directory ?>/<?= $relative_path ?></code></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
#[Route('<?= $route_path ?>')]
|
||||
class <?= $class_name ?> extends AbstractController
|
||||
{
|
||||
<?= $generator->generateRouteForControllerMethod('/', sprintf('%s_index', $route_name), ['GET']) ?>
|
||||
<?php if (isset($repository_full_class_name)): ?>
|
||||
public function index(<?= $repository_class_name ?> $<?= $repository_var ?>): Response
|
||||
{
|
||||
return $this->render('<?= $templates_path ?>/index.html.twig', [
|
||||
'<?= $entity_twig_var_plural ?>' => $<?= $repository_var ?>->findAll(),
|
||||
]);
|
||||
}
|
||||
<?php else: ?>
|
||||
public function index(EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$<?= $entity_var_plural ?> = $entityManager
|
||||
->getRepository(<?= $entity_class_name ?>::class)
|
||||
->findAll();
|
||||
|
||||
return $this->render('<?= $templates_path ?>/index.html.twig', [
|
||||
'<?= $entity_twig_var_plural ?>' => $<?= $entity_var_plural ?>,
|
||||
]);
|
||||
}
|
||||
<?php endif ?>
|
||||
|
||||
<?= $generator->generateRouteForControllerMethod('/new', sprintf('%s_new', $route_name), ['GET', 'POST']) ?>
|
||||
public function new(Request $request, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$<?= $entity_var_singular ?> = new <?= $entity_class_name ?>();
|
||||
$form = $this->createForm(<?= $form_class_name ?>::class, $<?= $entity_var_singular ?>);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->persist($<?= $entity_var_singular ?>);
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('<?= $route_name ?>_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('<?= $templates_path ?>/new.html.twig', [
|
||||
'<?= $entity_twig_var_singular ?>' => $<?= $entity_var_singular ?>,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
<?= $generator->generateRouteForControllerMethod(sprintf('/{%s}', $entity_identifier), sprintf('%s_show', $route_name), ['GET']) ?>
|
||||
public function show(<?= $entity_class_name ?> $<?= $entity_var_singular ?>): Response
|
||||
{
|
||||
return $this->render('<?= $templates_path ?>/show.html.twig', [
|
||||
'<?= $entity_twig_var_singular ?>' => $<?= $entity_var_singular ?>,
|
||||
]);
|
||||
}
|
||||
|
||||
<?= $generator->generateRouteForControllerMethod(sprintf('/{%s}/edit', $entity_identifier), sprintf('%s_edit', $route_name), ['GET', 'POST']) ?>
|
||||
public function edit(Request $request, <?= $entity_class_name ?> $<?= $entity_var_singular ?>, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$form = $this->createForm(<?= $form_class_name ?>::class, $<?= $entity_var_singular ?>);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$entityManager->flush();
|
||||
|
||||
return $this->redirectToRoute('<?= $route_name ?>_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->render('<?= $templates_path ?>/edit.html.twig', [
|
||||
'<?= $entity_twig_var_singular ?>' => $<?= $entity_var_singular ?>,
|
||||
'form' => $form,
|
||||
]);
|
||||
}
|
||||
|
||||
<?= $generator->generateRouteForControllerMethod(sprintf('/{%s}', $entity_identifier), sprintf('%s_delete', $route_name), ['POST']) ?>
|
||||
public function delete(Request $request, <?= $entity_class_name ?> $<?= $entity_var_singular ?>, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
if ($this->isCsrfTokenValid('delete'.$<?= $entity_var_singular ?>->get<?= ucfirst($entity_identifier) ?>(), $request->request->get('_token'))) {
|
||||
$entityManager->remove($<?= $entity_var_singular ?>);
|
||||
$entityManager->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('<?= $route_name ?>_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<form method="post" action="{{ path('<?= $route_name ?>_delete', {'<?= $entity_identifier ?>': <?= $entity_twig_var_singular ?>.<?= $entity_identifier ?>}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ <?= $entity_twig_var_singular ?>.<?= $entity_identifier ?>) }}">
|
||||
<button class="btn">Delete</button>
|
||||
</form>
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
{{ form_start(form) }}
|
||||
{{ form_widget(form) }}
|
||||
<button class="btn">{{ button_label|default('Save') }}</button>
|
||||
{{ form_end(form) }}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?= $helper->getHeadPrintCode('Edit '.$entity_class_name) ?>
|
||||
|
||||
{% block body %}
|
||||
<h1>Edit <?= $entity_class_name ?></h1>
|
||||
|
||||
{{ include('<?= $templates_path ?>/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<a href="{{ path('<?= $route_name ?>_index') }}">back to list</a>
|
||||
|
||||
{{ include('<?= $templates_path ?>/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<?= $helper->getHeadPrintCode($entity_class_name.' index'); ?>
|
||||
|
||||
{% block body %}
|
||||
<h1><?= $entity_class_name ?> index</h1>
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach ($entity_fields as $field): ?>
|
||||
<th><?= ucfirst($field['fieldName']) ?></th>
|
||||
<?php endforeach; ?>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for <?= $entity_twig_var_singular ?> in <?= $entity_twig_var_plural ?> %}
|
||||
<tr>
|
||||
<?php foreach ($entity_fields as $field): ?>
|
||||
<td>{{ <?= $helper->getEntityFieldPrintCode($entity_twig_var_singular, $field) ?> }}</td>
|
||||
<?php endforeach; ?>
|
||||
<td>
|
||||
<a href="{{ path('<?= $route_name ?>_show', {'<?= $entity_identifier ?>': <?= $entity_twig_var_singular ?>.<?= $entity_identifier ?>}) }}">show</a>
|
||||
<a href="{{ path('<?= $route_name ?>_edit', {'<?= $entity_identifier ?>': <?= $entity_twig_var_singular ?>.<?= $entity_identifier ?>}) }}">edit</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="<?= (count($entity_fields) + 1) ?>">no records found</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('<?= $route_name ?>_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?= $helper->getHeadPrintCode('New '.$entity_class_name) ?>
|
||||
|
||||
{% block body %}
|
||||
<h1>Create new <?= $entity_class_name ?></h1>
|
||||
|
||||
{{ include('<?= $templates_path ?>/_form.html.twig') }}
|
||||
|
||||
<a href="{{ path('<?= $route_name ?>_index') }}">back to list</a>
|
||||
{% endblock %}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
<?= $helper->getHeadPrintCode($entity_class_name) ?>
|
||||
|
||||
{% block body %}
|
||||
<h1><?= $entity_class_name ?></h1>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<?php foreach ($entity_fields as $field): ?>
|
||||
<tr>
|
||||
<th><?= ucfirst($field['fieldName']) ?></th>
|
||||
<td>{{ <?= $helper->getEntityFieldPrintCode($entity_twig_var_singular, $field) ?> }}</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('<?= $route_name ?>_index') }}">back to list</a>
|
||||
|
||||
<a href="{{ path('<?= $route_name ?>_edit', {'<?= $entity_identifier ?>': <?= $entity_twig_var_singular ?>.<?= $entity_identifier ?>}) }}">edit</a>
|
||||
|
||||
{{ include('<?= $templates_path ?>/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
<?= "<?php\n" ?>
|
||||
<?php use Symfony\Bundle\MakerBundle\Str; ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> extends WebTestCase<?= "\n" ?>
|
||||
{
|
||||
private KernelBrowser $client;
|
||||
private EntityManagerInterface $manager;
|
||||
private EntityRepository $repository;
|
||||
private string $path = '<?= $route_path; ?>/';
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->client = static::createClient();
|
||||
$this->manager = static::getContainer()->get('doctrine')->getManager();
|
||||
$this->repository = $this->manager->getRepository(<?= $entity_class_name; ?>::class);
|
||||
|
||||
foreach ($this->repository->findAll() as $object) {
|
||||
$this->manager->remove($object);
|
||||
}
|
||||
|
||||
$this->manager->flush();
|
||||
}
|
||||
|
||||
public function testIndex(): void
|
||||
{
|
||||
$crawler = $this->client->request('GET', $this->path);
|
||||
|
||||
self::assertResponseStatusCodeSame(200);
|
||||
self::assertPageTitleContains('<?= ucfirst($entity_var_singular); ?> index');
|
||||
|
||||
// Use the $crawler to perform additional assertions e.g.
|
||||
// self::assertSame('Some text on the page', $crawler->filter('.p')->first());
|
||||
}
|
||||
|
||||
public function testNew(): void
|
||||
{
|
||||
$this->markTestIncomplete();
|
||||
$this->client->request('GET', sprintf('%snew', $this->path));
|
||||
|
||||
self::assertResponseStatusCodeSame(200);
|
||||
|
||||
$this->client->submitForm('Save', [
|
||||
<?php foreach ($form_fields as $form_field => $typeOptions): ?>
|
||||
'<?= $form_field_prefix; ?>[<?= $form_field; ?>]' => 'Testing',
|
||||
<?php endforeach; ?>
|
||||
]);
|
||||
|
||||
self::assertResponseRedirects('/sweet/food/');
|
||||
|
||||
self::assertSame(1, $this->getRepository()->count([]));
|
||||
}
|
||||
|
||||
public function testShow(): void
|
||||
{
|
||||
$this->markTestIncomplete();
|
||||
$fixture = new <?= $entity_class_name; ?>();
|
||||
<?php foreach ($form_fields as $form_field => $typeOptions): ?>
|
||||
$fixture->set<?= ucfirst($form_field); ?>('My Title');
|
||||
<?php endforeach; ?>
|
||||
|
||||
$this->manager->persist($fixture);
|
||||
$this->manager->flush();
|
||||
|
||||
$this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));
|
||||
|
||||
self::assertResponseStatusCodeSame(200);
|
||||
self::assertPageTitleContains('<?= ucfirst($entity_var_singular); ?>');
|
||||
|
||||
// Use assertions to check that the properties are properly displayed.
|
||||
}
|
||||
|
||||
public function testEdit(): void
|
||||
{
|
||||
$this->markTestIncomplete();
|
||||
$fixture = new <?= $entity_class_name; ?>();
|
||||
<?php foreach ($form_fields as $form_field => $typeOptions): ?>
|
||||
$fixture->set<?= ucfirst($form_field); ?>('Value');
|
||||
<?php endforeach; ?>
|
||||
|
||||
$this->manager->persist($fixture);
|
||||
$this->manager->flush();
|
||||
|
||||
$this->client->request('GET', sprintf('%s%s/edit', $this->path, $fixture->getId()));
|
||||
|
||||
$this->client->submitForm('Update', [
|
||||
<?php foreach ($form_fields as $form_field => $typeOptions): ?>
|
||||
'<?= $form_field_prefix; ?>[<?= $form_field; ?>]' => 'Something New',
|
||||
<?php endforeach; ?>
|
||||
]);
|
||||
|
||||
self::assertResponseRedirects('<?= $route_path; ?>/');
|
||||
|
||||
$fixture = $this->repository->findAll();
|
||||
|
||||
<?php foreach ($form_fields as $form_field => $typeOptions): ?>
|
||||
self::assertSame('Something New', $fixture[0]->get<?= ucfirst($form_field); ?>());
|
||||
<?php endforeach; ?>
|
||||
}
|
||||
|
||||
public function testRemove(): void
|
||||
{
|
||||
$this->markTestIncomplete();
|
||||
$fixture = new <?= $entity_class_name; ?>();
|
||||
<?php foreach ($form_fields as $form_field => $typeOptions): ?>
|
||||
$fixture->set<?= ucfirst($form_field); ?>('Value');
|
||||
<?php endforeach; ?>
|
||||
|
||||
$this->manager->remove($fixture);
|
||||
$this->manager->flush();
|
||||
|
||||
$this->client->request('GET', sprintf('%s%s', $this->path, $fixture->getId()));
|
||||
$this->client->submitForm('Delete');
|
||||
|
||||
self::assertResponseRedirects('<?= $route_path; ?>/');
|
||||
self::assertSame(0, $this->repository->count([]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
#[ORM\Entity(repositoryClass: <?= $repository_class_name ?>::class)]
|
||||
<?php if ($should_escape_table_name): ?>#[ORM\Table(name: '`<?= $table_name ?>`')]
|
||||
<?php endif ?>
|
||||
<?php if ($api_resource): ?>
|
||||
#[ApiResource]
|
||||
<?php endif ?>
|
||||
<?php if ($broadcast): ?>
|
||||
#[Broadcast]
|
||||
<?php endif ?>
|
||||
class <?= $class_name."\n" ?>
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> extends Fixture
|
||||
{
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
// $product = new Product();
|
||||
// $manager->persist($product);
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
<?= "<?php\n"; ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<<?= $entity_class_name; ?>>
|
||||
<?= $with_password_upgrade ? " * @implements PasswordUpgraderInterface<$entity_class_name>\n" : "" ?>
|
||||
*
|
||||
* @method <?= $entity_class_name; ?>|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method <?= $entity_class_name; ?>|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method <?= $entity_class_name; ?>[] findAll()
|
||||
* @method <?= $entity_class_name; ?>[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class <?= $class_name; ?> extends ServiceEntityRepository<?= $with_password_upgrade ? " implements PasswordUpgraderInterface\n" : "\n" ?>
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, <?= $entity_class_name; ?>::class);
|
||||
}
|
||||
<?php if ($include_example_comments): // When adding a new method without existing default comments, the blank line is automatically added.?>
|
||||
|
||||
<?php endif; ?>
|
||||
<?php if ($with_password_upgrade): ?>
|
||||
/**
|
||||
* Used to upgrade (rehash) the user's password automatically over time.
|
||||
*/
|
||||
public function upgradePassword(<?= sprintf('%s ', $password_upgrade_user_interface->getShortName()); ?>$user, string $newHashedPassword): void
|
||||
{
|
||||
if (!$user instanceof <?= $entity_class_name ?>) {
|
||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class));
|
||||
}
|
||||
|
||||
$user->setPassword($newHashedPassword);
|
||||
$this->getEntityManager()->persist($user);
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
|
||||
<?php endif ?>
|
||||
<?php if ($include_example_comments): ?>
|
||||
// /**
|
||||
// * @return <?= $entity_class_name ?>[] Returns an array of <?= $entity_class_name ?> objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('<?= $entity_alias; ?>')
|
||||
// ->andWhere('<?= $entity_alias; ?>.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('<?= $entity_alias; ?>.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?<?= $entity_class_name."\n" ?>
|
||||
// {
|
||||
// return $this->createQueryBuilder('<?= $entity_alias ?>')
|
||||
// ->andWhere('<?= $entity_alias ?>.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
<?php endif; ?>
|
||||
}
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
{# Learn how to use Turbo Streams: https://github.com/symfony/ux-turbo#broadcast-doctrine-entities-update #}
|
||||
{% block create %}
|
||||
<turbo-stream action="append" target="<?= $class_name_plural ?>">
|
||||
<template>
|
||||
<div id="{{ '<?= $class_name ?>_' ~ id }}">
|
||||
#{{ id }} created
|
||||
</div>
|
||||
</template>
|
||||
</turbo-stream>
|
||||
{% endblock %}
|
||||
|
||||
{% block update %}
|
||||
<turbo-stream action="update" target="<?= $class_name ?>_{{ id }}">
|
||||
<template>
|
||||
#{{ id }} updated
|
||||
</template>
|
||||
</turbo-stream>
|
||||
{% endblock %}
|
||||
|
||||
{% block remove %}
|
||||
<turbo-stream action="remove" target="<?= $class_name ?>_{{ id }}"></turbo-stream>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
final class <?= $class_name."\n" ?>
|
||||
{
|
||||
#[AsEventListener(event: <?= $event ?>)]
|
||||
public function <?= $method_name ?>(<?= $event_arg ?>): void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> implements EventSubscriberInterface
|
||||
{
|
||||
public function <?= $method_name ?>(<?= $event_arg ?>): void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
<?= $event ?> => '<?= $method_name ?>',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
<?php foreach ($form_fields as $form_field => $typeOptions): ?>
|
||||
<?php if (null === $typeOptions['type'] && !$typeOptions['options_code']): ?>
|
||||
->add('<?= $form_field ?>')
|
||||
<?php elseif (null !== $typeOptions['type'] && !$typeOptions['options_code']): ?>
|
||||
->add('<?= $form_field ?>', <?= $typeOptions['type'] ?>::class)
|
||||
<?php else: ?>
|
||||
->add('<?= $form_field ?>', <?= $typeOptions['type'] ? ($typeOptions['type'].'::class') : 'null' ?>, [
|
||||
<?= $typeOptions['options_code']."\n" ?>
|
||||
])
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
<?php if ($bounded_class_name): ?>
|
||||
'data_class' => <?= $bounded_class_name ?>::class,
|
||||
<?php else: ?>
|
||||
// Configure your form options here
|
||||
<?php endif ?>
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
final class <?= $class_name."\n" ?>
|
||||
{
|
||||
/*
|
||||
* Add whatever properties and methods you need
|
||||
* to hold the data for this message class.
|
||||
*/
|
||||
|
||||
// private $name;
|
||||
|
||||
// public function __construct(string $name)
|
||||
// {
|
||||
// $this->name = $name;
|
||||
// }
|
||||
|
||||
// public function getName(): string
|
||||
// {
|
||||
// return $this->name;
|
||||
// }
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
#[AsMessageHandler]
|
||||
final class <?= $class_name ?>
|
||||
{
|
||||
public function __invoke(<?= $message_class_name ?> $message)
|
||||
{
|
||||
// do something with your message
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
final class <?= $class_name; ?> implements MiddlewareInterface
|
||||
{
|
||||
public function handle(Envelope $envelope, StackInterface $stack): Envelope
|
||||
{
|
||||
// ...
|
||||
return $stack->next()->handle($envelope, $stack);
|
||||
}
|
||||
}
|
||||
Vendored
+106
@@ -0,0 +1,106 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name; ?> extends AbstractController
|
||||
{
|
||||
<?php if ($will_verify_email): ?>
|
||||
private <?= $generator->getPropertyType($email_verifier_class_details) ?>$emailVerifier;
|
||||
|
||||
public function __construct(<?= $email_verifier_class_details->getShortName() ?> $emailVerifier)
|
||||
{
|
||||
$this->emailVerifier = $emailVerifier;
|
||||
}
|
||||
|
||||
<?php endif; ?>
|
||||
<?= $generator->generateRouteForControllerMethod($route_path, $route_name) ?>
|
||||
public function register(Request $request, <?= $password_hasher_class_details->getShortName() ?> $userPasswordHasher<?= $authenticator_full_class_name ? sprintf(', UserAuthenticatorInterface $userAuthenticator, %s $authenticator', $authenticator_class_name) : '' ?>, EntityManagerInterface $entityManager): Response
|
||||
{
|
||||
$user = new <?= $user_class_name ?>();
|
||||
$form = $this->createForm(<?= $form_class_name ?>::class, $user);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
// encode the plain password
|
||||
$user->set<?= ucfirst($password_field) ?>(
|
||||
$userPasswordHasher->hashPassword(
|
||||
$user,
|
||||
$form->get('plainPassword')->getData()
|
||||
)
|
||||
);
|
||||
|
||||
$entityManager->persist($user);
|
||||
$entityManager->flush();
|
||||
<?php if ($will_verify_email): ?>
|
||||
|
||||
// generate a signed url and email it to the user
|
||||
$this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
|
||||
(new TemplatedEmail())
|
||||
->from(new Address('<?= $from_email ?>', '<?= $from_email_name ?>'))
|
||||
->to($user-><?= $email_getter ?>())
|
||||
->subject('Please Confirm your Email')
|
||||
->htmlTemplate('registration/confirmation_email.html.twig')
|
||||
);
|
||||
<?php endif; ?>
|
||||
// do anything else you need here, like send an email
|
||||
|
||||
<?php if ($authenticator_full_class_name): ?>
|
||||
return $userAuthenticator->authenticateUser(
|
||||
$user,
|
||||
$authenticator,
|
||||
$request
|
||||
);
|
||||
<?php else: ?>
|
||||
return $this->redirectToRoute('<?= $redirect_route_name ?>');
|
||||
<?php endif; ?>
|
||||
}
|
||||
|
||||
return $this->render('registration/register.html.twig', [
|
||||
'registrationForm' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
<?php if ($will_verify_email): ?>
|
||||
|
||||
<?= $generator->generateRouteForControllerMethod('/verify/email', 'app_verify_email') ?>
|
||||
public function verifyUserEmail(Request $request<?php if ($translator_available): ?>, TranslatorInterface $translator<?php endif ?><?= $verify_email_anonymously ? sprintf(', %s %s', $repository_class_name, $repository_var) : null ?>): Response
|
||||
{
|
||||
<?php if (!$verify_email_anonymously): ?>
|
||||
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
|
||||
<?php else: ?>
|
||||
$id = $request->query->get('id');
|
||||
|
||||
if (null === $id) {
|
||||
return $this->redirectToRoute('app_register');
|
||||
}
|
||||
<?php if ('$manager' === $repository_var): ?>
|
||||
|
||||
$repository = $manager->getRepository(<?= $user_class_name ?>::class);
|
||||
$user = $repository->find($id);
|
||||
<?php else: ?>
|
||||
|
||||
$user = <?= $repository_var; ?>->find($id);
|
||||
<?php endif; ?>
|
||||
|
||||
if (null === $user) {
|
||||
return $this->redirectToRoute('app_register');
|
||||
}
|
||||
<?php endif; ?>
|
||||
|
||||
// validate email confirmation link, sets User::isVerified=true and persists
|
||||
try {
|
||||
$this->emailVerifier->handleEmailConfirmation($request, <?= $verify_email_anonymously ? '$user' : '$this->getUser()' ?>);
|
||||
} catch (VerifyEmailExceptionInterface $exception) {
|
||||
$this->addFlash('verify_email_error', <?php if ($translator_available): ?>$translator->trans($exception->getReason(), [], 'VerifyEmailBundle')<?php else: ?>$exception->getReason()<?php endif ?>);
|
||||
|
||||
return $this->redirectToRoute('<?= $route_name ?>');
|
||||
}
|
||||
|
||||
// @TODO Change the redirect on success and handle or remove the flash message in your templates
|
||||
$this->addFlash('success', 'Your email address has been verified.');
|
||||
|
||||
return $this->redirectToRoute('app_register');
|
||||
}
|
||||
<?php endif; ?>
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<h1>Hi! Please confirm your email!</h1>
|
||||
|
||||
<p>
|
||||
Please confirm your email address by clicking the following link: <br><br>
|
||||
<a href="{{ signedUrl|raw }}">Confirm my Email</a>.
|
||||
This link will expire in {{ expiresAtMessageKey|trans(expiresAtMessageData, 'VerifyEmailBundle') }}.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Cheers!
|
||||
</p>
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?= $helper->getHeadPrintCode('Register'); ?>
|
||||
|
||||
{% block body %}
|
||||
<?php if ($will_verify_email): ?>
|
||||
{% for flash_error in app.flashes('verify_email_error') %}
|
||||
<div class="alert alert-danger" role="alert">{{ flash_error }}</div>
|
||||
{% endfor %}
|
||||
|
||||
<?php endif; ?>
|
||||
<h1>Register</h1>
|
||||
|
||||
{{ form_errors(registrationForm) }}
|
||||
|
||||
{{ form_start(registrationForm) }}
|
||||
{{ form_row(registrationForm.<?= $username_field ?>) }}
|
||||
{{ form_row(registrationForm.plainPassword, {
|
||||
label: 'Password'
|
||||
}) }}
|
||||
{{ form_row(registrationForm.agreeTerms) }}
|
||||
|
||||
<button type="submit" class="btn">Register</button>
|
||||
{{ form_end(registrationForm) }}
|
||||
{% endblock %}
|
||||
Vendored
+48
@@ -0,0 +1,48 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements ?>
|
||||
|
||||
class <?= $class_name ?> extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('plainPassword', RepeatedType::class, [
|
||||
'type' => PasswordType::class,
|
||||
'options' => [
|
||||
'attr' => [
|
||||
'autocomplete' => 'new-password',
|
||||
],
|
||||
],
|
||||
'first_options' => [
|
||||
'constraints' => [
|
||||
new NotBlank([
|
||||
'message' => 'Please enter a password',
|
||||
]),
|
||||
new Length([
|
||||
'min' => 6,
|
||||
'minMessage' => 'Your password should be at least {{ limit }} characters',
|
||||
// max length allowed by Symfony for security reasons
|
||||
'max' => 4096,
|
||||
]),
|
||||
],
|
||||
'label' => 'New password',
|
||||
],
|
||||
'second_options' => [
|
||||
'label' => 'Repeat Password',
|
||||
],
|
||||
'invalid_message' => 'The password fields must match.',
|
||||
// Instead of being set onto the object directly,
|
||||
// this is read and encoded in the controller
|
||||
'mapped' => false,
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([]);
|
||||
}
|
||||
}
|
||||
Vendored
+160
@@ -0,0 +1,160 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
#[Route('/reset-password')]
|
||||
class <?= $class_name ?> extends AbstractController
|
||||
{
|
||||
use ResetPasswordControllerTrait;
|
||||
|
||||
public function __construct(
|
||||
private ResetPasswordHelperInterface $resetPasswordHelper,
|
||||
private EntityManagerInterface $entityManager
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display & process form to request a password reset.
|
||||
*/
|
||||
#[Route('', name: 'app_forgot_password_request')]
|
||||
public function request(Request $request, MailerInterface $mailer<?php if ($translator_available): ?>, TranslatorInterface $translator<?php endif ?>): Response
|
||||
{
|
||||
$form = $this->createForm(<?= $request_form_type_class_name ?>::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
return $this->processSendingPasswordResetEmail(
|
||||
$form->get('<?= $email_field ?>')->getData(),
|
||||
$mailer<?php if ($translator_available): ?>,
|
||||
$translator<?php endif ?><?= "\n" ?>
|
||||
);
|
||||
}
|
||||
|
||||
return $this->render('reset_password/request.html.twig', [
|
||||
'requestForm' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirmation page after a user has requested a password reset.
|
||||
*/
|
||||
#[Route('/check-email', name: 'app_check_email')]
|
||||
public function checkEmail(): Response
|
||||
{
|
||||
// Generate a fake token if the user does not exist or someone hit this page directly.
|
||||
// This prevents exposing whether or not a user was found with the given email address or not
|
||||
if (null === ($resetToken = $this->getTokenObjectFromSession())) {
|
||||
$resetToken = $this->resetPasswordHelper->generateFakeResetToken();
|
||||
}
|
||||
|
||||
return $this->render('reset_password/check_email.html.twig', [
|
||||
'resetToken' => $resetToken,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and process the reset URL that the user clicked in their email.
|
||||
*/
|
||||
#[Route('/reset/{token}', name: 'app_reset_password')]
|
||||
public function reset(Request $request, UserPasswordHasherInterface $passwordHasher<?php if ($translator_available): ?>, TranslatorInterface $translator<?php endif ?>, string $token = null): Response
|
||||
{
|
||||
if ($token) {
|
||||
// We store the token in session and remove it from the URL, to avoid the URL being
|
||||
// loaded in a browser and potentially leaking the token to 3rd party JavaScript.
|
||||
$this->storeTokenInSession($token);
|
||||
|
||||
return $this->redirectToRoute('app_reset_password');
|
||||
}
|
||||
|
||||
$token = $this->getTokenFromSession();
|
||||
if (null === $token) {
|
||||
throw $this->createNotFoundException('No reset password token found in the URL or in the session.');
|
||||
}
|
||||
|
||||
try {
|
||||
$user = $this->resetPasswordHelper->validateTokenAndFetchUser($token);
|
||||
} catch (ResetPasswordExceptionInterface $e) {
|
||||
$this->addFlash('reset_password_error', sprintf(
|
||||
'%s - %s',
|
||||
<?php if ($translator_available): ?>$translator->trans(<?= $problem_validate_message_or_constant ?>, [], 'ResetPasswordBundle')<?php else: ?><?= $problem_validate_message_or_constant ?><?php endif ?>,
|
||||
<?php if ($translator_available): ?>$translator->trans($e->getReason(), [], 'ResetPasswordBundle')<?php else: ?>$e->getReason()<?php endif ?><?= "\n" ?>
|
||||
));
|
||||
|
||||
return $this->redirectToRoute('app_forgot_password_request');
|
||||
}
|
||||
|
||||
// The token is valid; allow the user to change their password.
|
||||
$form = $this->createForm(<?= $reset_form_type_class_name ?>::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
// A password reset token should be used only once, remove it.
|
||||
$this->resetPasswordHelper->removeResetRequest($token);
|
||||
|
||||
// Encode(hash) the plain password, and set it.
|
||||
$encodedPassword = $passwordHasher->hashPassword(
|
||||
$user,
|
||||
$form->get('plainPassword')->getData()
|
||||
);
|
||||
|
||||
$user-><?= $password_setter ?>($encodedPassword);
|
||||
$this->entityManager->flush();
|
||||
|
||||
// The session is cleaned up after the password has been changed.
|
||||
$this->cleanSessionAfterReset();
|
||||
|
||||
return $this->redirectToRoute('<?= $success_redirect_route ?>');
|
||||
}
|
||||
|
||||
return $this->render('reset_password/reset.html.twig', [
|
||||
'resetForm' => $form->createView(),
|
||||
]);
|
||||
}
|
||||
|
||||
private function processSendingPasswordResetEmail(string $emailFormData, MailerInterface $mailer<?php if ($translator_available): ?>, TranslatorInterface $translator<?php endif ?>): RedirectResponse
|
||||
{
|
||||
$user = $this->entityManager->getRepository(<?= $user_class_name ?>::class)->findOneBy([
|
||||
'<?= $email_field ?>' => $emailFormData,
|
||||
]);
|
||||
|
||||
// Do not reveal whether a user account was found or not.
|
||||
if (!$user) {
|
||||
return $this->redirectToRoute('app_check_email');
|
||||
}
|
||||
|
||||
try {
|
||||
$resetToken = $this->resetPasswordHelper->generateResetToken($user);
|
||||
} catch (ResetPasswordExceptionInterface $e) {
|
||||
// If you want to tell the user why a reset email was not sent, uncomment
|
||||
// the lines below and change the redirect to 'app_forgot_password_request'.
|
||||
// Caution: This may reveal if a user is registered or not.
|
||||
//
|
||||
// $this->addFlash('reset_password_error', sprintf(
|
||||
// '%s - %s',
|
||||
// <?php if ($translator_available): ?>$translator->trans(<?= $problem_handle_message_or_constant ?>, [], 'ResetPasswordBundle')<?php else: ?><?= $problem_handle_message_or_constant ?><?php endif ?>,
|
||||
// <?php if ($translator_available): ?>$translator->trans($e->getReason(), [], 'ResetPasswordBundle')<?php else: ?>$e->getReason()<?php endif ?><?= "\n" ?>
|
||||
// ));
|
||||
|
||||
return $this->redirectToRoute('app_check_email');
|
||||
}
|
||||
|
||||
$email = (new TemplatedEmail())
|
||||
->from(new Address('<?= $from_email ?>', '<?= $from_email_name ?>'))
|
||||
->to($user-><?= $email_getter ?>())
|
||||
->subject('Your password reset request')
|
||||
->htmlTemplate('reset_password/email.html.twig')
|
||||
->context([
|
||||
'resetToken' => $resetToken,
|
||||
])
|
||||
;
|
||||
|
||||
$mailer->send($email);
|
||||
|
||||
// Store the token object in session for retrieval in check-email route.
|
||||
$this->setTokenObjectInSession($resetToken);
|
||||
|
||||
return $this->redirectToRoute('app_check_email');
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace ?>;
|
||||
|
||||
<?= $use_statements ?>
|
||||
|
||||
class <?= $class_name ?> extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('<?= $email_field ?>', EmailType::class, [
|
||||
'attr' => ['autocomplete' => 'email'],
|
||||
'constraints' => [
|
||||
new NotBlank([
|
||||
'message' => 'Please enter your email',
|
||||
]),
|
||||
],
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([]);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Password Reset Email Sent{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<p>
|
||||
If an account matching your email exists, then an email was just sent that contains a link that you can use to reset your password.
|
||||
This link will expire in {{ resetToken.expirationMessageKey|trans(resetToken.expirationMessageData, 'ResetPasswordBundle') }}.
|
||||
</p>
|
||||
<p>If you don't receive an email please check your spam folder or <a href="{{ path('app_forgot_password_request') }}">try again</a>.</p>
|
||||
{% endblock %}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
<h1>Hi!</h1>
|
||||
|
||||
<p>To reset your password, please visit the following link</p>
|
||||
|
||||
<a href="{{ url('app_reset_password', {token: resetToken.token}) }}">{{ url('app_reset_password', {token: resetToken.token}) }}</a>
|
||||
|
||||
<p>This link will expire in {{ resetToken.expirationMessageKey|trans(resetToken.expirationMessageData, 'ResetPasswordBundle') }}.</p>
|
||||
|
||||
<p>Cheers!</p>
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Reset your password{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% for flash_error in app.flashes('reset_password_error') %}
|
||||
<div class="alert alert-danger" role="alert">{{ flash_error }}</div>
|
||||
{% endfor %}
|
||||
<h1>Reset your password</h1>
|
||||
|
||||
{{ form_start(requestForm) }}
|
||||
{{ form_row(requestForm.<?= $email_field ?>) }}
|
||||
<div>
|
||||
<small>
|
||||
Enter your email address, and we will send you a
|
||||
link to reset your password.
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary">Send password reset email</button>
|
||||
{{ form_end(requestForm) }}
|
||||
{% endblock %}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Reset your password{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Reset your password</h1>
|
||||
|
||||
{{ form_start(resetForm) }}
|
||||
{{ form_row(resetForm.plainPassword) }}
|
||||
<button class="btn btn-primary">Reset password</button>
|
||||
{{ form_end(resetForm) }}
|
||||
{% endblock %}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> implements UserProviderInterface, PasswordUpgraderInterface
|
||||
{
|
||||
/**
|
||||
* Symfony calls this method if you use features like switch_user
|
||||
* or remember_me.
|
||||
*
|
||||
* If you're not using these features, you do not need to implement
|
||||
* this method.
|
||||
*
|
||||
* @throws UserNotFoundException if the user is not found
|
||||
*/
|
||||
public function loadUserByIdentifier($identifier): UserInterface
|
||||
{
|
||||
// Load a User object from your data source or throw UserNotFoundException.
|
||||
// The $identifier argument may not actually be a username:
|
||||
// it is whatever value is being returned by the getUserIdentifier()
|
||||
// method in your User class.
|
||||
throw new \Exception('TODO: fill in loadUserByIdentifier() inside '.__FILE__);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 5.3, loadUserByIdentifier() is used instead
|
||||
*/
|
||||
public function loadUserByUsername($username): UserInterface
|
||||
{
|
||||
return $this->loadUserByIdentifier($username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the user after being reloaded from the session.
|
||||
*
|
||||
* When a user is logged in, at the beginning of each request, the
|
||||
* User object is loaded from the session and then this method is
|
||||
* called. Your job is to make sure the user's data is still fresh by,
|
||||
* for example, re-querying for fresh User data.
|
||||
*
|
||||
* If your firewall is "stateless: true" (for a pure API), this
|
||||
* method is not called.
|
||||
*/
|
||||
public function refreshUser(UserInterface $user): UserInterface
|
||||
{
|
||||
if (!$user instanceof <?= $user_short_name ?>) {
|
||||
throw new UnsupportedUserException(sprintf('Invalid user class "%s".', $user::class));
|
||||
}
|
||||
|
||||
// Return a User object after making sure its data is "fresh".
|
||||
// Or throw a UsernameNotFoundException if the user no longer exists.
|
||||
throw new \Exception('TODO: fill in refreshUser() inside '.__FILE__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells Symfony to use this provider for this User class.
|
||||
*/
|
||||
public function supportsClass(string $class): bool
|
||||
{
|
||||
return <?= $user_short_name ?>::class === $class || is_subclass_of($class, <?= $user_short_name ?>::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades the hashed password of a user, typically for using a better hash algorithm.
|
||||
*/
|
||||
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
|
||||
{
|
||||
// TODO: when hashed passwords are in use, this method should:
|
||||
// 1. persist the new password in the user storage
|
||||
// 2. update the $user object with $user->setPassword($newHashedPassword);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
class <?= $class_name ?> extends Voter
|
||||
{
|
||||
public const EDIT = 'POST_EDIT';
|
||||
public const VIEW = 'POST_VIEW';
|
||||
|
||||
protected function supports(string $attribute, mixed $subject): bool
|
||||
{
|
||||
// replace with your own logic
|
||||
// https://symfony.com/doc/current/security/voters.html
|
||||
return in_array($attribute, [self::EDIT, self::VIEW])
|
||||
&& $subject instanceof \App\Entity\<?= str_replace('Voter', null, $class_name) ?>;
|
||||
}
|
||||
|
||||
protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool
|
||||
{
|
||||
$user = $token->getUser();
|
||||
// if the user is anonymous, do not grant access
|
||||
if (!$user instanceof UserInterface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ... (check conditions and return true to grant permission) ...
|
||||
switch ($attribute) {
|
||||
case self::EDIT:
|
||||
// logic to determine if the user can EDIT
|
||||
// return true or false
|
||||
break;
|
||||
case self::VIEW:
|
||||
// logic to determine if the user can VIEW
|
||||
// return true or false
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $controller_name ?> extends AbstractController
|
||||
{
|
||||
#[Route(path: '/login', name: 'app_login')]
|
||||
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||
{
|
||||
// get the login error if there is one
|
||||
$error = $authenticationUtils->getLastAuthenticationError();
|
||||
|
||||
// last username entered by the user
|
||||
$lastUsername = $authenticationUtils->getLastUsername();
|
||||
|
||||
return $this->render('<?= $template_path ?>/login.html.twig', [
|
||||
'last_username' => $lastUsername,
|
||||
'error' => $error,
|
||||
]);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block title %}Log in!{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form method="post">
|
||||
{% if error %}
|
||||
<div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
|
||||
{% endif %}
|
||||
|
||||
<?php if ($logout_setup): ?>
|
||||
{% if app.user %}
|
||||
<div class="mb-3">
|
||||
You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<?php endif; ?>
|
||||
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
|
||||
<label for="username"><?= $username_label; ?></label>
|
||||
<input type="<?= $username_is_email ? 'email' : 'text'; ?>" value="{{ last_username }}" name="_username" id="username" class="form-control" autocomplete="<?= $username_is_email ? 'email' : 'username'; ?>" required autofocus>
|
||||
<label for="password">Password</label>
|
||||
<input type="password" name="_password" id="password" class="form-control" autocomplete="current-password" required>
|
||||
|
||||
<input type="hidden" name="_csrf_token"
|
||||
value="{{ csrf_token('authenticate') }}"
|
||||
>
|
||||
|
||||
{#
|
||||
Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
|
||||
See https://symfony.com/doc/current/security/remember_me.html
|
||||
|
||||
<div class="checkbox mb-3">
|
||||
<label>
|
||||
<input type="checkbox" name="_remember_me"> Remember me
|
||||
</label>
|
||||
</div>
|
||||
#}
|
||||
|
||||
<button class="btn btn-lg btn-primary" type="submit">
|
||||
Sign in
|
||||
</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> implements EncoderInterface, DecoderInterface
|
||||
{
|
||||
public const FORMAT = '<?= $format ?>';
|
||||
|
||||
public function encode($data, string $format, array $context = []): string
|
||||
{
|
||||
// TODO: return your encoded data
|
||||
return '';
|
||||
}
|
||||
|
||||
public function supportsEncoding(string $format, array $context = []): bool
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
|
||||
public function decode(string $data, string $format, array $context = [])
|
||||
{
|
||||
// TODO: return your decoded data
|
||||
return '';
|
||||
}
|
||||
|
||||
public function supportsDecoding(string $format, array $context = []): bool
|
||||
{
|
||||
return self::FORMAT === $format;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> implements NormalizerInterface, CacheableSupportsMethodInterface
|
||||
{
|
||||
public function __construct(private ObjectNormalizer $normalizer)
|
||||
{
|
||||
}
|
||||
|
||||
public function normalize($object, string $format = null, array $context = []): array
|
||||
{
|
||||
$data = $this->normalizer->normalize($object, $format, $context);
|
||||
|
||||
// TODO: add, edit, or delete some data
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function supportsNormalization($data, string $format = null, array $context = []): bool
|
||||
{
|
||||
return $data instanceof \App\Entity\<?= str_replace('Normalizer', '', $class_name) ?>;
|
||||
}
|
||||
|
||||
public function hasCacheableSupportsMethod(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
/*
|
||||
* The following line makes this controller "lazy": it won't be downloaded until needed
|
||||
* See https://github.com/symfony/stimulus-bridge#lazy-controllers
|
||||
*/
|
||||
/* stimulusFetch: 'lazy' */
|
||||
export default class extends Controller {
|
||||
<?= $targets ? " static targets = $targets\n" : "" ?>
|
||||
<?php if ($values) { ?>
|
||||
static values = {
|
||||
<?php foreach ($values as $value): ?>
|
||||
<?= $value['name'] ?>: <?= $value['type'] ?>,
|
||||
<?php endforeach; ?>
|
||||
}
|
||||
<?php } ?>
|
||||
// ...
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use <?= $api_test_case_fqcn; ?>;
|
||||
|
||||
class <?= $class_name ?> extends ApiTestCase
|
||||
{
|
||||
public function testSomething(): void
|
||||
{
|
||||
$response = static::createClient()->request('GET', '/');
|
||||
|
||||
$this->assertResponseIsSuccessful();
|
||||
$this->assertJsonContains(['@id' => '/']);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php /* @deprecated remove this method when removing make:unit-test and make:functional-test */ ?>
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements ?>
|
||||
|
||||
class <?= $class_name ?> extends <?= $panther_is_available ? 'PantherTestCase' : 'WebTestCase' ?><?= "\n" ?>
|
||||
{
|
||||
public function testSomething(): void
|
||||
{
|
||||
<?php if ($panther_is_available): ?>
|
||||
$client = static::createPantherClient();
|
||||
<?php else: ?>
|
||||
$client = static::createClient();
|
||||
<?php endif ?>
|
||||
$crawler = $client->request('GET', '/');
|
||||
|
||||
<?php if ($web_assertions_are_available): ?>
|
||||
<?php if (!$panther_is_available): ?>
|
||||
$this->assertResponseIsSuccessful();
|
||||
<?php endif ?>
|
||||
$this->assertSelectorTextContains('h1', 'Hello World');
|
||||
<?php else: ?>
|
||||
<?php if (!$panther_is_available): ?>
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
<?php endif ?>
|
||||
$this->assertStringContainsString('Hello World', $crawler->filter('h1')->text());
|
||||
<?php endif ?>
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
class <?= $class_name ?> extends KernelTestCase
|
||||
{
|
||||
public function testSomething(): void
|
||||
{
|
||||
$kernel = self::bootKernel();
|
||||
|
||||
$this->assertSame('test', $kernel->getEnvironment());
|
||||
// $routerService = static::getContainer()->get('router');
|
||||
// $myCustomService = static::getContainer()->get(CustomService::class);
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\Component\Panther\PantherTestCase;
|
||||
|
||||
class <?= $class_name ?> extends PantherTestCase
|
||||
{
|
||||
public function testSomething(): void
|
||||
{
|
||||
$client = static::createPantherClient();
|
||||
$crawler = $client->request('GET', '/');
|
||||
|
||||
<?php if ($web_assertions_are_available): ?>
|
||||
$this->assertSelectorTextContains('h1', 'Hello World');
|
||||
<?php else: ?>
|
||||
$this->assertStringContainsString('Hello World', $crawler->filter('h1')->text());
|
||||
<?php endif ?>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class <?= $class_name ?> extends TestCase
|
||||
{
|
||||
public function testSomething(): void
|
||||
{
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php /* @deprecated remove this method when removing make:unit-test and make:functional-test */ ?>
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name ?> extends TestCase
|
||||
{
|
||||
public function testSomething(): void
|
||||
{
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
class <?= $class_name ?> extends WebTestCase
|
||||
{
|
||||
public function testSomething(): void
|
||||
{
|
||||
$client = static::createClient();
|
||||
$crawler = $client->request('GET', '/');
|
||||
|
||||
<?php if ($web_assertions_are_available): ?>
|
||||
$this->assertResponseIsSuccessful();
|
||||
$this->assertSelectorTextContains('h1', 'Hello World');
|
||||
<?php else: ?>
|
||||
$this->assertSame(200, $client->getResponse()->getStatusCode());
|
||||
$this->assertStringContainsString('Hello World', $crawler->filter('h1')->text());
|
||||
<?php endif ?>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
|
||||
|
||||
#[AsTwigComponent]
|
||||
final class <?= $class_name."\n" ?>
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements ?>
|
||||
|
||||
class <?= $class_name ?> extends AbstractExtension
|
||||
{
|
||||
public function getFilters(): array
|
||||
{
|
||||
return [
|
||||
// If your filter generates SAFE HTML, you should add a third
|
||||
// parameter: ['is_safe' => ['html']]
|
||||
// Reference: https://twig.symfony.com/doc/3.x/advanced.html#automatic-escaping
|
||||
new TwigFilter('filter_name', [<?= $runtime_class_name ?>::class, 'doSomething']),
|
||||
];
|
||||
}
|
||||
|
||||
public function getFunctions(): array
|
||||
{
|
||||
return [
|
||||
new TwigFunction('function_name', [<?= $runtime_class_name ?>::class, 'doSomething']),
|
||||
];
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
||||
use Symfony\UX\LiveComponent\DefaultActionTrait;
|
||||
|
||||
#[AsLiveComponent]
|
||||
final class <?= $class_name."\n" ?>
|
||||
{
|
||||
use DefaultActionTrait;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements ?>
|
||||
|
||||
class <?= $class_name ?> implements RuntimeExtensionInterface
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
// Inject dependencies if needed
|
||||
}
|
||||
|
||||
public function doSomething($value)
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
<div{{ attributes }}>
|
||||
<!-- component html -->
|
||||
</div>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*
|
||||
* @Target({"PROPERTY", "METHOD", "ANNOTATION"})
|
||||
*/
|
||||
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
|
||||
class <?= $class_name ?> extends Constraint
|
||||
{
|
||||
/*
|
||||
* Any public properties become valid options for the annotation.
|
||||
* Then, use these in your validator class.
|
||||
*/
|
||||
public $message = 'The value "{{ value }}" is not valid.';
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
|
||||
class <?= $class_name ?> extends ConstraintValidator
|
||||
{
|
||||
public function validate($value, Constraint $constraint)
|
||||
{
|
||||
/** @var <?= $constraint_class_name ?> $constraint */
|
||||
|
||||
if (null === $value || '' === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: implement the validation here
|
||||
$this->context->buildViolation($constraint->message)
|
||||
->setParameter('{{ value }}', $value)
|
||||
->addViolation();
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<?= "<?php\n" ?>
|
||||
|
||||
namespace <?= $namespace; ?>;
|
||||
|
||||
<?= $use_statements; ?>
|
||||
|
||||
class <?= $class_name; ?><?= "\n" ?>
|
||||
{
|
||||
public function __construct(
|
||||
private VerifyEmailHelperInterface $verifyEmailHelper,
|
||||
private MailerInterface $mailer,
|
||||
private EntityManagerInterface $entityManager
|
||||
) {
|
||||
}
|
||||
|
||||
public function sendEmailConfirmation(string $verifyEmailRouteName, UserInterface $user, TemplatedEmail $email): void
|
||||
{
|
||||
$signatureComponents = $this->verifyEmailHelper->generateSignature(
|
||||
$verifyEmailRouteName,
|
||||
$user-><?= $id_getter ?>(),
|
||||
<?php if ($verify_email_anonymously): ?>
|
||||
$user-><?= $email_getter ?>(),
|
||||
['id' => $user->getId()]
|
||||
<?php else: ?>
|
||||
$user-><?= $email_getter ?>()
|
||||
<?php endif; ?>
|
||||
);
|
||||
|
||||
$context = $email->getContext();
|
||||
$context['signedUrl'] = $signatureComponents->getSignedUrl();
|
||||
$context['expiresAtMessageKey'] = $signatureComponents->getExpirationMessageKey();
|
||||
$context['expiresAtMessageData'] = $signatureComponents->getExpirationMessageData();
|
||||
|
||||
$email->context($context);
|
||||
|
||||
$this->mailer->send($email);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws VerifyEmailExceptionInterface
|
||||
*/
|
||||
public function handleEmailConfirmation(Request $request, UserInterface $user): void
|
||||
{
|
||||
$this->verifyEmailHelper->validateEmailConfirmation($request->getUri(), $user-><?= $id_getter ?>(), $user-><?= $email_getter?>());
|
||||
|
||||
$user->setIsVerified(true);
|
||||
|
||||
$this->entityManager->persist($user);
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user