DiLoader::containsPath()   A
last analyzed

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 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 2
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
    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