Completed
Push — master ( cf9a3d...3ae770 )
by Théo
24:54 queued 09:56
created

ServicesBuilder::resolveArguments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3
Metric Value
dl 0
loc 18
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 11
nc 3
nop 3
crap 3
1
<?php
2
3
/*
4
 * This file is part of the LaravelYaml package.
5
 *
6
 * (c) Théo FIDRY <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Fidry\LaravelYaml\DependencyInjection\Builder;
13
14
use Fidry\LaravelYaml\DependencyInjection\Builder\Instantiator\ServiceInstantiator;
15
use Fidry\LaravelYaml\DependencyInjection\Definition\Reference;
16
use Fidry\LaravelYaml\DependencyInjection\Definition\Service;
17
use Fidry\LaravelYaml\DependencyInjection\Resolver\BaseReferenceResolver;
18
use Fidry\LaravelYaml\DependencyInjection\Resolver\BuiltParameterResolver;
19
use Fidry\LaravelYaml\DependencyInjection\Resolver\ParameterResolverInterface;
20
use Fidry\LaravelYaml\DependencyInjection\Resolver\ReferenceResolverInterface;
21
use Fidry\LaravelYaml\Exception\DependencyInjection\Exception;
22
use Fidry\LaravelYaml\Exception\DependencyInjection\Resolver\Exception as ResolverException;
23
use Fidry\LaravelYaml\Exception\ServiceNotFoundException;
24
use Illuminate\Contracts\Config\Repository as ConfigRepository;
25
use Illuminate\Contracts\Container\BindingResolutionException;
26
use Illuminate\Contracts\Foundation\Application;
27
28
/**
29
 * @author Théo FIDRY <[email protected]>
30
 */
31
final class ServicesBuilder implements BuilderInterface
32
{
33
    /**
34
     * @var array
35
     */
36
    private $parameters;
37
38
    /**
39
     * @var ReferenceResolverInterface
40
     */
41
    private $referenceResolver;
42
43
    /**
44
     * @var Service[]
45
     */
46
    private $services;
47
48
    /**
49
     * @var ParameterResolverInterface|null
50
     */
51
    private $parameterResolver;
52
53
    /**
54
     * @param Service[]                       $services
55
     * @param array                           $parameters
56
     * @param ParameterResolverInterface|null $parameterResolver
57
     * @param ReferenceResolverInterface|null $referenceResolver
58 24
     */
59
    public function __construct(
60
        array $services,
61
        array $parameters,
62
        ParameterResolverInterface $parameterResolver = null,
63
        ReferenceResolverInterface $referenceResolver = null
64 24
    ) {
65 24
        $this->services = $services;
66 24
        $this->parameters = $parameters;
67 24
        $this->parameterResolver = $parameterResolver;
68 24
        $this->referenceResolver = (null === $referenceResolver) ? new BaseReferenceResolver() : $referenceResolver;
69
    }
70 24
71
    public function build(Application $application)
72
    {
73
        try {
74 24
            $parameterResolver = $this->getParameterResolver($application);
75 24
            $instantiator = new ServiceInstantiator($parameterResolver, $this->referenceResolver, $application);
76 21
            foreach ($this->services as $service) {
77 10
                $this->buildService($service, $instantiator, $application);
78
            }
79 15
80 9
            return $this->parameters;
81 3
        } catch (BindingResolutionException $exception) {
82 6
            throw new Exception(sprintf('Could not load "%s" class', ConfigRepository::class), 0, $exception);
83 3
        } catch (ResolverException $exception) {
84 3
            throw new Exception('Could not resolve the parameters', 0, $exception);
85 3
        } catch (\Exception $exception) {
86
            throw new Exception('Could not build the parameters', 0, $exception);
87
        }
88
    }
89
90
    /**
91
     * @param Application $application
92
     *
93
     * @return ParameterResolverInterface
94 24
     */
95
    private function getParameterResolver(Application $application)
96 24
    {
97
        if (null !== $this->parameterResolver) {
98
            return $this->parameterResolver;
99
        }
100
        $config = $application->make(ConfigRepository::class);
101
102 24
        return new BuiltParameterResolver($this->parameters, $config);
103
    }
104
105 21
    private function buildService(
106
        Service $service,
107
        ServiceInstantiator $instantiator,
108
        Application $application
109
    ) {
110 21
        $instance = $instantiator->create($service);
111
112 15
        $application->instance($service->getName(), $instance);
113 15
        $application->bind($service->getClass(), $service->getName());
114 12
        $this->bindAutowiringTypes($service, $application);
115 12
        $this->tagService($service, $application);
116 12
    }
117
118
    private function bindAutowiringTypes(Service $service, Application $application)
119
    {
120
        foreach ($service->getAutowiringTypes() as $binding) {
121
            $application->bind($binding, $service->getName());
122
        }
123
    }
124
125 21
    private function tagService(Service $service, Application $application)
126
    {
127
        if (count($service->getTags()) !== 0) {
128
            $application->tag($service->getName(), array_keys($service->getTags()));
129
        }
130 21
    }
131
}
132