Completed
Push — master ( e502a6...b659c5 )
by Michael
08:23
created

ContainerMagicTrait   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 0

Importance

Changes 0
Metric Value
wmc 11
lcom 3
cbo 0
dl 0
loc 92
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B extend() 0 18 5
A factory() 0 6 1
A keys() 0 4 1
A protect() 0 6 1
A raw() 0 10 3
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * Contains trait ContainerMagicTrait.
5
 *
6
 * PHP version 7.0+
7
 *
8
 * LICENSE:
9
 * This file is part of Yet Another Php Eve Api Library also know as Yapeal
10
 * which can be used to access the Eve Online API data and place it into a
11
 * database.
12
 * Copyright (C) 2016 Michael Cummings
13
 *
14
 * This program is free software: you can redistribute it and/or modify it
15
 * under the terms of the GNU Lesser General Public License as published by the
16
 * Free Software Foundation, either version 3 of the License, or (at your
17
 * option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful, but WITHOUT
20
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
22
 * for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public License
25
 * along with this program. If not, see
26
 * <http://spdx.org/licenses/LGPL-3.0.html>.
27
 *
28
 * You should be able to find a copy of this license in the COPYING-LESSER.md
29
 * file. A copy of the GNU GPL should also be available in the COPYING.md file.
30
 *
31
 * @author    Michael Cummings <[email protected]>
32
 * @copyright 2016 Michael Cummings
33
 * @license   LGPL-3.0+
34
 */
35
namespace Yapeal\Container;
36
37
/**
38
 * Trait ContainerMagicTrait.
39
 *
40
 * @method bool offsetExists($id)
41
 * @property array $values
42
 * @property \SplObjectStorage $factories
43
 * @property bool[] $keys
44
 * @property \SplObjectStorage $protected
45
 * @property mixed[] $raw
46
 */
47
trait ContainerMagicTrait
48
{
49
    /**
50
     * Extends an object definition.
51
     *
52
     * Useful when you want to extend an existing object definition,
53
     * without necessarily loading that object.
54
     *
55
     * @param string|int $id       The unique identifier for the object
56
     * @param callable   $callable A service definition to extend the original
57
     *
58
     * @return callable The wrapped callable
59
     *
60
     * @throws \InvalidArgumentException if the identifier is not defined or not a service definition
61
     */
62
    public function extend($id, callable $callable): callable
63
    {
64
        if (!$this->offsetExists($id)) {
65
            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
66
        }
67
        if (!is_object($this->values[$id]) || !method_exists($this->values[$id], '__invoke')) {
68
            throw new \InvalidArgumentException(sprintf('Identifier "%s" does not contain an object definition.', $id));
69
        }
70
        $factory = $this->values[$id];
71
        $extended = function ($c) use ($callable, $factory) {
72
            return $callable($factory($c), $c);
73
        };
74
        if (isset($this->factories[$factory])) {
75
            $this->factories->detach($factory);
76
            $this->factories->attach($extended);
77
        }
78
        return $this[$id] = $extended;
79
    }
80
    /**
81
     * Marks a callable as being a factory service.
82
     *
83
     * @param callable $callable A service definition to be used as a factory
84
     *
85
     * @return callable The passed callable
86
     */
87
    public function factory(callable $callable): callable
88
    {
89
        /** @noinspection PhpParamsInspection */
90
        $this->factories->attach($callable);
91
        return $callable;
92
    }
93
    /**
94
     * Returns all defined value names.
95
     *
96
     * @return array An array of value names
97
     */
98
    public function keys(): array
99
    {
100
        return array_keys($this->keys);
101
    }
102
    /**
103
     * Protects a callable from being interpreted as a service.
104
     *
105
     * This is useful when you want to store a callable as a parameter.
106
     *
107
     * @param callable $callable A callable to protect from being evaluated
108
     *
109
     * @return callable The passed callable
110
     *
111
     * @throws \InvalidArgumentException Service definition has to be a closure of an invokable object
112
     */
113
    public function protect(callable $callable): callable
114
    {
115
        /** @noinspection PhpParamsInspection */
116
        $this->protected->attach($callable);
117
        return $callable;
118
    }
119
    /**
120
     * Gets a parameter or the closure defining an object.
121
     *
122
     * @param string $id The unique identifier for the parameter or object
123
     *
124
     * @return mixed The value of the parameter or the closure defining an object
125
     *
126
     * @throws \InvalidArgumentException if the identifier is not defined
127
     */
128
    public function raw(string $id)
129
    {
130
        if (!$this->offsetExists($id)) {
131
            throw new \InvalidArgumentException(sprintf('Identifier "%s" is not defined.', $id));
132
        }
133
        if (array_key_exists($id, $this->raw)) {
134
            return $this->raw[$id];
135
        }
136
        return $this->values[$id];
137
    }
138
}
139