Symfony in Barcelona

| Comments

Barcelona, one of the best cities in the world.

For you, Symfony lover. Do you know where is Barcelona, right? Well, this is a call for all Symfony lovers who want something special, something really different. Amazing people, amazing food and tons and tons of new experiences with one of the greatest Symfony Communities around the world.

A lot of companies are actually being built in this city, so we really want you with us. No matter your Symfony expertise, no matter how good you really are… in Barcelona only matters one simple thing… How good you want to be. If you want to be one of the bests, then Barcelona can be your new home :)

If you want to know more about it, just send an email to Symfony Barcelona User Group and you will be properly helped to move here with us. The group email is symfonybarcelona@gmail.com

You want to join us, but you don’t know it yet :)

Re-thinking Event Listeners

| Comments

Let’s talk about Event Listeners. Do you know what an Event Listener is?

Well, if you are used to working with Symfony, then you should know what is intended for. If you don’t, don’t hesitate to take a look at the Symfony documentation.

This post aims to start a small discussion about how an Event Listener should look like if we really want to keep things decoupled.

TL;DR

  • If we place our business logic inside the Event Listeners, we will not be able to use this logic from other points, for example sending a “Order created” email by hand from our Admin using a simple button.
  • What we could do is place ALL the logic inside a service that ONLY sends that email, exposing a simple and documented api.
  • Then, considering that this service is injectable using any Dependency Injection implementation, we can inject it into the Event Listener.
  • So, EventListeners are only a point of entry to your service layer

Using Event Listeners

To understand what I am talking about, let’s use an small example to make things more clear…

1
2
3
4
5
6
7
8
9
10
11
Scenario: You buy something in an e-commerce, so, internally, your Cart became 
an Order. Of course, and because user experience is important in that cases, you 
want to send an email to the user with some Order information, so you need to 
send an email to the Customer.

Problem: You want to create this feature in a very decoupled way, of course. The
e-commerce framework provides you that way, by proposing you an event once the
Order is created. You can access the Order itself and the Customer.

Solution: Create a new Event Listener object, subscribed to this event called
order.oncreate, and sending that email.

Let’s see a small example about how this Event Listener should look like. We will follow the simple way, only focusing about sending that email in a decoupled way with the action.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class OrderEmailEventListener
{
    /**
     * We send an email to the Customer once an order is created
     *
     * @param OrderOnCreatedEvent $event Event
     */
    public function sendEmail(OrderOnCreatedEvent $event)
    {
        $order = $event->getOrder();
        $customer = $event->getCustomer();

        /**
         * Send the email
         */
    }
}

And we could use this configuration in our bundle.

1
2
3
4
5
6
7
8
9
services:

    #
    # Event Listeners
    #
    project.event_listener.order_created_email:
        class: My\Bundle\EventListener\OrderCreatedEmailEventListener
        tags:
            - { name: kernel.event_listener, event: order.oncreate, method: sendEmail }

So this could be a simple implementation. I’ve been using it since the beginning of times as this could be considered a good practice. But, during this time doing more and more Event Listeners, some questions have come to my mind.

Decoupling from the Event

Let’s consider that our project has an admin panel. Of course, we should be able to send this email any time we need (for example, our email server was down during the order conversion and we must re-send it). Is this possible with this implementation?

Yes. Let’s do this considering that we have injected our EventListener and this one is accessible locally!

1
2
3
4
5
$event = new OrderCreatedEmailEventListener(
    $order,
    $customer
);
$orderCreatedEmailEventListener->sendEmail($event);

Well, this piece of code will really send the email… but is this implementation enough right? I don’t think so…

This Event should only be dispatched when the real event happens. It has no sense to create a new OrderEmailEventListener instance without using the event dispatcher. This means that, indeed, any Order has been created.

So first of all, creating a new Event out of turn, is not a good practice at all.

For solving this, We could do that.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class OrderCreatedEmailEventListener
{
    /**
     * We send an email to the Customer once an order is created
     *
     * @param OrderOnCreatedEvent $event Event
     */
    public function sendEmail(OrderOnCreatedEvent $event)
    {
        $order = $event->getOrder();
        $customer = $event->getCustomer();

        $this->sendOrderCreatedEmail(
            $order,
            $customer
        );
    }

    /**
     * We send an email to the Customer once an order is created, given the 
     * order and the customer
     *
     * @param OrderInterface    $order    Order
     * @param CustomerInterface $customer Customer
     */
    public function sendOrderCreatedEmail(
        OrderInterface $order,
        CustomerInterface $customer
    ) {
        /**
         * Send the email
         */
    }
}

And then, we could do this

1
2
3
4
$orderCreatedEmailEventListener->sendOrderCreatedEmail(
    $order,
    $customer
);

Much better, right? But is this good enough? No is not.

Decoupling from the Listener

We are using an instance of an Event Listener to send an email. Our analysis could be exactly the same than before… Should we use an Event Listener even when an event is not dispatched?

No we should not.

An Event Listener is an event listener. Listens one event, and that should be all its work. So, we should never inject any event listener, anywhere. Let’s do some refactor here!

