ServicesTrait::has()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Webino™ (http://webino.sk)
4
 *
5
 * @link        https://github.com/webino for the canonical source repository
6
 * @copyright   Copyright (c) 2015-2017 Webino, s.r.o. (http://webino.sk)
7
 * @author      Peter Bačinský <[email protected]>
8
 * @license     BSD-3-Clause
9
 */
10
11
namespace WebinoAppLib\Application\Traits;
12
13
use WebinoAppLib\Exception;
14
use Zend\ServiceManager\Exception\ServiceNotFoundException;
15
use Zend\ServiceManager\FactoryInterface;
16
use Zend\ServiceManager\ServiceManager;
17
18
/**
19
 * Trait ServiceProviderTrait
20
 */
21
trait ServicesTrait
22
{
23
    /**
24
     * @var ServiceManager
25
     */
26
    private $services;
27
28
    /**
29
     * @return ServiceManager
30
     */
31
    public function getServices()
32
    {
33
        return $this->services;
34
    }
35
36
    /**
37
     * Return registered service
38
     *
39
     * @param string $service Service name
40
     * @return mixed
41
     * @throws Exception\UnknownServiceException
42
     */
43
    public function get($service)
44
    {
45
        try {
46
            return $this->getServices()->get($service);
47
        } catch (ServiceNotFoundException $exc) {
48
            throw (new Exception\UnknownServiceException('Unable to get an instance for %s', null, $exc))
49
                ->format($service);
50
        }
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function set($service, $factory = null)
57
    {
58
        $services = $this->getServices();
59
60
        if ($factory instanceof FactoryInterface
61
            || is_callable($factory)
62
            || (is_string($factory) && class_exists($factory))
63
        ) {
64
            // factory
65
            $services->setFactory($service, $factory);
0 ignored issues
show
Bug introduced by
It seems like $factory can also be of type object<Zend\ServiceManager\FactoryInterface>; however, Zend\ServiceManager\ServiceManager::setFactory() does only seem to accept callable, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
66
            return $this;
67
        }
68
69
        if (null !== $factory && is_string($service)) {
70
            // service object
71
            $services->setService($service, $factory);
72
            return $this;
73
        }
74
75
        // invokable
76
        if (is_array($service)) {
77
            $services->setInvokableClass(key($service), current($service));
78
        } elseif (is_string($service)) {
79
            $services->setInvokableClass($service, $service);
80
        }
81
82
        return $this;
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88
    public function has($service)
89
    {
90
        return $this->getServices()->has((string) $service);
91
    }
92
93
    /**
94
     * Require service from services into application
95
     *
96
     * @param string $service Service name
97
     * @throws Exception\DomainException Unable to get service
98
     */
99
    protected function requireService($service)
100
    {
101
        if (!$this->services->has($service)) {
102
            throw (new Exception\DomainException('Unable to get required application service %s'))->format($service);
103
        }
104
105
        $this->setService($service);
106
    }
107
108
    /**
109
     * Set optional service from services into application
110
     *
111
     * @param string $service Service name
112
     */
113
    protected function optionalService($service)
114
    {
115
        $this->services->has($service) and $this->setService($service);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
116
    }
117
118
    /**
119
     * @param $service
120
     */
121
    private function setService($service)
122
    {
123
        call_user_func([$this, 'set' . $service], $this->services->get($service), false);
124
    }
125
126
    /**
127
     * @param string $name
128
     * @param mixed $service
129
     */
130
    protected function setServicesService($name, $service)
131
    {
132
        $this->services
133
            ->setAllowOverride(true)
134
            ->setService($name, $service)
135
            ->setAllowOverride(false);
136
    }
137
}
138