Completed
Branch BUG-10738-inconsistency-in-ses... (a1eed8)
by
unknown
24:27 queued 12:29
created

CoffeeMaker::resolveClassAndFilepath()   C

Complexity

Conditions 7
Paths 4

Size

Total Lines 22
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 9
nc 4
nop 1
dl 0
loc 22
rs 6.9811
c 0
b 0
f 0
1
<?php
2
namespace EventEspresso\core\services\container;
3
4
use EventEspresso\core\exceptions\InvalidClassException;
5
use EventEspresso\core\exceptions\InvalidIdentifierException;
6
use EventEspresso\core\services\container\exceptions\InstantiationException;
7
8
if ( ! defined('EVENT_ESPRESSO_VERSION')) {
9
    exit('No direct script access allowed');
10
}
11
12
13
14
/**
15
 * Class CoffeeMaker
16
 * Abstract Parent class for CoffeeMakers which are responsible
17
 * for building objects that are requested from the CoffeeShop
18
 *
19
 * @package       Event Espresso
20
 * @author        Brent Christensen
21
 * @since         4.9.1
22
 */
23
abstract class CoffeeMaker implements CoffeeMakerInterface
24
{
25
26
    /**
27
     * Indicates that CoffeeMaker should construct a NEW entity instance from the provided arguments (if given)
28
     */
29
    const BREW_NEW = 'new';
30
31
    /**
32
     * Indicates that CoffeeMaker should always return a SHARED instance
33
     */
34
    const BREW_SHARED = 'shared';
35
36
    /**
37
     * Indicates that CoffeeMaker should only load the file/class/interface but NOT instantiate
38
     */
39
    const BREW_LOAD_ONLY = 'load_only';
40
41
42
    /**
43
     * @var CoffeePotInterface $coffee_pot
44
     */
45
    private $coffee_pot;
46
47
    /**
48
     * @var DependencyInjector $injector
49
     */
50
    private $injector;
51
52
53
54
    /**
55
     * @return array
56
     */
57
    public static function getTypes()
58
    {
59
        return (array)apply_filters(
60
            'FHEE__EventEspresso\core\services\container\CoffeeMaker__getTypes',
61
            array(
62
                CoffeeMaker::BREW_NEW,
63
                CoffeeMaker::BREW_SHARED,
64
                CoffeeMaker::BREW_LOAD_ONLY,
65
            )
66
        );
67
    }
68
69
70
71
    /**
72
     * @param $type
73
     * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
74
     */
75
    public static function validateType($type)
76
    {
77
        $types = CoffeeMaker::getTypes();
78
        if ( ! in_array($type, $types, true)) {
79
            throw new InvalidIdentifierException(
80
                is_object($type) ? get_class($type) : gettype($type),
81
                __(
82
                    'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)',
83
                    'event_espresso'
84
                )
85
            );
86
        }
87
        return $type;
88
    }
89
90
91
92
    /**
93
     * CoffeeMaker constructor.
94
     *
95
     * @param CoffeePotInterface $coffee_pot
96
     * @param InjectorInterface  $injector
97
     */
98
    public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector)
99
    {
100
        $this->coffee_pot = $coffee_pot;
101
        $this->injector = $injector;
0 ignored issues
show
Documentation Bug introduced by
$injector is of type object<EventEspresso\cor...iner\InjectorInterface>, but the property $injector was declared to be of type object<EventEspresso\cor...ner\DependencyInjector>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
102
    }
103
104
105
106
    /**
107
     * @return \EventEspresso\core\services\container\CoffeePotInterface
108
     */
109
    protected function coffeePot()
110
    {
111
        return $this->coffee_pot;
112
    }
113
114
115
116
    /**
117
     * @return \EventEspresso\core\services\container\DependencyInjector
118
     */
119
    protected function injector()
120
    {
121
        return $this->injector;
122
    }
123
124
125
126
    /**
127
     * Examines the constructor to determine which method should be used for instantiation
128
     *
129
     * @param \ReflectionClass $reflector
130
     * @return mixed
131
     * @throws InstantiationException
132
     */
133
    protected function resolveInstantiationMethod(\ReflectionClass $reflector)
134
    {
135
        if ($reflector->getConstructor() === null) {
136
            return 'NewInstance';
137
        } else if ($reflector->isInstantiable()) {
138
            return 'NewInstanceArgs';
139
        } else if (method_exists($reflector->getName(), 'instance')) {
140
            return 'instance';
141
        } else if (method_exists($reflector->getName(), 'new_instance')) {
142
            return 'new_instance';
143
        } else if (method_exists($reflector->getName(), 'new_instance_from_db')) {
144
            return 'new_instance_from_db';
145
        } else {
146
            throw new InstantiationException($reflector->getName());
147
        }
148
    }
149
150
151
152
    /**
153
     * Ensures files for classes that are not PSR-4 compatible are loaded
154
     * and then verifies that classes exist where applicable
155
     *
156
     * @param RecipeInterface $recipe
157
     * @return bool
158
     * @throws InvalidClassException
159
     */
160
    protected function resolveClassAndFilepath(RecipeInterface $recipe)
161
    {
162
        $paths = $recipe->paths();
163
        if ( ! empty($paths)) {
164
            foreach ($paths as $path) {
165
                if (strpos($path, '*') === false && is_readable($path)) {
166
                    require_once($path);
167
                }
168
            }
169
        }
170
        // re: using "false" for class_exists() second param:
171
        // if a class name is not already known to PHP, then class_exists() will run through
172
        // all of the registered spl_autoload functions until it either finds the class,
173
        // or gets to the end of the registered spl_autoload functions.
174
        // When the second parameter is true, it will also attempt to load the class file,
175
        // but it will also trigger an error if the class can not be loaded.
176
        // We don't want that extra error in the mix, so we have set the second param to "false"
177
        if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) {
178
            throw new InvalidClassException($recipe->identifier());
179
        }
180
        return true;
181
    }
182
183
184
185
186
}
187
// End of file CoffeeMaker.php
188
// Location: /CoffeeMaker.php