First of all, let’s isolate our business logic in a new service. This service will only do one thing; sending this email.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class OrderCreatedEmailSender
{
    /**
     * We send an email to the Customer once an order is created, given the 
     * order and the customer
     *
     * @param OrderInterface    $order    Order
     * @param CustomerInterface $customer Customer
     */
    public function sendEmail(
        OrderInterface $order,
        CustomerInterface $customer
    ) {
        /**
         * Send the email
         */
    }
}

This service has only one mission. Sending this email, no matter what event executes it, no matter its environment. So if we take a look at what the Event Listener implementation should look like now…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class OrderCreatedEmailEventListener
{
    /**
     * @var OrderCreatedEmailSender
     *
     * Order created email sender
     */
    private $orderCreatedEmailSender;

    /**
     * Constructor
     *
     * @param OrderCreatedEmailSender $orderCreatedEmailSender
     */
    public function __construct(OrderCreatedEmailSender $orderCreatedEmailSender)
    {
        $this->orderCreatedEmailSender = $orderCreatedEmailSender;
    }

    /**
     * We send an email to the Customer once an order is created
     *
     * @param OrderOnCreatedEvent $event Event
     */
    public function sendEmail(OrderOnCreatedEvent $event)
    {
        $order = $event->getOrder();
        $customer = $event->getCustomer();

        $this
            ->orderCreatedEmailSender
            ->sendEmail(
                $order,
                $customer
            );
    }
}

Finally, we should refactor as well the way we have defined our service in the DependencyInjection config file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
services:

    #
    # Business layer
    #
    project.business.order_created_email_sender:
        class: My\Bundle\Business\OrderCreatedEmailSender

    #
    # Event Listeners
    #
    project.event_listener.order_created_email:
        class: My\Bundle\EventListener\OrderCreatedEmailEventListener
        arguments:
            - @project.business.order_created_email_sender
        tags:
            - { name: kernel.event_listener, event: order.oncreate, method: sendEmail }

And that’s all. This example is so easy and simple, but I am sure that if you take a look at your project, you will find a lot of logic inside your Event Listeners. Maybe could be a good idea start moving all this logic out of the box, treating these listeners as real entry points, like we do with our Commands, Controllers or Twig extensions.

Defeating Expression Language

| Comments

How beautiful Expression Language definitions are, right? I mean, inserting that complex expressions in a Dependency Injection configuration file is so nice and fast if you need to inject the result of a method in a service (one of the multiple examples we can see)

Let’s see a simple example of how we use this library.

1
2
3
4
5
6
7
8
9
10
services:

    #
    # My managers
    #
    some_manager:
        class: This\Is\My\Manager
        arguments:
            - @=service("another_manager").someCall("value")
            - @=service("yet_another_manager").getInjectableInstance(parameter("my_parameter"))

This is not a bad idea, really, but because we are engineers and we should have as much information as possible in order to be able to choose between the best option, always, I will show you another way of defining this piece of code.

Let’s do that!

Factories

Remember the Factory pattern in Symfony2 post I wrote some time ago? I talked about how this pattern can be implemented in your Symfony projects.

Well, just for your information, most of your Expression Language definitions can be nicely done using Factories.

Let’s reproduce the same example using factories.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
services:

    #
    # My managers
    #
    some_manager:
        class: This\Is\My\Manager
        arguments:
            - @my_injectable_value
            - @my_injectable_service

    my_injectable_value:
        class: StdClass
        factory:
            - @another_manager
            - someCall
        arguments:
            - value

    my_injectable_service:
        class: This\Is\My\Injectable\Class
        factory:
            - @yet_another_manager
            - getInjectableInstance
        arguments:
            - %my_parameter%

Dependency

Take a look and realise that we’ve removed a package dependency from your project, as you don’t need symfony/expression-language anymore, and your DIC definition will be easily exportable to another format if someday is needed.

Reflexion

Is Expression Language a bad choice? Well, only you should be able to know if using this library is a good choice or not, because only you know your needs and your resources, but every time you add a new Expression Language line, just ask yourself…

Can I use simple DI definitions here? Is the only way I can do that?

Crowdfunding Soundtrack - El Evento

| Comments

This post is written in Spanish, but I will translate it soon. Stay tuned for the translation :D

Finalmente, y después de unas semanas cociendo la idea, valorando pros y contras y el impacto que puede tener en mi vida personal lo que os voy a contar, he decidido tirar para delante la idea más estúpida que se me ha podido ocurrir en los 29 años de edad que tengo.

En pocas palabras, a modo introductorio y declarativo.

La idea es hacer una iniciativa CrowdFunding durante un periodo de 3 meses y conseguir el dinero suficiente para cumplir los siguientes objetivos.

  • Dado una lista de spotify donde he agrupado mis temas favoritos de bandas sonoras, que una Orquestra Sinfónica interprete los temas en un evento público.
  • Yo, por mi parte, estudiar durante un periodo de tiempo dirección de orquestra básico. Evidentemente lo justo para entender los conceptos necesarios y defenderme.
  • Dirigir yo, personalmente, uno de los temas.
  • Donar absolutamente todo el dinero que se recaude en el evento (entradas, dinero que no se haya gastado después de la iniciativa) al desarrollo y la investigación de la sordera. Aún estoy buscando organización, universidad o instituto.
  • Cumplir uno de mis retos personales, y con ello, ayudar a que otros cumplan los suyos.

