To bundle or not to bundle, that is the question.

123 views
Skip to first unread message

Myke Hines

unread,
Jun 11, 2012, 7:02:18 PM6/11/12
to vespol...@googlegroups.com
All,
We have been having a discussion on IRC about the current and future use of Bundles to provide features on the Vespolina project. One school of thought is to provide separate bundles for each functionality, for example ProductDownloadableBundle, ProductConfigurableBundle, and ProductTimedBundle. Each bundle would be installed from the composer.json for each deployment. Another school of thought is to provide as many features into a single ProductBundle. Obviously anything in that bundle could be customized, but all Controllers, Tests, Models would exist in that single bundle.

Personally I believe that providing 6-10 bundles to handle the entire platform provides a lower point of entry for new users, simplifies pull requests, bug fixes, and testing. This is the direction that the Symfony CMF project took and is also what most commerce packages provide.

We'd like some feedback from everyone on the desired direction of the project.
Thanks!

Luis Cordova

unread,
Jun 11, 2012, 8:00:00 PM6/11/12
to vespol...@googlegroups.com
Sounds like it is reasonable to follow the example from cmf project. Also User bundle provides a lot of functionality, it becomes chubby but makes sense as it allows a lot of functionality. Could you detail what is the advantage of handling things more separately? Perhaps it is easy to bring up specific things with greater flexibility?

David Buchmann

unread,
Jun 12, 2012, 2:54:14 AM6/12/12
to vespol...@googlegroups.com, Myke Hines
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

hi,

as one of the core developpers of the cmf, i wanted to point out that
we recently moved the code out of the symfony-cmf/symfony-cmf
repository. this is now just a meta-package requiring almost all of
the cmf bundles.

our philosophy is to provide chunks of features that strongly belong
together in one bundle to reduce the number of bundles, but not put
too much into them either. for example we have separate bundles for
routing, menu and content, plus one that provides for multilanguage
support in all those bundles.

with composer, it is much less of a hassle to have several bundles and
dependencies and allow the user to only get what he really needs.
having everything in one bundle and using configuration to load
services or not is somehow the same in less elegant. however, too many
bundles make it harder to understand again.

in the vespolina case, i think having just a ProjectBundle sounds
scary to me. maybe you could do for the example a ProductBundle and a
VirtualProductBundle that groups download handling, time limit and
other things you need only for service products and not for physical
products. then another bundle about CustomizableProduct to handle
options (t-shirt size, color, the message to print onto the mug,
whatever) when ordering, and so on...

cheers,david
- --
Liip AG // Agile Web Development // T +41 26 422 25 11
CH-1700 Fribourg // PGP 0xA581808B // www.liip.ch
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk/W55IACgkQqBnXnqWBgIupWgCfWQ7jutL8KAly5H7jyP4KlL8s
JN8AoLZOwxd4GCz4cHhMx5Ik7ekBr3oc
=4okL
-----END PGP SIGNATURE-----

Richard Shank

unread,
Jun 12, 2012, 5:02:54 AM6/12/12
to vespol...@googlegroups.com
One of the earliest goals for Vespolina was to make it small enough, that you could use it for about any type of site, within any type of site and grow it to an enterprise level. We also decided it would be a Symfony2 product using MongoDB, at the very least for products, with hopes for everything being persisted in MongoDB. So in the beginning, to do that meant breaking things up into bundles, based on the role they play in the ecommerce workflow. We had one project that basically needed just a product bundle that would show the products available from a company, with no purchasing or even a hint of price. Just a catalog of products. We also had another project that was a funnel for a large number of companies, with a wide range of products, that needed some level of inventory tracking, plus ways of determining how different parts of the order would be shipped. Additionally, with Daniel living more in the enterprise sphere had a different set of requirements.

