Cómo crear Third party bundles de Symfony completamente extensibles y sobreescribibles

33 %
67 %
Information about Cómo crear Third party bundles de Symfony completamente extensibles y...

Published on December 15, 2016

Author: dualhand

Source: slideshare.net

1. C THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES.

2. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES gerfignaedytebfodavegmiguelvilata araquemario almacbe frankey90 driera_comraulo79

3. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES wolfwolker JL_Laso araquemario almacbe frankey90 driera_comraulo79 gerfignaedytebfodavegmiguelvilata paolacaracola

4. BEST PRACTICES FOR REUSABLE BUNDLES CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

5. BEST PRACTICE # 1 NOMBRE DE LOS BUNDLES

6. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES AcmeBlogBundle

7. AcmeBlogBundle CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

8. AcmeBundleBlogBundle CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

9. AcmeBlogBundle CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

10. PSR4 Vendor(Category)*BundleName ~ Bundle CamelCase Descriptivo y corto No más de dos palabras NOMBRE DE LOS BUNDLES: CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

11. BEST PRACTICE # 2 ESTRUCTURA DE DIRECTORIOS

12. ¿Qué ficheros y carpetas son obligados? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

13. AcmeBlogBundle.php README.(md | rst) LICENSE Resources/doc/index.rst ESTRUCTURA DE LOS DIRECTORIOS: CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

14. Commands → Command/ Controllers → Controller/ Service Container Extensions → DependencyInjection/ Model classes → Model/ Configuration → Resources/config/ Web Resources (CSS, JS, images) → Resources/public/ Translation files → Resources/translations/ Templates → Resources/views/ Unit and Functional Tests → Tests/ CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES ESTRUCTURA DE LOS DIRECTORIOS:

15. ¿Cómo se tiene que llamar la carpeta donde estén los Listeners y/o Subscribers? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

16. EventListener CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

17. El directorio de un bundle es de solo lectura CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

18. Y si tu bundle necesita generar algún fichero, ¿dónde lo crearías? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

19. Solo si formarán parte del repositorio... CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

20. app/logs o app/cache CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

21. CLASES BEST PRACTICE # 3

22. ContentController.php del Bundle AcmeBlogBundle ¿directorio? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

23. Acme/BlogBundle/Controller/ContentController.php CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

24. ContentController.php del Bundle AcmeBlogBundle ¿FQC? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

25. AcmeBlogBundleControllerContentController CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

26. SYMFONY CODING STANDARD BEST PRACTICE # 4

27. class FooBar { const SOMECONST = 42; /** * @var string */ private $foo_bar; private function transformText($dummy, array $options = array()) { $defaultOptions = [ 'some_default' => 'values', 'another_default' => 'more values' ]; foreach ($options as $option) { if (!in_array($option, $defaultOptions)) { throw new RuntimeException(sprintf('Unrecognized option "%s"', $option)); } } $mergedOptions = array_merge($defaultOptions, $options ); if (true === $dummy) { return; } if ($dummy === 'string') { if ('values' === $mergedOptions['some_default']) { return substr($dummy, 0, 5); } return ucwords($dummy); } } }

28. class FooBar { const SOMECONST = 42; /** * @var string */ private $foo_bar; private function transformText($dummy, array $options = array()) { $defaultOptions = [ 'some_default' => 'values', 'another_default' => 'more values' ]; foreach ($options as $option) { if (!in_array($option, $defaultOptions)) { throw new RuntimeException(sprintf('Unrecognized option "%s"', $option)); } } $mergedOptions = array_merge($defaultOptions, $options ); if (true === $dummy) { return; } if ($dummy === 'string') { if ('values' === $mergedOptions['some_default']) { return substr($dummy, 0, 5); } return ucwords($dummy); } } }

29. Sufijo Listener si escucha a algún evento CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

30. Clases Exception deben de ir en un sub-space Exception CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

31. TESTS BEST PRACTICE # 5