Si en este punto sigues leyendo sin pensar que estoy mal de la cabeza, recapacita; lo estoy. Aún así, eso no debería impedir que uno haga lo que realmente quiere hacer, pues que seríamos sin sueños estúpidos, solo estúpidos sin sueños.

Los temas musicales

Podéis encontrar el enlace de la lista de Spotify en el parágrafo anterior (debo decir que falta un track de “La Roca” inexistente en Spotify. A continuación adjunto dicha lista.

  • The chase – The Rock
  • I don’t think now it the best time – Pirates of the Caribbean – At world’s end
  • A dark knight – The dark knight
  • Flight – Man of Steel
  • Comming back around – How to train your dragon
  • Spectres in the fog – The last samurai
  • The all spark – Transformers
  • My name is Lincoln – The island
  • War – Pearl Harbor
  • Chevaliers de Sangreal – The Da Vinci Code
  • Sound the Buggle now – Spirit, Stallion of the Cimarron
  • Run Free – Spirit, Stallion of the Cimarron
  • The Wheat – Gladiator
  • The Battle – Gladiator

Cada uno de estos temas compone la banda sonora de mi vida.

Crowdfunding

Algunos os preguntaréis… bueno Marc, y todo esto cuanto vale? Pues aún estoy trabajando en ello, pero es bastante dinero. Calculo que alrededor de unos 200.000 euros para ser específicos.

No tengo aún muy claro como voy a configurar los niveles de colaboración (hay distintos mínimos de aportaciones, y cada uno de ellos te proporciona un retorno de cierto nivel. En este caso el retorno será reducido para maximizar el volumen de donación final)

Lo que si tengo claro es el tipo de público al que va la iniciativa.

  • Patrocinadores – Empresas que quieran hacer que esto sea posible. Serán los niveles de patrocinio más altos.
  • Individuales – Todo aquel que quiera hacer una donación a la investigación y quiera que el evento ocurra podrá hacerlo mediante dicho evento. A partir de uno de los niveles de patrocinio, habrá entrada gratuita al evento.
  • Aportaciones – Fuera del evento crowdfunding también se aceptarán donaciones, aunque es preferible que todas entren por el evento.

La plataforma

Finalmente, y después de solucionar un dilema mental que tenía entre si hacerlo internacional o local, he decidido ejecutar el evento a nivel español. Para esto trataré de utilizar la plataforma Verkami dado que tengo muy buenas referencias.

El porqué

En realidad, últimamente estoy hablando mucho de emprendedores y de intentar todo aquello que crees que deberías intentar. La idea de hacer eventos me gusta mucho, de hecho soy organizador de un evento en Barcelona bastante chulo, aunque local, por el momento.

El hecho también que me guste la música hasta límites indecentes hace que quiera poner toda la carne en el asador, sin preguntarme demasiado el porqué hago todo esto. Creo ser un músico frustrado y siempre me quedará el intentar, por todos los medios posibles e imposibles, cumplir alguno de mis hitos indiscutibles.

El dirigir una orquestra es uno de ellos. Desde hace muchos años.

Y como he dicho alguna vez, el mejor consejo que me han dado nunca en mi vida ha sido “No lo intentes”, por lo que, haciendo caso omiso a las personas vacías de locura, no lo voy a intentar, lo voy a hacer.

Próximos pasos

  • En unos días voy a colgar la iniciativa en Verkami.
  • Hacer ruido. Mucho ruido. Demostrar que todo es posible.
  • Buscar organización o similar para donar todo el dinero ganado.
  • Trabajar bien el evento y todas las piezas componen organizar un acontecimiento de estas características.
  • Encontrar un grupo de gente motivada con la idea que quiera ayudarme una vez se cierre la iniciativa con resultado positivo.
  • Seguir trabajando en la idea, hasta el final.

Si quieres estar actualizado sobre el evento, puedes seguir-me en Twitter o suscribirte a mi blog, desde donde voy a escribir de forma periódica todas las actualizaciones sobre el evento.

Saludos a todos.

Lazy Commands in Symfony

| Comments

Have you ever had this scenario?

1
2
3
4
5
$ php app/console doctrine:database:drop --force
$ php app/console doctrine:database:create

    [Doctrine\DBAL\Exception\ConnectionException]
    An exception occured in driver: SQLSTATE[42000] [1049] Unknown database 'mydatabase'

Well, it happens and I will tell you why.

Command as a Service

Since Symfony version 2.4 you can define your controllers and commands as services. This is so useful as long as you need to treat your classes as much decoupled as possible. You can check some information about how to define them as services in Symfony Documentation.

Then, let’s figure out that our command is intended to check an entity from your database. Of course, your command should be as empty as possible, placing all your business logic inside your service layer (this is not the only strategy, of course, but there is no strategy where you lace your logic inside your command).

Then, using commands as services, you will have this

  • ObjectManager as a service (or Repository)
  • Your service, intended to do whatever you need to do, for example, check that your entities are all enabled. Your ObjectManager or Repository will be injected here
  • Your command, intended to work as the simple layer between your cli interface and your service layer. Your service will be injected here.

Given this schema, when we require this command through the DI Container, of course a new Service instance will be created in order to inject it through the command constructor, and the object will have to be created as well to be injected inside the service.

It means create a new connection to the database. Fair enough till now :)

