viernes, 25 de octubre de 2013

FOSUserBundle - Parte IV - Overriding Registration

Si empezamos a usar las rutas del FOSUserBundle nos daremos cuenta que todas funcionan. Las rutas pueden ser tomadas usando el comando de Symfony router debug:

php app/console router:debug

fos_user_security_login           ANY      ANY    ANY  /login
fos_user_security_check           POST     ANY    ANY  /login_check
fos_user_security_logout          ANY      ANY    ANY  /logout
fos_user_profile_show             GET      ANY    ANY  /profile/
fos_user_profile_edit             ANY      ANY    ANY  /profile/edit
fos_user_registration_register    ANY      ANY    ANY  /register/
fos_user_registration_check_email GET      ANY    ANY  /register/check-email
fos_user_registration_confirm     GET      ANY    ANY  /register/confirm/{token}
fos_user_registration_confirmed   GET      ANY    ANY  /register/confirmed
fos_user_resetting_request        GET      ANY    ANY  /resetting/request
fos_user_resetting_send_email     POST     ANY    ANY  /resetting/send-email
fos_user_resetting_check_email    GET      ANY    ANY  /resetting/check-email
fos_user_resetting_reset          GET|POST ANY    ANY  /resetting/reset/{token}
fos_user_change_password          GET|POST ANY    ANY  /profile/change-password


Los usuarios pueden:
logguearse, desloggearse, ver su perfil, editar su perfil, registrarse, solicitar cambiar su contraseña, cambiar su contraseña, etc.

pero, a todas estas páginas les falta estilos.

Primero comenzaremos con la página de registro, si vemos el archivo:

vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/views/Registration/register.html.twig

veremos que su contenido es simple:

{% extends "FOSUserBundle::layout.html.twig" %}

{% block fos_user_content %}
{% include "FOSUserBundle:Registration:register_content.html.twig" %}
{% endblock fos_user_content %}

sólo hereda del layout e incluye la plantilla register_content, esto ocurre en todas las plantillas a sustituir, por lo que haremos será solo sustituir las plantillas que terminen en "_content.html.twig"

así que para copiar el archivo register_content.html.twig a nuestro bundle hijo, primero creamos la carpeta "Registration" para poder alojarlo.

mkdir src/Peteramas/MyFOSUserBundle/Resources/views/Registration/

cp vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/views/Registration/register_content.html.twig src/Peteramas/MyFOSUserBundle/Resources/views/Registration/

y luego cambiamos su contenido de:

{% trans_default_domain 'FOSUserBundle' %}

<form action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST" class="fos_user_registration_register">
    {{ form_widget(form) }}
    <div>
        <input type="submit" value="{{ 'registration.submit'|trans }}" />
    </div>
</form>

a esto:

{% extends 'PetramasMainBundle::layout.html.twig' %}

{% block content -%}
<form action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST" class="form-horizontal fos_user_registration_register" role="form">
    {{ form_errors(form) }}
    <div class="form-group{% if form.email.vars.errors[0].message is defined %} has-error{% endif %}">
        {{ form_label(form.email, null, {'label_attr': {'class': 'col-sm-2 control-label'}}) }}
        <div class="col-sm-10">
            {{ form_widget(form.email, {'attr': {'class': 'form-control'}}) }}
            {% if form.email.vars.errors[0].message is defined %}
            <span class="help-block">
                {{ form.email.vars.errors[0].message }}
            </span>
            {% endif %}
        </div>
    </div>
    <div class="form-group{% if form.username.vars.errors[0].message is defined %} has-error{% endif %}">
        {{ form_label(form.username, null, {'label_attr': {'class': 'col-sm-2 control-label'}}) }}
        <div class="col-sm-10">
            {{ form_widget(form.username, {'attr': {'class': 'form-control'}}) }}
            {% if form.username.vars.errors[0].message is defined %}
            <span class="help-block">
                {{ form.username.vars.errors[0].message }}
            </span>
            {% endif %}
        </div>
    </div>
    <div class="form-group{% if form.plainPassword.first.vars.errors[0].message is defined %} has-error{% endif %}">
        {{ form_label(form.plainPassword.first, null, {'label_attr': {'class': 'col-sm-2 control-label'}}) }}
        <div class="col-sm-10">
            {{ form_widget(form.plainPassword.first, {'attr': {'class': 'form-control'}}) }}
            {% if form.plainPassword.first.vars.errors[0].message is defined %}
            <span class="help-block">
                {{ form.plainPassword.first.vars.errors[0].message }}
            </span>
            {% endif %}
        </div>
    </div>
    <div class="form-group{% if form.plainPassword.second.vars.errors[0].message is defined %} has-error{% endif %}">
        {{ form_label(form.plainPassword.second, null, {'label_attr': {'class': 'col-sm-2 control-label'}}) }}
        <div class="col-sm-10">
            {{ form_widget(form.plainPassword.second, {'attr': {'class': 'form-control'}}) }}
            {% if form.plainPassword.second.vars.errors[0].message is defined %}
            <span class="help-block">
                {{ form.plainPassword.second.vars.errors[0].message }}
            </span>
            {% endif %}
        </div>
    </div>
    <button class="btn btn-primary" type="submit">{{ 'registration.submit'|trans({}, 'FOSUserBundle') }}</button>
{{ form_end(form) }}
{% endblock %}

Hemos hecho uso de lo aprendido en las entradas anteriores, ya que al devolver un error, FOSUserBundle, nos mostrará bien formateado y con estilos bootstrap, incluso pone todo el label y el input de rojo al submitear un campo inválido.

Para acabar con Registration, hacemos lo mismo con la confirmación del registro:

copiamos el archivo confirmed.html.twig

cp vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/views/Registration/confirmed.html.twig src/Peteramas/MyFOSUserBundle/Resources/views/Registration/


y modificamos su contenido de esto:

{% extends "FOSUserBundle::layout.html.twig" %}

{% trans_default_domain 'FOSUserBundle' %}

{% block fos_user_content %}
    <p>{{ 'registration.confirmed'|trans({'%username%': user.username}) }}</p>
    {% if app.session is not empty %}
        {% set targetUrl = app.session.get('_security.' ~ app.security.token.providerKey ~ '.target_path') %}
        {% if targetUrl is not empty %}<p><a href="{{ targetUrl }}">{{ 'registration.back'|trans }}</a></p>{% endif %}
    {% endif %}
{% endblock fos_user_content %}

a esto:

{% extends 'PetramasMainBundle::layout.html.twig' %}

{% block content -%}
{% trans_default_domain 'FOSUserBundle' %}
    <h3>{{ 'registration.confirmed'|trans({'%username%': user.username}) }}</h3>
    {% if app.session is not empty %}
        {% set targetUrl = app.session.get('_security.' ~ app.security.token.providerKey ~ '.target_path') %}
        {% if targetUrl is not empty %}
            <p>
                <a class="btn btn-primary" href="{{ targetUrl }}">
                    {{ 'registration.back'|trans({}, 'FOSUserBundle') }}
                </a>
            </p>
        {% endif %}
    {% endif %}
{% endblock %}