clase 14 bundles útiles
DESCRIPTION
www.hydrascs.comTRANSCRIPT
Bundles útiles:SonataBundleJsRoutingBundleDoctrineFixturesBundle
Realizada por:Christian Aquino |@cj_aquinoDiego Ramirez |@thedarsideofitGonzalo Alonso |@GonzaloAlonsoDDiego Barros |@Inmzombie
Para: Hydras C&S |@hydras_csBasada en Libro Symfony 2 en español Nacho Pacheco y The Book
¿Que es Sonata?
Sonata fue creado por el entusiasta symfonyano Thomas Rabaix.La meta del proyecto Sonata es proveer una solución e-commerce basado en Sf2. Pensado como un conjunto de herramientas para hacer e-commerce de una manera fácil.
● Admin Bundle : Un bundle para generar una interface robusta y amistosa para el usuario. ● Media Bundle : Un bundle para manejar datos multimedia, la multimedia se refiere a archivos,
videos,imagenes. ● Page Bundle : Un bundle para transformar las acciones de Sf2 en un CMS.
Instalando y configurando
Añadir lo siguiente a tu archivo composer.json:
$ php composer.phar update
{ "require": { ...
"sonata-project/admin-bundle": "dev-master","friendsofsymfony/user-bundle": "dev-master","sonata-project/user-bundle": "dev-master","sonata-project/doctrine-orm-admin-bundle": "dev-master"
...}
}
Registramos los bundles en app/AppKernel.php
// ...public function registerBundles(){ $bundles = array( // ... new FOS\UserBundle\FOSUserBundle(),
new Sonata\jQueryBundle\SonatajQueryBundle(),new Sonata\AdminBundle\SonataAdminBundle(),new Sonata\BlockBundle\SonataBlockBundle(),new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),new Knp\Bundle\MenuBundle\KnpMenuBundle(),new Sonata\UserBundle\SonataUserBundle('FOSUserBundle'),new Sonata\EasyExtendsBundle\SonataEasyExtendsBundle(),
// ... ); // ...}
Editar los archivos config.yml, security.yml según la configuración definida en:
http://blog.dayo.fr/2012/12/symfony2-1-sonata-admin-sonata-user-fos-userbundle-en/
Listado de campos:<?php
namespace Sonata\NewsBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class PostAdmin extends Admin
{
protected function configureListFields (ListMapper $listMapper)
{
$listMapper
->addIdentifier('title')
->add('author')
->add('enabled')
->add('tags')
->add('commentsEnabled' )
// add custom action links
->add('_action', 'actions', array(
'actions' => array(
'view' => array(),
'edit' => array(),)
));
}
}
Tipos disponibles:
● boolean● datetime● decimal● identifier● integer● many_to_one : a link will be added to the related edit action● string● text● date● time
Acciones en el listado:
<?php
$listMapper->add('_action', 'actions', array(
'actions' => array(
'view' => array(),
'edit' => array(),
)
))
Podemos editar y quitar las acciones. Podemos especificar las templates de renderizado
<?php
$listMapper->add('_action', 'actions', array(
'actions' => array(
'view' => array(),
'edit' => array(),
'delete' => array('template' => 'MyBundle:MyController:my_partial.html.twig' ),
)
))
Mostrar sub entidades:
<?php
namespace Acme\AcmeBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class UserAdmin extends Admin
{
protected function configureListFields (ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->addIdentifier('firstName')
->addIdentifier('lastName')
->addIdentifier('address.street' )
->addIdentifier('address.ZIPCode' )
->addIdentifier('address.town' )
;
}
}
Personalizando Templates
<?php
namespace Sonata\MediaBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
class MediaAdmin extends Admin
{
protected function configureListFields (ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->add('image', 'string', array('template' => 'SonataMediaBundle:MediaAdmin:list_image.html.twig' ))
->add('custom', 'string', array('template' => 'SonataMediaBundle:MediaAdmin:list_custom.html.twig' ))
;
}
}
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field%}
<div>
<strong> {{ object.name }}</strong> <br />
{{ object.providername }} : {{ object.width }}x{{ object.height }} <br />
</div>
{% endblock %}
La template quedaría:
Redefinir el controlador CRUD
<?php
// src/Tutorial/BlogBundle/Controller/CommentAdminController.php
namespace Tutorial\BlogBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
class CommentAdminController extends Controller
{
}
DoctrineFixturesBundle
Los accesorios se utilizan para cargar en una base de datos un juego de datos controlado. Puedes utilizar estos datos para pruebas o podrían ser los datos iniciales necesarios para ejecutar la aplicación sin problemas. Symfony2 no tiene integrada forma alguna de administrar accesorios, pero Doctrine2 cuenta con una biblioteca para ayudarte a escribir accesorios para el ORM u ODM de Doctrine.
Instalando y configurando
Añadir lo siguiente a tu archivo composer.json:
{ "require": { "doctrine/doctrine-fixtures-bundle": "dev-master" }}
$ php composer.phar update
Actualizar el composer
Por último, registramos el paquete DoctrineFixturesBundle en app/AppKernel.php
// ...public function registerBundles(){ $bundles = array( // ... new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(), // ... ); // ...}
Escribiendo fixtures:Los fixtures de Doctrine2 son clases PHP que pueden crear y persistir objetos a la base de datos. Al igual que todas las clases en Symfony2, los fixtures deben estar alojado dentro de uno de los paquetes de tu aplicación.Para un paquete situado en src/Acme/HelloBundle, las clasesed los fixtures deben estar dentro de src/Acme/HelloBundle/DataFixtures/ORM o src/Acme/HelloBundle/DataFixtures/MongoDB, para ORM y ODM respectivamente, esta guía asume que estás utilizando el ORM — pero, los accesorios se pueden agregar con la misma facilidad si estás utilizando ODM.
// src/Acme/HelloBundle/DataFixtures/ORM/LoadUserData.phpnamespace Acme\HelloBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\FixtureInterface;use Doctrine\Common\Persistence\ObjectManager;use Acme\HelloBundle\Entity\User;
class LoadUserData implements FixtureInterface{ /** * {@inheritDoc} */ public function load(ObjectManager $manager) { $userAdmin = new User(); $userAdmin->setUsername('admin'); $userAdmin->setPassword('test');
$manager->persist($userAdmin); $manager->flush(); }}
Cargando los fixtures
php app/console doctrine:fixtures:load
php app/console doctrine:mongodb:fixtures:load
La tarea buscará dentro del directorio DataFixtures/ORM (o DataFixtures/MongoDB paraODM) de cada paquete y ejecutará cada clase que implemente la FixtureInterface.Ambas órdenes vienen con unas cuantas opciones:
● --fixtures=/ruta/al/accesorio — Usa esta opción para especificar manualmente el directorio de donde se deben cargar las clases accesorio;
● --append — Utiliza esta opción para añadir datos en lugar de eliminarlos antes de cargarlos (borrar primero es el comportamiento predeterminado);
● --em=manager_name — Especifica manualmente el gestor de la entidad a utilizar para cargar los datos.
Compartiendo objetos entre fixturesSi tenemos varias clases de fixtures y queremos referir a los datos cargados en otras clases. Deberemos.
// src/Acme/HelloBundle/DataFixtures/ORM/LoadUserData.phpnamespace Acme\HelloBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;use Doctrine\Common\DataFixtures\OrderedFixtureInterface;use Doctrine\Common\Persistence\ObjectManager;use Acme\HelloBundle\Entity\User;
class LoadUserData extends AbstractFixture implements OrderedFixtureInterface{ public function load(ObjectManager $manager) { $userAdmin = new User(); $userAdmin->setUsername('admin'); $userAdmin->setPassword('test');
$manager->persist($userAdmin); $manager->flush();
$this->addReference('admin-user', $userAdmin); }
public function getOrder() { return 1; // el orden en el cual serán cargados los accesorios }
// src/Acme/HelloBundle/DataFixtures/ORM/LoadUserGroupData.php
namespace Acme\HelloBundle\DataFixtures\ORM;
use Doctrine\Common\DataFixtures\AbstractFixture;use Doctrine\Common\DataFixtures\OrderedFixtureInterface;use Doctrine\Common\Persistence\ObjectManager;use Acme\HelloBundle\Entity\UserGroup;
class LoadUserGroupData extends AbstractFixture implements OrderedFixtureInterface{ public function load(ObjectManager $manager) { $userGroupAdmin = new UserGroup(); $userGroupAdmin->setUser($this->getReference('admin-user')); $userGroupAdmin->setGroup($this->getReference('admin-group'));
$manager->persist($userGroupAdmin); $manager->flush(); } public function getOrder() { return 3; }}
Los fixtures ahora se ejecutan en orden ascendente del valor devuelto por getOrder(). Cualquier objeto que se establece con el método setReference() se puede acceder a través de getReference() en las clases accesorio que tienen un orden superior.
JsRoutingBundle:
Instalando y configurandoAñadir lo siguiente a tu archivo composer.json:
{
"require": {
"friendsofsymfony/jsrouting-bundle": "dev-
master"
}
}
$ php composer.phar update friendsofsymfony/jsrouting-bundle
Actualizar el composer
Registramos en el app/AppKernel.php
// ...
public function registerBundles()
{
$bundles = array(
// ...
new FOS\JsRoutingBundle\FOSJsRoutingBundle(),
// ... ); // ...}
# app/config/routing.yml
fos_js_routing: resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
$ php app/console assets:install --symlink web
Agregamos las siguientes líneas que apuntan al javascript edl bundle
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script><script src="{{ path('fos_js_routing_js', {"callback": "fos.Router.setData"}) }}"></script>
Para usar agregamos en donde se debe especificar la url:
Routing.generate('route_id', /* your params */).
Ejemplo de routing
# app/config/routing.yml
my_route_to_expose:
pattern: /foo/{id}/bar
defaults: { _controller: HelloBundle:Hello:index }
options:
expose: true
my_route_to_expose_with_defaults: pattern: /blog/{page} defaults: { _controller: AcmeBlogBundle:Blog:index, page: 1 } options: expose: true
Routing.generate('my_route_to_expose', { id: 10 });// will result in /foo/10/bar
Routing.generate('my_route_to_expose', { id: 10, foo: "bar" });// will result in /foo/10/bar?foo=bar
$.get(Routing.generate('my_route_to_expose', { id: 10, foo: "bar" }));// will call /foo/10/bar?foo=bar
Routing.generate('my_route_to_expose_with_defaults');// will result in /blog/1
Routing.generate('my_route_to_expose_with_defaults', { id: 2 });// will result in /blog/2
Routing.generate('my_route_to_expose_with_defaults', { foo: "bar" });// will result in /blog/1?foo=bar
Routing.generate('my_route_to_expose_with_defaults', { id: 2, foo: "bar" });// will result in /blog/2?foo=bar