Commands list

Let me show you some lines of code. This method is placed in a class called Application inside the bundle FrameworkBundle. This class is intended to add the possibility of adding Commands as services in the main Application class of Command Component.

Symfony\Bundle\FrameworkBundle\Console\Application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected function registerCommands()
{
    $container = $this->kernel->getContainer();
    foreach ($this->kernel->getBundles() as $bundle) {
        if ($bundle instanceof Bundle) {
            $bundle->registerCommands($this);
        }
    }
    if ($container->hasParameter('console.command.ids')) {
        foreach ($container->getParameter('console.command.ids') as $id) {
            $this->add($container->get($id));
        }
    }
}

Oh, wait… what?

Register a command means instantiate it! So if we have a command with a service injected which has an object manager injected… then we have a problem. If we don’t have the database created we will not be able to create it using the Doctrine command.

~ironic~ Perfect scenario for deployment ~/ironic~

Using Lazy services

Of course we should find a solution for this scenario, in order to be able to call this command when is needed.

When we define as lazy a service, this is not instanced when is injected, but only when is accessed. You can find some information about lazy services in Symfony Documentation.

The point here is to define our service intended to work with the model as lazy. The result will be that when we instance the Command, then a proxy object is created and injected with all the service information.

Because our command will not be used as long as we don’t need it, then the service will not be instanced and the ObjectManager not created. We will be able to list all the commands, and finally, call php app/console doctrine:database:create properly.

Implementation

Some tips here…

  • Why instancing all services when we just need them to be listed? Is it really necessary? Doing than we are forcing some service to be defined as lazy just because of it, and this is not and will never be a good practice.
  • If the command needs to be instanced to be listed, and assuming that this information should could be cached, then, is it necessary to call the constructor? We could get the class, build the object using \ReflectionClass and request all the needed information.

I invoke the community for some feedback on that. If this is really a need for some people, we should do some push (and organize us for an implementation, maybe) to change this implementation for next Symfony 3 version.

Feedback, feedback :)

Montando a Pau Garcia-Milà

| Comments

Hace apenas unas semanas, en un diario nacional español, aparecía un escrito inquietante, al menos a simple vista, sobre algunos puntos discutibles alrededor del ya más que conocido emprendedor Pau Garcia-Milà.

Post original

Para los interesados, decir que el propio Pau respondió días más tarde en su blog, respondiendo a ciertas afirmaciones.

Respuesta de Pau

En dicho escrito, se analizan algunos de los puntos importantes y críticos por los que nuestro protagonista ha pasado durante los últimos años, dejando al lector la tarea de leer a simple vista un gran elenco de comentarios de algunas personas cuya opinión se les fue requerida, entiendo yo.

Antes de todo decir escuetamente que yo recuerdo a Pau en sus inicios, cuando empezó a ser un personaje público. Añadir también que, tras un tiempo teniéndolo en mi top of mind como referencia y recordándolo como simplemente, brillante, y por alguna razón que no logré entender durante mucho tiempo, pasó a ser mi vende-humos favorito.

Éste no ha hecho nada. Solo habla de ideas. Yo también tengo muchas ideas! Mirad! Un percebe con alas! Fundemos una empresa que se llame Engonga associated y conquistemos el mundo. Ah, no, esperad, que con una idea uno no tiene ni para empezar… Nada, vuelvo al mundo real, en mi sofá de pensar.

Pero gracias a Dios, a veces en la vida te encuentras a grandes personas que te bautizan de golpe como ex-hater, y te das cuenta que el odio es, habitualmente, proporcional a la envidia, y quién mejor que una persona a la que envidias para empezar a admirar.

He aquí mi pequeño paso hacia la redención relativa. Mi objetivo, la completa madurez. :)

Reflexiones

En este post, y como persona emprendedora que creo ser, añado algunas respuestas a comentarios del post original sin entrar demasiado al detalle.

Ha empezado cosas, pero no ha terminado ninguna. Son habilidades distintas. Creo que es un grandísimo comunicador y tiene éxito con eso, pero como emprendedor no lo ha demostrado

En realidad esta frase es la que más me duele a mi, como emprendedor que soy. Hace un poco más de un año y medio que trabajo en un proyecto, y siento decir que, por ahora, no he demostrado nada a nadie. ¿Eso me convierte en menos emprendedor?

Trabajo un mínimo de 80 horas semanales en un proyecto de código libre de índole internacional, llevo una comunidad de desarrolladores Web local cuyos eventos son referenciados en todo el mundo, tengo unos cuantos proyectos personales también de código libre utilizados en multitud de empresas reales, y en el tiempo más libre de mi tiempo libre, soy ponente en eventos alrededor del globo.

