Parametros de configuracion de un bundle distribuible

Hola amigos ¡

Para los que no hayais leido los anteriores posts sobre como crear un bundle y distribuirlo a los proyectos, os recomiendo que os paseis antes por aqui.

El truco de hoy consiste en como incluimos parametros de configuracion obligatorios en nuestros bundles distribuibles, para que el usuario que haga uso de este bundle se encargue de definirlos correctamente para el buen funcionamiento del bundle.

Para ello y revisando la documentacion oficial de Symfony explicare paso a paso como se consigue de una forma mas facil y clara (al menos a mi me a costado trabajo comprenderlo).

Imaginemos que nuestro bundle distribuible tiene un servicio que necesita varios parametros para conectarse a un API de terceros y por lo tanto hay que forzar al usuario a definir esa configuracion.

1- Definir los parametros en el DependencyInjection/Configuration.php

/**
 * This is the class that validates and merges configuration from your app/config files.
 *
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/configuration.html}
 */
class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('common');

        // Here you should define the parameters that are allowed to
        // configure your bundle. See the documentation linked above for
        // more information on that topic.
        $rootNode
            ->children()
                ->arrayNode('request_manager')
                    ->children()
                        ->scalarNode('api_url')->end()
                        ->scalarNode('api_user')->end()
                        ->scalarNode('api_password')->end()
                        ->scalarNode('api_token_auth')->end()
                    ->end()
                ->end()
            ->end();

        return $treeBuilder;
    }
}

En mi caso necesito 4 parametros a configurar en mi bundle distribuible llamado ‘common‘ que son:

-api_url

-api_user

-api_password

-api_token_auth

2- Añadir los parametros en el DI y sustituirlos en el servicio que los necesite en el archivo DependencyInjection/CommonBundle (sustituye Common por el nombre de tu bundle)

/**
 * This is the class that loads and manages your bundle configuration.
 *
 * @link http://symfony.com/doc/current/cookbook/bundles/extension.html
 */
