Creating A Block¶
Creating a Bldr Block for Bldr is fairly similar to creating a Bundle for Symfony. Here’s a quick guide:
1. Create a repo¶
Try and stay with the naming convention used by the other blocks: <name>-block
2. Initialize composer in the repo¶
cd your-repo && composer init
3. Add Bldr as a dev dependency¶
In your composer.json file, you will want to add bldr-io/bldr as a require-dev dependency. Because embedded composer and composer are unstable packages by definition or they do not have a stable release you will have to add them too into your composer.json as below:
{
"require-dev": {
"bldr-io/bldr": "~7.0.0",
"dflydev/embedded-composer": "dev-master@dev",
"composer/composer": "dev-master@dev"
}
}
4. Create a Block class¶
All of bldr, and the official extensions follow PSR-4 (as well as all the other applicable PSR’s, and most, if not all, of the bylaws). With that, create your directory structure and your Block class:
mkdir src && vim src/AcmeDemoBlock.php
All blocks must extend the BldrDependencyInjectionAbstractBlock, so your class, empty, will look something like this:
src/AcmeDemoBlock.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Bldr\DependencyInjection\AbstractBlock;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author John Doe <john@doh.com>
*/
class AcmeDemoBlock extends AbstractBlock
{
/**
* {@inheritDoc}
*/
protected function assemble(array $config, ContainerBuilder $container)
{
}
}
The assemble function is where the magic happens. If you take a look at the AbstractBlock, there are some helper functions in there to make it easier to add new calls, services, and parameters to the Container.
5. Create your Task¶
As a demo, let’s say we want to make a task that will output a random number to the user when running the task.
First, lets create the task. Directory structure doesn’t really matter, but the core structure is normally src/Task/<Name>Task.php. Similar to blocks, all tasks should extend `Bldr\Block\Core\Task\AbstractTask`_ and must implement `Bldr\Task\TaskInterface`_.
Lets make the src/Task directory, and create the new task: .. code-block:: shell
mkdir src/Task && vim src/Task/OutputRandomNumberCall.php
Then, let’s build the task class! Extending the AbstractTask, suggests that we implement configure and requires that we implement run.
src/Task/OutputRandomNumberTask.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo\Task;
use Bldr\Block\Core\Task\AbstractTask;
use Symfony\Component\Console\Output\OutputInterface;
/**
* @author John Doe <john@doh.com>
*/
class OutputRandomNumberTask extends AbstractTask
{
/**
* {@inheritDoc}
*/
public function configure()
{
$this->setName('acme_demo:output_random_number')
->setDescription('This call outputs a random number. If min and max are specified, it will use those as the range')
->addParameter('min', true, 'Minimum number in range', 0)
->addParameter('max', true, 'Maximum number in range', 100)
;
}
/**
* {@inheritDoc}
*/
public function run(OutputInterface $output)
{
$random = rand($this->getParameter('min'), $this->getParameter('max'));
$output->writeln(['', 'Random Number: '.$random, '']);
}
}
Next, we need to add the task to the container, so we can use it in .bldr.yml(.dist) files:
src/AcmeDemoBlock.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Bldr\DependencyInjection\AbstractBlock;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author John Doe <john@doh.com>
*/
class AcmeDemoBlock extends AbstractBlock
{
/**
* {@inheritDoc}
*/
protected function assemble(array $config, ContainerBuilder $container)
{
// Here's one of the shortcut methods! This method will return a Symfony DI Definition
// that is tagged as `bldr`. If you need to, you can easily add arguments to the constructor,
// or calls to methods.
$task = $this->addTask('acme_demo.output_random_number', 'Acme\Block\Demo\Task\OutputRandomNumberTask');
// If you need dependencies, you could do the following:
// $task->setArgument(0, new Reference('some_service'));
// or
// $arguments = array(new Reference('some_service'));
// $task->addMethodCall('someMethodName', $arguments);
// If you want to add a service, that isn't a task, you can also use:
// $this->addService($name, $class);
// Which will also return a Symfony DI Definition
}
}
6. Register block with bldr¶
In the composer.json file, add the following:
{
"extra": {
"block-class": "Namespace\\To\\Your\\Block\\Class"
}
}
With this, you should be able to install it with the bldr.json file and add it to a .bldr.yml file:
bldr:
name: some/name
profile:
test:
jobs:
- randomize
jobs:
randomize:
tasks:
-
type: acme_demo:output_random_number
min: 0
max: 100000
And run it!
./bldr.phar run test
There’s some more advanced stuff, like being able to specify configuration:
src/AcmeDemoBlock.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Bldr\DependencyInjection\AbstractBlock;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author John Doe <john@doh.com>
*/
class AcmeDemoBlock extends AbstractBlock
{
// ...
/**
* {@inheritDoc}
*/
protected function getConfigurationClass()
{
return 'Acme\Block\Demo\Configuration';
}
}
7. Advanced Config¶
Then make a Configuration.php file. This config is the config from Symfony. You can read their docs for more information.
src/Configuration.php
<?php
/**
* License Information
*/
namespace Acme\Block\Demo;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
/**
* @author John Doe <john@doh.com>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_demo');
// here you will build the configuration tree
return $treeBuilder;
}
}