Purchasable Architecture

It’s been a long time since our last blog post, but we have some very good news to share with you.

During the last months we’ve been working on new projects for Elcodi. Some of them are not available yet, but some of them have been merged recently. This post is basically to show you what has changed and improved in Elcodi and to spread the word about our new Roadmap for the next months. This roadmap is exactly the same one, but with different dates due to these new changes.

Purchasable

From almost the beginning of the life of our project, and because the entity product and related ones are one of the main topic of all e-commerce projects, we have tried to manage how abstract should be all this entity family. For example, should we create a Purchasable interface to be used in Cart and Order? Should we use only one entity to manage all kind of purchasable entities? Should we use traits for that? How many interfaces?

Like all software projects, this is a question that can be solved in several ways. One of these ways is analyzing our needs and creating a software model from these needs. Of course, this is the right way if you have time, money and resources. Another way is just by trying one approach. Working with it, dealing with it as much as possible, and listening yourself, looking for your needs. This approach needs time, only time, and the capacity of refactoring, of action, of change.

Well. This one, the last one, is the approach we’ve used some time ago. At the beginning, using two entities, Product and Variant, to define both purchasable types has been a good choice. And it’s been like this until now. Since some months ago, one of the most asked questions have been… well, how can I create my own purchasable?, and with this approach, was not simple, was not logical.

Well. We have reacted and a new Purchasable implementation is here.

Instead of dealing with products and variants, Elcodi’s cart is going to deal only with purchasable implementations. We’ve started using Doctrine CTI (Class Table Inheritance) to allow other implementation coexist with current ones, so if you need to work with your own purchasable implementation… just create it, implement this interface and it’s done :)

That simple!

Elcodi v2.0.0

Our Roadmap was clear. Elcodi v1.1.0 had to be tagged the first of January, but we really wanted this feature to be available and in master as soon as possible.

A change like that can needs a major version change, and even we know that is too soon to create a new major version, we think that this is the best for the project and the best for our evolution.

We are not specialists in maintaining several branches at all, so we will not support versions v1.0 actively. What we will do for sure is supporting somehow all projects that want to go from v1.0 to v2.0. At this moment we don’t have any tool for that but, if there are some requests, we will do it for sure.

So, if you need us, just Ask for help

New Roadmap

Of course our roadmap has changed, but only with dates.
Let’s take a look at the new plan.

v2.1

  • Released the 1st of June, 2016
  • Search engine using ElasticSearch will be introduced here
  • Product API will be added
  • User API will be added
  • Cart API will be added
  • Some Media improvements, like new media types
  • New shop template will be added
  • Back panel documentation
  • Code Coverage of all components and bundles over 60%
  • Templates documentation

v2.2

  • Released the 1st of September, 2016
  • Multistore. Switch between stores in the same installation
  • Shop API will be added
  • New shop template will be added
  • New tempates and plugins website with tons of cool new stuff for all Elcodi and Bamboo implementations
  • Code Coverage of all components and bundles over 70%

v2.3

  • Released the 1st of January, 2017
  • We will remove all deprecated code
  • Bamboo will use Symfony3 and maybe new version of Doctrine
  • Updated all dependencies
  • Marketplace
  • Elcodi community site will be created.
  • Unknown bunch of new and cool stuff
  • Code Coverage of all components and bundles over 80%

Try us

You can start using Elcodi in a very very fast way, just… DO IT!

Install Elcodi

Last thoughts

Well, Elcodi project is keep doing. Remember that we need a lot of help, and we really want you to test our project, take a small tour around what we offer and if you like, only if you like…

Suggest Our Next Features

For sure some of you already know about Elcodi’s first online meetup. It will be next November 25th at 6:00pm GMT+1, and for joining us, you only have to enter our gitter room, say hello, and join our discussion about Elcodi, Symfony and E-commerce.

One of the topics we’ll talk about will be our roadmap. We’ve configured it just by thinking what features would be nice to have in the future present, but Elcodi is a community-first project, so we would love to bring you some voice, at least to help us deciding about what features we should put our effort the next months.

Of course, your voice is the most wanted voice in Elcodi. Make sure you really say what you think, so we can improve day by day.

For that, from today until the start of the meeting, you will be able to join our room and show us your proposals. This wednesday we will vote each one, and the most voted will be part of our v1.3 roadmap, creating a group of volunteers for that development.

Propose a feature

