Passed
Push — master ( 5b8585...da319f )
by Petr
07:39
created

DiLoader::getPaths()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace kalanis\kw_clipr\Loaders;
4
5
6
use kalanis\kw_clipr\Clipr\Useful;
7
use kalanis\kw_clipr\CliprException;
8
use kalanis\kw_clipr\Interfaces;
9
use kalanis\kw_clipr\Tasks\ATask;
10
use Psr\Container;
11
use ReflectionException;
12
13
14
/**
15
 * Class DiLoader
16
 * @package kalanis\kw_clipr\Tasks
17
 * Factory for creating tasks/commands from obtained name
18
 * It contains dependency injection - so everything loaded is from source targeted by that DI
19
 * @codeCoverageIgnore because of that internal autoloader
20
 */
21
class DiLoader implements Interfaces\ITargetDirs
22
{
23
    /** @var Container\ContainerInterface */
24
    protected $container = null;
25
    /** @var array<string, array<string>> */
26
    protected $paths = [];
27
28
    /**
29
     * @param Container\ContainerInterface $container
30
     * @param array<string, array<string>> $paths where will DI be looking for tasks
31
     * @throws CliprException
32
     */
33
    public function __construct(Container\ContainerInterface $container, array $paths = [])
34
    {
35
        $this->container = $container;
36
        foreach ($paths as $namespace => $path) {
37
            $pt = implode(DIRECTORY_SEPARATOR, $path);
38
            if (false === $real = realpath($pt)) {
39
                throw new CliprException(sprintf('Unknown path *%s*!', $pt), Interfaces\IStatuses::STATUS_BAD_CONFIG);
40
            }
41
            $this->paths[$namespace] = explode(DIRECTORY_SEPARATOR, $real);
42
        }
43
    }
44
45
    /**
46
     * @param string $classFromParam
47
     * @throws CliprException
48
     * @throws Container\ContainerExceptionInterface
49
     * @throws Container\NotFoundExceptionInterface
50
     * @throws ReflectionException
51
     * @return ATask|null
52
     */
53
    public function getTask(string $classFromParam): ?ATask
54
    {
55
        $classPath = Useful::sanitizeClass($classFromParam);
56
        foreach ($this->paths as $namespace => $path) {
57
            if ($this->containsPath($classPath, $namespace) && $this->container->has($classPath)) {
58
                $task = $this->container->get($classPath);
59
                $reflection = new \ReflectionClass($classPath);
60
                if (!$reflection->isInstantiable()) {
61
                    // cannot initialize the class - abstract one, interface, trait, ...
62
                    return null;
63
                }
64
                if (!$task instanceof ATask) {
65
                    // the class inside is not an instance of ATask necessary to run
66
                    throw new CliprException(sprintf('Class *%s* is not instance of ATask - check interface or query', $classPath), Interfaces\IStatuses::STATUS_LIB_ERROR);
67
                }
68
                return $task;
69
            }
70
        }
71
        return null;
72
    }
73
74
    protected function containsPath(string $classPath, string $namespace): bool
75
    {
76
        return (0 === mb_strpos($classPath, $namespace));
77
    }
78
79
    public function getPaths(): array
80
    {
81
        return $this->paths;
82
    }
83
}
84