symplify/package-builder

Dependency Injection, Console and Kernel toolkit for Symplify packages.

Installs: 2 922 376

Dependents: 58

Suggesters: 0

Security: 0

Stars: 137

Watchers: 4

Forks: 1

8.3.17 2020-09-22 19:02 UTC

This package is auto-updated.

Last update: 2020-09-26 19:26:04 UTC


README

Downloads total

This tools helps you with Collectors in DependecyInjection, Console shortcuts, ParameterProvider as service and many more.

Install

composer require symplify/package-builder

Use

Get All Parameters via Service

# app/config/services.yaml
parameters:
    source: "src"

services:
    _defaults:
        autowire: true

    Symplify\PackageBuilder\Parameter\ParameterProvider: ~

Then require in __construct() where needed:

<?php

declare(strict_types=1);

namespace App\Configuration;

use Symplify\PackageBuilder\Parameter\ParameterProvider;

final class ProjectConfiguration
{
    /**
     * @var ParameterProvider
     */
    private $parameterProvider;

    public function __construct(ParameterProvider $parameterProvider)
    {
        $this->parameterProvider = $parameterProvider;
    }

    public function getSource(): string
    {
        // returns "src"
        return $this->parameterProvider->provideParameter('source');
    }
}

Get Vendor Directory from Anywhere

<?php

declare(strict_types=1);

$vendorDirProvider = new Symplify\PackageBuilder\Composer\VendorDirProvider();
// returns path to vendor directory
$vendorDirProvider->provide();

Merge Parameters in .yaml Files Instead of Override?

In Symfony the last parameter wins by default*, which is bad if you want to decouple your parameters.

# first.yaml
parameters:
    another_key:
       - skip_this
# second.yaml
imports:
    - { resource: 'first.yaml' }

parameters:
    another_key:
       - skip_that_too

The result will change with Symplify\PackageBuilder\Yaml\FileLoader\ParameterMergingYamlFileLoader:

 parameters:
     another_key:
+       - skip_this
        - skip_that_too

How to use it?

<?php

declare(strict_types=1);

namespace App;

use Symfony\Component\Config\Loader\DelegatingLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Loader\GlobFileLoader;
use Symfony\Component\HttpKernel\Config\FileLocator;
use Symfony\Component\HttpKernel\Kernel;
use Symplify\PackageBuilder\Yaml\FileLoader\ParameterMergingYamlFileLoader;

final class AppKernel extends Kernel
{
    /**
     * @param ContainerInterface|ContainerBuilder $container
     */
    protected function getContainerLoader(ContainerInterface $container): DelegatingLoader
    {
        $kernelFileLocator = new FileLocator($this);

        $loaderResolver = new LoaderResolver([
            new GlobFileLoader($container, $kernelFileLocator),
            new ParameterMergingYamlFileLoader($container, $kernelFileLocator),
        ]);

        return new DelegatingLoader($loaderResolver);
    }
}

In case you need to do more work in YamlFileLoader, just extend the abstract parent Symplify\PackageBuilder\Yaml\FileLoader\AbstractParameterMergingYamlFileLoader and add your own logic.


Do you Need to Merge YAML files Outside Kernel?

Instead of creating all the classes use this helper class:

<?php

declare(strict_types=1);

$parameterMergingYamlLoader = new Symplify\PackageBuilder\Yaml\ParameterMergingYamlLoader();

$parameterBag = $parameterMergingYamlLoader->loadParameterBagFromFile(__DIR__ . '/config.yaml');

var_dump($parameterBag);
// instance of "Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface"

Smart Compiler Passes for Lazy Programmers ↓

How to add compiler pass?


Always Autowire this Type

Do you want to allow users to register services without worrying about autowiring? After all, they might forget it and that would break their code. Set types to always autowire:

<?php

declare(strict_types=1);

namespace App;

use PhpCsFixer\Fixer\FixerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symplify\PackageBuilder\DependencyInjection\CompilerPass\AutowireInterfacesCompilerPass;

final class AppKernel extends Kernel
{
    protected function build(ContainerBuilder $containerBuilder): void
    {
        $containerBuilder->addCompilerPass(new AutowireInterfacesCompilerPass([FixerInterface::class]));
    }
}

This will make sure, that PhpCsFixer\Fixer\FixerInterface instances are always autowired.


That's all :)