La primera versión del framework Symfony2 se publicó hace más de tres años. Durante este tiempo, la comunidad de programadores Symfony ha originado una serie de buenas prácticas oficiosas que han sido adoptadas por la mayoría de aplicaciones.
Lamentablemente muchas de estas prácticas tienen poco que ver con la visión original de los creadores de Symfony y complican en exceso el desarrollo de las aplicaciones.
En esta sesión se presentarán muchas de las buenas prácticas oficiales recomendadas por Fabien Potencier, creador de Symfony. Sorpréndete con una visión totalmente renovada y pragmática del desarrollo de aplicaciones Symfony profesionales.
CRUD básico con Symfony. Esta presentación es una continuación de lo contado en la II Symfony Zaragoza. Explica un ejemplo sencillo de un CRUD para mostrar como realizar modelos, controladores, vistas, formularios, etc.
Documento Formativo de Symfony2 en el que explica desde qué es Symfony hasta los primeros pasos básicos: instalación, configuración, entidades, Twig, YAML...
PHP es un lenguaje de scripting orientado al desarrollo de aplicaciones web. En una primera parte se explica los principios del lenguaje, algunas herramientas y un esbozo de una aplicación web escrita en PHP. En una segunda parte se presenta Symfony, un framework PHP que reúne las mejores prácticas de desarrollo de aplicaciones web.
CRUD básico con Symfony. Esta presentación es una continuación de lo contado en la II Symfony Zaragoza. Explica un ejemplo sencillo de un CRUD para mostrar como realizar modelos, controladores, vistas, formularios, etc.
Documento Formativo de Symfony2 en el que explica desde qué es Symfony hasta los primeros pasos básicos: instalación, configuración, entidades, Twig, YAML...
PHP es un lenguaje de scripting orientado al desarrollo de aplicaciones web. En una primera parte se explica los principios del lenguaje, algunas herramientas y un esbozo de una aplicación web escrita en PHP. En una segunda parte se presenta Symfony, un framework PHP que reúne las mejores prácticas de desarrollo de aplicaciones web.
Composer es un administrador de paquetes flexible, simple y que se encarga de la administración de dependencias de nuestro proyecto. Está inspirado en npm de node.js y Bundler de Ruby.
Composer ha cambiado la comunidad PHP y está reinventado la forma de trabajar con PHP.
Gracias a Composer la comunidad PHP es más feliz y podrá dejar de reinventar la rueda una y otra vez.
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...Pablo Godel
AngularJS es un framework Javascript relativamente nuevo, patrocinado por Google, que está ganando mucha popularidad gracias a su potencia, flexibilidad y simplicidad.
En esta charla haremos una introducción de sus caulidades más importantes, veremos como se acopla con Symfony para la creación de aplicaciones web con interfaz ricas y complejas, incluyendo consejos prácticos de como diseñar nuestra aplicación establecer su estructura.
Por último, mostraremos una aplicación escrita en AngularJS que se conecta a servidores REST y WebSockets creados con Symfony.
PHP, una introducción a modo de presentación como tutorial básico llegando hasta clases y pasando por la conexión con una oferta de servicios web mediante protocolo SOAP con WSDL.
¿Qué son los patrones de diseño?. El patrón Singleton. El patrón Registry
El patrón Factory. El patrón Decorator
El patrón Observer. El patrón Front Controller.
El patrón MVC
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasosJavier Eguiluz
Instalación y primeros pasos fue la primera ponencia impartida durante las Jornadas Symfony 2011. Se trata de la primera parte de las seis que forman el tutorial de desarrollo de la aplicación github.com/desymfony.
Durante la misma se explIca cómo instalar y configurar Symfony2, cómo instalar el proyecto deSymfony, cómo crear los bundles con el generador interactivo y también se introduce el funcionamiento de la arquitectura MVC en Symfony2 mediante la programación de la parte dedicada a mostrar las páginas estáticas de la aplicación.
Seguridad Web
Conceptos y buenas prácticas.
Ataques XSS
Ataques CSRF
Ataques SQL-injection
Ataques de sesión: Session riding
Inyección remota de código
Las Jornadas Symfony 2011 comenzaron con una breve introducción a Symfony2.
Durante la presentación se muestran algunas de las características más destacadas de Symfony2 a través de diez palabras clave.
Presentación del primer taller de PHP realizada por Francisco Calderón para la Asociación de Webmasters de Málaga.
Puntos tratados:
- ¿Qué es PHP?
- Características
- IDE: Netbeans
- Servidor PHP + Apache + MySQL
- Sintaxis y Operadores
- Strings
- Condiciones (If, Switch)
- Bucles (for, while)
Charla de introducción a zope3: Qué es Zope 3 - Propositos de la plataforma, Aplicación, Qué es Grok, como desarrollar una aplicación con Grok, vistas, zcmls, expresiones tal, generando html desde python, formularios, almacenamiento de datos, contenedores,
Composer es un administrador de paquetes flexible, simple y que se encarga de la administración de dependencias de nuestro proyecto. Está inspirado en npm de node.js y Bundler de Ruby.
Composer ha cambiado la comunidad PHP y está reinventado la forma de trabajar con PHP.
Gracias a Composer la comunidad PHP es más feliz y podrá dejar de reinventar la rueda una y otra vez.
deSymfony 2013 - Creando aplicaciones web desde otro ángulo con Symfony y A...Pablo Godel
AngularJS es un framework Javascript relativamente nuevo, patrocinado por Google, que está ganando mucha popularidad gracias a su potencia, flexibilidad y simplicidad.
En esta charla haremos una introducción de sus caulidades más importantes, veremos como se acopla con Symfony para la creación de aplicaciones web con interfaz ricas y complejas, incluyendo consejos prácticos de como diseñar nuestra aplicación establecer su estructura.
Por último, mostraremos una aplicación escrita en AngularJS que se conecta a servidores REST y WebSockets creados con Symfony.
PHP, una introducción a modo de presentación como tutorial básico llegando hasta clases y pasando por la conexión con una oferta de servicios web mediante protocolo SOAP con WSDL.
¿Qué son los patrones de diseño?. El patrón Singleton. El patrón Registry
El patrón Factory. El patrón Decorator
El patrón Observer. El patrón Front Controller.
El patrón MVC
Desymfony 2011 - Tutorial #1: Instalacion y primeros pasosJavier Eguiluz
Instalación y primeros pasos fue la primera ponencia impartida durante las Jornadas Symfony 2011. Se trata de la primera parte de las seis que forman el tutorial de desarrollo de la aplicación github.com/desymfony.
Durante la misma se explIca cómo instalar y configurar Symfony2, cómo instalar el proyecto deSymfony, cómo crear los bundles con el generador interactivo y también se introduce el funcionamiento de la arquitectura MVC en Symfony2 mediante la programación de la parte dedicada a mostrar las páginas estáticas de la aplicación.
Seguridad Web
Conceptos y buenas prácticas.
Ataques XSS
Ataques CSRF
Ataques SQL-injection
Ataques de sesión: Session riding
Inyección remota de código
Las Jornadas Symfony 2011 comenzaron con una breve introducción a Symfony2.
Durante la presentación se muestran algunas de las características más destacadas de Symfony2 a través de diez palabras clave.
Presentación del primer taller de PHP realizada por Francisco Calderón para la Asociación de Webmasters de Málaga.
Puntos tratados:
- ¿Qué es PHP?
- Características
- IDE: Netbeans
- Servidor PHP + Apache + MySQL
- Sintaxis y Operadores
- Strings
- Condiciones (If, Switch)
- Bucles (for, while)
Charla de introducción a zope3: Qué es Zope 3 - Propositos de la plataforma, Aplicación, Qué es Grok, como desarrollar una aplicación con Grok, vistas, zcmls, expresiones tal, generando html desde python, formularios, almacenamiento de datos, contenedores,
Desarrollo rápido con PHP y Symfony (I): Introducción a SymfonyDavid J. Brenes
Introducción al framework de desarrollo Symfony, explicando la estructura de una aplicación Symfony, el funcionamiento de su consola y detalles de su configuración
Todos pasamos por la mala experiencia de tomar un proyecto para encontrarnos con un cáos total en la hoja de estilos y/o descubrir que cada miembro del equipo ha hecho las cosas a su manera. Ni hablar de retomar un trabajo luego de mucho tiempo y no poder entender ni encontrar lo que hicimos ni cómo lo hicimos. Esta charla pretende plantear soluciones a estos problemas para un mejor desarrollo y organización de nuestros proyectos, particularmente en el uso del CSS.
Web Performance Optimization: Mejorando el proceso de cargaJesus Pernas Alonso
Presentación sobre WPO de la clase impartida en el Curso de SEO para principiantes patrocinado por la Fundación De Mar a Mar y Marketing & Web el 13 de marzo de 2015.
- Motivos para cuidar el WPO
- Acciones para mejorar el proceso de carga de la web
- Herramientas que te ayudarán a cuidar y monitorizar el WPO
Herramientas para desarrollar rápidamenteCarlos Toxtli
Más de 150 herramientas en linea que debes conocer para crear desarrollos asombrosos en muy poco tiempo. La era de hacer todo desde cero cada vez es más lejana, ahora tenemos herramientas que pueden hacer que un desarrollo antes tardaría 2 meses tarde menos de 2 semanas.
Programación de apps multiplataforma con Apache Cordova
(parte 2 de 2).
Explicación de qué es y cómo desarrollar aplicaciones con AngularJS e Ionic Framework. Controllers, services, filters, directives, etc.
Charla para el evento Sevilla Mobility Day.
Desde hace pocos años, desarrollar sitios y aplicaciones web aplicando diseños responsive ha dejado de ser opcional.
Para dispositivos móviles, empieza a ser necesario ir más allá y crear experiencias de usuario dedicadas a estos entornos.
IONIC, el framework para crear aplicaciones híbridas multiplataformabetabeers
En esta charla, Juan nos va a enseñar los conceptos básicos para crear una aplicación móvil multiplataforma usando el framework "IONIC". Aprenderemos cómo instalar las herramientas básicas para su uso, haremos una breve aproximación a los distintos plugins que nos ofrece "Cordova" y aprenderemos un poco de la arquitectura interna de IONIC (basado en un patrón MVC, el cuál usa AngularJS, Typescript y CSS (bajo SASS).
Esta charla tiene por objetivo discutir los patrones de diseño de la web 2.0 y las nuevas tendencias de la web semántica. Los 12 patrones que dirigen la presentación son: Information sharing, User-centered design, MVC architecture, Participation & collaboration, Social networking, Search & recommendation engines, Folksonomy, Community & collective intelligence, Inter-operability & data portability, Rich user experience, Separation of content and presentation, Web as a platform (ubiquity).
Junto con esto se presentan brevemente algunos frameworks y módulos de Python que permiten el desarrollo de este tipo de aplicaciones web. Asimismo, se muestran ejemplos de consumo de APIs de servicios web populares (JSON, XML, feeds y HTML scraping) y un ejemplo de procesamiento de contenido a través de herramientas semánticas.
More info at:
http://ar.pycon.org/2009/conference/schedule/event/30/
Download original slideshow in PDF format at:
http://ar.pycon.org/2009/conference/schedule/event/30/
Licensing and Acknowledgements at: http://ar.pycon.org/2009/conference/schedule/event/30/
Python en la Web Semántica by Santiago Andrés Coffey is licensed under a Creative Commons Reconocimiento-No comercial-Compartir bajo la misma licencia 2.5 Argentina License.
http://creativecommons.org/licenses/by-nc-sa/2.5/ar/
Similar a Las buenas prácticas oficiales para aplicaciones Symfony (20)
(PROYECTO) Límites entre el Arte, los Medios de Comunicación y la Informáticavazquezgarciajesusma
En este proyecto de investigación nos adentraremos en el fascinante mundo de la intersección entre el arte y los medios de comunicación en el campo de la informática.
La rápida evolución de la tecnología ha llevado a una fusión cada vez más estrecha entre el arte y los medios digitales, generando nuevas formas de expresión y comunicación.
Continuando con el desarrollo de nuestro proyecto haremos uso del método inductivo porque organizamos nuestra investigación a la particular a lo general. El diseño metodológico del trabajo es no experimental y transversal ya que no existe manipulación deliberada de las variables ni de la situación, si no que se observa los fundamental y como se dan en su contestó natural para después analizarlos.
El diseño es transversal porque los datos se recolectan en un solo momento y su propósito es describir variables y analizar su interrelación, solo se desea saber la incidencia y el valor de uno o más variables, el diseño será descriptivo porque se requiere establecer relación entre dos o más de estás.
Mediante una encuesta recopilamos la información de este proyecto los alumnos tengan conocimiento de la evolución del arte y los medios de comunicación en la información y su importancia para la institución.
Actualmente, y debido al desarrollo tecnológico de campos como la informática y la electrónica, la mayoría de las bases de datos están en formato digital, siendo este un componente electrónico, por tanto se ha desarrollado y se ofrece un amplio rango de soluciones al problema del almacenamiento de datos.
3Redu: Responsabilidad, Resiliencia y Respetocdraco
¡Hola! Somos 3Redu, conformados por Juan Camilo y Cristian. Entendemos las dificultades que enfrentan muchos estudiantes al tratar de comprender conceptos matemáticos. Nuestro objetivo es brindar una solución inclusiva y accesible para todos.
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta in...espinozaernesto427
Las lámparas de alta intensidad de descarga o lámparas de descarga de alta intensidad son un tipo de lámpara eléctrica de descarga de gas que produce luz por medio de un arco eléctrico entre electrodos de tungsteno alojados dentro de un tubo de alúmina o cuarzo moldeado translúcido o transparente.
lámparas más eficientes del mercado, debido a su menor consumo y por la cantidad de luz que emiten. Adquieren una vida útil de hasta 50.000 horas y no generan calor alguna. Si quieres cambiar la iluminación de tu hogar para hacerla mucho más eficiente, ¡esta es tu mejor opción!
Las nuevas lámparas de descarga de alta intensidad producen más luz visible por unidad de energía eléctrica consumida que las lámparas fluorescentes e incandescentes, ya que una mayor proporción de su radiación es luz visible, en contraste con la infrarroja. Sin embargo, la salida de lúmenes de la iluminación HID puede deteriorarse hasta en un 70% durante 10,000 horas de funcionamiento.
Muchos vehículos modernos usan bombillas HID para los principales sistemas de iluminación, aunque algunas aplicaciones ahora están pasando de bombillas HID a tecnología LED y láser.1 Modelos de lámparas van desde las típicas lámparas de 35 a 100 W de los autos, a las de más de 15 kW que se utilizan en los proyectores de cines IMAX.
Esta tecnología HID no es nueva y fue demostrada por primera vez por Francis Hauksbee en 1705. Lámpara de Nernst.
Lámpara incandescente.
Lámpara de descarga. Lámpara fluorescente. Lámpara fluorescente compacta. Lámpara de haluro metálico. Lámpara de vapor de sodio. Lámpara de vapor de mercurio. Lámpara de neón. Lámpara de deuterio. Lámpara xenón.
Lámpara LED.
Lámpara de plasma.
Flash (fotografía) Las lámparas de descarga de alta intensidad (HID) son un tipo de lámparas de descarga de gas muy utilizadas en la industria de la iluminación. Estas lámparas producen luz creando un arco eléctrico entre dos electrodos a través de un gas ionizado. Las lámparas HID son conocidas por su gran eficacia a la hora de convertir la electricidad en luz y por su larga vida útil.
A diferencia de las luces fluorescentes, que necesitan un recubrimiento de fósforo para emitir luz visible, las lámparas HID no necesitan ningún recubrimiento en el interior de sus tubos. El propio arco eléctrico emite luz visible. Sin embargo, algunas lámparas de halogenuros metálicos y muchas lámparas de vapor de mercurio tienen un recubrimiento de fósforo en el interior de la bombilla para mejorar el espectro luminoso y reproducción cromática. Las lámparas HID están disponibles en varias potencias, que van desde los 25 vatios de las lámparas de halogenuros metálicos autobalastradas y los 35 vatios de las lámparas de vapor de sodio de alta intensidad hasta los 1.000 vatios de las lámparas de vapor de mercurio y vapor de sodio de alta intensidad, e incluso hasta los 1.500 vatios de las lámparas de halogenuros metálicos.
Las lámparas HID requieren un equipo de control especial llamado balasto para funcionar
En este documento analizamos ciertos conceptos relacionados con la ficha 1 y 2. Y concluimos, dando el porque es importante desarrollar nuestras habilidades de pensamiento.
Sara Sofia Bedoya Montezuma.
9-1.
Índice del libro "Big Data: Tecnologías para arquitecturas Data-Centric" de 0...Telefónica
Índice del libro "Big Data: Tecnologías para arquitecturas Data-Centric" de 0xWord escrito por Ibón Reinoso ( https://mypublicinbox.com/IBhone ) con Prólogo de Chema Alonso ( https://mypublicinbox.com/ChemaAlonso ). Puedes comprarlo aquí: https://0xword.com/es/libros/233-big-data-tecnologias-para-arquitecturas-data-centric.html
9. ¿Por qué?
Las buenas prácticas oficiosas
complican mucho el desarrollo
de aplicaciones y no siguen la
filosofía pragmática de los
creadores de Symfony.
10. Definición de “Best Practice”
A well defined procedure
that is known to produce
near-optimum results.
21. No uses las buenas prácticas …
• En bundles compartidos (públicos o
privados).
22. No uses las buenas prácticas …
• En bundles compartidos (públicos o
privados).
• En aplicaciones muy complejas o con
arquitecturas muy especiales.
23. No uses las buenas prácticas …
• En bundles compartidos (públicos o
privados).
• En aplicaciones muy complejas o con
arquitecturas muy especiales.
• Si tienes tus propias buenas prácticas.
32. ¿Cómo crear un sistema de plugins?
• Deben funcionar de manera
autónoma.
33. ¿Cómo crear un sistema de plugins?
• Deben funcionar de manera
autónoma.
• Pueden definir su propia
configuración.
34. ¿Cómo crear un sistema de plugins?
• Deben funcionar de manera
autónoma.
• Pueden definir su propia
configuración.
• Pueden incluir plantillas y assets.
59. No añadas un vendor a los bundles privados
AcmeNetworksAcmeWebsiteMarketingBundle
!
AcmeNetworksAcmeWebsiteMarketingBundle:Default:index.html.twig
!
{{ render(controller(
'AcmeNetworksAcmeWebsiteMarketingBundle:Default:latestNews'
)) }}
60. No añadas un vendor a los bundles privados
AcmeNetworksAcmeWebsiteMarketingBundle
!
AcmeNetworksAcmeWebsiteMarketingBundle:Default:index.html.twig
!
{{ render(controller(
'AcmeNetworksAcmeWebsiteMarketingBundle:Default:latestNews'
)) }}
Esto lo he visto con
mis propios ojos
69. Nueva organización de plantillas
aplicacion/
$" app/Resources/views/
!" contact/
# !" index.html.twig
# $" show.html.twig
. . .
!
$" product/
!" index.html.twig
!" category.html.twig
$" show.html.twig
70. La nueva notación de las plantillas
$this->render('AcmeDemoBunde:Default:index.html.twig');
$this->render('default/index.html.twig');
!
$this->render('AcmeDemoBundle::index.html.twig');
$this->render('index.html.twig');
71. La nueva notación de las plantillas
{% extends '::layout.html.twig' %}
{% extends 'layout.html.twig' %}
!
{{ include('AcmeDemoBundle:Default:subdir/index.html.twig') }}
{{ include('default/subdir/index.html.twig') }}
!
{{ include('AcmeDemoBundle:Default/subdir:index.html.twig') }}
{{ include('default/subdir/index.html.twig') }}
72. Los problemas de la notación tradicional
AcmeDemoBundle:Default:subdir/index.html.twig
73. Los problemas de la notación tradicional
• Requiere explicársela a cada diseñador/programador.
AcmeDemoBundle:Default:subdir/index.html.twig
74. Los problemas de la notación tradicional
• Requiere explicársela a cada diseñador/programador.
• Tiene excepciones (alguna de sus partes puede estar
vacía) e inconsistencias (subdirectorios).
AcmeDemoBundle:Default:subdir/index.html.twig
75. Los problemas de la notación tradicional
• Requiere explicársela a cada diseñador/programador.
• Tiene excepciones (alguna de sus partes puede estar
vacía) e inconsistencias (subdirectorios).
• No es inmediato saber dónde está la plantilla (debes
traducir la notación a un directorio).
AcmeDemoBundle:Default:subdir/index.html.twig
80. En resumen
• Si utilizas mal los bundles, estás repitiendo
la estructura de la aplicación sin necesidad
• Si no vas a compartir tus bundles, utiliza
los directorios de la aplicación (app/
Resources/ y web/).
• El número de archivos se mantiene, los
directorios y la complejidad se reducen.
83. Escala de sensibilidad
para programadores
Política
Religión
Fútbol
Estándar de código
Editor de código
Anotaciones
84. Anotaciones PHP
use AppBundleEntityPost;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
!
class CommentController extends Controller
{
/**
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction(Post $post)
{ ... }
!
/*
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction(Post $post)
{ ... }
}
85. Anotaciones PHP
use AppBundleEntityPost;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
!
class CommentController extends Controller
{
/**
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction(Post $post)
{ ... }
!
/*
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction(Post $post)
{ ... }
}
Anotación
86. Anotaciones PHP
use AppBundleEntityPost;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
!
class CommentController extends Controller
{
/**
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction(Post $post)
{ ... }
!
/*
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction(Post $post)
{ ... }
}
Anotación
Comentario
94. Los ParamConvertes en la práctica
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use AppBundleEntityPost;
!
class CommentController extends Controller
{
/**
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction(Post $post)
{
}
}
use SensioBundleFrameworkExtraBundleConfigurationRoute;
!
!
class CommentController extends Controller
{
/**
* @Route("/edit/{id}", name = "post_edit")
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$post = $em->getRepository('AppBundle:Post')->find($id);
!
if (!$post) {
throw $this->createNotFoundException();
}
}
}
95. Un controlador Symfony de ejemplo
namespace AppBundleController;
!
use AppBundleEntityPost;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
!
class BlogController extends Controller
{
/**
* @Route("/edit/{id}", name="post_edit")
*/
public function editAction(Post $post)
{
return $this->render('blog/edit.html.twig', array(
'post' => $post
));
}
}
97. Los atajos de los controladores
$this->forward();
$this->redirect();
$this->redirectToRoute();
$this->getUser();
$this->getDoctrine();
$this->generateUrl();
$this->createNotFoundException();
$this->createAccessDeniedException()
102. Restricciones sencillas y comunes
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationSecurity;
!
/**
* @Route("/new", name="admin_post_new")
* @Security("has_role('ROLE_ADMIN')")
*/
public function newAction()
{
// ...
}
103. Restricciones sencillas y comunes
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationSecurity;
!
/**
* @Route("/new", name="admin_post_new")
*/
public function newAction()
{
if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) {
throw $this->createAccessDeniedException();
}
!
!
// ...
}
104. Restricciones sencillas y comunes
use AppBundleEntityPost;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationSecurity;
!
/**
* @Route("/{id}/edit", name="admin_post_edit")
* @Security("user.getEmail() == post.getAuthorEmail()")
*/
public function editAction(Post $post)
{
// ...
}
105. Restricciones sencillas y comunes
// src/AppBundle/Entity/Post.php
// ...
!
class Post
{
// ...
!
public function isAuthor(User $user = null)
{
return $user && $user->getEmail() == $this->getAuthorEmail();
}
}
106. Restricciones sencillas y comunes
use AppBundleEntityPost;
use SensioBundleFrameworkExtraBundleConfigurationSecurity;
!
/**
* @Route("/{id}/edit", name="admin_post_edit")
* @Security("post.isAuthor(user)")
*/
public function editAction(Post $post)
{
// ...
}
!
!
{% if post.isAuthor(app.user) %}
<a href=""> ... </a>
{% endif %}
107. Restricciones avanzadas (voters)
namespace AppBundleSecurity;
!
use SymfonyComponentSecurityCoreAuthorizationVoterAbstractVoter;
use SymfonyComponentSecurityCoreUserUserInterface;
!
class PostVoter extends AbstractVoter
{
protected function getSupportedAttributes()
{
return array('create', 'edit');
}
!
protected function getSupportedClasses()
{
return array('AppBundleEntityPost');
}
!
protected function isGranted($attribute, $post, $user = null)
{
// ...
}
}
109. Nombres de servicios en apps Symfony
// Servicios Symfony
$this->get('doctrine')
$this->get('logger')
$this->get('session')
$this->get('validator')
!
// Servicios de terceros
$this->get('imagine.filter.loader.thumbnail')
$this->get('knp_menu.renderer_provider')
$this->get('sonata.admin.form.filter.type.datetime_range')
110. Nombres de servicios propios
$this->get('slugger')
$this->get('parser')
$this->get('markdown_parser')
$this->get('stats_aggregator')
!
// Aceptable también
$this->get('app.slugger')
$this->get('app.parser')
$this->get('app.markdown_parser')
$this->get('app.stats_aggregator')
111. No definas parámetros para las clases
# app/config/services.yml
parameters:
slugger.class: AppBundleUtilsSlugger
!
services:
slugger:
class: "%slugger.class%"
112. No definas parámetros para las clases
# app/config/services.yml
parameters:
slugger.class: AppBundleUtilsSlugger
!
services:
slugger:
class: "%slugger.class%"
Innecesario y
poco útil en la
práctica
113. No definas parámetros que no cambian
# app/config/config.yml
parameters:
homepage.num_items: 10
!
// src/AppBundle/Entity/Post.php
class Post {
const NUM_ITEMS = 10;
!
// ...
}
114. No definas parámetros que no cambian
# app/config/config.yml
parameters:
homepage.num_items: 10
!
// src/AppBundle/Entity/Post.php
class Post {
const NUM_ITEMS = 10;
!
// ...
}
Este valor
seguramente no
cambia nunca
115. No añadas botones en los formularios
class PostType extends AbstractType {
public function buildForm($builder, $options) {
$builder
// ...
->add('save', 'submit', array('label' => 'Create Post'))
;
}
!
// ...
}
116. No añadas botones en los formularios
class PostType extends AbstractType {
public function buildForm($builder, $options) {
$builder
// ...
->add('save', 'submit', array('label' => 'Create Post'))
;
}
!
// ...
}
Te dificulta
reutilizar los
formularios
118. No generes las URLs en los tests
public function testBlogArchives()
{
$client = self::createClient();
$url = $client->getContainer()->get('router')->generate('blog_archives');
$client->request('GET', $url);
// ...
}
!
!
public function testBlogArchives()
{
$client = self::createClient();
$client->request('GET', '/blog/archives/');
// ...
}
119. No generes las URLs en los tests
public function testBlogArchives()
{
$client = self::createClient();
$url = $client->getContainer()->get('router')->generate('blog_archives');
$client->request('GET', $url);
// ...
}
!
!
public function testBlogArchives()
{
$client = self::createClient();
$client->request('GET', '/blog/archives/');
// ...
}
Si rompes la URL
no te enteras
121. Configuración
no cambia de un ordenador a otro
proyecto/app/config/
!" config.yml
!" parameters.yml
$" parameters.yml.dist
122. Configuración
no cambia de un ordenador a otro
cambia de un ordenador a otro
no se sube al repositorio
proyecto/app/config/
!" config.yml
!" parameters.yml
$" parameters.yml.dist
123. Configuración
no cambia de un ordenador a otro
cambia de un ordenador a otro
no se sube al repositorio
este sí se sube al repositorio
proyecto/app/config/
!" config.yml
!" parameters.yml
$" parameters.yml.dist
124. No utilices una configuración semántica
public function getConfigTreeBuilder() {
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('framework');
!
$rootNode
->children()
->scalarNode('secret')->end()
->scalarNode('http_method_override')
->info("Set true to enable support for ...”)
->defaultTrue()
->end()
->arrayNode('trusted_proxies')
->beforeNormalization()
->ifTrue(function ($v) { return !is_array($v) && null !== $v; })
->then(function ($v) { return is_bool($v) ? array() : preg_split('/s*,s*/', $v); })
->end()
->prototype('scalar')
->validate()
->ifTrue(function ($v) {
if (empty($v)) {
return false;
}
!
if (false !== strpos($v, '/')) {
Sólo es útil en
configuraciones
muy complejas