Symfony 2 split application to more bundles - symfony

I want to split my application to two bundles.
Back-end bundle which will be something like CMS admin(reusable to another projects), and Front-end bundle.
I moved whole backend application including controllers, templates and model to new bundle, but I have a problem with 3rd-party bundles on which my project is dependent.
For example AsseticBundle. When I add assetic configuration to BackendBundle/config.yml i recieve a exception.
There is no extension able to load the configuration for "assetic"
Is there some good tutorial showing how to split application to two cooperating bundles with one config and both dependent to 3rd-party libraries?
Thanks for any advice.

If I understand you correctly, you're trying to add 3rd party bundle configuration to your own bundle config.
This can be achieved only in app/config/config.yml, which is loaded by default by Symfony. It's the only place where Symfony looks.
What you can do, is prepend configuration via own extension. That can be placed in your bundle:
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
class BackendBundleExtension extends Extension implements PrependExtensionInterface
{
public function prepend(ContainerBuilder $container)
{
$container->prependExtensionConfig('assetic', array(
'key' => 'value'
));
}
}
Let me know, if this is sufficient explanation.

Related

How does Symfony know where to find the services.yml config file?

In Symfony 3.0 (and I'm sure 2.X as well), if I want to make a custom constraint validator with a dependency, I have to register that validator as a service in the dependency injection container (which is described by default in project_directory/app/config/services.yml) using a special tag ( as described here).
This means that the Validator component must know where to look for the service container. This issue also comes up for the ControllerResolver. Since controllers can be registered as services, the ControllerResolver must know where the service container is.
How do the Symfony components know where to look for the service container, and how can I configure this? I ask because I want to build a custom framework using the Symfony components, which means I'll be making my own service container, and I'd like to be able to point the Validator and the ControllerResolver to that service container.
In Symfony Standard Edition, the container is initialised by the Kernel. Have a look at the AppKernel and its parent class.
The kernel loads a configuration file in the registerContainerConfiguration() method:
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load($this->getRootDir().'/config/config_'.$this->getEnvironment().'.yml');
}
This code will load an environment specific configuration file (config_prod.yml, config_dev.yml etc). In a standard setup that file imports the main config.yml file.
The services.yml file is loaded with an import in config.yml:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
If you're thinking of building your own framework (which is a good learning experience), you'll need to read more code of existing frameworks first. Also, it's worth to read the excellent Create your own PHP framework.
This means that the Validator component must know where to look for the service container
This is scary. I see no connection between validation and the service container. I'd think of a better design.
P.S. Everyone should write their own framework once. The next step should be deleting it.

How to run Symfony Bundle without setting up Symfony app?

I have created a standalone Symfony bundle now is it possible to run the bundle alone without setting up Symfony?
I have performed unit tests and it is ok now I want to run the controller of the bundle in the browser (is it possible?)
Thanks in advance!
Bundle is Symfony specific and it only makes sense in a Symfony context.
The only context I can think of when it might be useful to call bundle controllers without installing the bundle in a Symfony project is tests. If that's what you're after, it is possible to set up a stripped down Symfony kernel just for tests. See my article on the subject: How to run Behat scenarios and functional tests from a Symfony bundle in isolation of a project
I have also implemented a DemoBundle where you can see it working with both phpunit and Behat tests.
You can take the same approach if you simply need to test your bundle manually in a browser, but you don't really want to install the whole framework.
Bottom line is you need to set up at least a minimal Symfony kernel.
You can't use a bundle inside Symfony context without letting know Symfony that it is "installed". To do so, you have to enable bundle in your AppKernel:
// app/AppKernel.php
// ...
class AppKernel extends Kernel
{
// ...
public function registerBundles()
{
$bundles = array(
// ...,
new FOS\UserBundle\FOSUserBundle(),
);
// ...
}
}

How do I change the 'template' for controller generation on Symfony's CLI?

I'm currently porting an app to Symfony2, and I'm doing a lot of repetitive work. I'm generating the controllers for all the routes, and they all look alike (minor differences here and there). They are nothing like the default controller symfony generates with doctrine:generate:crud, though.
I was wondering if I could just change the way symfony generates those controllers, instead of writing my own controller generation command.
There's nothing on the documentation, nor could I find it on Google.
You could try to override default controller skeleton templates. They are located in vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/Resources/skeleton/controller
Here is how to override them - http://symfony.com/doc/current/bundles/SensioGeneratorBundle/index.html#overriding-skeleton-templates

Silex + FOQElasticaBundle

My goal is to link the FOQElasticBundle with my Silex website.
The problem is that the documentationn of FOQElasticBundle states that I only have to put some basic stuff in my config.yml file.
See: https://github.com/Exercise/FOQElasticaBundle#declare-a-client
So far I can't find a config.yml file anywhere and I don't know if I have to create it and if so where to put it.
Did I made the wrong choice making my website with Silex instead of Symfony itself?
Or is it possible to load the FOQElasticBundle?
You cant use Symfony Bundles in Silex directly.
Silex integrates third party libraries via Service Providers, which act like some sort of adapters for third party libs.
If you want the convenience of bundles i suggest you better use Symfony.
Otherwise you could try to write a Service Provider for the Elastica library yourself
or integrate it directly as its done here:
https://github.com/4devs/demo-silex/blob/master/web/index.php
$app['elastica.host'] = "localhost";
$app['elastica.port'] = 9200;
$app['elastica'] = function ($app) {
return new \Elastica\Client(array(
'host' => $app['elastica.host'],
'port' => $app['elastica.port']
));
};
Unfortunatly there is no Elastica Service Provider listed here:
https://github.com/silexphp/Silex/wiki/Third-Party-ServiceProviders

How can I access Symfony2 services from an external legacy system?

We are slowly migrating our current system to Symfony2, but the majority of the codebase is still in an inhouse framework. I want to leverage some functionality built in Symfony2 from within classes in the old legacy framework. Is there an easy way to access a Symfony2 service from outside of the Symfony framework?
class MyOldClass extends SomethingOld
{
public function getSomethingViaSymfony()
{
$service = new SomeSymfonyService();
$results = $service->getResults();
}
}
My assumption is that this would be a failure, for the dependencies wouldn't be injected.
you would need to initialize symfony without dispatching any actions. this basicly means taking the code from the symfony front controller file in web/index.php, modifying it a bit and paste it to some initialization file of your legacy app.
// legacy/init.php
require_once 'PATH_TO_SYMFONY/app/bootstrap.php.cache';
require_once 'PATH_TO_SYMFONY/app/AppKernel.php';
$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$GLOBALS['service_container'] = $kernel->getContainer();
note that this code is not tested but i'm pretty sure it'll work because symfony is great;)
also you could think about a different strategy in which you embed the legacy action into symfony and not the other way around.
you would have to implement a legacy controller and give it a catch all route at the end of the routing definition. this controller can initialize the legacy application and dispatch actions to it. afterwards you can successively define new routes at the top of the routing file and dispatch them with symfony.
this strategy is imho much better because you can leave the legacy application almost untouched and kill it piece by piece.

Resources