32. PHPUnit Tests/ Los test funcionales solo deben testear la response y la información de profiling si creas alguna. No puede existir un test que sea AllTest.php Tiene que haber un phpunit.xml.dist TESTS CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

33. ¿Cuánto % de cobertura tiene que haber? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

34. >= 95% CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

35. DOCUMENTACIÓN BEST PRACTICE # 6

36. PHPDoc. reStructuredText en Resources/doc/ DOCUMENTACIÓN: CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

37. INSTRUCCIONES DE INSTALACIÓN README.md Step 1: Download the Bundle --------------------------- composer require blabla/blabla Step 2: Enable the Bundle ------------------------- Step 3, Step 4, etc. otros requisitos como registrar rutas... CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

38. RUTAS BEST PRACTICE # 7

39. ¿Alias de AcmeBlogBundle? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

40. acme_blog CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

41. Todas las rutas tiene que tener el alias como prefijo CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

42. TRADUCCIONES BEST PRACTICE # 8

43. ¿formato recomendado yml, xliff, po ...? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

44. XLIFF CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

45. XLIFF Symfony Best Practices CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

46. ¿Nombre del dominio de las traducciones para AcmeBlogBundle? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

47. acme_blog_domain CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

48. Un bundle NO tiene que sobreescribir otros dominios de traducción CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

49. Un bundle NO tiene que sobreescribir otros dominios de traducción Symfony Best Practices CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

50. CONFIGURACIÓN BEST PRACTICE # 9

51. Parámetros CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

52. # app/config/config.yml parameters: # @FrameworkBundle/Resources/config/translation.xml translator.class: AcmeHelloBundleTranslationTranslator CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

53. Semantic bundle configuration CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

54. # app/config/config.yml acme_social: twitter: client_id: 123 client_secret: $ecret CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

55. // src/Acme/SocialBundle/DependencyInjection/Configuration.php namespace AcmeSocialBundleDependencyInjection; use SymfonyComponentConfigDefinitionBuilderTreeBuilder; use SymfonyComponentConfigDefinitionConfigurationInterface; class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('acme_social'); $rootNode ->children() ->arrayNode('twitter') ->children() ->integerNode('client_id')-> defaultValue(123123)->end() ->scalarNode('client_secret')-> defaultValue('k453jhdaj492')->end() ->end() ->end() // twitter ->end() ; return $treeBuilder; } }

56. // src/Acme/SocialBundle/DependencyInjection/Configuration.php namespace AcmeSocialBundleDependencyInjection; use SymfonyComponentConfigDefinitionBuilderTreeBuilder; use SymfonyComponentConfigDefinitionConfigurationInterface; class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('acme_social'); $rootNode ->children() ->arrayNode('twitter') ->children() ->integerNode('client_id')-> defaultValue(123123)->end() ->scalarNode('client_secret')-> defaultValue('k453jhdaj492')->end() ->end() ->end() // twitter ->end() ; return $treeBuilder; } }

57. VERSIONADO BEST PRACTICE # 10

58. Semantic Versioning Standard. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

59. MAJOR.MINOR.PATCH CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

60. ¿Qué implicaciones tiene estar en la versión 0.x.x? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

61. “4 - Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable.” CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

62. SERVICIOS BEST PRACTICE # 11

63. ¿Cómo tiene que ser el id de los servicios? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

64. bundle_alias.service_id CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

65. ¿Qué hacemos con los servicios que no son usados por la aplicación si no internamente en el bundle? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

66. services: foo: class: ExampleFoo public: false CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

67. ¿Qué implica que un servicio sea privado? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

68. No se puede hacer: $container->get('foo'); Solo se puede inyectar en otro servicio en su definición. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

69. ¿Cómo vamos hasta aquí? ¿bien? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

70. MECANISMOS DE SOBRE- ESCRITURA Y HERENCIA CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

71. BUNDLES MECANISMOS... # 1

72. ¿Cómo hacemos que un bundle herede de otro? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

