jueves, 25 de septiembre de 2014

Upload Files and persist to Doctrine Entity - Parte III - User CRUD Templates

Si actualizamos el formulario de creación de usuarios, entonces nos daremos cuenta de que hay un error, el campo path no esta declarado en nuestro UserType, para ello debemos eliminar todo el DIV donde aparece el campo $path no usado:

nano src/Petramas/MainBundle/Resources/views/User/new.html.twig
    <div class="form-group{% if form.path.vars.errors[0].message is defined %} has-error{% endif %}">
        {{ form_label(form.path, null, {'label_attr': {'class': 'col-sm-2 control-label' } }) }}
        <div class="col-sm-10">
            {{ form_widget(form.path, {'attr': {'class': 'form-control' } }) }}
            {% if form.path.vars.errors[0].message is defined %}
            <span class="help-block">
                {{ form.path.vars.errors[0].message }}
            </span>
            {% endif %}
        </div>
    </div>

una vez eliminado del formulario el siguiente inconveniente será que el nuevo campo file no tiene estilos, entonces agregamos el campo con estilos Bootstrap 3:

    <div class="form-group{% if form.file.vars.errors[0].message is defined %} has-error{% endif %}">
        {{ form_label(form.file, null, {'label_attr': {'class': 'col-sm-2 control-label' } }) }}
        <div class="col-sm-10">
            {{ form_widget(form.file, {'attr': {'class': 'form-control' } }) }}
            {% if form.file.vars.errors[0].message is defined %}
            <span class="help-block">
                {{ form.file.vars.errors[0].message }}
            </span>
            {% endif %}
        </div>
    </div>

Ahora el formulario se ve bien, pero al probar subir una imagen nada sucede, esto es debido a que el formulario no acepta subida de archivos, para que lo soporte debemos agregar el atributo de formulario "enctype":

{{ form_start(form, {'attr': {'class': 'form-horizontal', 'role': 'form', 'enctype': 'multipart/form-data' } }) }}


Hacemos exáctamente lo mismo con la plantilla de edición de usuarios:

nano src/Petramas/MainBundle/Resources/views/User/edit.html.twig

en este momento el archivo fue subido y la ruta fue guardada, así como el nombre original, pero al momento de listar los usuarios en el campo $path, se encuentra el nombre hash del archivo subido, que no tiene porque ser mostrado al usuario, sino el nombre original.

Para esto modificamos la plantilla index:

nano src/Petramas/MainBundle/Resources/views/User/index.html.twig

reemplazando

{{ entity.path }}

por:

{{ entity.original }}

por último, donde queremos mostrar la imágen, debemos imprimir entity.path, precedido de la ruta en donde se suben las fotos, en nuestro caso "web/uploads/documents", para poder mostrar esto último, debemos consultarlo en nuestro controlador y pasárselo a la vista en este caso vamos a poner de ejemplo en la plantilla para mostrar el detalle del usuario:

nano src/Petramas/MainBundle/Controller/UserController.php 

entonces en el método showAction agregamos, luego de devuelta la entidad seleccionada por Id, el método getUploadDir así:

    /**
     * Finds and displays a User entity.
     *
     * @Route("/{id}", name="user_show")
     * @Method("GET")
     * @Template()
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $entity = $em->getRepository('PetramasMainBundle:User')->find($id);
        $entity->uploaddir = $entity->getUploadDir();
        if (!$entity) {
            throw $this->createNotFoundException('Unable to find GelImage entity.');
        }

        $deleteForm = $this->createDeleteForm($id);

        return array(
            'entity'      => $entity,
            'delete_form' => $deleteForm->createView(),
        );
    }

por último en la plantilla show modificamos el "path" a mostrar:

{{ entity.path }}

y podemos hacerlo así:

    <p>File name: {{ entity.original }}</p>
    <img src="/{{ entity.uploaddir }}/{{ entity.path }}">