¿Demostrado? Si se refiere a si he vendido alguna empresa por 20 millones de euros, pues no… ¿Emprendedor? Hombre, pues creo que algo si, ¿no?

Debo decir con gran aplomo que ningún emprendedor tiene que demostrar nada a nadie para serlo, y es que la palabra emprendedor, uno, se la gana con el trabajo y el sudor, no con los éxitos (y menos midiendo los éxitos en cifras o en rondas de inversión).

Emprendedor es el que crea sitios de trabajo, el que crea equipos sanos y empresas con ideales humanos. Emprendedor es quien no se rinde a pesar de sus innumerables fracasos. Emprendedor es el que tras un “No lo vas a conseguir” ve un “Debes conseguirlo”.

Emprendedor es quien persigue lo que todo el mundo ha dejado por imposible.

Está claro que Pau es un gran comunicador y también está claro que ha tenido éxito con ello, pero seamos realistas y no nos dejemos llevar por la envidia y el descontrol: Un chico que a los 28 años ha tratado de levantar 3 empresas (la cuarta recientemente) y haya vendido una, cuales fueran las condiciones de dicha transacción y cuya información no me interesa en absoluto, absolutamente nadie puede tacharle de no ser emprendedor (evidentemente mencionar sus libros, charlas y todo el ecosistema que ha creado alrededor).

Yo me quito el sombrero, al menos, por haberlo intentado.

Pero está claro que es más simple y fácil entrar en la crítica destructiva y sensacionalista. Nos alimenta mucho más el ego interior y nos hace sentir más fuertes a nosotros, seres iluminados. Pero la realidad es que tras la fachada de un comunicador como Pau hay, en la mayoría de los casos, una mente brillante y un trabajo constante. Otra cosa es tener interés en conocer este trabajo y valorarlo como se debe.

Que difícil es hacer esto.

pero hay grandes emprendedores en España que son menos mediáticos. Mi experiencia me dice que el éxito de un emprendedor es inversamente proporcional a sus seguidores en Twitter. No suele ser mediático.

El número de seguidores que tiene una persona en Twitter es directamente proporcional a varios elementos, como el campo en que esta persona haya decidido ser emprendedor (no es lo mismo un químico que un informático) o el carácter comunicativo que dicha persona tenga en su personalidad (No es lo mismo una persona expansiva y sociable que una persona itrovertida y tímida).

Algunos ejemplos rápidos.

  • Bill Gates, co-fundador de Microsoft, 21.8 millones de followers
  • Steve Wozniak, co-fundador de Apple, 402 mil followers
  • Elon Musk, fundador de Tesla y PayPal, 2.06 millones de followers
  • Jimmy Wales, fundador de Wikipedia, 110 mil followers
  • Charles W. Hull, inventor de la impresora 3D (nada, es posible que solo revolucione el modelo industrial en los próximos años)… 0 followers
  • Steve Chen, co-fundador de Youtube, 3599 followers

Podría seguir, pero carece de sentido categorizar a estos emprendedores como ejemplos de qué es tener poco éxito… Personas como ellas hacen que la sociedad avance en campos como la medicina, la tecnología o el bienestar.

Evidentemente esto no quita que hay emprendedores de éxito abismal que, por decisión propia, han preferido quedarse en segundo plano en temas sociales. Y esta es una decisión igual de factible, correcta e indiscutible que cualquier otra.

Tenemos que animar con credibilidad. Lo bueno es que nos fijemos en los que ya han tenido éxito, porque es lo que cuenta: si no, se genera la sensación de que esto no es serio

Comentario propio del que lo tuvo todo muy fácil.

Precisamente la gente necesita ver a personas que lo intentan a pesar de que las cosas van en contra, y aceptar que fallar nos hace aún más humanos. La credibilidad se demuestra con los caminos que uno hace a lo largo de su vida, la credibilidad la marca la honestidad y la ley del esfuerzo, sea cual sea el resultado final.

Adjudicar seriedad al grado de éxito es, a mi parecer, una falta de respeto para los que aún no hemos conseguido nada, aún lo intentemos con todas nuestras fuerzas. Y lo que me parece más grave, me parece una falta de respeto innecesaria, un comentario fuera de lugar y una doctrina tóxica para una sociedad desanimada y desorientada como es la nuestra.

Reflexión, por favor.

Conclusión

Emprendedor, no emprendedor. Da igual, lo importante para una sociedad es el esfuerzo. Hable en público, tenga seguidores en Twitter o toque la pandereta con los ojos cerrados y en sol sostenido, son elementos personales, injuzgables más allá de uno mismo, y menos cuando el impacto social es positivo, mires por donde lo mires.

Repito una frase con la que empezaba mi post dado que encuentro interesante y reveladora.

el odio es, habitualmente, proporcional a la envidia, y quién mejor que una persona a la que envidias para empezar a admirar

Mi consejo siempre es el mismo. Que el miedo a intentar cosas no os impida no hacerlas, y que simplemente os hagan más cautos. No os dejéis llevar por la mediocridad social a la hora de juzgar a personas que trabajan por su futuro y sed críticos más allá de 4 medios de comunicación de intenciones puramente marketinianas.

