DiLoader   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 60
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 22
c 1
b 0
f 0
dl 0
loc 60
ccs 0
cts 46
cp 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getTask() 0 19 6
A __construct() 0 9 3
A containsPath() 0 3 1
A getPaths() 0 3 1
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
    protected Container\ContainerInterface $container;
24
    /** @var array<string, array<string>> */
25
    protected array $paths = [];
26
27
    /**
28
     * @param Container\ContainerInterface $container
29
     * @param array<string, array<string>> $paths where will DI be looking for tasks
30
     * @throws CliprException
31
     */
32
    public function __construct(Container\ContainerInterface $container, array $paths = [])
33
    {
34
        $this->container = $container;
35
        foreach ($paths as $namespace => $path) {
36
            $pt = implode(DIRECTORY_SEPARATOR, $path);
37
            if (false === $real = realpath($pt)) {
38
                throw new CliprException(sprintf('Unknown path *%s*!', $pt), Interfaces\IStatuses::STATUS_BAD_CONFIG);
39
            }
40
            $this->paths[$namespace] = explode(DIRECTORY_SEPARATOR, $real);
41
        }
42
    }
43
44
    /**
45
     * @param string $classFromParam
46
     * @throws CliprException
47
     * @throws Container\ContainerExceptionInterface
48
     * @throws Container\NotFoundExceptionInterface
49
     * @throws ReflectionException
50
     * @return ATask|null
51
     */
52
    public function getTask(string $classFromParam): ?ATask
53
    {
54
        $classPath = Useful::sanitizeClass($classFromParam);
55
        foreach ($this->paths as $namespace => $path) {
56
            if ($this->containsPath($classPath, $namespace) && $this->container->has($classPath)) {
57
                $task = $this->container->get($classPath);
58
                $reflection = new \ReflectionClass($classPath);
59
                if (!$reflection->isInstantiable()) {
60
                    // cannot initialize the class - abstract one, interface, trait, ...
61
                    return null;
62
                }
63
                if (!$task instanceof ATask) {
64
                    // the class inside is not an instance of ATask necessary to run
65
                    throw new CliprException(sprintf('Class *%s* is not instance of ATask - check interface or query', $classPath), Interfaces\IStatuses::STATUS_LIB_ERROR);
66
                }
67
                return $task;
68
            }
69
        }
70
        return null;
71
    }
72
73
    protected function containsPath(string $classPath, string $namespace): bool
74
    {
75
        return (0 === mb_strpos($classPath, $namespace));
76
    }
77
78
    public function getPaths(): array
79
    {
80
        return $this->paths;
81
    }
82
}
83