Vote the features

  • Enter our gitter room next November 25th at 6:00pm GMT+1
  • Say hello! :)
  • Vote your more exciting features (before starting the meetup, you will have the link for voting)
  • Join the development!
  • Enjoy as much as possible ;)

We really look forward to see you all there! By sharing this post you will really help us creating this community :)

Elcodi Online Meetup

Elcodi is growing so fast.

Elcodi is an E-commerce platform based on Symfony components. Is composed by some PHP Components, by some Symfony Bundles and by a Full-stack project based on the Symfony Framework. A all-in-one E-commerce solution, splitted in several isolated parts.

We started this project two and a half years ago, and our community is getting bigger day after day. That’s great because the project grows as well as long as more people start using it (more needs, more ideas, more contributions, more fun).

We will start doing monthly meetings online in our Gitter channel. Right now, some people is daily contributing to Elcodi and having some nice and constructive talks, but we want to make it even bigger.

Our first monthly meeting will be next November 25th at 6:00pm GMT+1. This meeting will be hosted by the core team of the project, Marc Morera and Emanuele Minotto.

Agenda

This meeting will be focused on creating some working groups for the next weeks. Depending on the people attending at the meeting, we will create more or less groups, focused on some parts of the application.

These are the points we will talk about.

  • Tasks for next version v1.1.
  • Documentation update and revision.
  • Test coverage for v1.1.
  • Community action. How to make as many people as possible involved.

Attendees

Maybe you’re asking yourself if this meeting is for you.

Well, it depends on your interests. If your job is all about E-commerce, even if your Symfony skills are no so good, then you should join us. You will have the opportunity to share some time with really skilled people and to know the way we have created this project.

If your interest is open source, join us as well. Elcodi is a young project, focused on finding the right equilibrium between pragmatism and clean architecture. We use Event-Driven Architecture and annotations at the same time. Do you want to know why? What are our thoughts? Ask us :)

In other words, if you want to have a nice time with some really good people, then you definitely should join us and say a big Hello!

Remember, next November 25th at…

  • Mexico City, La Havana – 11:00am
  • London – 05:00pm
  • Barcelona, Paris, Warsaw – 06:00pm
  • Moscow – 08:00pm

Looking forward to see you all there!

Meet Deliberry

As an open source project, whenever a project touches success using our technology, our pride feelings are indescribable. Each project based on Elcodi means a different and unique story for us. Each one as much important as the best.

But in this case, we want to talk about one of our first projects using Elcodi as the main technology. And we want to do that because we really love this company, and the way they want to really change the world. Like we want.

The name of the project is Deliberry, and they are placed in Barcelona.

Deliberry

They deliver your supermarket purchases in less than one hour. This is great, right? They used Elcodi components as the main technology, and our Bamboo project as the basis for their front engine and their admin site.

They started using Elcodi some months ago, when we were working on version v0.5.0. These days, Elcodi was very unstable, so day after day, we introduced new changes, affecting strongly the BC standard. Even with that scenario, Deliberry has been always our first tester for new versions, working side by side with us, and reporting us as many issues as possible.

And believe us… For a new open source project… this is the best gift we’ve had.

Changing the world with us

One of the biggest things that makes this project really awesome, is that they are really changing the world.

We are very used of thinking that, for a company than simply delivers food, changing the world means delivering it faster and better. Of course, this is great, but your are only changing part of the world, and probably, the part than less need a change.

Deliberry works side by side with an organization name Cáritas. This organization helps people suffering of social exclusion (yes, in Spain we have a lot of this, sadly). People without many resources, that cannot enjoy whether the purchase is fast or not: they cannot even buy anything.

Deliberry help this organization by hiring people from this organization for buying people’s food, or delivering it. And everything, in less than one hour.

Isn’t it fantastic?

Deliberry TV1

Deliberry is our hero. Thanks for being part of the Elcodi history, and keep changing the world, we will try to do the same :)

Try Deliberry

At the moment, Deliberry is only working on Barcelona, but if you are living here, we encourage you to try it. And even better, we want to give you a nice discount for your next purchase.

Use the discount code ELCODI, and with a minimum purchase of 40€ you will recieve 10€ of discount. And if is your first time, the delivery fees will be free!

Hurry up! You can use this discount during this year :)

Change the world too

We are looking for projects that want to change the world, somehow, somewhere. If you have in mind one of them, consider the usage of Elcodi. Our biggest effort goes to providing happiness and joy between E-commerce developers, mastering amazing projects full of creativity and innovation.

Only this scenario turns on the best projects ever, and only the best projects ever can change this world.