Dicho esto, sed felices y volad cometas.

Visithor, Testing Your Routes Without Pain

| Comments

Do you like testing? I like testing. Well, in fact I like testing once I have understood how the engine I am using works. Until this moment, everything is a completely disaster.

And because this learning curve, many of my personal projects have reached an MVP without any type of testing environment. And sincerely, I don’t really like this scenario.

Many years ago I was thinking about a simple and fast tool to test specific routes, expecting specific HTTP codes and providing an easy environment of ensuring properly your HTTP layer.

So… I present you Visithor, a PHP based library that provides you this functionality, with a simple configuration definition and a very easy way of installation.

Let’s see an example.

Execute Visithor

With this lines of code you will download Visithor, ready to be used.

1
2
3
4
$ git clone git@github.com:visithor/visithor.git
$ cd visithor
$
$ build/visithor.phar

You can download it as a global executable

1
2
3
4
5
$ git clone git@github.com:visithor/visithor.git
$ cd visithor
$ cp build/visithor.phar /usr/local/bin/visithor
$
$ visithor

Creating your configuration

As easy as it seems. This is a random configuration file with a random set of urls. If your visithor.yml file is placed in the same folder than you are, then you don’t have to specify its location. Otherwise, please use the [—config|-c] option.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
defaults:
    #
    # This value can be a simple HTTP Code or an array of acceptable HTTP Codes
    # - 200
    # - [200, 301]
    #
    http_codes: [200, 302]

