Completed
Push — master ( febdbe...957a77 )
by Fran
03:33
created

NOSQLService   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 38
eloc 102
dl 0
loc 217
rs 9.36
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getCollections() 0 7 2
B parseCollection() 0 30 10
A getDomains() 0 12 4
A getTypes() 0 3 1
A setTypes() 0 3 1
A getValidations() 0 7 2
A setCollections() 0 27 5
A syncCollections() 0 22 5
A init() 0 4 1
A writeTemplateToFile() 0 14 4
A extractTypes() 0 8 3
1
<?php
2
namespace NOSQL\Services;
3
4
use MongoDB\Model\BSONDocument;
5
use NOSQL\Dto\CollectionDto;
6
use NOSQL\Dto\Validation\EnumPropertyDto;
7
use NOSQL\Dto\Validation\JsonSchemaDto;
8
use NOSQL\Dto\Validation\NumberPropertyDto;
9
use NOSQL\Dto\Validation\StringPropertyDto;
10
use NOSQL\Services\Base\NOSQLBase;
11
use PSFS\base\Cache;
12
use PSFS\base\dto\Field;
13
use PSFS\base\Logger;
14
use PSFS\base\Service;
15
use PSFS\base\Template;
16
use PSFS\base\types\helpers\GeneratorHelper;
17
18
/**
19
* Class NOSQLService
20
* @package NOSQL\Services
21
* @author Fran López <[email protected]>
22
* @version 1.0
23
* Autogenerated service [2019-01-03 15:23:58]
24
*/
25
class NOSQLService extends Service {
26
27
    /**
28
     * @Injectable
29
     * @var \PSFS\base\Cache
30
     */
31
    protected $cache;
32
33
    /**
34
     * @var array
35
     */
36
    private $types = [];
37
38
    /**
39
     * @return array
40
     */
41
    public function getTypes()
42
    {
43
        return $this->types;
44
    }
45
46
    /**
47
     * @param array $types
48
     */
49
    public function setTypes($types)
50
    {
51
        $this->types = $types;
52
    }
53
54
    /**
55
     * @throws \ReflectionException
56
     */
57
    private function extractTypes() {
58
        $baseClass = new \ReflectionClass(NOSQLBase::class);
59
        if(null !== $baseClass) {
60
            $types = [];
61
            foreach($baseClass->getConstants() as $constant) {
62
                $types[] = $constant;
63
            }
64
            $this->setTypes($types);
65
        }
66
    }
67
68
    /**
69
     * @throws \ReflectionException
70
     */
71
    public function init()
72
    {
73
        parent::init();
74
        $this->extractTypes();
75
    }
76
77
    /**
78
     * @return array
79
     */
80
    public function getDomains() {
81
        $domains = [];
82
        $storedDomains = $this->cache->getDataFromFile(CONFIG_DIR . DIRECTORY_SEPARATOR . 'domains.json', Cache::JSON, TRUE);
83
        if(!empty($storedDomains)) {
84
            foreach($storedDomains as $domain => $data) {
85
                $domainLabel = str_replace(['@', '/'], '', $domain);
86
                if('ROOT' !== $domainLabel) {
87
                    $domains[] = $domainLabel;
88
                }
89
            }
90
        }
91
        return $domains;
92
    }
93
94
    /**
95
     * @param string $module
96
     * @return array
97
     */
98
    public function getCollections($module) {
99
        $collections = [];
100
        $schemaFilename = CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'Config' . DIRECTORY_SEPARATOR . 'schema.json';
101
        if(file_exists($schemaFilename)) {
102
            $collections = $this->cache->getDataFromFile($schemaFilename, Cache::JSON, TRUE);
103
        }
104
        return $collections;
105
    }
106
107
    /**
108
     * @param string $module
109
     * @param array $collections
110
     * @throws \PSFS\base\exception\GeneratorException
111
     */
112
    public function setCollections($module, $collections) {
113
        $schemaFilename = CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'Config' . DIRECTORY_SEPARATOR . 'schema.json';
114
        $this->cache->storeData($schemaFilename, $collections, Cache::JSON, true);
115
        $tpl = Template::getInstance();
116
        $tpl->addPath(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'Templates', 'NOSQL');
117
        $files = [
118
            '@NOSQL/generator/model.base.php.twig' => CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'Models' . DIRECTORY_SEPARATOR . 'Base',
119
            '@NOSQL/generator/model.php.twig' => CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'Models',
120
            '@NOSQL/generator/api.php.twig' => CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'Api',
121
            '@NOSQL/generator/api.base.php.twig' => CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'Api' . DIRECTORY_SEPARATOR . 'Base',
122
            '@NOSQL/generator/dto.php.twig' => CORE_DIR . DIRECTORY_SEPARATOR . $module . DIRECTORY_SEPARATOR . 'Dto' . DIRECTORY_SEPARATOR . 'Models',
123
        ];
124
        foreach($collections as $raw) {
125
            $collection = new CollectionDto(false);
126
            $collection->fromArray($raw);
127
            foreach($files as $template => $path) {
128
                GeneratorHelper::createDir($path);
129
                $templateDump = $tpl->dump($template, [
130
                    'domain' => $module,
131
                    'model' => $collection->name,
132
                    'properties' => $collection->properties,
133
                ]);
134
                $force = false;
135
                if(false !== strpos($template, 'dto') || false !== strpos(strtolower($template), 'base')) {
136
                    $force = true;
137
                }
138
                $this->writeTemplateToFile($templateDump, $path . DIRECTORY_SEPARATOR . $collection->name . '.php', $force);
139
            }
140
        }
141
    }
142
143
    /**
144
     * @param string $fileContent
145
     * @param string $filename
146
     * @param bool $force
147
     * @return bool
148
     */
149
    private function writeTemplateToFile($fileContent, $filename, $force = false)
150
    {
151
        $created = false;
152
        if ($force || !file_exists($filename)) {
153
            try {
154
                $this->cache->storeData($filename, $fileContent, Cache::TEXT, true);
155
                $created = true;
156
            } catch (\Exception $e) {
157
                Logger::log($e->getMessage(), LOG_ERR);
158
            }
159
        } else {
160
            Logger::log($filename . t(' not exists or cant write'), LOG_ERR);
161
        }
162
        return $created;
163
    }
164
165
    /**
166
     * @param $module
167
     * @return bool
168
     * @throws \PSFS\base\exception\GeneratorException
169
     */
170
    public function syncCollections($module) {
171
        $db = ParserService::getInstance()->createConnection($module);
172
        $collections = $this->getCollections($module);
173
        $success = true;
174
        foreach($collections as $raw) {
175
            $jsonSchema = $this->parseCollection($raw);
176
            try {
177
                /** @var BSONDocument $result */
178
                $result = $db->createCollection($raw['name'], [
179
                    'validation' => [
180
                        '$jsonSchema' => $jsonSchema->toArray(),
181
                    ]
182
                ]);
183
                $response = $result->getArrayCopy();
184
                $success = array_key_exists('ok', $response) && $response['ok'] > 0;
185
            } catch(\Exception $exception) {
186
                if($exception->getCode() !== 48) {
187
                    $success = false;
188
                }
189
            }
190
        }
191
        return $success;
192
    }
193
194
    /**
195
     * @param array $raw
196
     * @return JsonSchemaDto
197
     * @throws \PSFS\base\exception\GeneratorException
198
     */
199
    private function parseCollection($raw)
200
    {
201
        $jsonSchema = new JsonSchemaDto(false);
202
        foreach ($raw['properties'] as $rawProperty) {
203
            switch ($rawProperty['type']) {
204
                case NOSQLBase::NOSQL_TYPE_INTEGER:
205
                case NOSQLBase::NOSQL_TYPE_DOUBLE:
206
                case NOSQLBase::NOSQL_TYPE_LONG:
207
                    $property = new NumberPropertyDto(false);
208
                    break;
209
                case NOSQLBase::NOSQL_TYPE_ENUM:
210
                    $property = new EnumPropertyDto(false);
211
                    $property->enum = explode('|', $rawProperty['enum']);
212
                    break;
213
                default:
214
                    $property = new StringPropertyDto(false);
215
                    break;
216
            }
217
            if(array_key_exists('type', $rawProperty)) {
218
                $property->bsonType = $rawProperty['type'];
219
            }
220
            if(array_key_exists('description', $rawProperty)) {
221
                $property->description = $rawProperty['description'];
222
            }
223
            if (array_key_exists('required', $rawProperty) && $rawProperty['required']) {
224
                $jsonSchema->required[] = $rawProperty['name'];
225
            }
226
            $jsonSchema->properties[$rawProperty['name']] = $property->toArray();
227
        }
228
        return $jsonSchema;
229
    }
230
231
    /**
232
     * @return array
233
     * @throws \ReflectionException
234
     */
235
    public function getValidations() {
236
        $fieldTypes = new \ReflectionClass(Field::class);
237
        $validations = [];
238
        foreach($fieldTypes->getConstants() as $validation) {
239
            $validations[] = $validation;
240
        }
241
        return $validations;
242
    }
243
}
244