So… we are looking for you.
Join us!

Install Elcodi

In order to decrease the time of installation of Elcodi, and with our new Beta release

Bamboo v1.0.0-beta3
Elcodi v1.0.0-beta3

we’ve been working on how fast you can create a new shop in your localhost and start tuning it. It is important right?

New elcodi:install command

Elcodi is Symfony based. This means that to make it work you need to execute some commands in order to do some common actions (create database, update schema, populate fixtures…)

To improve this step, we have created a new console command in order to decrease this installation time and the number of steps required to play with your localhost.

4 steps to rule them all, and less than 3 minutes to start with Elcodi.

1
2
3
4
$ curl -s http://getcomposer.org/installer | php
$ php composer.phar create-project elcodi/bamboo bamboo -sdev
$ cd bamboo/
$ php app/console elcodi:install

As soon as Bamboo is installed, you can create a temporary server by using the PHP built-in server

1
$ php app/console server:run

And check your Bamboo installation in your browser by accessing to http://localhost:8000.

GD instead of ImageMagick

Because we have implemented some needs using adapters, we have implemented a new image resize adapter based on the PHP GD engine. The good thing is that GD is already installed in all standard PHP versions, so you don’t really need to install any extra library.

This new adapter has been proposed and accepted as the default one, and of course, ImageMagick adapter can be still used by changing the configuration value.

1
2
3
4
elcodi_media:
    images:
        resize:
            adapter: elcodi.media_resize.imagemagick

Location repository

In Elcodi you can populate new countries. With this new installation command, and by using --country option, you can add already generated countries in seconds. You can see available pregenerated countries in our LocationDumps repository. We will generate all countries over time.

If you want to use the demo application, make sure you install Spain. All already built addresses are from Spain. Otherwise, feel free to build your Location database as you need.

Imagine you want to install France and Italy. Well, you should do that

1
$ php app/console elcodi:install --country=FR --country=IT

Elcodi Beta Is Here

… and we did it.

It is something really amazing. We’ve finally reached our first Beta stage. After more than 1 year of hard and non-stop work, we have tagged our first beta version in order to provide some stability to all Elcodi installations.

What means Beta

If you read some literature about software versions, you’ll find that there is always a set of pre-defined steps based on the stability of the project

  • v1.0.0-alpha1: Hey developer! We’re building it but we’re not ready to be used in production. Possible big BC breaks, incremental set of features and less communication. Careful!
  • v1.0.0-beta1: Hey developer! Well, we think that we’re done. We think that we’re done with features so we aim to stabilize the version. Testing and documentation is part of the development here. C’mon!
  • v1.0.0-RC1: Hey developer! Tested enough, so… how about make this package stable? Lets purpose a set of BC promises and let’s make possible the usage of ^1.0 in composer.
  • v1.0.0: Hey everyone! We’re here! This package is stable. We think that we’ve no many issues here, so don’t hesitate to using us in your projects.

Of course, some people or projects will understand these steps in a different way, but in Elcodi, this is the idea.

Communication

For the last months, we have been focused on developing.

  • elcodi/elcodi
    • 1.616 commits
    • 239 Issues closed
    • 586 PR accepted
    • 21 Contributors
  • elcodi/bamboo
    • 1.763 commits
    • 49 Issues closed
    • 450 PR accepted
    • 21 Contributors

Of course, developing have been our priority and we’ve lost the opportunity of showing the world our great work. Our communication has been poor and insufficient because of our lack of time. And we know that this aspect of the project need to change.

Since today, we’ll return with our “A week of Elcodi”. Each week we will document all our work. Each project using Elcodi will have a lot of feedback. Each change affecting the BC compatibility will be announced in a properly way and since today, we will take care about all projects by creating and promoting our own community events and User Groups around the world.

Remember all the core team is in Gitter so if you have doubts and you want to talk about any aspect of the project, don’t hesitate to talk with us :)

Follow us on Twitter to join us!

Reaching RC

We’re done with features. We have developed a nice Plugin infrastructure that will be documented as soon as possible, in order to externalize all extra implementations. Our maximum priority right now is to finish what we begin one year ago.

The project is pretty stable, being used in some projects in production, selling and working properly. For example deliberry.com, a company based in Barcelona that is actually growing day by day, based in Elcodi.

We’re proud!

We’ll have soon a great directory with projects based on Elcodi, so if your company is Elcodi based, please, show us your case :)

So, for the next 2 months, we will support all projects based on Elcodi, with a big testing layer with more Unit, Functional, Behavioral and Response testing.

