dcs/password-reset-explain-view-bundle
Installation
Add the bundle to your composer.json:
composer require dcs/password-reset-explain-view-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Damianociarla\DCSPasswordResetExplainViewBundle\DCSPasswordResetExplainViewBundle::class => ['all' => true],
];
Publish Assets Run the following command to publish the default Twig templates and translations:
php bin/console dcs:password-reset-explain:install
This creates:
templates/bundles/dcs_password_reset_explain_view/ (Twig templates)translations/ (translation files for supported locales)First Use Case
Trigger the password reset flow by visiting /reset-password (or your configured route). The bundle provides:
Example route configuration (in config/routes.yaml):
dcs_password_reset_explain:
path: /reset-password
controller: Damianociarla\DCSPasswordResetExplainViewBundle\Controller\PasswordResetExplainController::explainAction
Customizing the Flow
Override the default Twig templates by copying them from:
vendor/damianociarla/dcs-password-reset-explain-view-bundle/templates/bundles/dcs_password_reset_explain_view/
to your project’s templates/bundles/dcs_password_reset_explain_view/.
Extend the base templates (e.g., explain.html.twig) to add branding, additional steps, or dynamic content.
Example: Add a custom step in explain.html.twig:
{% extends 'bundles/dcs_password_reset_explain_view/explain.html.twig' %}
{% block additional_steps %}
<div class="custom-step">
<h3>{{ 'Check your spam folder'|trans }}</h3>
<p>{{ 'If you don’t receive the email within 5 minutes, check your spam folder.'|trans }}</p>
</div>
{% endblock %}
Localization
Translate strings by extending the default translation files (e.g., translations/messages.en.yaml):
dcs_password_reset_explain:
explain:
title: "Recover Your Account"
step_1: "Enter your email below to begin the recovery process."
step_2: "We’ll send you a secure link to create a new password."
Load translations in Twig:
{{ 'dcs_password_reset_explain.explain.title'|trans }}
Form Customization
Extend the form class (PasswordResetExplainType) to add fields or validation:
// src/Form/Extension/PasswordResetExplainTypeExtension.php
namespace App\Form\Extension;
use Damianociarla\DCSPasswordResetExplainViewBundle\Form\Type\PasswordResetExplainType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
class PasswordResetExplainTypeExtension extends AbstractTypeExtension
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('captcha', RecaptchaType::class, [
'mapped' => false,
'constraints' => [new NotBlank()],
]);
}
public static function getExtendedType(): string
{
return PasswordResetExplainType::class;
}
}
Event Listeners Hook into the password reset flow using events. Example: Log reset attempts or send analytics:
// src/EventListener/PasswordResetListener.php
namespace App\EventListener;
use Damianociarla\DCSPasswordResetExplainViewBundle\Event\PasswordResetExplainEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class PasswordResetListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
PasswordResetExplainEvent::RESET_INITIATED => 'onResetInitiated',
];
}
public function onResetInitiated(PasswordResetExplainEvent $event)
{
$email = $event->getEmail();
// Log or track the reset request
}
}
API Integration Use the bundle’s services to trigger the flow programmatically:
use Damianociarla\DCSPasswordResetExplainViewBundle\Service\PasswordResetExplainService;
class SomeController
{
public function __construct(private PasswordResetExplainService $resetService) {}
public function triggerReset(Request $request)
{
$email = $request->request->get('email');
$this->resetService->initiateReset($email);
// Redirect to a custom success page
}
}
Template Overrides
php bin/console cache:clear), changes won’t reflect.Route Conflicts
/reset-password) may conflict with existing routes.config/routes.yaml or use _path helpers:
dcs_password_reset_explain_custom:
path: /account/recover
controller: Damianociarla\DCSPasswordResetExplainViewBundle\Controller\PasswordResetExplainController::explainAction
Translation Loading
translator.paths config:
# config/packages/translation.yaml
framework:
translator:
paths:
- '%kernel.project_dir%/vendor/damianociarla/dcs-password-reset-explain-view-bundle/Resources/translations'
- '%kernel.project_dir%/translations'
CSRF Protection
{{ form_start(form, {'attr': {'novalidate': 'novalidate'}}) }}
{{ form_widget(form) }}
{{ form_end(form) }}
Email Delivery
Mailer component.Swiftmailer:
# config/packages/mailer.yaml
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
Check Events Enable debug mode to see if events are dispatched:
// config/packages/dev/debug.yaml
framework:
profiler: { only_exceptions: false }
Use the Symfony Profiler to inspect dispatched events under the "Events" tab.
Form Validation Validate form submission manually if needed:
$form = $this->createForm(PasswordResetExplainType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
// Proceed
}
Template Debugging Dump template variables for debugging:
{% if app.debug %}
<pre>{{ dump(_context) }}</pre>
{% endif %}
Custom Steps
Add dynamic steps by extending the explainAction controller or creating a custom template block (as shown above).
Multi-Step Forms Split the flow into multiple steps using Symfony’s form components or a state machine:
// Example: Store step progress in session
$session->set('password_reset_step', 2);
Third-Party Integrations
friendsofsymfony/user-bundle for two-factor authentication.Access Control Restrict access to the reset flow using Symfony’s security system:
# config/packages/security.yaml
access_control:
- { path: ^/reset-password, roles: PUBLIC_ACCESS }
Testing
Test the flow using Symfony’s WebTestCase:
public function testPasswordResetFlow()
{
$client = static::createClient();
$crawler = $client->request('GET', '/reset-password');
$this->assertSelectorTextContains('h1', 'Recover Your Account');
$form = $crawler->
How can I help you explore Laravel packages today?