73. Bundles <?php use SymfonyComponentHttpKernelBundleBundle; class UserBundle extends Bundle { public function getParent() { return 'FOSUserBundle'; } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

74. ¿Qué implica esto? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

75. Poder sobreescribir casi cualquier archivo del bundle padre creándolo en el mismo sitio que el padre. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

76. CONTROLADORES MECANISMOS... # 2

77. ¿Cómo sobreescribimos el comportamiento de un controlador? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

78. Controladores // src/UserBundle/Controller/RegistrationController.php namespace UserBundleController; use FOSUserBundleControllerRegistrationController as BaseController; class RegistrationController extends BaseController { public function registerAction() { $response = parent::registerAction(); // ... do custom stuff return $response; } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

79. Controladores // src/UserBundle/Controller/RegistrationController.php namespace UserBundleController; use FOSUserBundleControllerRegistrationController as BaseController; class RegistrationController extends BaseController { public function registerAction() { $response = parent::registerAction(); // ... do custom stuff return $response; } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

80. ¿Siempre que una ruta apunte a ese action de ese controlador se llamará al sobreescrito? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

81. route_id: path: /register defaults: { _controller: FOSUserBundle:Registration:register } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

82. ¿De qué otra forma se puede hacer referencia a un controlador? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

83. UserBundleControllerRegistrationController::registerAction CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

84. route_id: path: /register defaults: { _controller: UserBundleControllerRegistrationController::registerAction } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

85. ¿y otra forma? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

86. ¿se podría declarar como servicio un controlador? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

87. services: fos_user.registration_controller: class: FOSUserBundleControllerRegistrationController ... CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

88. route_id: path: /register defaults: { _controller: fos_user.registration_controller:registerAction } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

89. route_id: path: /register defaults: { _controller: fos_user.registration_controller:registerAction } Sí, pero de otra forma. Más adelante! CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

90. Por tanto, solo se sobreescribirá si se usa ¿cómo? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

91. FOSUserBundle:Registration:register CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

92. FOSUserBundle:Registration:register CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

93. TEMPLATES MECANISMOS... # 3

94. ¿Cómo “encuentra” Symfony2 los templates twig? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

95. ::index.html.twig CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

96. AcmeBlogBundle::index.html.twig CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

97. AcmeBlogBundle:Blog:index.html.twig CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

98. Orden de búsqueda 1. app/Resources/AcmeBlogBundle/views/layout.html.twig 2. src/Acme/BlogBundle/Resources/views/layout.html.twig 3. src/MyAcmeBlogBundle/Resources/views/layout.html.twig - si fuera un bundle de vendors que hemos sobreescrito. public function Bundle::getParent ( return ‘AcmeBlogBundle’; ) 4. vendor/Acme/src/BlogBundle/Resources/views/layout.html.twig - si fuera un bundle de vendors. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

99. ¿Qué dice Symfony Best Practices sobre dónde tienen que ir los templates del proyecto? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

100. app/Resources CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

101. ¿por qué? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

102. RUTAS MECANISMOS... # 4

103. “Routing is never automatically imported in Symfony. If you want to include the routes from any bundle, then they must be manually imported from somewhere in your application (e.g. app/config/routing.yml).” CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

104. “Routing is never automatically imported in Symfony. If you want to include the routes from any bundle, then they must be manually imported from somewhere in your application (e.g. app/config/routing.yml).” Symfony Best Practices CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

105. “Copiar” las rutas del bundle y solo importar y/o modificar las que se deseen. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

106. TRADUCCIONES MECANISMOS... # 5

107. ¿Qué son los dominios de las traducciones? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

108. $translator->trans('Symfony is great'); CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

109. ¿Cuál es el dominio de esa traducción? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

110. messages.{lang}.{yml|po|xliff} CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

111. ¿Cómo se selecciona el dominio en el translator? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

112. $translator->trans('label.is_valid', array(), 'SonataAdminBunde'); {{ 'label.is_valid'|trans({}, 'SonataAdminBundle') }} CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

113. $translator->trans('label.is_valid', array(), 'SonataAdminBunde'); {{ 'label.is_valid'|trans({}, 'SonataAdminBundle') }} CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

114. La sobreescritura de traducciones está relacionado con el dominio y no con el bundle CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

115. WHAT?! CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

116. “The last translation file always wins...” “Translation files are also not aware of bundle inheritance...” CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

117. WTF?! CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

118. app/Resources/translations CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

119. app/Resources/translations Symfony Best Practices CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

120. VALIDACIONES MECANISMOS... # 6

121. Grupos de validación CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

122. Grupo de Validación class User implements UserInterface { /** * @AssertEmail(groups={"registration"}) */ private $email; /** * @AssertNotBlank(groups={"registration"}) * @AssertLength(min=7, groups={"registration"}) */ private $password; /** * @AssertValid() * @ORMOneToOne(targetEntity="Address" , mappedBy="address") */ private $address; /** * @AssertLength(min=2) */ private $city; } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

123. class User implements UserInterface { /** * @AssertEmail(groups={"registration"}) */ private $email; /** * @AssertNotBlank(groups={"registration"}) * @AssertLength(min=7, groups={"registration"}) */ private $password; /** * @AssertValid() * @ORMOneToOne(targetEntity="Address" , mappedBy="address") */ private $address; /** * @AssertLength(min=2) */ private $city; } Grupo de Validación CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

124. ¿y cómo sobreescribimos las validaciones? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

125. “Symfony loads all validation configuration files from every bundle and combines them into one validation metadata tree. This means you are able to add new constraints to a property, but you cannot override them.” CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

126. “To override this, the 3rd party bundle needs to have configuration for validation groups.” CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

127. Y…? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

128. fos_user: registration: form: validation_groups: [Registration, Default] CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

129. <service id="fos_user.registration.form.factory" class="FOSUserBundleFormFactoryFormFactory"> <argument type="service" id="form.factory" /> <argument>%fos_user.registration.form.name%</argument> <argument>%fos_user.registration.form.type%</argument> <argument>%fos_user.registration.form.validation_groups%</argument> </service> CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

130. $form = $this->createFormBuilder($users, array( 'validation_groups' => array('Registration', 'Default'), ))->add(...); CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

131. $errors = $validator ->validate($author, null, array('Registration', 'Default')); CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

132. SERVICIOS MECANISMOS... # 7

133. 1ª Sobreescribir parámetro de la clase del servicio CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

134. # app/config/config.yml parameters: # @FrameworkBundle/Resources/config/translation.xml translator.class: AcmeHelloBundleTranslationTranslator CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

135. 2ª Sobreescribiendo el servicio creando otro con el mismo id CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

136. 2ª Sobreescribiendo el servicio creando otro con el mismo id Muy mala práctica CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

137. 3ª Usando CompilerPass CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

138. ¿Qué es un CompilerPass? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

139. Es el modo en que Symfony2 permite interactuar con los servicio y parámetros definidos globalmente y en los bundles cuando han sido cargados, pero antes de que se hayan compilado y optimizados en el DependencyInjection Component (DIC) CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

140. original_service_id: class: OriginalBundleServiceClass CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

141. // src/Acme/DemoBundle/DependencyInjection/Compiler/OverrideServiceCompilerPass.php namespace AcmeDemoBundleDependencyInjectionCompiler; use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface; use SymfonyComponentDependencyInjectionContainerBuilder; class OverrideServiceCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { $definition = $container->getDefinition('original-service-id'); $definition->setClass('AcmeDemoBundleYourService'); } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

142. FORMULARIOS MECANISMOS... # 8

143. Declarado como servicio CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

144. services: app.form.type.task: class: AppBundleFormTypeTaskType arguments: ["@app.my_service"] tags: - { name: form.type } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

145. services: app.form.type.task: class: AppBundleFormTypeTaskType arguments: ["@app.my_service"] tags: - { name: form.type }Como un servicio CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

146. Herencia de Forms CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

147. class GenderType extends AbstractType { ... public function getParent() { return ChoiceType::class; } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

148. ¿Si queremos que un nuevo formulario entre dentro del comportamiento del bundle con alguna nueva funcionalidad? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

149. El bundle tiene que proveer esa “lógica” y permitir su configuración CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

150. ¿Cómo? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

151. fos_user: registration: form: type: FOSUserBundleFormTypeRegistrationFormType CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

152. <service id="fos_user.registration.form.factory" class="FOSUserBundleFormFactoryFormFactory"> <argument type="service" id="form.factory" /> <argument>%fos_user.registration.form.name%</argument> <argument>%fos_user.registration.form.type%</argument> <argument>%fos_user.registration.form.validation_groups%</argument> </service> CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

153. Form Type Extension CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

154. Form Type Extension Documentación CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

155. ¿MUCHA INFORMACIÓN? CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

156. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES ¿ABURRIDO?

157. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES ¿SUEÑO?

158. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES TOMA AIRE ...

159. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES … RESPIRA ...

160. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES … Y PREPÁRATE ...

161. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES ¡QUÉ VIENE LO COMPLICADO!

162. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES ¡RELEVO!

163. ENTITIES & ENTITY MAPPING CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

164. Due to the way Doctrine works, it is not possible to override entity mapping of a bundle. However, if a bundle provides a mapped superclass (such as the User entity in the FOSUserBundle) one can override attributes and associations. Learn more about this feature and its limitations in the Doctrine documentation. http://symfony.com/doc/current/cookbook/bundles/override.html#entities-entity-mapping CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

165. ENTITIES & ENTITY MAPPING # 1 CONCEPTOS BASE

166. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES ORM: Object-Relational Mapping

167. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES ORM ≠ Active Record

168. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

169. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

170. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Tenemos que dar doctrine la información de “mapping”

171. MAPPING FORMATS ENTITIES & ENTITY MAPPING # 2

172. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES XML: <field name="name" type="string" length=100 />

173. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES YML: fields: name: type: string length: 100

174. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES PHP: $classMetadata ->mapField(array( 'fieldName' => 'slug', 'type' => 'string', 'nullable' => true ));

175. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Annotations: /** * @ORMColumn(type="string", length=100) */ protected $name;

176. AUTOMAPPING ENTITIES & ENTITY MAPPING # 3

177. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Automapping: Busca información de mapeo: ● 1º ./Resources/config/doctrine/entityname. [xml | yml | php] ● 2º Annotation en ./Entity

178. En un bundle no se pueden mezclar formatos (annotation, xml, yml) CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

179. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Automapping: Funciona sólo si tengo una única conexión a BD

180. # Doctrine Configuration doctrine: dbal: driver: "%database_driver%" host: "%database_host%" port: "%database_port%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%" charset: UTF8 orm: auto_generate_proxy_classes: "%kernel.debug%" default_entity_manager: default entity_managers: default: auto_mapping: true mappings: AppBundle: type: xml dir: SomeResources/config/doctrine CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES http://symfony.com/doc/current/reference/configuration/doctrine.html

181. INHERITANCE MAPPING ENTITIES & ENTITY MAPPING # 4

182. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Mapped Superclass: No es una entidad, pero participa de alguna manera en el árbol de herencia de clases

183. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Mapped Superclass: Su objetivo es definir información de mapeo que van a heredar otras entidades

184. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Mapped Superclass: <mapped-superclass name="FOSUserBundleEntityUser"> <field name="username" column="username" type="string" length="255" /> ….

185. Table Inheritance CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Herencia de clases reflejada en base de datos

186. 1 - Single Table Inheritance /** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

187. 1 - Single Table Inheritance /** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

188. 1 - Single Table Inheritance /** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES CUIDADO CON LOS CAMPOS NO NULLABLES

189. 2 - Class Table Inheritance /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

190. 2 - Class Table Inheritance /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

191. 2 - Class Table Inheritance /** * @Entity * @InheritanceType("JOINED") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person" = "Person", "employee" = "Employee"}) */ class Person { // ... } /** * @Entity */ class Employee extends Person { // ... } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES PERFORMANCE IMPACT

192. DYNAMIC MAPPING ENTITIES & ENTITY MAPPING # 5

193. Bind mapping files and classes #AcmeMyBundle.php private function buildMappingCompilerPass () { $arguments = array( array( realpath (__DIR__ . '/Resources/config/doctrine-base' )), '.orm.xml' ); $locator = new Definition ('DoctrineCommonPersistenceMappingDriverDefaultFileLocator' , $arguments ); $driver = new Definition ('DoctrineORMMappingDriverXmlDriver' , array( $locator )); return new DoctrineOrmMappingsPass ($driver, array( 'FullNamespace' ) , array( 'your_bundle.manager_name' ) , 'your_bundle.orm_enabled' ); } How to Provide Model Classes for several Doctrine Implementations (link) CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

194. Bind mapping files and classes #AcmeMyBundle.php private function buildMappingCompilerPass () { $arguments = array( array( realpath (__DIR__ . '/Resources/config/doctrine-base' )), '.orm.xml' ); $locator = new Definition ('DoctrineCommonPersistenceMappingDriverDefaultFileLocator' , $arguments ); $driver = new Definition ('DoctrineORMMappingDriverXmlDriver' , array( $locator )); return new DoctrineOrmMappingsPass ($driver, array( 'FullNamespace' ) , array( 'your_bundle.manager_name' ) , 'your_bundle.orm_enabled' ); } How to Provide Model Classes for several Doctrine Implementations (link) CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

195. loadClassMetadata event # Acme/MyBundle/EventLister/MyMapper.php public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) { $classMetadata = $eventArgs->getClassMetadata(); if (null === $classMetadata->reflClass) { return; } if ($this->isTimestampable($classMetadata)) { if ($this->getClassAnalyzer()->hasMethod($classMetadata->reflClass, 'updateTimestamps')) { $classMetadata->addLifecycleCallback('updateTimestamps', Events::prePersist); $classMetadata->addLifecycleCallback('updateTimestamps', Events::preUpdate); } foreach (array('createdAt', 'updatedAt') as $field) { if (!$classMetadata->hasField($field)) { $classMetadata->mapField(array( 'fieldName' => $field, 'type' => $this->dbFieldType, 'nullable' => true )); } } } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

196. loadClassMetadata event # Acme/MyBundle/EventLister/MyMapper.php public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) { $classMetadata = $eventArgs->getClassMetadata(); if (null === $classMetadata->reflClass) { return; } if ($this->isTimestampable($classMetadata)) { if ($this->getClassAnalyzer()->hasMethod($classMetadata->reflClass, 'updateTimestamps')) { $classMetadata->addLifecycleCallback('updateTimestamps', Events::prePersist); $classMetadata->addLifecycleCallback('updateTimestamps', Events::preUpdate); } foreach (array('createdAt', 'updatedAt') as $field) { if (!$classMetadata->hasField($field)) { $classMetadata->mapField(array( 'fieldName' => $field, 'type' => $this->dbFieldType, 'nullable' => true )); } } } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

197. Sonata Doctrine Collector (EasyExtendsBundle) /** * @param array $config * * @throws Exception */ protected function addDoctrineDiscriminators(array $config) { $collector = DoctrineCollector::getInstance(); $purchasableClass = 'ReusableBundleEntityAbstractsAbstractPurchasable'; $collector->addDiscriminator($purchasableClass, 'PRODUCT', $config['class']['product']); $types = $config['class']['purchasable_mapping']; foreach ($types as $type) { list($key, $class) = array_values($type); if (!class_exists($class)) { throw new Exception(sprintf('Class %s not found', $class)); } //Add custom type $collector->addDiscriminator($purchasableClass, $key, $class); } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

198. Sonata Doctrine Collector (EasyExtendsBundle) /** * @param array $config * * @throws Exception */ protected function addDoctrineDiscriminators(array $config) { $collector = DoctrineCollector::getInstance(); $purchasableClass = 'ReusableBundleEntityAbstractsAbstractPurchasable'; $collector->addDiscriminator($purchasableClass, 'PRODUCT', $config['class']['product']); $types = $config['class']['purchasable_mapping']; foreach ($types as $type) { list($key, $class) = array_values($type); if (!class_exists($class)) { throw new Exception(sprintf('Class %s not found', $class)); } //Add custom type $collector->addDiscriminator($purchasableClass, $key, $class); } } CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

199. Relationships with abstract classes and interfaces <?xml version="1.0" encoding="UTF-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"...> <mapped-superclass name="ReusableBundleEntityAbstractsAbstractCartLine"> <id name="id" type="integer" column="id"> <generator strategy="AUTO"/> </id> <field name="quantity" column="quantity" type="integer" nullable="false" /> <many-to-one target-entity="ReusableBundleEntityAbstractsAbstractPurchasable" field="purchasable" /> <many-to-one target-entity="ReusableBundleModelInterfacesCartInterface" inversed-by="cartLines" field="cart" /> </mapped-superclass> </doctrine-mapping> CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

200. Relationships with abstract classes and interfaces <?xml version="1.0" encoding="UTF-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"...> <mapped-superclass name="ReusableBundleEntityAbstractsAbstractCartLine"> <id name="id" type="integer" column="id"> <generator strategy="AUTO"/> </id> <field name="quantity" column="quantity" type="integer" nullable="false" /> <many-to-one target-entity="ReusableBundleEntityAbstractsAbstractPurchasable" field="purchasable" /> <many-to-one target-entity="ReusableBundleModelInterfacesCartInterface" inversed-by="cartLines" field="cart" /> </mapped-superclass> </doctrine-mapping> CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

201. Relationships with abstract classes and interfaces # app/config/config.yml doctrine: # ... orm: # ... resolve_target_entities: AcmeReusableBundleModelInterfacesCartInterface: AcmeAppBundleEntityCart CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

202. PUTTING ALL TOGETHER ENTITIES & ENTITY MAPPING # 6

203. Via MappedSuperClass ENTITIES & ENTITY MAPPING # 6.1

204. FOSUserBundle Sonata * Bundle The bundle provides base classes which are already mapped for most fields to make it easier to create your entity. Here is how you use it: 1. Extend the base User class 2. Map the id field. It must be protected as it is inherited from the parent class. When you extend from the mapped superclass provided by the bundle, don't redefine the mapping for the other fields as it is provided by the bundle. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

205. FOSUserBundle Sonata * Bundle The bundle provides base classes which are already mapped for most fields to make it easier to create your entity. Here is how you use it: 1. Extend the base User class 2. Map the id field. It must be protected as it is inherited from the parent class. When you extend from the mapped superclass provided by the bundle, don't redefine the mapping for the other fields as it is provided by the bundle. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

206. FOSUserBundle Sonata * Bundle The bundle provides base classes which are already mapped for most fields to make it easier to create your entity. Here is how you use it: 1. Extend the base User class 2. Map the id field. It must be protected as it is inherited from the parent class. When you extend from the mapped superclass provided by the bundle, don't redefine the mapping for the other fields as it is provided by the bundle. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

207. FOSUserBundle Sonata * Bundle The bundle provides base classes which are already mapped for most fields to make it easier to create your entity. Here is how you use it: 1. Extend the base User class 2. Map the id field. It must be protected as it is inherited from the parent class. When you extend from the mapped superclass provided by the bundle, don't redefine the mapping for the other fields as it is provided by the bundle. CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

208. FOSUserBundle Sonata * Bundle FOSUser no crea las relaciones entre User - Group Las deja del lado del cliente CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

209. via configuration ENTITIES & ENTITY MAPPING # 6.2

210. simple shopping cart CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Cart - user - createdAt - ... CartLine - cart - purchasable - quantity - ... Purchasable - name - price - ... Product - media - size - ... Ticket - date - ... Book - isbn - ... DeliverableTrait - width - height - weight

211. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Declarar clases abstractas y mapearlas como mapped-super-class

212. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Declarar una interfaz para cada clase

213. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Heredar de la clase abstracta evitando auto-mapping

214. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Hacer configurable acme_reusable: class: product: AppBundleEntityProduct cart: ... cart_line: ... purchasables: ticket: { key: TICKET, class: AppBundleEntityTickets } book: { key: BOOK, class: AppBundleEntityBook }

215. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Hacer configurable acme_reusable: class: product: AppBundleEntityProduct cart: ... cart_line: ... purchasables: ticket: { key: TICKET, class: AppBundleEntityTickets } book: { key: BOOK, class: AppBundleEntityBook }

216. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES Hacer configurable acme_reusable: class: product: AppBundleEntityProduct cart: ... cart_line: ... purchasables: ticket: { key: TICKET, class: AppBundleEntityTickets } book: { key: BOOK, class: AppBundleEntityBook }

217. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES // AcmeReusableExtension.php protected function setConfiguration(ContainerBuilder $container, $config) { $container->setParameter('acme_reusable.model_manager_name', $config['model_manager_name']); $container->setParameter('acme_reusable.orm_enabled', $config['orm_enabled']); $this->configureClass($container, $config); }

218. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $treeBuilder->root('acme_reusable') ->children() ->arrayNode('class') ->children() ->scalarNode('product')->cannotBeEmpty()->defaultValue(self::PRODUCT_CLASS)->end() ->scalarNode('cart')->cannotBeEmpty()->defaultValue(self::CART_CLASS)->end() …. ->arrayNode('purchasable_mapping') ->prototype('array') ->children() ->scalarNode('key')->end() ->scalarNode('class')->end() ->end() ->end() ->end() ->end() ->end() ->end() ->end(); return $treeBuilder; }

219. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES // AcmeReusableBundle.php private function buildOrmCompilerPass(ContainerBuilder $container) { $arguments = array(array(realpath(__DIR__.'/Resources/config/doctrine-model')), '.orm.xml'); $locator = new Definition('DoctrineCommonPersistenceMappingDriverDefaultFileLocator', $arguments); $driver = new Definition('DoctrineORMMappingDriverXmlDriver', array($locator)); foreach ($this->getContainerExtension()->getEntitiesOverrides() as $configKey => $entity) { $container->addCompilerPass( new DoctrineOrmMappingsPass( $driver, array("%acme_reusable.$configKey.class%"), array('acme_reusable.model_manager_name', 'orm'), "acme_reusable.use_default.$configKey" ) ); } }

220. Estrategia CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES // AcmeReusableBundle.php public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) { $this->classMetadata = $eventArgs->getClassMetadata(); $classMetadata = $this->classMetadata; if ($classMetadata->reflClass === $this->cartClass) { $classMetadata->mapOneToMany(array( 'fieldName' => 'cartLines', 'targetEntity' => $this->cartLineClass, 'cascade' => array( 1 => 'all', ), 'mappedBy' => 'cart', 'orphanRemoval' => true, )); } }

221. Un ejemplo https://github.com/gerfigna/ReusableBundle https://github.com/gerfigna/DummyApp CÓMO CREAR THIRD PARTY BUNDLES DE SYMFONY COMPLETAMENTE EXTENSIBLES Y SOBREESCRIBIBLES

222. GRACIAS

223. Alfonso Machado email@alfonsomachado.com almacbe Germán Figna gfigna@gmail.com gerfigna

Add a comment

Related pages

[PHP-Valencia] Propuestas de charlas - Google Groups

Como empecé con Symfony y acabe con festop.com ... compartir la experiencia y los asombros de alguien que se enfrenta por primera vez al mundo de la programación. ...
Read more