We will add tons of documentation showing how to do every single thing inside the Elcodi world and finally, as soon Elcodi is stable enough, then we will tag the first RC version.

Test us!

We are Open Source, and supporting us will never mean paying us. Elcodi is free because is born from and for the community, so the best way to promote Elcodi is talking about it.

Elcodi is not only E-commerce and Symfony, is about developing, sharing, enjoying and improving. Each member of the community is important and we will demonstrate this not only with words but with a strong layer of support.

As soon as the community will grow, we will lead the creation of user groups around the world. We will show how we work and what using Elcodi is not only an experience but a way of understanding the E-commerce development.

Test us now and share your thoughts, your non-valuable feedback, or just say hello :)

Translating Elcodi

Hi everyone.

This is a call to the multi language fairy. Our project is still learning some new and nice languages. Bamboo talks English, Spanish, Catalan and some French, but we want to be a project for everyone in this world, no matter where you live, no matter what you talk.

We are looking for some contributors to maintain some other interesting translations. Indeed, all of them!

  • Euskal
  • Galego
  • Deutsch
  • Italiano
  • Português
  • Nederlands

We are looking for smaller translations, for those shops that want to provide specific and local languages.

  • Irish
  • Andalúz
  • Sardu
  • Esperanto

Finally we are looking for some popular and fictitious languages. We want to be for everyone, remember?

  • Klingon
  • Elvish
  • Dwarf language
  • Lorem Ipsum
  • Random language

If you have any interest in translate the application here, please tell us something nice here or keep in touch with us at gitter.

Enjoy your week :)

Introducing the Directors in Symfony

Have you ever worked with Entity Managers, Repositories or Factories in Symfony? Yes, for sure you’ve done that. Indeed, if you work with entities in your project, these type of objects will be your daily, so we want to introduce you a new concept, born in Elcodi project and created in order to simplify the management of an entity inside a service, fixture or functional test.

Please, welcome the Director class.

Director

Imagine you have a service called CartWrapper. This service is meant to be a wrapper of a cart, and its behavior is that easy.

  • If you require an existing user’s cart, retrieve it from database and return it
  • Otherwise, create a new Cart, save it and return it.

Let’s see a small implementation of such service.

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
 * CartWrapper
 */
class cartWrapper
{
    /**
     * @var EntityManager
     *
     * Cart entity manager
     */
    protected $entityManager;

    /**
     * @var CartFactory
     *
     * Cart factory
     */
    protected $cartFactory;

    /**
     * @var CartRepository
     *
     * Cart repository
     */
    protected $cartRepository;

    /**
     * Construct
     *
     * @param EntityManager  $entityManager  Entity manager
     * @param CartFactory    $cartFactory    Cart factory
     * @param CartRepository $cartRepository Cart repository
     */
    public function __construct(
        EntityManager $entityManager,
        CartFactory $cartFactory,
        CartRepository $cartRepository
    )
    {
        $this->entityManager = $entityManager;
        $this->cartFactory = $cartFactory;
        $this->cartRepository = $cartRepository;
    }

    /**
     * Load cart
     *
     * @param UserInterface $user User
     *
     * @return CartInterface
     */
    public function loadCart($user)
    {
        $userCart = $this
            ->cartRepository
            ->findOneBy([
                'user' => $user
            ]);

        if (!($userCart instanceof CartInterface)) {

            $newCart = $this
                ->cartFactory
                ->create($user);

            $this
                ->entityManager
                ->persist($newCart);

            $this
                ->entityManager
                ->flush($newCart);

            $userCart = $newCart;
        }

        return $userCart;
    }
}

As you can see, this services needs 3 dependencies, and would be difficult to reduce this number in order to reduce the complexity of the class. This service is intended to do one single thing.

What is the strategy here? Do you know what the Facade pattern is, right? Well, the way for solving this amount of classes is creating a new facade called Director, intended to provide a small set of usable methods simplifying the management of the entities.

Let’s see the implementation of this class. You can find the real implementation in elcodi/core.

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
namespace Elcodi\Component\Core\Services;

use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;
use UnexpectedValueException;

use Elcodi\Component\Core\Factory\Abstracts\AbstractFactory;

/**
 * Class ObjectDirector
 *
 * This object is a facade for these different persistence-related elements
 *
 * * Object Manager
 * * Repository
 * * Factory
 *
 * Allows final user to manage in a simple way an entity or a set of entities.
 * Provides a reduced (but useful) set of methods.
 */
