We know that we want to use a Filesystem library within our module, and we also want to use PhpSpec while writing it, so let’s create a composer.json file in the root of our module.
Each package needs a name that Composer can reference. It needs a description so humans know what it does. We always need a license so we know how we can use the module. Finally, and most importantly, we need the type. The type magento2-module is unique to Magento 2 and it is read by the additional Magento 2 hooks to Composer that will place the files in the correct location.
So we know that we can use Composer to install packages that will make development easier (“easier” in the sense that we are not rewriting everything from scratch; we can use community packages in our work). Now let’s pull in a symfony package for filesystem, as well as a yaml configuration, just in case we want to add some configuration options. Open up your composer.json file and add the following:
We want to ensure people can only install this module if they are using PHP 5.4 or above. We want yaml and filesystem and, because Magento 2 installs modules via Composer, we need to include the Composer package.
2. Require dev
We also want to include some packages while developing our module, but we don’t want these dependencies to ever make it to production. For this, Composer has the helpful section of require-dev. When installing on the production environment, we can use the –no-dev switch to exclude these packages from reaching production.
Add the below to your composer.json file under the require section:
Let’s talk through what we are installing. PhpSpec will help us design our code. PHPUnit is included for its assertion library, and we also include Magento 2 as a module dependency so we can reliably mock what parts of Magento 2 we need. But, because Magento 2 is not part of the Packagist repository, we need to add it as a repository withincomposer.json, so Composer knows where to install it from.
3. Let Magento know how to install the module
At the time of writing this guide and while working from the merchant_beta branch of Magento 2, there is no method to autoload modules from the vendor directory. This has been introduced in the Magento 2 develop, but for now I will show how we move modules into our code base.
Before we had to include Composer as a dependency. This was so we can use extra commands to move modules around:
By adding the above to your composer.json file, Composer will know to move all of the files from this directory into PocketGuide/Generators within app/code when someone installs the module.
4. Autoloading for development
I mentioned earlier that we require Magento 2 as a dependency so that we can mock objects. We need to autoload Magento 2 and framework, in order to do this. We use Composer’s autoloading methods to achieve this. Open up composer.json for the last time and add the following:
In a nutshell we are adding PocketGuide Magento andframework to Composer’s autoloader that PhpSpec can use to autoload the files
5. Configure PhpSpec
So now we want to start using PhpSpec to help design and test our module. If you are new to PhpSpec there are many good tutorials online that can help you get started, such as this.
Because of the module structure we are using for this tutorial, we need to configure PhpSpec to know where to place files that are going to be generated. Create a file phpspec.yml in the root of the module app/code/PocketGuide/Generators with the following content:
- Register a suite that PhpSpec will use to generate classes of our namespace.
- Define the namespace we want to use as well as a PSR-4 namespace.
- Tell PhpSpec where to generate the classes.
If we did not have this configuration, PhpSpec would try to create the classes within a srcfolder.
6. Registering the commands
Magento 2 uses Symfony’s console command package so it makes handling CLI applications really simple. We need to start by creating our first command. Create aCommands folder within our module:
You should then have a class that looks like this:
This is nothing special – special just a empty class with our namespace. Let’s start to add some of the other classes that are required to make the CLI work.
Below the namespace add:
These are all the extra classes that will handle Input and Output within our CLI command.
We then need to extend from the Command class:
Let’s add a constructor into our class. Over time we will use the constructor to inject dependencies, but for now it’s very basic and just calls the parents construct method:
The Command class that we extended requires that we set some configuration information. This is what is shown when we run the Command and is also used to add command options to the CLI.
Begin by setting a name for the command. This is what we will type at the Command Line to invoke this class. Then set a description so people using the CLI will know the intended purpose of this command. Next, add an argument this is the input we expect. Here, we want the name that will reference a module we want to generate.
Finally execute the CLI method using the execute method:
To get started, use the helper method from output to write this handle’s output to the CLI formatting.