findAllResourceOptions()   D
last analyzed

Complexity

Conditions 9
Paths 3

Size

Total Lines 40
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 9

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 29
cts 29
cp 1
rs 4.909
c 0
b 0
f 0
cc 9
eloc 26
nc 3
nop 1
crap 9
1
<?php
2
namespace Staticus\Resources\Commands;
3
4
use League\Flysystem\FilesystemInterface;
5
use Staticus\Resources\Exceptions\CommandErrorException;
6
use Staticus\Resources\ResourceDOAbstract;
7
use Staticus\Resources\ResourceDOInterface;
8
9
/** @noinspection PropertyCanBeStaticInspection */
10
class FindResourceOptionsCommand implements ResourceCommandInterface
11
{
12
    const DIRECTORY_RELATIVE = 'directory_relative';
13
    /**
14
     * @var ResourceDOInterface
15
     */
16
    protected $resourceDO;
17
    /**
18
     * @var FilesystemInterface
19
     */
20
    protected $filesystem;
21
22
    protected $allowedProperties = [];
23
24 24
    public function __construct(ResourceDOInterface $resourceDO, FilesystemInterface $filesystem)
25
    {
26 24
        $this->resourceDO = $resourceDO;
27 24
        $this->filesystem = $filesystem;
28 24
    }
29
30 24
    public function __invoke(array $filter = [])
31
    {
32 24
        $this->allowedProperties = $filter;
33 24
        $options = $this->findAllResourceOptions($this->resourceDO);
34
35 20
        return $this->filterResourceOptions($options);
36
    }
37
38 20
    public function filterResourceOptions($options)
39
    {
40 20
        if (!empty($this->allowedProperties)) {
41 10
            foreach ($options as &$item) {
42 9
                $item = array_filter($item, [$this, 'filterAllowedProperties'], ARRAY_FILTER_USE_BOTH);
43 10
            }
44 10
            $options = array_filter($options);
45 10
        }
46
47 20
        return $options;
48
    }
49
50 24
    protected function findAllResourceOptions(ResourceDOInterface $resourceDO)
51
    {
52
        /** @var \League\Flysystem\FilesystemInterface $filesystem */
53 24
        $filesystem = $this->filesystem;
54 24
        $uuid = $resourceDO->getUuid();
55 24
        $type = $resourceDO->getType();
56 24
        $name = $resourceDO->getName();
57 24
        if (!$name || !$type) {
58 4
            throw new CommandErrorException('Can not look for options: resource is empty');
59
        }
60 20
        $basename = $resourceDO->getBaseDirectory();
61 20
        $namespace = $resourceDO->getNamespace();
62
        $path = $basename
63 20
            . ($namespace ? $namespace . DIRECTORY_SEPARATOR : '')
64 20
            . $type . DIRECTORY_SEPARATOR
65 20
        ;
66 20
        $found = $filesystem->listContents($path, true);
67 20
        $found = array_filter($found, function($file) use ($uuid, $type) {
68
69 19
            return array_key_exists('filename', $file)
70 19
            && $file['filename'] === $uuid
71 19
            && array_key_exists('extension', $file)
72 19
            && $file['extension'] === $type
73 19
            && array_key_exists('type', $file)
74
            // Warning: type field will be replaced by resource
75 19
            && $file['type'] === 'file'
76
77 19
                ;
78 20
        });
79 20
        array_walk(
80
            $found
81 20
            , [$this, 'hydrateElementFile']
82 20
            , [
83 20
                'resourceDO' => $resourceDO,
84
            ]
85 20
        );
86 20
        $found = array_values($found); // reset keys
87
88 20
        return $found;
89
    }
90
91 19
    protected function hydrateElementFile(&$file, $key, $args)
92
    {
93 19
        if (!array_key_exists('resourceDO', $args) || !$args['resourceDO'] instanceof ResourceDOInterface) {
94
            throw new CommandErrorException('Method expects ResourceDO in arguments');
95
        }
96
97
        /** @var ResourceDOInterface $resourceDO */
98 19
        $resourceDO = $args['resourceDO'];
99 19
        $file[static::DIRECTORY_RELATIVE] = str_replace(
100 19
            $resourceDO->getBaseDirectory()
101 19
            . ($resourceDO->getNamespace() ? $resourceDO->getNamespace() . DIRECTORY_SEPARATOR : '')
102 19
            , ''
103 19
            , DIRECTORY_SEPARATOR . $file['dirname']
104 19
        );
105 19
        $tokens = $resourceDO->getDirectoryTokens();
106 19
        $this->splitDirectoryByTokens($file, array_keys($tokens));
107 19
    }
108
109 9
    protected function filterAllowedProperties($value, $key)
110
    {
111
112 9
        return in_array($key, $this->allowedProperties, true);
113
    }
114
115
    /**
116
     * @param $file
117
     * @param $tokens
118
     * @return mixed
119
     */
120 19
    protected function splitDirectoryByTokens(&$file, $tokens)
121
    {
122 19
        $split = null;
123 19
        foreach ($tokens as $token) {
124 19
            if (ResourceDOAbstract::TOKEN_BASEDIRECTORY === $token) {
125 19
                continue;
126
            }
127 19
            if (ResourceDOAbstract::TOKEN_NAMESPACE === $token) {
128 19
                continue;
129
            }
130 19
            $split = null === $split
131 19
                ? strtok($file[static::DIRECTORY_RELATIVE], DIRECTORY_SEPARATOR)
132 19
                : strtok(DIRECTORY_SEPARATOR);
133 19
            $file[$token] = $split;
134 19
        }
135 19
        while (($split = strtok(DIRECTORY_SEPARATOR)) !== false) {
136
            $file['sub-options'][] = $split;
137
        }
138
    }
139
}