I jsut started learning about the framework symfony
What does a recipe mean in the Symfony PHP framework?
what is a flex ?
Update :
https://symfony.com/doc/current/quick_tour/flex_recipes.html#flex-recipes-and-aliases
And second, Flex installs a recipe for symfony/twig-bundle. What's a recipe? It's a way for a library to automatically configure itself by adding and modifying files. Thanks to recipes, adding features is seamless and automated: install a package and you're done!
A recipe is a file returned by Symfony Flex which contains information (instructions) about how to modify the require, update, and remove commands of Composer. Essentially, recipes enable Symfony to automate the installation, update or removal of plugins in Symfony applications. For clarity, plugins are called bundles in Symfony lingo.
Symfony Flex is a Composer plugin designed for Symfony. This plugin helps to automate the installation, update or removal of Symfony bundles. Prior to Symfony Flex, after installation of a bundle for instance, you may need to perform additional manual configurations in some Symfony files in order to make use of the bundle in your application. With Flex, you install a bundle and Symfony automatically updates your file system and your bundle is ready for use in your application
Symfony flex also helps to install Symfony bundles using aliases for the specific bundles. For instance, prior to Symfony Flex, to install the SwiftmailerBundle, you have to execute composer require symfony/swiftmailer-bundle but with Symfony Flex, there is an alias composer require mailer which installs the same bundle.
So back to Recipes as files. Let's consider an example of the installation of the SwiftmailerBundle. If Symfony Flex is installed, before the Symfony application tries to execute composer require mailer, it first sends that command to the Symfony Flex server. In this case, Symfony Flex recognizes that composer require mailer is an alias for composer require symfony/swiftmailer-bundle so Symfony Flex will return a file (called a Recipe) to the Symfony application. This recipe will contain the actual composer command composer require symfony/swiftmailer-bundle to install the bundle, in addition to other post installation instructions for that bundle (if any).
Note that without Symfony Flex, the Symfony application will simply execute the command composer require mailer which will return an error because composer does not recognize a package with such installation command.
An example post installation instruction could instruct the Symfony application to modify a configuration file in the application with some configuration instructions, in order to get the bundle ready for use. This means the developer doesn't need to manually go to the configuration file and make changes in order to use the bundle, as was the case before Symfony Flex.
From Symfony 4.0, Flex is used by default (though optional). More information on Symfony Docs
From flex.symfony.com:
Symfony Flex is the way to manage Symfony applications.
It is based on Symfony Recipes, which are a set of automated
instructions to integrate third-party packages into Symfony
applications.
My own explaination:
With Composer you are able to add code components (bundles) to your Symfony project. Except the php code you have to add configuration, routes and assets for example in different configuration files or direcories. With "Flex recipes" this may happen automatically. This makes installing 3th party bundles more easy and quicker.
Related
I'm trying to add a missing feature to a bundle. Here is what I've done so far:
Spoke to the project owner and got their approval
Created a fork and cloned it locally into a directory outside of my project
Made a feature branch
Ran composer install
Now, the question is, how can I include this into my own Symfony project so that it would be autoloaded? I want to test my changes inside my own project before I send a pull request.
See How to require a fork with composer, to be specific, require a VCS repository as described in Composer docs
Or a bit faster way for improving developing process (which is independent on Github), try using local repositories.
You can archive in two manner:
You can hack the vendor folder replacing the folder of the bundle with a symlink of the third-party bundle
[RECOMENDED] Put in the composer.json file of your project the reference of your personal github project instead of the official version
There is a main application, let's call it APP.
APP has several dependencies (including open source projects and proprietary libraries).
There are multiple clients that use their own instance of APP (on different domains that I manage). Some of these clients use a slightly adjusted version of APP. I implemented this by creating a specific module (let's call it SM) for each client that I just add to their instance of APP (so that I don't change any of the code from APP).
Currently, I've implemented this as follows:
Develop APP locally, use Composer to update its dependencies (composer update), push APP on central repo
For each regular client, pull APP from central repo and install the Composer dependencies (composer install)
For clients with specific implementation, create a new SM (specific module), that has the following composer.json file:
...
"require": {
"APP": "X.X.X"
}
...
Then apply the same steps as before for this SM (composer update locally, PUSH to central repo, PULL from central repo, composer install).
Everything is fine, except for two issues that I'd like to overcome:
composer.lock from APP will be ignored by SM (since APP is loaded as a library in the vendor/ folder, and composer ignores the composer.lock files of libraries); this is not good at all, as I will not be confident that the specific clients will use the exact same libraries as APP.
Each time I fix a bug or implement a new feature in APP (and this happens frequently - a few times a day), apart from the steps that I perform for the regular clients, I also need to rebuild the SMs (since one of their libraries - APP - was updated to a new version that I need to use). This is an overhead since most of the changes that I perform are inside APP (and not SM). So, if it was the other way (APP having SM as a dependency), it would have been working faster (since I wouldn't need to composer update on each SM).
Are there any known workflows or best practices that cover this scenario in order to mitigate the two issues above or at least to decrease the complexity of the upgrade/deployment process?
Please note that most of the steps above are already automated, so my question is not about the automation part, but the complexity of this architecture
I implemented this by creating a specific module (let's call it SM) for each client that I just add to their instance of APP
For clients with specific implementation, create a new SM (specific module), that has the following composer.json file:
It's an application with a client specific module (next to other dependencies).
The application has the module as dependency (APP having SM as a dependency).
And not: the module pulls the application as it's vendor dependency in.
This will only cause extra steps to take during the development phase (your issue 2).
I would suggest to refactor the application and it's modules until you get the following folder structure:
|-application #< the application has dependencies
|-src
|-tests
|-vendor
|-framework #< maybe your application is framework based
|-libs #< more dependencies
|-... #< other modules
|-sm #< the client specific module
This allows to pull in dependencies, which extend "the application" for client-specific needs.
This overcomes your issue 1, because APP is the main repository and contains the lock file. It's essential to lock the versions, so that all developers are bound to the same versions and also for packaging exactly the same set of versions.
So, if it was the other way (APP having SM as a dependency), it would have been working faster (since I wouldn't need to composer update on each SM).
Yes! The need to rebuild the module, each time you change APP would vanish, if you start to "develop inside APP" with module dependencies.
And for multiple clients, simply use multiple application repos, which have a custom set of requirements. 10 clients, 10 application repos, 10 composer.json files. Run composer install no-dev then pre-package each repo and place zip into downloads. Done.
You can use a "container" or "packaging" project here, where the composer.json of each project would include the app and the specific modules. You might utilize the caret or tilde operator to specify a version range for the app ("vendor/app": "^1.2.3") and then simply update and repackage, after a new version of the application is released. This approach should work with the composer autoloading, because the application will remain inside the vendor folder, too. Only a little wrapper is needed, to set the composer autoloader up and switch over to your application.
Or, if the application is really modular. Just package the main application and provide the client-specific modules as extra downloads. With this approach upgrades will have multiple download steps: upgrade app, upgrade modules. Think of it as "wordpress-style" updates/upgrades.
You might reduce the complexity of the upgrade/deployment process further by dropping the composer install --no-dev part on the client machine
by building "client-specific application archives" on the developer machine.
These are basically the "--no-dev" package of the application with all it's dependencies, including the client-specific module(s) = pre-packaged.
Like, Application-v1.2.3-WithModuleAForClientA-v3.2.1.zip.
On the dev machine: composer install --no-dev --optimize-autoloader + zip.
To install or upgrade simply download to the client, extract, execute the upgrade script. Done.
So I can't quite figure this one out. We have an API as a composer project.
No we which to add functionality to this API in a modular fashion creating separate composer projects for each module.
But how do I resolve dependencies while developing? Each module need access to the "core" API project to be able to test out code.
The current API is not a real composer package yet. But my initial thought is to create a new package for the module I'm about to develope, and then add a dev-dependency for the "core" API.
Or how should I do it?
Are your modules standalone resp. without the "Core" package usable?
I suppose not, so the "Core" module is a dependency for each of your modules.
Ergo the "you/core" package needs to be in the require block of composer.json of every module.
Note that this is not a dev-dependancy then, because i suppose your module wouldnt be usable without the core package.
Phpunit is a classic dev-dependency because the functionality of your module would still work if there would be no phpunit.
To test & develop the module, you would run a composer install in your module project folder to fetch all dependencies into a vendor folder. Then you can develop and have all your dependencies present. You would need to require the composer autoloader, though. F.e in your phpunit.xml.dist.
Dont forget to add vendor to your .gitignore
We created a ZF2 project with skeleton app and it works fine for a simple test application. Now we are working on a real project. My question is what we should store in the repository (SVN), the whole project structure or just the new source code? ZF2 comes with a vendor directory which is almost 31MB in size (which has the ZF libraries). Should we store the whole vendor folder in SVN?
This is the first time we are using PHP and ZF so are not clear in how we will deliver the complete project to production from SVN. Also what is the build process if at all exists. Any clues/links to "ZF2 project packaging" is appreciated.
No, don't include dependencies in your repository! Putting your dependencies under version control doesn't do any good, it just blows up your repo for no reason.
You want to add the skeleton to your repository and your own library but definitely not the framework or any other dependencies.
The way to go is to use composer for dependency installation and some kind of build tool like Phing to automate installation of your project.
See the relevant chapter on phptherightway for more information on how to build your application.
The most simple build process doesn't even need a build tool
checkout your project from SVN/git
run php composer.phar install to install the needed dependencies (defined in your composer.json)
But most probably you want to do some more stuff like setup up the environment, deleting some files, etc.
A word about ZF packages. They're not available from packagist but you can install them with composer anyways. You just have to add the dedicated repository to your composer.json as described here: http://framework.zend.com/downloads/composer
I have several web projects built with Symfony v1.0, but I am excited by the new features in Symfony version 1.4 (Improved security, native email support and improved performance).
How can I continue to develop my 1.0 projects but also create a testing environment for version 1.4?
Guide to Installing Multiple versions of Symfony
Thankyou to Guillaume Flandre for pointing it out, there is a fantastic article written by eHabib on SymfonyNerds.com - http://symfonynerds.com/blog/?p=123
Here is the basic outline, read the whole article here.
Step 1 - Un-install Symfony via PEAR
Step 2 - Setup a structure for Symfony: Install symfony in /usr/share/php/symfony
Step 3 - Checkout each Symfony version you need
Use SVN checkout to grab each Symfony version. Put these in a different folder under the base Symfony directory.
Step 4 - Create symbolic links for each version
Create and test symlinks for each version of Symfony. Lets place these in the standard bin directory
Step 5 - Creating a new project
Use the relevant Symfony command. For example, to create a Symfony 1.0 project:
sudo symfony10 init-project test1
sudo symfony11 generate:project test11
sudo symfony12 generate:project test12
Step 6 - Check in the project Config to ensure its picked up the right version.
This link should be useful: http://symfonynerds.com/blog/?p=123
It points to an article named: Your complete guide to running multiple Symfony versions on the same environment
It's fairly easy to do.
As also said in the article, I define it in lib/vendor as svn:externals: symfony http://svn.symfony-project.com/branches/1.2
So there's no symfony to be installed on the server at all and you can use as many versions without influence on other apps.