ptmr.io
ptmr.io

Reputation: 2315

Symfony Bundle that needs a file that differs per project

I've written a small newsletter bundle for the multiple sites I host/develop for. The newsletter fetches the recipients from a newsletter source that differs from project to project. Could be a csv file, could be a database, ...

So in my Controller I thought about writing a NewsletterQueueImportModel() which is being called upon hitting the button "import".

...
$import = new NewsletterQueueImportModel();
$subscribers = $import->getSubscribers($this->getDoctrine());
...

However this file is still delivered with my bundle and in the vendor folder. So I need to change this file on a per project basis.

  1. Override the file, but how? I do not think this is possible.
  2. Remove the file from the newsletter bundle itself and refer to AppBundle/NewsletterQueueImportModel (e.g. use AppBundle instead of use NewsletterBundle - downsides: all projects need to be named AppBundle and I feel it is poor design

I thought about registering a service or something like that, but I really don't know the beste way to do. So what is the best way to create a file on which a bundle depends but differs from project to project?

Upvotes: 1

Views: 32

Answers (1)

revengeance
revengeance

Reputation: 891

Well, I have been doing something similar but with views.

So I had 2 sites running on one bundle - in one site I needed to see some sections which i don't need in other site.

I managed to do that with configuration.

1) In each of your site - app/config/config.yml you can define parameters. In my case it was something like

reviews_admin:
    views:
        table_favorite_block: true
        table_brand_view: true
        table_image_view: true

2) Then in bundle you must create folder named DependencyInjection with 2 files in it. Configuration and your bundle extension

    class Configuration implements ConfigurationInterface
{
    /**
     * {@inheritdoc}
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('reviews_admin', 'array');

        $rootNode
            ->children()
            ->arrayNode('views')
            ->children()
            ->booleanNode('table_favorite_block')->defaultTrue()->end()
            ->booleanNode('table_brand_view')->defaultTrue()->end()
            ->booleanNode('table_image_view')->defaultTrue()->end()
            ->end()
            ->end()
            ->end();

        return $treeBuilder;
    }
}

Extension

  class ReviewsAdminExtension extends Extension
    {
        /**
         * {@inheritdoc}
         */
        public function load(array $configs, ContainerBuilder $container)
        {
            $configuration = new Configuration();
            $config = $this->processConfiguration($configuration, $configs);

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

            $container->setParameter('reviews_admin_view', $config['views']);
        }
    }

I'm not sure if this will suite your situation, but for me it seems like the most convenient way how to manage things in bundles which depends on projects.

Also you can try to make one base class in bundle (which contains things that will be same for all projects (for imports))

And then extend it in site side ?

Upvotes: 1

Related Questions