Passed
Push — master ( e140d0...d9458c )
by Gabriel
12:38
created

DiscoverProvider::doDiscovery()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 6
ccs 1
cts 1
cp 1
rs 10
cc 3
nc 3
nop 0
crap 3
1
<?php
2
3
namespace ByTIC\EventDispatcher\ListenerProviders\Discover;
4
5
use ByTIC\EventDispatcher\ListenerProviders\DefaultProvider;
6
7
/**
8
 * Class DiscoverProvider
9
 * @package ByTIC\EventDispatcher\ListenerProviders\Discover
10
 *
11
 * @internal
12
 */
13
class DiscoverProvider extends DefaultProvider
14
{
15
    protected $discovered = null;
16
17
    protected $discoveryPath = null;
18
19
    /**
20 1
     * @inheritDoc
21
     */
22 1
    public function getListenersForEvent(object $event): iterable
23 1
    {
24
        $this->discover();
25
        return parent::getListenersForEvent($event);
26 1
    }
27
28 1
    protected function discover()
29
    {
30
        if ($this->discovered !== null) {
31 1
            return;
32 1
        }
33 1
        $this->doDiscovery();
34 1
        $this->discovered = true;
35
    }
36
37 1
    protected function doDiscovery()
38
    {
39
        $eventsArray = DiscoverEvents::within($this->discoverEventsWithin());
40
        foreach ($eventsArray as $event => $listeners) {
41
            foreach ($listeners as $listener) {
42
                $this->listen($event, $listener);
43
            }
44 1
        }
45
    }
46 1
47
    /**
48
     * Get the listener directories that should be used to discover events.
49
     *
50 1
     * @return array
51
     */
52
    protected function discoverEventsWithin(): array
53
    {
54
        if ($this->discoveryPath === null) {
55
            $this->discoveryPath = $this->detectDiscoveryPath();
56 1
        }
57
58 1
        return $this->discoveryPath;
59 1
    }
60
61
    /**
62
     * @param string $path
63
     */
64
    public function addDiscoveryPath(string $path)
65
    {
66
        $this->discoveryPath[] = $path;
67
    }
68
69
    /**
70
     * @return array
71
     */
72
    protected function detectDiscoveryPath(): array
73
    {
74
        $paths = $this->detectDiscoveryFromConfig();
75
        if (count($paths)) {
76
            return $paths;
77
        }
78
        return $this->detectDiscoveryFromApplication();
79
    }
80
81
    protected function detectDiscoveryFromConfig(): array
82
    {
83
        if (!function_exists('config')) {
84
            return [];
85
        }
86
87
        $config = config('event-dispatcher.listener_paths');
88
        if (!$config) {
89
            return [];
90
        }
91
        $paths = $config->toArray();
92
        foreach ($paths as $key => $path) {
93
            if (!is_dir($path)) {
94
                unset($paths[$key]);
95
            }
96
        }
97
        return $paths;
98
    }
99
100
    protected function detectDiscoveryFromApplication(): array
101
    {
102
        $basePath = $this->detectApplicationPath();
103
        if (!is_dir($basePath)) {
0 ignored issues
show
Bug introduced by
It seems like $basePath can also be of type false; however, parameter $filename of is_dir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

103
        if (!is_dir(/** @scrutinizer ignore-type */ $basePath)) {
Loading history...
104
            return [];
105
        }
106
107
        $folder = $basePath . '/Listeners';
0 ignored issues
show
Bug introduced by
Are you sure $basePath of type false|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

107
        $folder = /** @scrutinizer ignore-type */ $basePath . '/Listeners';
Loading history...
108
        if (!is_dir($folder)) {
109
            return [];
110
        }
111
112
        return [
113
            $folder,
114
        ];
115
    }
116
117
    /**
118
     * @return false|string
119
     */
120
    protected function detectApplicationPath()
121
    {
122
        if (defined('APPLICATION_PATH')) {
123
            return APPLICATION_PATH;
0 ignored issues
show
Bug introduced by
The constant ByTIC\EventDispatcher\Li...scover\APPLICATION_PATH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
124
        }
125
        if (!function_exists('app')) {
126
            return false;
127
        }
128
        $app = app();
129
        if ($app->has('path')) {
130
            return $app->get('path');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $app->get('path') also could return the type object which is incompatible with the documented return type false|string.
Loading history...
131
        }
132
       return false;
133
    }
134
}
135