class ObjectDirector
{
    /**
     * @var ObjectManager
     *
     * Manager
     */
    protected $manager;

    /**
     * @var ObjectRepository
     *
     * Repository
     */
    protected $repository;

    /**
     * @var AbstractFactory
     *
     * Factory
     */
    protected $factory;

    /**
     * Construct
     *
     * @param ObjectManager    $manager    Manager
     * @param ObjectRepository $repository Repository
     * @param AbstractFactory  $factory    Factory
     */
    public function __construct(
        ObjectManager $manager,
        ObjectRepository $repository,
        AbstractFactory $factory
    ) {
        $this->manager = $manager;
        $this->repository = $repository;
        $this->factory = $factory;
    }

    /**
     * Finds an object by its primary key / identifier.
     *
     * @param mixed $id The identifier.
     *
     * @return object|null Fetched object
     */
    public function find($id)
    {
        return $this
            ->repository
            ->find($id);
    }

    /**
     * Finds all objects in the repository.
     *
     * @return array Set of fetched objects
     */
    public function findAll()
    {
        return $this
            ->repository
            ->findAll();
    }

    /**
     * Finds objects by a set of criteria.
     *
     * Optionally sorting and limiting details can be passed. An implementation may throw
     * an UnexpectedValueException if certain values of the sorting or limiting details are
     * not supported.
     *
     * @param array        $criteria
     * @param array|null   $orderBy
     * @param integer|null $limit
     * @param integer|null $offset
     *
     * @return array Set of fetched objects
     *
     * @throws UnexpectedValueException
     */
    public function findBy(
        array $criteria,
        array $orderBy = null,
        $limit = null,
        $offset = null)
    {
        return $this
            ->repository
            ->findBy(
                $criteria,
                $orderBy,
                $limit,
                $offset
            );
    }

    /**
     * Finds a single object given a criteria.
     *
     * @param array $criteria The criteria.
     *
     * @return object|null Fetched object
     */
    public function findOneBy(array $criteria)
    {
        return $this
            ->repository
            ->findOneBy(
                $criteria
            );
    }

    /**
     * Create a new entity instance, result of the factory creation method
     *
     * @return Object new Instance
     */
    public function create()
    {
        return $this
            ->factory
            ->create();
    }

    /**
     * Save the instance into database. Given data can be a single object or
     * an array of objects.
     *
     * This method will persist and flush given object/array of objects
     *
     * @param object|array $data Data to save into database
     *
     * @return object|array Saved data
     */
    public function save($data)
    {
        if (is_array($data)) {
            foreach ($data as $entity) {
                $this
                    ->manager
                    ->persist($entity);
            }
        } else {
            $this
                ->manager
                ->persist($data);
        }

        $this
            ->manager
            ->flush($data);

        return $data;
    }

    /**
     * Remove the instance from the database. Given data can be a single object or
     * an array of objects.
     *
     * This method will remove and flush given object/array of objects
     *
     * @param object|array $data Data to remove from database
     *
     * @return object|array Removed data
     */
    public function remove($data)
    {
        if (is_array($data)) {
            foreach ($data as $entity) {
                $this
                    ->manager
                    ->remove($entity);
            }
        } else {
            $this
                ->manager
                ->remove($data);
        }

        $this
            ->manager
            ->flush($data);

        return $data;
    }
}

This implementation provides us a simple set of actions for our entities (maybe the most used).

  • find(…)
  • findAll()
  • findBy(…)
  • findOneBy(…)
  • create()
  • save()
  • remove()

This implementation is so useful for many scenarios, but in our case what we found is that using Directors, our tests are reduced in many ways (less lines of code, less complexity, more effectiveness), and the fixtures are totally improved, focusing on the most important thing: our business logic.

Directors as a service

To use a Director as a service you need to define your repository as a service as well, assuming that your factory is already a service called cart_factory and assuming as well that we will work with the default entity manager doctrine.orm.default_entity_manager (not a good practice, but let’s suppose it is in this example).

Let’s see how to define your repository as a service.

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

    #
    # Doctrine Repository
    #
    cart_repository:
        class: Doctrine\Common\Persistence\ObjectRepository
        factory:
            - @elcodi.provider.repository
            - getRepositoryByEntityNamespace
        arguments:
            - My\Cart\Namespace

You will find the service elcodi.provider.repository inside the Bundle elcodi/core-bundle. This bundle is not coupled to any Elcodi functionality so you can use it in your own projects as a set of isolated features.

