Completed
Branch BUG-10626-dst-unit-test (8c5dd4)
by
unknown
138:48 queued 126:51
created

CoffeeMaker::resolveClassAndFilepath()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 21
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 8
nc 4
nop 1
dl 0
loc 21
rs 7.551
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
     */
74 View Code Duplication
    public static function validateType($type)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
    {
76
        $types = CoffeeMaker::getTypes();
77
        if ( ! in_array($type, $types)) {
78
            throw new InvalidIdentifierException(
79
                is_object($type) ? get_class($type) : gettype($type),
80
                __(
81
                    'recipe type (one of the class constants on \EventEspresso\core\services\container\CoffeeMaker)',
82
                    'event_espresso'
83
                )
84
            );
85
        }
86
        return $type;
87
    }
88
89
90
91
    /**
92
     * CoffeeMaker constructor.
93
     *
94
     * @param CoffeePotInterface $coffee_pot
95
     * @param InjectorInterface  $injector
96
     */
97
    public function __construct(CoffeePotInterface $coffee_pot, InjectorInterface $injector)
98
    {
99
        $this->coffee_pot = $coffee_pot;
100
        $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...
101
    }
102
103
104
105
    /**
106
     * @return \EventEspresso\core\services\container\CoffeePotInterface
107
     */
108
    protected function coffeePot()
109
    {
110
        return $this->coffee_pot;
111
    }
112
113
114
115
    /**
116
     * @return \EventEspresso\core\services\container\DependencyInjector
117
     */
118
    protected function injector()
119
    {
120
        return $this->injector;
121
    }
122
123
124
125
    /**
126
     * Examines the constructor to determine which method should be used for instantiation
127
     *
128
     * @param \ReflectionClass $reflector
129
     * @return mixed
130
     */
131
    protected function resolveInstantiationMethod(\ReflectionClass $reflector)
132
    {
133
        if ($reflector->getConstructor() === null) {
134
            return 'NewInstance';
135
        } else if ($reflector->isInstantiable()) {
136
            return 'NewInstanceArgs';
137
        } else if (method_exists($reflector->getName(), 'instance')) {
138
            return 'instance';
139
        } else if (method_exists($reflector->getName(), 'new_instance')) {
140
            return 'new_instance';
141
        } else if (method_exists($reflector->getName(), 'new_instance_from_db')) {
142
            return 'new_instance_from_db';
143
        } else {
144
            throw new InstantiationException($reflector->getName());
145
        }
146
    }
147
148
149
150
    /**
151
     * Ensures files for classes that are not PSR-4 compatible are loaded
152
     * and then verifies that classes exist where applicable
153
     *
154
     * @param RecipeInterface $recipe
155
     * @throws InvalidClassException
156
     */
157
    protected function resolveClassAndFilepath(RecipeInterface $recipe)
158
    {
159
        $paths = $recipe->paths();
160
        if ( ! empty($paths)) {
161
            foreach ($paths as $path) {
162
                if (strpos($path, '*') === false && is_readable($path)) {
163
                    require_once($path);
164
                }
165
            }
166
        }
167
        // re: using "false" for class_exists() second param:
168
        // if a class name is not already known to PHP, then class_exists() will run through
169
        // all of the registered spl_autoload functions until it either finds the class,
170
        // or gets to the end of the registered spl_autoload functions.
171
        // When the second parameter is true, it will also attempt to load the class file,
172
        // but it will also trigger an error if the class can not be loaded.
173
        // We don't want that extra error in the mix, so we have set the second param to "false"
174
        if ($recipe->type() !== CoffeeMaker::BREW_LOAD_ONLY && ! class_exists($recipe->fqcn(), false)) {
175
            throw new InvalidClassException($recipe->identifier());
176
        }
177
    }
178
179
180
181
182
}
183
// End of file CoffeeMaker.php
184
// Location: /CoffeeMaker.php