class CommonExtension extends Extension
{
    /**
     * {@inheritdoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
        $loader->load('routing_api.yml');
        $loader->load('services.yml');

        $def = $container->getDefinition('my_vendor.request_manager_api');
        $def->replaceArgument(0, $config['request_manager']['api_url']);
        $def->replaceArgument(1, $config['request_manager']['api_user']);
        $def->replaceArgument(2, $config['request_manager']['api_password']);
        $def->replaceArgument(3, $config['request_manager']['api_token_auth']);
    }
}

De esta forma lo que se consigue es sustituir los parametros en la definicion del servicio por los que el usuario configure. Este servicio concreto tiene la siguiente definicion:

services:
    my_vendor.request_manager_api:
        class: MyVendor\CommonBundle\Services\RequestManagerAPI
        arguments:
            - '%api_url%'
            - '%api_email%'
            - '%api_password%'
            - '%api_token_auth%'
            - '@monolog.logger'
            - '@mrjeff.common.serializer'

Este servicio recibe 4 parametros en el constructor que sustituimos en el CommonExtension.

Guardamos los cambios del bundle en GIT  para que cuando lo actualicemos en otro proyecto se descarguen correctamente.

3- Actualizar el bundle en el proyecto donde lo usemos añadiendo la configuracion necesaria para dicho bundle y que nos dara error si no lo hacemos porque son parametros obligatorios. Para ello:

$ composer update

Esto nos instalara la nueva version del bundle con dichos parametros obligatorios

Ahora tenemos que crear esta configuracion con la misma estructura en el archivo app/config/config.yml, y quedaria algo asi:

common:
    request_manager:
        api_url: %api_url%
        api_user: %api_email%
        api_password: %api_password%
        api_token_auth: %api_token_auth%

Y como estamos haciendo referencia a parametros de nuestra aplicacion, tendremos que definirlos en nuestroparameters.yml/parameters.yml.dist tal que:

api_url: http://my-api-url.com
api_email: user@my-domain.com
api_password: XXX
api_token_auth: my-secret-token-is-not-visible

De esta forma nuestro proyecto ya podra usar el bundle con la configuracion necesaria para que funcione correctamente.

Espero haber sido claro y conciso sobre la forma de conseguirlo. Si teneis dudas no dudeis en preguntar o consultar la documentacion oficial para su uso de forma avanzada en http://symfony.com/doc/current/bundles/configuration.html

Un saludo SymfonyDevs ¡¡¡

Recordad compartir este articulo en vuestras redes sociales, no os cuesta nada y puede ayudar a muchos compañeros ¡

 

Anuncios

Obtener versiones de los vendors instalados con Composer

Una de las dudas que he tenido durante mucho tiempo al trabajar con composer es averiguar que versiones de los vendors se han instalado al ejecutar composer install o composer update.

Esta duda me surgia cada vez que al actualizar me daba algun error o “warning” por que algun vendor necesitaba una version superior o distinta de alguna otra libreria que tuviera instalada, y en un momento dado, en lugar de tener puestas que se instalen las que esten en la rama “dev-master”, quizas me interesaba instalar las que estuvieran en un tag o rama concreta para evitar “bugs” que hubieran sido detectados o cualquier otro motivo, es por eso que necesitaba saber que version tenia antes de actualizar mediante el comando “composer update”.

Para ello solamente tenemos que ejecutar el siguiente comando y nos sacara un listado de todos los vendors instalados y de la version de cada uno:

$ composer show -i

Captura de pantalla de 2016-07-13 12:41:25

Si ademas queremos ver para cada vendor, que dependencias tiene y que versiones requieren en forma de arbol solamente tendremos que añadir el parametro -t , tal que asi:

$ composer show -i -t

Captura de pantalla de 2016-07-13 12:40:46

Si en el listado que nos aparece, queremos concretar mas aun, y ver que version hay de un vendor en concreto, podemos ejecutar esto y nos dara la informacion mas detallada:

$ composer show — doctrine/doctrine-fixtures-bundle

composer how vendor

Documentacion:

Si os ha gustado este post, por favor compartidlo y dar “Me gusta” en las redes sociales.

Nos vemos en el siguiente post, symfonyDevs ¡¡

Crear un bundle distribuible para Symfony 2

vendorsHoy voy a explicar como se puede hacer un bundle para Symfony 2 distribuible y descargable para otros proyectos tuyos o de tipo Open Source y que cualquiera lo pueda descargar y usar en su proyecto.

Después de buscar y buscar documentación acerca de crear tus propios bundles y poder distribuirlos para la comunidad, por fin encontré una mini-guia que explica por encima como se puede hacer. Os voy a hacer yo una pequeña explicación de como lo he hecho yo para que podais ir practicando con vuestros bundles.

Empezamos ¡

1 – Crear un nuevo proyecto

Lo primero es crearse un proyecto nuevo vacío de Symfony en el cual vamos a crear un bundle y meteremos ahí todo el código que necesitemos, limpito de cualquier cosa para que no de problemas. Para ello ejecutamos:

*Si tenemos el instalador de Symfony:

> symfony new distributable-project

*Si no, siempre nos quedara composer(global):

> composer create-project symfony/framework-standard-edition distributable-project

Esto nos creara una nueva carpeta con la estructura del proyecto en Symfony. A continuación debemos crearnos un nuevo bundle.

> php app/console generate:bundle

Nos saltara el asistente donde deberemos completar todas las preguntas que nos hace:

-Bundle namespace: Company/YourBundle

Bundle name [CompanyYourBundle]: YourBundle

Target Directory [src/]: (Pulsamos Intro)

Configuration format (annotation, yml, xml, php) [xml]: annotation (Elegid la que mas os guste)

Y listo, ya hemos creado nuestro nuevo bundle.

2 – Crear el repositorio

Lo siguiente que haremos sera crear un repositorio en Github dentro de nuestra cuenta para ir subiendo los cambios que vayamos metiendo y además poder descargar en otros proyectos el bundle desde allí.

2.1 – Github

Accedemos con nuestro usuario en Github y creamos un nuevo proyecto dandole un nombre.

2.2 – Inicializamos nuestro repositorio Git en local

Ahora viene la pieza clave de todo esto. Como lo que queremos es distribuir un bundle, nuestro repositorio Git deberá ser inicializado dentro de ese bundle:

> cd src/Company/YourBundle

>git init

> git add -A

> git commit -m “First commit”

> git remote add origin https://github.com/YourAccount/YourBundle.git

> git push -u origin master

De esta forma hemos metido todo el bundle dentro de Github.

2.3 – Crear el composer.json

Ahora otra pieza clave es crear el archivo composer.json dentro del bundle que queremos distribuir.

> sudo nano src/Company/YourBundle/composer.json

{
    "name" : "company/your-bundle",
    "version": "v1.0.0",
    "description" : "Fill with your description",
    "type" : "symfony-bundle",
    "authors" : [{
        "name" : "Your name",
        "email" : "Your email",
        "homepage": "Your site"
    }],
    "keywords" : [
        "put",
        "your",
        "keywords",
        "here"
    ],
    "license" : [
        "MIT"
    ],
    "require" : {
        "php": ">=5.4",
        "symfony/framework-bundle": ">=2.2",
        "symfony/symfony": ">=2.2",
        //Add your require libraries here...
    },
    "autoload" : {
        "psr-4" : {
            "Company\\NameBundle\\" : ""
        }
    }
}

Este es un ejemplo de como podría ser el composer.json. Podeis ajustarlo a vuestras necesidades según los requisitos de vuestro bundle.

Por descontado, tenemos que subir este fichero al repositorio en Github.

> git add -A

> git commit -m “Added composer json file”

> git push origin master

3 – Probar a instalar dicho bundle en otro proyecto

Ahora solo nos queda usar dicho bundle dentro de otro proyecto, ya sea nuevo o uno que ya estemos desarrollando. Para ello tenemos que añadir en nuestro composer.json del proyecto donde vayamos a usar nuestro bundle distribuido lo siguiente:

 

“require”: {

…,

“company/your-bundle”: “dev-master” //o la rama que queramos

},

repositories”: [{

“type”: “vcs”,

“url”: “https://github.com/YourAccount/YourBundle.git

}]

Ahora solo nos queda actualizar nuestros vendors y ver si efectivamente se ha instalado nuestro bundle como un vendor dentro de nuestro proyecto:

>> composer update company/your-bundle

> … Installing company/yourbundle (dev-master)

Si todo a ido bien, deberíamos tener dentro de /vendor/Company/YourBundle nuestro bundle ya instalado.

Ahora debemos inicializarlo en nuestro archivo appKernel.php para poder hacer uso de el:

$bundles = [

… ,

new Company\YourBundle\YourBundle()

];

Y ya esta ¡ Con esto ya podremos empezar a usar nuestro bundle en cualquier otro proyecto.

En symfony recomiendan seguir una serie de buenas practicas a la hora de hacer un bundle ditribuible y ademas ojear otros proyectos famosos para ver como lo han resuelto ellos. Os dejo aquí el enlace de las buenas practicas para que le pegueis un vistazo.

4 – Resumen

Eso es todo por hoy.

Por supuesto que el composer.json es un pequeño ejemplo y debereis buscar mas información acerca de todas las opciones que os ofrece Composer para ese fichero.

Tampoco cabe decir que, esto son algunas pruebas que voy haciendo yo y que me sirve de recordatorio para en un futuro acordarme como lo hice y poder hacerlo en otros proyectos. Este articulo esta sujeto a errores y fallos como todo en este mundo, asi que se comprensible y no me castigues muy duro. Es más, ayudame a mejorar y si ves algun fallo o sugerencia siempre seran bienvenidos.

Uno de mis objetivos a corto-medio plazo es el de crear un bundle que hice para uno de los proyectos en los que trabaje y distribuirlo ya que no encontre nada sencillo que se pudiera acoplar a lo que necesitaba, pero eso sera mas adelante.

Gracias por leer, y si me haces un favor, comparte este post con tu equipo, o en redes sociales y ayudame a difundir el conocimiento y aprendizaje con Symfony2.

Nos vemos pronto ¡

Fuentes:

-http://stackoverflow.com/questions/21523481/symfony2-creating-own-vendor-bundle-project-and-git-strategy
-https://github.com/LilaConcepts/LilaConceptsBestPracticeBundle/blob/master/composer.json

Actualización(29/02/2016):

Puede ocurrir que si el bundle no es “publico” quizas no encuentre el repositorio de donde descargarse el bundle para nuestro proyecto y composer nos arroje un error en consola al intentar descargase ese “vendor”.

En ese caso, habria que rellenar lo siguiente para decirle la url del repositorio en nuestro composer.json:

"repositories": [{
    "type": "package",
    "package": {
        "name": "shtumi/useful-bundle",
        "version": "2.0",
        "source": {
            "url": "https://github.com/shtumi/ShtumiUsefulBundle.git",
            "type": "git",
            "reference": "2.0"
        }
    }
}],
"require": {
    ...
    "shtumi/useful-bundle": "2.0"
},

Despues hacemos >>composer update -o y listo.

Saludos ¡¡