As we move forward, we kept finding that keeping things separate in bundles either meant we had little control of typecasting in interfaces, dependencies between bundles or just a giant mess. I wasn't happy so I started looking for solutions. Around the same time, I also had a conversation with Kris Wallsmith about moving part of the code into a library to be used outside of Symfony. I saw the importance of that, and starting thinking about how to make that happen with Vespolina. I was formulating some ideas around all of these things but never quite hit upon it. Then this discussion happened https://groups.google.com/forum/?fromgroups#!topic/symfony-devs/BAYC8E6TGsk In the discussion, babereli mentioned this video http://confreaks.com/videos/759-rubymidwest2011-keynote-architecture-the-lost-years It filled in the missing pieces for me. I started working on moving the app out of the bundles. You can see some of that work, https://github.com/vespolina/VespolinaCore and https://github.com/vespolina/VespolinaProduct . Composer is the final piece of the puzzle that can provide us a middle ground on this Bundles vs picking only what you need for your site.

I think its a good idea to move from the current 25 down to 6 or 10. In the irc conversation Myke suggested this "StoreBundle|CoreBundle (includes store configurations), ProductBundle (all product types, inventory), CheckoutBundle (cart management, checkout workflow), SalesBundle (includes Orders, Invoices, Fulfillment, Discount rules (coupons) and mangement). all bundles contain admin tools on managing themselves and are integrated from the corebundle" I think this is a good place to start the conversation.

I will not go into all of the bundles but I will show how I see the ProductBundle being organized. First, think about Symfony2 as just being a way of handing request/response and code to help facilitaing what goes on during that cycle. Bundles are first class citizens, so from my perspective, they are just tools in the Symfony2 system to interface and interact with your application code. With that perspective, here is my proposal.

This would be the ProductBundle directories/classes
VespolinaProductBundle
  - Command
  - Controller
    ProductAdminController.php
  - DependencyInjection
    - Compiler
      ProductHandlerFactoryPass.php
    Configuration.php
    VespolinaProductExtension.php
  - Form
  - Recources
    - config
    - doc
    - views
  VespolinaProductBundle.php

What is missing from this are Entity, Document and Model. This includes interfaces, base classes and managers. This code is application specific and should live outside of the tool to help interface with the application (the Bundle). By moving this code out, we can then use factories to decide, which types of Products we need in our online shops. Benefits of moving the app code out of the bundle is we can then look at it from the perspective of what it is trying to accomplish w/o being mentally bogged down with details that are really not part of the code. This makes the code easier to test and maintain. A big added benefit of doing this is the ability to use Vespolina within ANY php5.3+ website. 