urls:
    #
    # By default, is there is no specified HTTP Code, then default one is used
    # as the valid one
    #
    - http://google.es
    - http://elcodi.io

    #
    # There are some other formats available as well
    #
    - [http://shopery.com, 200]
    - [http://mmoreram.com, [200, 302]]
    - [http://nonexistingurl.com, [200]]

In this case, the execution result is 0

Executing Visithor

Once you have it installed and you have a configuration file, let’s see what happens!

1
2
3
4
5
6
7
8
9
10
11
12
13
$ visithor visithor:go

Visithor by Marc Morera and contributors.

Configuration read from /var/www/my/project

OK [200] http://google.es
OK [200] http://elcodi.io
OK [200] http://shopery.com
OK [200] http://mmoreram.com
KO [404] http://nonexistingurl.com

Time: 1002 ms, Memory: 15.5Mb

As you can see, we have an error. We expect a 200 code when we call http://nonexistingurl.com but the real response is 404, so it fails. Then, the execution result is 1.

Integrations

You can integrate Visithor with your Symfony projects right now. I expect some other integrations will be available soon.

If you use this bundle, then you will be able to define your routes not with the final path but with the route name and a bunch of parameters, as it is shown here.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
defaults:
    #
    # This value can be a simple HTTP Code or an array of acceptable HTTP Codes
    # - 200
    # - [200, 301]
    #
    http_codes: [200, 302]

urls:
    #
    # This Bundle adds some extra formats
    #
    - [store_homepage, 200]
    - [[store_category_products_list, {'slug': 'women-shirts', 'id': 1}], 200]
    - [[store_category_products_list, {'slug': 'another-name', 'id': 1}], 302]
    - [[store_homepage, {_locale: es}]]

This project is being so useful for me, I expect it will be for you as well :)

Travis

Of course, you can add Visithor in your travis tests suite. You can use the [—format|-f] option to change the format and use dots

1
2
3
4
script:
    - bin/behat -fprogress --tags="~javascript"
    - bin/phpunit -c app
    - bin/visithor --format=dots visithor:go

Behat and Data-test

| Comments

Tests should be as robust as possible.

I think you will agree with me with that phrase. If your tests are too coupled with your implementation, a simple modification of your code will need the modification of your tests, and that’s so annoying, right?

I’ve using Behat for the last months in my projects, and as soon as you dominate the tool it becomes really useful to make sure that any future refactoring or change will break these user stories you have already defined and tested.

So, thinking about coupling I saw this method in Behat implementation.

1
2
3
4
5
6
7
8
9
/**
 * Presses button with specified id|name|title|alt|value.
 *
 * @When /^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/
 */
public function pressButton($button)
{
    //
}

What do you think? Do you think that this method helps people to really decouple the tests from their implementation? I don’t really think so… Let me explain.

Design v Test

My question is… should the frontend of your website be aware of the how your Behat tests are built? In my opinion, nope.

Your tests should live in a simple layout on top of your application, emulating some cases and ensuring that your users will be able to do what they should be able to.

Said this, you cannot build your tests depending on final implementation. So, whats the problem there?

HTML Properties

Dear backend. Between you and me… we have nothing to do with some html properties, and you know that… This is the frontend world and we have nothing to say about that :)

So why referring to html property id in your Behat cases? It has no sense indeed. You will need to change all your tests every time your frontend says… refactoring time!!, and we have no enough time for this, right?

So… first property strikethrough.

Translations

Dear backend (again, yes). Between you and me… we have neither nothing to do with translations, and we both know as well that translations is something really changeable (that means evolving… so yes, that are good news indeed), so how about coupling your fantastic tests to translations?

How do you really know that your submission button copy will be always send? What if someone thinks that is better submit? The point is that you don’t know that, and you will never do.

If you don’t want to do that, please, don’t use title, alt nor value. All these html properties are very used to changing if you use them properly, so if you have your site in several countries with some modifications, you will not be able to reuse any scenario.

Bad choice again.

Symfony Forms

We still have the name property, a very important property for forms and references inside your DOM. In fact, too much important to be an starting point for your test cases.

For example, you can fill a value in a Symfony Form input, but you know what? Symfony Forms define themselves how their forms are named, in order to know how to build them again after submitting them.

If you use name property, and for example you have different teams for developing your applications and for testing them, you will add an extra and useless coupling layer between them. This means more points of failure and, at the end, less agility.

Not valid.

So what?

Well, this is a problem really easy to solve. Have you ever meet the property data-test? You can build any property starting with data- and will be okay. So, in that case you can safely reference your elements using it.

  • Your front-ends have nothing to do with it. They will see data-test and will know that they belong to the testing layer. Then, they will ignore it, and even if they decide to refactor a page, they will preserve this property (if they can and want, of course) and your tests will not have any reason to expire.
  • Your tests will have nothing to do with translation, product people and other tactical nor strategical changes.
  • People of your team will now have a unique way of referencing visible elements of your application.

That’s so nice!

Implementation

Well, after this analysis, I propose to add data-test in all pre-defined selectors in order to allow people to uncouple from implementation.

1
2
3
4
5
6
7
8
9
/**
 * Presses button with specified id|name|title|alt|value|data-test.
 *
 * @When /^(?:|I )press "(?P<button>(?:[^"]|\\")*)"$/
 */
public function pressButton($button)
{
    //
}

Please, I would like to have some feedback, specially if you are used to working with Behat or any kind of Behavioral Testing Tool.

Thanks and enjoy your day!

Reflexiones De Un Pequeño Emprendedor

| Comments

Ya hace un poco más de un año que estoy a bordo de este proyecto llamado Elcodi. Para los que no conozcáis el proyecto, solo unas simples pistas…

Hace bastantes semanas que tenía ganas de formular una entrada al blog de éste índole. Normalmente intento hacer mis posts en inglés, pero me pareció adecuado hacer éste en español, dado que lo hago desde una perspectiva más de emprendedor que no de técnico.

Debo decir brevemente que no me gusta la palabra “emprendedor”. Durante los últimos años se le ha dado un significado demasiado Trending y se le ha asociado a figuras de visibilidad pública. Desde mi punto de vista, emprendedor es aquel que se desvive por su trabajo, sea cual sea, y que lo entiende como una forma de vida. Utilizaré esta palabra desde esta perspectiva

Os quiero contar de forma bastante breve lo que, después de éste tiempo, considero son algunos puntos importantes de un emprendedor. Considerando que soy una persona formada de forma pura en el mundo técnico y que he experimentado una transición un poco brusca hacia el mundo de la emprendeduría empresarial, quiero dejar claro que estos son mis puntos de vista dada mi trayectoria, por lo que es probable que algunos no sean mundialmente compartidos por todos.

La Idea

Tengo la sensación que se le asigna demasiado valor a la idea. Como se suele decir, la idea no vale nada. Una semilla tal vez, nada más. El auténtico valor reside en considerar ésta misma idea importante durante el tiempo adecuado. El mérito está en mantener la expectativa y la motivación en su punto más álgido lo suficiente como para que la ejecución tome la mínima forma como para que sea algo real.

Es en este punto es donde te das cuenta que lo más fácil en realidad fue tener dicha idea, y que lo más cómodo hubiera sido dejar de lado la motivación para hacer algo más significativo a corto plazo.

El auténtico emprendedor entiende de raíz que dicho esfuerzo, con su parte proporcional y proporcionada de suerte, ayuda y café, siempre acaba siendo más rentable para todo el mundo a largo plazo.

El Desarrollo

Todo proceso que te lleva de la mano de ésta idea amorfa hasta la definición y ejecución de la misma requiere un esfuerzo que, en la mayoría de los casos, te aísla de forma inconsciente de todo lo demás.

Quien dice emprendedor, dice luchador Luchador cuya soledad le invade en su lucha Y en medio del silencio oye su respiración Y entiende su existencia

Es un gran ejercicio de descubrimiento personal. Te das cuenta de lo que puedes, de los que sabes y de lo que eres capaz. Y cuando crees que no puedes saber más, te das cuenta que apenas sabes nada. Aprendes a aprender mientras aprendes a desaprender.

Hasta aquí un intento descarado y fracasado de poesía. Ahora vuelvo a la simple y terrenal prosa, más digna de mi focalizado potencial…

Ha sido el año más duro y a la vez delicioso de mi carrera profesional. He aprendido a lidiar con mentes completamente distintas a la mía, y esto me ha dado cierta capacidad de análisis teniendo múltiples puntos de vista, muy necesario para cualquiera con alguna aspiración empresarial.

Debo decir que a día de hoy sigo sin entender muchas cosas, algo que me hace seguir siendo lo suficiente ingenuo como para estar demasiado ilusionado por todo.

De todas formas, el camino sigue, y espero poder seguir teniendo este análisis absolutamente positivo año tras año… significará que seguiré en mi lucha por buscar algo realmente grande, aún habiéndolo encontrado.

Las Ganas

Y en éste camino, debo reconocer que el concepto ganas, mundialmente conocido por motivación, suele experimentar un movimiento sinusoidal más típico de una montaña rusa del siglo XXI.

Mi único apunte sobre este tema, y es algo que yo he llegado a aprender con el tiempo, es que una buena técnica para poder sobrevivir a todo esto es teniendo en cuenta que tu cabeza no tiene siempre la razón. Me refiero a que hay días en los que los pensamientos negativos parecen la única materia generada por tu astuto cerebro.

Bien, ignóralo.

¿Días de estos en que, literalmente lo ves todo negro? Bien, quédate en casa, tómate un respiro y descansa. Te darás cuenta que ignorando estos pensamientos darás paso de nuevo a otros mejores. Seguro que el día siguiente puedes seguir como si nada.

Debo decir que a mi me funciona. Mis ganas suelen regenerarse después de un alto desgaste debido a una frenética entrega o a una época difícil.

El Equipo

Y a todo esto hay que añadirle el ingrediente más importante.

El equipo.

De manual. Esta frase suele salir de forma prefabricada de la boca de cualquier persona que quiera ser algo trending. De todas formas, siempre he pensado que había otra forma de hacer las cosas que se saliera un poco de la tradicional a la que nos tienen acostumbrados.

Debo decir que soy de ideas fuertes, y desde que salí de la carrera y durante mi corta trayectoria profesional me he cruzado con líderes y con jefes. Debo añadir de forma categórica que hubiera seguido a los líderes hasta los confines del fracaso, mientras que no hubiera dedicado un solo segundo a buscar el éxito al lado de ningún jefe.

Y es que los líderes hacen girar el mundo. O dicho mejor, los líderes hacen que todos hagamos girar el mundo de una forma optimista y valiente.

Dicho esto, y tras haberme cruzado con un poco de todo, decidí que era hora de poner a prueba mis teorías. El mejor equipo hace la mejor empresa, y para que sea así, la mejor empresa debe tener el mejor equipo. Y debo reconocer que, si de por sí no es nada fácil buscar gente para un equipo potente, menos lo es si tienes en cuenta ciertos parámetros de convivencia, motivación y encaje.

Con el tiempo me he dado cuenta que algo merece gran cantidad de mi fuerza vital y esfuerzo es buscar un equipo con el que pasar las horas disfrutando de mi trabajo. Éste equipo será tu mano derecha y tu mano izquierda. Será tu apoyo en los mejores y peores momentos, y será tu mayor crítico cuando necesites de una voz sincera y dura.

Mi equipo.

El mejor equipo del mundo.

Conclusión

Como podéis ver, y termino, Elcodi es un proyecto sano. Debo reconocer que estoy abrumado por el equipo humano que tenemos en la empresa. Nuestra máxima prioridad es que en el día a día del equipo sea lo más agradable posible, y que el trabajo se convierta en algo realmente fascinante.

Por mi parte estoy satisfecho por todo, con perspectivas de incalculable valor y rodeado de, literalmente, los mejores compañeros de viaje que uno podría tener.

Mucha suerte y mucha fuerza a todos los que habéis decidido que el camino más largo y duro es el que mejor encaja en vuestra vida. Os mando mi energía y mis mayores deseos de éxito.

PDD Manifesto

| Comments

Hi everyone.

I’ve been talking about PDD for a while. Pragmatism-Driven Development, a methodology that takes in account the development environment and the circumstances before of deciding the tools and the architectural decisions of your projects.

Pragmatic Driver Development

Some people asked me for the manifesto. And because I think that some people will appreciate another way of doing things more realistic, I started the first draft of that manifesto some time ago.

After discussions with the ecosystem where I work, finally, I can release the first version of the manifesto.

These are just some ideas, not a dogma, so please, don’t use them as the only way of doing things, making the same mistake again and again.

I will appreciate as well your constructive comments, so the real objective of that kind of things are, indeed, to make people more comfortable with their projects.

The more useful projects, the more knowledge shared, the more fun for everyone.

Be happy!

PDD Manifesto

Good practices

  • All good practice is only good if it is.
  • A good practice is good, indeed, if the executor knows it enough.
  • Otherwise, a good practice becomes always a bad practice; Ipso Facto.

Bad practices

  • All bad practice can be accepted, if, and only if, is well known by the executor.
  • Knowing them means to have a strict control of your current bad practices.
  • The absence of this control turns any bad practice in a poorly executed project.

Analyzing

  • Every project must be analyzed according to needs and own tools.
  • Accepting that these needs and tools are static is accepting their failure.
  • Starting a project destined to fail is the worst practice of all.

Evolving

  • These needs can change along the time, so the tools have to change as well.
  • Internal and staff training is essential for the evolution of a team, and therefore a project.
  • All components of such team must evolve to self-acceptance and practice of good practices.