#deSymfony @aferrandini
NO HABLARÉ DE COMIDA#deSymfony @aferrandini
#deSymfony @aferrandini
¿QUIÉN SOY?
•Ariel Ferrandini Price (11-11-85)
•Programador PHP
•Symfony lover (0.9.8beta)
•DeSymfony early adopter
•¡Me encanta viajar!
ORIGEN DE LAS ANOTACIONES
anotación
1. nota crítica o explicatoria agregados a un texto.
Java 1.5, especificación JSR-175 en 2002 y aprobadas en septiembre de 2004.
Las anotaciones no afectan directamente a la semántica del programa, pero afectan a la forma en que los programas son tratados por herramientas y bibliotecas, que a su vez pueden afectar a la semántica del programa en ejecución. Las anotaciones se pueden leer
en clases mediante reflexión en tiempo de ejecución.
#deSymfony @aferrandini
#deSymfony @aferrandini
¿Qué diceeste loco?
Request
¿Cómo funcionan las anotaciones?
#deSymfony @aferrandini
FrontControllerSymfony Kernel
Eventos
¿Cómo funcionan las anotaciones?
#deSymfony @aferrandini
ReaderDriver Semántica
@AnnotationControllerFoo()@AnnotationActionFoo()
<?php
namespace Namespace\Foo;
use AnnotationFoo;
/** * @AnnotationControllerFoo() */class Controller{ /** * @AnnotationActionFoo() */ public function fooAction() { // ... }}
¿Cómo funcionan las anotaciones?
Response
#deSymfony @aferrandini
ANOTACIONESEN
#deSymfony @aferrandini
FRAMEWORK EXTRA BUNDLE
# app/config/config.ymlsensio_framework_extra: router: { annotations: true } request: { converters: true } view: { annotations: true } cache: { annotations: true }
Habilitar las anotaciones
FRAMEWORK EXTRA BUNDLE
Agregar las anotaciones con use
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
ENRUTAMIENTO
# app/config/routing.yml
# importar rutas de una clase Controlleragenda: resource: "@DeSymfonyWebBundle/Controller/AgendaController.php" type: annotation
# importar todas las clases Controller de un directorioweb: resource: "@DeSymfonyWebBundle/Controller" type: annotation
Activar rutas con anotaciones
ENRUTAMIENTO
@Route @Method
#deSymfony @aferrandini
@ROUTE
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php
/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/”, name=”agenda”) */ public function agendaAction() { }}
Configurar rutas con anotaciones
@ROUTE
Configurar rutas con anotaciones// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php
/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{dia}”, name=”agenda”) */ public function agendaAction($dia) { }}
@ROUTE
Configurar rutas con anotaciones// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php
/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{dia}”, name=”agenda”, requirements={“dia”=”\d+”}, defaults={“dia”=21}) */ public function agendaAction($dia) { }}
ROUTING
@Route @Method
#deSymfony @aferrandini
@METHOD
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/editar/{id}”, name=”editar_agenda”) * @Method({“GET”, “POST”}) */ public function editarAction($id) { }}
Configurar método con anotaciones
CONVERSORES
@ParamConverter
#deSymfony @aferrandini
@PARAMCONVERTER
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{id}”, name=”agenda”) * @ParamConverter(“agenda”, class=”DeSymfonyWebBundle:Agenda”) */ public function agendaAction(Agenda $agenda) { }}
Convierte parámetros en objetos
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{id}”, name=”agenda”) * @ParamConverter(“agenda”, class=”DeSymfonyWebBundle:Agenda”, options={“entity_manager” = “foo”) */ public function agendaAction(Agenda $agenda) { }
@PARAMCONVERTER
Convierte parámetros en objetos
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{id}/{agenda_id}”, name=”agenda”) * @ParamConverter(“agenda”, class=”DeSymfonyWebBundle:Agenda”, options={“id” = “agenda_id”) */ public function agendaAction(Agenda $agenda) { }
@PARAMCONVERTER
Convierte parámetros en objetos
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{slug}”, name=”agenda”) * @ParamConverter(“agenda”, class=”DeSymfonyWebBundle:Agenda”, options={“mapping”: {“slug”: “slug”}}) */ public function agendaAction(Agenda $agenda) { }
@PARAMCONVERTER
Convierte parámetros en objetos
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{inicio}/{fin}”, name=”agenda”) * @ParamConverter(“inicio”, options={“format”: “Y-m-d”}) * @ParamConverter(“fin”, options={“format”: “Y-m-d”}) */ public function agendaAction(\DateTime $inicio, \DateTime $fin) { }
@PARAMCONVERTER
Convierte parámetros en objetos
CACHE
@Cache
#deSymfony @aferrandini
@CACHE
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Cache(expires=”tomorrow”) */class AgendaController extends Controller{ /** * @Cache(expires=”+5 days”) */ public function indexAction() { }}
Establece la cache de Response
@Cache(expires=”tomorrow”)
@Cache(smaxage=”15”)
@Cache(maxage=”15”)
@Cache(vary=[”Cookie”])
$response->setExpires()
$response->setSharedMaxAge()
$response->setMaxAge()
$response->setVary()
@CACHE
Establece la cache de Response
VISTA
@Template
#deSymfony @aferrandini
@TEMPLATE
Asocia un método acción con una plantilla// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/”, name=”agenda”) * @Template(“DeSymfonyWebBundle:Agenda:agenda.html.twig”) */ public function agendaAction() { }}
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/”, name=”agenda”) * @Template */ public function agendaAction() { }}
@TEMPLATE
Asocia un método acción con una plantilla
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{id}”, name=”agenda”) * @ParamConverter(“agenda”, class=”DeSymfonyWebBundle:Agenda”) * @Template(“DeSymfonyWebBundle:Agenda:agenda.html.twig”, vars={“agenda”}) */ public function agendaAction(Agenda $agenda) { }
@TEMPLATE
Asocia un método acción con una plantilla
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{id}”, name=”agenda”) * @ParamConverter(“agenda”, class=”DeSymfonyWebBundle:Agenda”) * @Template(vars={“agenda”}) */ public function agendaAction(Agenda $agenda) { }
@TEMPLATE
Asocia un método acción con una plantilla
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/{id}”, name=”agenda”) * @Template(engine=”php”) */ public function agendaAction($id) { }}
@TEMPLATE
Asocia un método acción con una plantilla
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html
DOCTRINE
http://docs.doctrine-project.org/projects/doctrine-common/en/latest/reference/annotations.html
#deSymfony @aferrandini
http://docs.doctrine-project.org/projects/doctrine-mongodb-odm/en/latest/reference/annotations-reference.html
Doctrine Common
Doctrine ORM
Doctrine ODM
DOCTRINE ORM@Column@Entity @Index @Id @OrderBy@Table
@HasLifecycleCallbacks
@ManyToOne @ManyToMany @OneToOne @OneToMany
@PostLoad @PostPersist @PostRemove@PostUpdate
@PrePersist @PreRemove@PreUpdate
#deSymfony @aferrandini
DOCTRINE ORM
@ColumnResult
@ChangeTrackingPolicy
@DiscriminatorColumn
@DiscriminatorMap
@EntityResult
@FieldResult
@GeneratedValue @InheritanceType
@JoinColumns@JoinColumn@JoinTable
@MappedSuperclass
@NamedNativeQuery
@SequenceGenerator
@SqlResultSetMapping
@UniqueConstraint
@Version
#deSymfony @aferrandini
SYMFONY2 ~ VALIDATORuse Symfony\Component\Validator\Constraints as Assert;
# app/config/config.ymlframework: validation: { enable_annotations: true }
Habilitar la validación con anotaciones
SYMFONY2 ~ VALIDATOR
@Assert\NotBlank
@Assert\Blank
@Assert\NotNull
@Assert\Null
@Assert\True
@Assert\False
@Assert\Type
use Symfony\Component\Validator\Constraints as Assert;
Restricciones básicas
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
SYMFONY2 ~ VALIDATOR
@Assert\Email
@Assert\Length
@Assert\Url
@Assert\Regex
@Assert\Ip
use Symfony\Component\Validator\Constraints as Assert;
Restricciones cadenas de texto
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
SYMFONY2 ~ VALIDATOR
@Assert\Range @Assert\Date
@Assert\DateTime
@Assert\Time
use Symfony\Component\Validator\Constraints as Assert;
Restricciones numéricas Restricciones con fechas
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
SYMFONY2 ~ VALIDATOR
@Assert\EqualTo
@Assert\NotEqualTo
@Assert\IdenticalTo
@Assert\NotIdenticalTo
@Assert\LessThan
@Assert\LessThanOrEqual
@Assert\GreaterThan
@Assert\GreaterThanOrEqual
use Symfony\Component\Validator\Constraints as Assert;
Restricciones comparativas
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
SYMFONY2 ~ VALIDATOR
@Assert\Choice
@Assert\Collection
@Assert\Count
@Assert\UniqueEntity
@Assert\Language
@Assert\Locale
@Assert\Country
use Symfony\Component\Validator\Constraints as Assert;
Restricciones de colecciones
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
SYMFONY2 ~ VALIDATOR
@Assert\File @Assert\Image
use Symfony\Component\Validator\Constraints as Assert;
Restricciones de archivos
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
SYMFONY2 ~ VALIDATOR
@Assert\CardScheme
@Assert\Luhn
@Assert\Iban
@Assert\Isbn
@Assert\Issn
use Symfony\Component\Validator\Constraints as Assert;
Restricciones bancarias y otras numéricas
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
SYMFONY2 ~ VALIDATOR
@Assert\Callback
@Assert\All
@Assert\UserPassword
@Assert\Valid
use Symfony\Component\Validator\Constraints as Assert;
Otras restricciones
@CustomAssert
http://symfony.com/doc/current/book/validation.html#deSymfony @aferrandini
Agregar las anotaciones con use
use JMS\SecurityExtraBundle\Annotation\Secure;
use JMS\SecurityExtraBundle\Annotation\SecureParam;
use JMS\SecurityExtraBundle\Annotation\SecureReturn;
use JMS\SecurityExtraBundle\Annotation\RunAs;
use JMS\SecurityExtraBundle\Annotation\SatisfiesParentSecurityPolicy;
JMSSECURITYEXTRABUNDLEJohannes Schmitt
@Secure @SecureParam
JMSSECURITYEXTRABUNDLE
@SecureReturn @RunAs
@SatisfiesParentSecurityPolicy#deSymfony @aferrandini
@SECURE
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @Route(“/editar/{id}”, name=”editar_agenda”) * @Method({“GET”, “POST”}) * @Secure(roles=”ROLE_EDITOR, ROLE_ADMIN, ROLE_FOO”) */ public function editarAction($id) { }
Define quién puede invocar el método
@Secure @SecureParam
JMSSECURITYEXTRABUNDLE
@SecureReturn @RunAs
@SatisfiesParentSecurityPolicy#deSymfony @aferrandini
@SECUREPARAM
// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @Route(“/agenda”) */class AgendaController extends Controller{ /** * @SecureParam(name="agenda", permissions="OWNER") * @Secure(roles=”ROLE_EDITOR, ROLE_ADMIN, ROLE_FOO”) */ public function editarAction(Agenda $agenda) { }}
Define restricciones para los parámetros
@Secure @SecureParam
JMSSECURITYEXTRABUNDLE
@SecureReturn @RunAs
@SatisfiesParentSecurityPolicy#deSymfony @aferrandini
@SECURERETURN
// DeSymfony/Bundle/WebBundle/Services/AgendaService.phpclass AgendaService{ /** * @SecureReturn(permissions=”VIEW”) */ public function agendaMethod() { return $objeto; }}
Define restricciones para el valor devuelto
@Secure @SecureParam
JMSSECURITYEXTRABUNDLE
@SecureReturn @RunAs
@SatisfiesParentSecurityPolicy#deSymfony @aferrandini
@RUNAS
Cambia el ROL de ejecución de un métodoclass AgendaPublicService{ protected $agendaPrivateService;
/** * @Secure(roles=”ROLE_USER”) * @RunAs(roles=”ROLE_PRIVATE”) */ public function agendaMethod() { return $this ->agendaPrivateService ->agendaPrivate(); }}
class AgendaPrivateService{ /** * @Secure(role=”ROLE_PRIVATE”) */ public function agendaPrivate() { // ... }}
Ejemplo de @CustomAnnotation
DisableBundle
https://github.com/aferrandini/DisableBundlePermite deshabilitar un Controlador o una Acción por tiempo y redireccionar a otra ruta.
@
#deSymfony @aferrandini
#deSymfony @aferrandini
Mother of Godde las
Anotaciones
@IGNOREANNOTATION
¡Anotación para ignorar anotaciones!// DeSymfony/Bundle/WebBundle/Controller/AgendaController.php/** * @IgnoreAnnotation(“AnotacionQueNoExiste”) */class AgendaController extends Controller{ /** * @Route(“/”, name=”agenda”) * @Template(“DeSymfonyWebBundle:Agenda:agenda.html.twig”) * @AnotacionQueNoExiste */ public function agendaAction() { }
¿PREGUNTAS?
#deSymfony @aferrandini
Buen provecho!
https://connect.sensiolabs.com/profile/aferrandini
MUCHAS GRACIAS#deSymfony
@aferrandini
https://joind.in/8849
http://es.linkedin.com/in/arielferrandini https://github.com/aferrandini http://twitter.com/aferrandini