Vespolina\Core holds interfaces and base classes for all Entites (maybe managers or handlers, I'm not sure yet) used in any Bundles. This eliminates the worries of having to include an entire bundle just to get the interface for inventory or fulfillment.

By moving the app of of the Bundle, we would have a Vespolina\Product with the Manager interface and class, ProductHandlers for dealing with specific product needs and a Gateway to deal with persistence. The Gateway concept is a big break away from what we currently do, but I think it brings a major benefit. Right now, if you look at the Document and Entity directories in most Bundles (within and outside of Vespolina), they are generally just extending the class in the Model directory, solely for the sake of the db mapping. I'm working on a solution that will map based on telling the location of the Entity class, not on an entire Bundle. Then we can use the same class for any persistence layer. The Gateway is basically a CRUD interface to be used in the manager. There is a Gateway class for the preferred persistence layer (or even a different layer for different classes, but no time soon). This removes any temptation of writing code based on how things are stored, in either the Manager or the Entity. I've started work on the Gateway idea, but it has a way to go.

So based on this information, here is how it would work. The idea is everything is set through configuration.

The project configuration might look something like this in your project's app/config/vespolina.yml file

vespolina_product_bundle:
    manager: Vespolina\Product\Manager\ProductManager
    gateway: Vespolina\Product\Gateway\DoctrineMongoDBGateway
    GenericProduct:
        class: Vespolina\Entity\Product
        handler: Vespolina\Product\Handler\Generic
    SubscriptionProduct:
        class: Vespolina\SubscriptionProduct\Entity\SubscriptionProduct
        handler: Vespolina\SubscriptionProduct\Handler\ProductHandler
    EventProduct:
        class: Vespolina\EventProduct\Entity\SubscriptionProduct
        handler: Vespolina\EventProduct\Handler\ProductHandler
        alias: my_event

In your project composer.json file you would have
"require": {
   ...
    "vespolina/product-bundle": "dev-master", // this would include "vespolina/core" and "vespolina/product" in its requirements
    "vespolina/product-subscription": "dev-master"
   ...
}

When you do any type of actions on a product, it happens through the manager
$productManager->createProduct("Vespolina\Entity\Product");
$productManager->createProduct("SubscriptionProduct");
$productManager->createProduct("my_event");

In the sandbox, we could as many products enabled as possible. We could provide different starting apps, based on the need of the site.

I believe that we can do a someone gradual transition from what we currently have over to this proposed system. If this approach seems to have merit, then I'll lay out some of those ideas.

I know this is a lot of information, but from my perspective it is a solution to a number of challenges, it keeps Vespolina very flexible, w/o being so damn intimidating with too many bundles. It also gives us the added benfit of being valuable outside of the Symfony2 community.

Willem-Jan Zijderveld

unread,
Jun 15, 2012, 6:24:41 PM6/15/12
to vespol...@googlegroups.com
Hi all,

I do like the idea of decoupling parts of the code. But I also think we should be careful with this.
Even though composer solves a lot of issues about maintaining the code, I do think that, without composer, people should still be able to install and understand the structure.
Documentation becomes extra important when we decouple more and more code.

Merging some bundles together sounds like a good idea, although I'm not yet convinced 6 will ever be enough :)
It still is e-commerce, which is not a simple subject that can be chopped in only a few pieces.

I'm still giving the ProductBundle some thought, I don't really like the idea of a separate bundle for each type of product.
But putting it al on 1 big heap doesn't really appeal me as well, but makes it easier to understand and to share common logic.

On IRC I already discussed a lot of the Gateway it Richard.
It took a while before I understood the way it would work, but know I think I understand :)
From a manager you would just say save(), and the gateway would save it.
You won't know where, how or in how many steps, you just know that the gateway saves the stuff you gave it.
The Entities he was talking about are abstract Entities, no ORM Entities.

Such an approach can be good, but can also cause a lot of headache when you are not familiar with it,
but still want to use Vespolina.In the long run, I do think such Gateways would simplify stuff.
As long as it gets good documentation, where is explained how this differs from the 'standard' methods.


Willem-Jan

Richard Shank

unread,
Jun 15, 2012, 9:00:45 PM6/15/12
to vespol...@googlegroups.com
One of the nice things about the way I'm wanting to structure is if you don't like the gateway idea, not a problem, just extend the Manager like we do now. In fact a lot of it is just moving what we currently have in the Model folder into its own library to keep it framework agnostic.

My reasoning for going with Entity instead of Model is the model triggers the idea of the MVC pattern. Entity can cause some confusion because of Doctrine ORM using the same terminology, but I haven't found a more fitting name for the concept. http://en.wikipedia.org/wiki/Entity_class 

The Gateway is probably more Manager specific than Entity specific. For example, the ProductManager deals with Products and Options. I probably wouldn't have a gateway for each, I would probably have have one gateway that has all of the methods to deal with those on their own when needed. Like with Options, its possible to have prebuilt OptionSets. Since that is so closely related to the product, I would just have productGateway::PersistOptionSet(). 

Persisting, Updating and Deleting don't require any type of querying, we know the Object that is being handled. The find() in the gateway needs to have some type of query language. I think I would prefer to see a more contextual language, even if they abbreviated like the MongoDB Operators http://docs.mongodb.org/manual/reference/operators/ 

