DocumentsLocator::processCompositions()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 25
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.439
c 0
b 0
f 0
cc 5
eloc 17
nc 5
nop 1
1
<?php
2
/**
3
 * Spiral Framework, IDE Helper
4
 *
5
 * @author    Dmitry Mironov <[email protected]>
6
 * @licence   MIT
7
 */
8
9
namespace Spiral\IdeHelper\Locators;
10
11
use Psr\Log\LoggerInterface;
12
use Spiral\IdeHelper\Model\ClassDefinition;
13
use Spiral\IdeHelper\Model\ClassProperty;
14
use Spiral\ODM\DocumentEntity;
15
use Spiral\ODM\Entities\DocumentCompositor;
16
use Spiral\ODM\ODM;
17
use Spiral\ODM\Schemas\Definitions\CompositionDefinition;
18
use Spiral\ODM\Schemas\DocumentSchema;
19
20
/**
21
 * Class DocumentsLocator
22
 *
23
 * @package Spiral\IdeHelper\Locators
24
 */
25
class DocumentsLocator implements LocatorInterface
26
{
27
    /**
28
     * @var \Psr\Log\LoggerInterface
29
     */
30
    private $logger;
31
32
    /**
33
     * @var \Spiral\ODM\Schemas\SchemaInterface[]
34
     */
35
    private $schemas;
36
37
    /**
38
     * @var \Spiral\ODM\Schemas\SchemaBuilder
39
     */
40
    private $builder;
41
42
    /**
43
     * DocumentsLocator constructor.
44
     *
45
     * @param LoggerInterface $logger
46
     * @param ODM             $odm
47
     */
48
    public function __construct(LoggerInterface $logger, ODM $odm)
49
    {
50
        $this->logger = $logger;
51
52
        $this->builder = $odm->schemaBuilder();
53
        $this->schemas = $this->builder->getSchemas();
54
    }
55
56
    /**
57
     * @inheritdoc
58
     */
59
    public function locate(): array
60
    {
61
        $documents = [];
62
63
        foreach ($this->schemas as $schema) {
64
            if ($schema instanceof DocumentSchema) {
65
                $className = $schema->getClass();
66
                $members = $this->scan($schema);
67
68
                $documents[] = new ClassDefinition($className, $members);
69
            } else {
70
                $this->logger->warning("Schema for {$schema->getClass()} is not "
71
                    . DocumentSchema::class . " instance");
72
            }
73
        }
74
75
        return $documents;
76
    }
77
78
    /**
79
     * @param DocumentSchema $schema
80
     * @return array
81
     */
82
    private function scan(DocumentSchema $schema): array
83
    {
84
        $fields = $this->processFields($schema->getFields());
85
        $mutators = $this->processMutators($schema->getMutators());
86
        $compositions = $this->processCompositions($schema->getCompositions($this->builder));
87
88
        $properties = array_merge($fields, $mutators, $compositions);
89
        $docs = [];
90
        foreach ($properties as $name => $type) {
91
            $docs[] = new ClassProperty($name, $type);
92
        }
93
94
        return $docs;
95
    }
96
97
    /**
98
     * @param array $fields
99
     * @return array
100
     */
101
    private function processFields(array $fields): array
102
    {
103
        $results = [];
104
105
        foreach ($fields as $name => $definition) {
106
            if (!is_array($definition)) {
107
                $class = $definition;
108
            } else {
109
                $class = $definition[0] . '[]';
110
            }
111
112
            $results[$name] = $class;
113
        }
114
115
        return $results;
116
    }
117
118
    /**
119
     * @param array $mutators
120
     * @return array
121
     */
122
    private function processMutators(array $mutators): array
123
    {
124
        $results = [];
125
126
        foreach ($mutators['accessor'] as $name => $type) {
127
            $results[$name] = $type;
128
        }
129
130
        return $results;
131
    }
132
133
    /**
134
     * @param array $compositions
135
     * @return array
136
     */
137
    private function processCompositions(array $compositions): array
138
    {
139
        $results = [];
140
141
        foreach ($compositions as $name => $definition) {
142
            if ($definition instanceof CompositionDefinition) {
143
                switch ($definition->getType()) {
144
                    case DocumentEntity::ONE:
145
                        $class = $definition->getClass();
146
                        break;
147
                    case DocumentEntity::MANY:
148
                        $class = $definition->getClass() . '[]';
149
                        break;
150
                    default:
151
                        throw new \RuntimeException('Unknown definition type: '
152
                            . $definition->getType());
153
                }
154
155
                $types = [DocumentCompositor::class, $class];
156
                $results[$name] = $types;
157
            }
158
        }
159
160
        return $results;
161
    }
162
}
163