Download the PHP package mmoreram/base-bundle without Composer
On this page you can find all versions of the php package mmoreram/base-bundle. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download mmoreram/base-bundle
More information about mmoreram/base-bundle
Files in mmoreram/base-bundle
Package base-bundle
Short Description Base Bundle for all standard Symfony Bundles
License MIT
Homepage https://github.com/mmoreram/BaseBundle
Informations about the package base-bundle
Base Bundle
The minimum requirements of this bundle is PHP 7.2 and Symfony 4.3 because the bundle is using features on both versions. If you're not using them yet, I encourage you to do it.
About the content
This bundle aims to be the base for all bundles in your Symfony project. Know about these big blocks.
Bundles
- Bundle extension
- Bundle dependencies
- Extension declaration
- Commands declaration
- SimpleBaseBundle
- Extension
- Extending BaseExtension
- Configuration
- Extension alias
- Extending BaseConfiguration
Functional Tests
- Functional Tests
- BaseKernel
- BaseFunctionalTest
- Fast testing methods
Bundle extension
All bundles in Symfony should start with a PHP class, the Bundle class. This
class should always implement the interface
Symfony\Component\HttpKernel\Bundle\BundleInterface
, but as you know Symfony
always try to make things easy, so you can simply extend the base implementation
of a bundle.
I've personally defended the magic behind some parts of the Framework, but you should always know what is that magic and discover how affect in your project. Let me explain a little bit your bundle behavior with this implementation.
Bundle dependencies
When we talk about dependencies we are used to talking about PHP dependencies. If we use a file, then this file should be inside our vendor folder, right? That sounds great, but what about if a bundle needs another bundle to be instanced as well in our kernel? How Symfony is supposed to handle this need?
Well, the project itself is not providing this feature at this moment, but even if the theory says that a bundle should never have an external bundle dependency, the reality is another one, and as far as I know, implementations cover mostly real problems not nice theories.
Let's check Symfony Bundle Dependencies. By using this BaseBundle, your bundle has automatically dependencies (by default, none).
If your bundle has dependencies, feel free to overwrite this method in your class and add them all. Take a look at the main library documentation to learn a bit more about how to work with dependencies in your Kernel.
Extension declaration
First of all, your extension will be loaded by magic. What does it mean? Well, the framework will look for your extension following an standard (the Symfony one). But what happens if your extension (by error or explicitly) doesn't follow this standard?
Well, nothing will happen. The framework will still looking for a non-existing class and your desired class will never be instanced. You will spend then some valuable time finding out where the problem is.
First step to do in your project: avoid this magic and define always your extension by instancing it in your bundle.
As you can see, your extensions will require the bundle itself as the first and only construct parameter. Check the configuration chapter to know why.
Even this is the default behavior you can be more explicit and overwrite this method to define that your bundle is not using any extension. That will help you to comprehend a little bit more your bundle requirements.
Compiler Pass declaration
One of the most unknown Symfony features is the Compiler Pass. If you want to know a little bit about what are they and how to use them, take a look at the fantastic cookbook How to work with Compiler Passes in bundles.
You can instance your Compiler Passes by using the build method inside your bundle as you can see in this example.
Let's make it easier. Use the BaseBundle and you will be able to use the getCompilerPasses method in order to define all your compiler passes.
Commands declaration
A bundle is also responsible to expose all commands into the main application. Magic is here as well, so all files ending with Command and extending Command or ContainerAwareCommand inside the main folder Command will be instanced and loaded each time the bundle is instanced.
Same rationale than the Extension one. You're responsible to know where are your classes, and the bundle should know it in a very explicit way.
By default, this BaseBundle abstract class removes the Command autoload, allowing you, in your main Bundle class, to return an array of Command instances. By default, this method returns empty array.
I highly recommend you to never use Commands with this kind of magic, as commands should be, as Controllers and EventListeners, only an entry point to your domain. You can define your commands as services, injecting there all you need to make it work.
How to define commands as services
SimpleBaseBundle
Even simpler.
Symfony should provide a RAD infrastructure that, in case you want to create a rapid bundle exposing an essential parts to the framework, didn't make you spend too much time and effort on that.
So, for your RAD applications, do you really think you need more than one single class to create a simple bundle? Not at all. Not anymore.
Please, welcome SimpleBaseBundle, a simple way of creating Bundles with one class for your RAD applications.
and that's it.
With this class, you will create the bundle with its dependencies, you will initialize the commands and the Compiler Passes if needed, you will load the yaml config files and you will initialize the entities with the given configuration defined in the MappingBagProvider.
No need to create a DependencyInjection folder.
If your project takes another dimension or quality degree, then feel free to change your bundle implementation and start extending BaseBundle instead of SimpleBaseBundle. Then, create the needed DependencyInjection folder.
Extension
Another pain point each time you need to create a new Bundle. The bundle Extension is some kind of port between the bundle itself and all the dependency injection environment. You may be used to seeing files like this.
Extending BaseExtension
Difficult to remember, right? Well, that should never be a problem anymore. Take a look at this implementation using the BaseExtension.
Maybe the file is larger, and you may notice that there are more lines of code, but seems to be easier to understand, right? This is what clean code means. There are only one thing this class will assume. Your services definitions use yml format. This is because is much more clear than XML and PHP, and because it's easier to interpret by humans. As you can see in the getConfigFiles method, you return the name of the file without the extension, being this always yml.
You can modify the container as well before and after the container is loaded by using these two methods.
Configuration
The way your bundle will request and validate some data from the outside (app) is by using a configuration file. You can check the official Configuration Documentation if you want to know a little bit about this amazing feature.
Let's create a new configuration file for our bundle, and let's discover some nice features this library will provide you by extending the Configuration file.
Ops! What happens here? Lets check it out step by step.
Extension Alias
First of all, the configuration file will never define it's own name again. The configuration file should only define what kind of data should request to the app but not under what namespace.
So, who should define this namespace? The Extension should as is the one that really extends the dependency injection environment. In other words, even if for sure this will never be your scenario, you should be able to share a configuration file between different extensions.
So... how we can do that? If your configuration files extend this one, then, as long as you want to initialize it, you will have to define it's namespace. Take a look at this example. This method is part of your Extension file.
Extending BaseConfiguration
By extending the BaseConfiguration class you have this alias parameter in the constructor by default.
Using this class, you don't have to worry anymore about how to create the validation tree. Just define the validation tree under your extension defined alias.
By default, if you don't overwrite this method, no parametrization will be added under your bundle.
Functional Tests
Some of the issues many projects have when they want to start testing their bundles in a functional way is that they don't really know how to handle with the kernel. The steps to follow are always the same.
- Create a small bundle where to test your features
- Create a kernel that works as a standalone application
- Create a configuration for that kernel
But then some issues come as long as we want to test against several kernels and different kernel configurations.
How can we solve this?
Well, this is not going to be a problem anymore, at least with this library. Let's see a functional test and the way you can do it since this moment.
As you can see, you can do as many things as you need in order to create a unique scenario. With a simple class (your test) you can define all your app environment.
Let's see step by step what can you do here
BaseKernel
This library provides you a special kernel for your tests. This kernel is testing ready and allow you to customize as much as you need your application in each scenario. Each testing class will work with a unique kernel configuration, so all test cases inside this test class will be executed against this kernel.
This kernel uses the Symfony Bundle Dependencies project by default, so make sure you take a look at this project. Using it is not a must but a great option.
Let's see what do you need to create your own Kernel using the one this library offers to you.
Only three needed parameters for the kernel creation.
-
Array of bundle namespaces you need to instance the kernel. If you don't want to use the Symfony Bundle Dependencies project, make sure you add all of them. Otherwise, if you use the project, you should only add the bundle/s you want to test.
-
Configuration for the dependency injection component. Use the same format as you were using yml files but in PHP.
- Routes. You can define single routes with an array of three positions. The first one is the path, the second one the Controller notation and the last one, the name of the route. You can define resources with the resource name.
In your configuration definition, and because of mostly all testing cases can be executed against FrameworkBundle and/or DoctrineBundle, you can preload a simple configuration per each bundle by adding these lines in your configuration array.
Cache and logs
The question here would be... okay, but where can I find my Kernel cache and
logs? Well, each kernel configuration (bundles, configuration and routing) is
hashed in a unique string. Then, the system creates a folder under the
var/test
folder and creates a unique {hash}
folder
inside.
Each time you reuse the same kernel configuration, this previous generated cache will be used in order to increase the performance of the tests.
To increase much more this performance, don't hesitate to create a tmpfs
inside this var/test/
folder by using this command.
BaseFunctionalTest
As soon as you have the definition of how you should instance you kernel, we should create our first functional test. Let's take a look at how we can do that.
In every scenario your kernel will be created and saved locally. You can create your own kernel or use the BaseKernel, in both cases this will work properly, but take in account that this kernel will be active in the whole scenario.
Fast testing methods
Functional tests should test only application behaviors, so we should be able to reduce all this work that is not related to this one.
BaseFunctionalTest has a set of easy-to-use methods for use.
->get()
if you want to use any container service just call this method (like in controllers)
->has()
if you want to check if a container service exists, call this method. Useful for service existence testing
->getParameter()
if you want to use any container parameter just call this method (like in controllers)
All versions of base-bundle with dependencies
symfony/framework-bundle Version ^5.1
symfony/yaml Version ^5.1
mmoreram/symfony-bundle-dependencies Version ^2.3