I should have some time next week to work on some of these ideas a little more.

Luis Cordova

unread,
Jun 16, 2012, 1:51:16 AM6/16/12
to vespol...@googlegroups.com
Just a little parenthesis in the path of thought.

( What would be the roadmap for all these changes and how can we come about to continue using what we have now for newcomers
like I would like to be able to use v along as we use symfony2 master, there may be need for an update.md to report the modifications and improvements )
i think this update.md is pretty neat concept and very practical.

I will try to be stoffing repos once in a while, would also like to write the documentation for all still. Anybody doing that that can help me or hold my hand?

Luis

IamPersistent

unread,
Jun 23, 2012, 3:32:53 PM6/23/12
to vespol...@googlegroups.com, cord...@gmail.com
I've starting updating the CartBundle to work with the Core. I've merged code from the Bundle into Core, so we can keep a git history of the code. I also started a changelog for CartBundle.

In response to Willem-Jan, I don't think people who are developing with Symfony that do not want to use composer should be our concern. Starting with 2.1, Symfony is using composer for distribution. Vespolina is realistically a 2.1+ project, so it makes sense to me that anyone using 2.1 should be using composer. Also, using composer, the developer can pick how many product types should be included in the project, so we can have just one ProductBundle and the different product types are just libraries that are loaded in by composer and set up through configuration. In fact, we could just make them recommended in the bundle and in the sandbox where we are showcasing everything, just include them in the sandbox level composer.json.

Cordoval, maybe we should start another discussion about documentation.
 
Are there any more comments about the changes Myke proposed? If there are not objections to narrowing down the number of bundles, then perhaps the discussion should move to which bundles and what responsibilities should be in those bundles. There was also a suggestion about changing the name of the project, to make it more Symfony oriented. I think the overall project is bigger than Symfony, but I am open to discussing the Bundles being in a separate project, with Symfony in the name.


On Friday, June 15, 2012 10:51:16 PM UTC-7, Luis Cordova wrote:
Just a little parenthesis in the path of thought.

( What would be the roadmap for all these changes and how can we come about to continue using what we have now for newcomers
like I would like to be able to use v along as we use symfony2 master, there may be need for an update.md to report the modifications and improvements )
i think this update.md is pretty neat concept and very practical.

I will try to be stoffing repos once in a while, would also like to write the documentation for all still. Anybody doing that that can help me or hold my hand?

Luis
On Fri, Jun 15, 2012 at 8:00 PM, Richard Shank  wrote:
One of the nice things about the way I'm wanting to structure is if you don't like the gateway idea, not a problem, just extend the Manager like we do now. In fact a lot of it is just moving what we currently have in the Model folder into its own library to keep it framework agnostic.

My reasoning for going with Entity instead of Model is the model triggers the idea of the MVC pattern. Entity can cause some confusion because of Doctrine ORM using the same terminology, but I haven't found a more fitting name for the concept. http://en.wikipedia.org/wiki/Entity_class 

The Gateway is probably more Manager specific than Entity specific. For example, the ProductManager deals with Products and Options. I probably wouldn't have a gateway for each, I would probably have have one gateway that has all of the methods to deal with those on their own when needed. Like with Options, its possible to have prebuilt OptionSets. Since that is so closely related to the product, I would just have productGateway::PersistOptionSet(). 

Persisting, Updating and Deleting don't require any type of querying, we know the Object that is being handled. The find() in the gateway needs to have some type of query language. I think I would prefer to see a more contextual language, even if they abbreviated like the MongoDB Operators http://docs.mongodb.org/manual/reference/operators/ 

I should have some time next week to work on some of these ideas a little more.

Michael Cole

unread,
Jul 13, 2012, 2:32:57 PM7/13/12
to vespol...@googlegroups.com
hi,

I'm moving a Symfony2 project to Symfony-CMF, and looking at shopping carts. I'm very interested in your project!