Finally, let’s create the Director definition by using the factory pattern.

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

    #
    # Directors
    #
    elcodi.director.cart:
        class: Elcodi\Component\Core\Services\ObjectDirector
        arguments:
            - @doctrine.orm.default_entity_manager
            - @cart_repository
            - @cart_factory

Take in account that each entity will have it’s own Director instance, so this is why we use the factory pattern here.

How can we use the new Director service in our first CartWrapper implementation by changing and improving the services dependencies? Let’s 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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
 * CartWrapper
 */
class cartWrapper
{
    /**
     * @var ObjectDirector
     *
     * Cart director
     */
    protected $cartDirector;

    /**
     * Construct
     *
     * @param ObjectDirector $cartDirector Cart Director
     */
    public function __construct(ObjectDirector $cartDirector)
    {
        $this->cartDirector = $cartDirector;
    }

    /**
     * Load cart
     *
     * @param UserInterface $user User
     *
     * @return CartInterface
     */
    public function loadCart($user)
    {
        $userCart = $this
            ->cartDirector
            ->findOneBy([
                'user' => $user
            ]);

        if (!($userCart instanceof CartInterface)) {

            $newCart = $this
                ->cartDirector
                ->create($user);

            $this
                ->cartDirector
                ->save($newCart);

            $userCart = $newCart;
        }

        return $userCart;
    }
}

Elcodi is fully based on the usage of Directors. This does not mean that we must use Directors everywhere. Sometimes you need to use only one of the wrapped objects, and in that case you must inject them one by one, so please, before using this new object think about it, think about the pros and the contras and be responsible about your implementation.

Don’t hesitate to comment about what do you think about this feature.

Have a nice day!

First Stable Release

Hi there everyone.

The Elcodi core team is glad to announce that next June 1st, we will tag the first stable release of the project (Elcodi will be still based on Symfony, you know how much we like Symfony and its community…)

Elcodi v1.0

  • Until this day, we’ll finish stabilization of all packages
  • We will work so hard to finish a documentation for all of you
  • All available features will be covered by unit, functional and behavioral tests, using PHPUnit and Behat 3.0
  • After v1.0 we will start working on v3.0. This new version will be released next November in order to be compatible with Symfony v3.*. It means as well that this new version will introduce some BC Break, of course.

So, we have less than 2 months to stabilize Elcodi package, and we need your help.

Some days ago, we announced the Elcodi Bug Hunting, remember? Well, initially this contest was during this past March, but we have decided to enlarge the period of the contest until June 1st, the day of the release.

Until now, we have received some help from some people. Special thanks for them.

But we need some extra help in order to accomplish our goal.

Win the MacBookPro

Easy and super-fast. Do you want to win the MacBookPro? Easy, just help us with some fast actions and you will be able to win the Apple Macbook Pro 2014 Retina (of course, with an Android/Ubuntu/Windows alternative or any geeky stuff with same price)

After that you will have 5 points, enough to access to the MacBookPro raffle.

A little bit more…

Are you interested in E-commerce and do you like Symfony? Well, there are some extra things you can do to help. You can win the battle and win the Ipad Air

  • [Download, install and try Bamboo)[http://elcodi.io/docs/quick-start.html)
  • If you find any kind of issue, please open an Issue in our repository and report it to us.
  • Oh, you know how to fix it? That’s wonderful! Create a Pull Request and be a collaborator of the project!
  • We are elaborating a documentation… maybe you could help us looking for some typo issues or creating new content…
  • Have you tried Elcodi and you want to express the world how much excited you are? Great! Do a post in your blog and explain us what did you create with Elcodi!
  • Elcodi is an international project, so we are looking for people able to translate Bamboo to all languages (even in Klingon and Esperanto!). Are you proud of your language? Well, help other people of your country for using this project :)

All this actions will give you some extra points.

Of course, if you need help, all Elcodi Core team will gladly help you. Just enter Elcodi Gitter room and say hello :)

Have a nice day!

Elcodi Changes Its Technology

This is an official statement from Elcodi Team.

This post was an April Fools joke. Elcodi will be based on Symfony for a long time. We love Symfony.

After some nice months using Symfony in our project Elcodi, and after many reflections on how to increase the project quality, we’re proud to announce that we are moving to Ruby on Rails.

Until version v0.6.* we will continue evolving our code for these people who is nowadays using Elcodi in their projects, but after that, we will move all our code to Ruby.

We love rails

If you need some information, feel free to keep in touch with us in our Gitter account