I don't have anything specific to add about Vespolina. From a Vespolina technical user perspective, I can relate this.

My primary use cases are:
1) Getting up and running quickly:

Yes! Fewer packages = Less finding things

2) Subclassing a product for my client's *extra* special product. Also, if I want to contribute it back to Vespolina, do I submit it to core?

Ok, having another bundle would be helpful - both for examples and contributions.

3) Upgrading. Will all contributed product types be in the product bundle? Will I have to update my Vespolina "core" every time a product type changes?

I've seen other projects use a "core" and "contrib" model. Everything that will be versioned and maintained with core goes into "core". It's a commitment by the core developers to keep the code quality and up to date.

Contributed code that won't be maintained by the core team goes into "contrib". That allows for separate versioning, examples, maintenance, and community contributions.

Hope this helps!

Mike

> We'd like some feedback from everyone on the desired direction of the project.
> Thanks!

IamPersistent

unread,
Jul 13, 2012, 2:57:23 PM7/13/12
to vespol...@googlegroups.com


On Friday, July 13, 2012 11:32:57 AM UTC-7, Michael Cole wrote:
hi,

I'm moving a Symfony2 project to Symfony-CMF, and looking at shopping carts.  I'm very interested in your project!

I don't have anything specific to add about Vespolina.  From a Vespolina technical user perspective, I can relate this.

My primary use cases are:
1) Getting up and running quickly:

   Yes!  Fewer packages = Less finding things

This makes sense. I think the conversation kind of died away before at what should go in which Bundles.
 

2) Subclassing a product for my client's *extra* special product.  Also, if I want to contribute it back to Vespolina, do I submit it to core?

   Ok, having another bundle would be helpful - both for examples and contributions.

Something like a special product type would probably not go into core. I would think it should have its own repo also with any supporting handlers or listeners. If you need to add that particular product, just include it in composer and configuration. I'll get more details of this worked out in the next week or so.
 

3) Upgrading.  Will all contributed product types be in the product bundle?  Will I have to update my Vespolina "core" every time a product type changes?  

There is still some discussion about this, but my opinion is there should be no product types in the ProductBundle. The ProductBundle should handle Symfony2 specific functionality to work with the Product. To be honest, I haven't thought through how to handle unique forms and templates needed for different product types, but I am very hesitant to require an update to ProductBundle everytime there is a new Product type contributed to the project. 
 

I've seen other projects use a "core" and "contrib" model.  Everything that will be versioned and maintained with core goes into "core".  It's a commitment by the core developers to keep the code quality and up to date.  

Contributed code that won't be maintained by the core team goes into "contrib".  That allows for separate versioning, examples, maintenance, and community contributions.

This makes sense and might be a workable solution for us as well.

Thanks for the feedback

Inspiran

unread,
Jul 17, 2012, 4:54:08 AM7/17/12
to vespol...@googlegroups.com
From a upgrade point of view it makes sense to decouple product types from the ProductBundle.  I do however that we should provide working base classes for commonly used product type to assure that other product types should not start from scratch.  For instance we should provide base classes to make difference between a one shot product and recurring service products (eg. hosting fees, subscriptions, plan based products, ...)

A product type should be considered a plugin to the V system and be installed individually.  Whether or not they should be in composer or another tooling I leave up for discussion.  Actually the same issue would not only exist for product types but also to other entities.  For instance if one needs a product type Job one might also need a JobCartItem and JobSalesOrderItem class.  So no matter what solution we choose we need to apply it consistently to all bundles.

To come back to the initial question of Mike, we might need indeed to consider to reduce the number of bundles.  However a bundle's purpose should be to tie the basic V functionality offered to the symfony2 system.  Base classes for a cart or invoice manager should  live outside of the bundle in the long term.

I'm going to give the restructuring of the bundles some thought and provide a proposition in a new thread.


Reply all
Reply to author
Forward
0 new messages