Passed
Push — master ( 23ee75...fcbf2b )
by Alexander
69:22 queued 67:57
created

CycleOrmHelper::getCurrentSchemaArray()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 20
c 2
b 0
f 0
nc 3
nop 1
dl 0
loc 29
ccs 0
cts 25
cp 0
crap 12
rs 9.6
1
<?php
2
3
namespace Yiisoft\Yii\Cycle\Helper;
4
5
use Cycle\Migrations\GenerateMigrations;
6
use Cycle\Annotated;
7
use Cycle\Schema\Compiler;
8
use Cycle\Schema\Generator\GenerateRelations;
9
use Cycle\Schema\Generator\GenerateTypecast;
10
use Cycle\Schema\Generator\RenderRelations;
11
use Cycle\Schema\Generator\RenderTables;
12
use Cycle\Schema\Generator\ResetTables;
13
use Cycle\Schema\Generator\SyncTables;
14
use Cycle\Schema\Generator\ValidateEntities;
15
use Cycle\Schema\Registry;
16
use Doctrine\Common\Annotations\AnnotationRegistry;
17
use Spiral\Database\DatabaseManager;
18
use Spiral\Migrations\Config\MigrationConfig;
19
use Spiral\Migrations\Migrator;
20
use Spiral\Tokenizer\ClassLocator;
21
use Symfony\Component\Finder\Finder;
22
use Yiisoft\Aliases\Aliases;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Aliases\Aliases was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Psr\SimpleCache\CacheInterface;
0 ignored issues
show
Bug introduced by
The type Psr\SimpleCache\CacheInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
25
class CycleOrmHelper
26
{
27
    /** @var DatabaseManager $dbal */
28
    private $dbal;
29
30
    /** @var Aliases */
31
    private $aliases;
32
33
    /** @var CacheInterface */
34
    private $cache;
35
36
    /** @var string */
37
    private $cacheKey = 'Cycle-ORM-Schema';
38
39
    /** @var string[] */
40
    private $entityPaths = [];
41
42
    /** @var int */
43
    private $tableNaming = Annotated\Entities::TABLE_NAMING_SINGULAR;
44
45
    public function __construct(DatabaseManager $dbal, Aliases $aliases, CacheInterface $cache)
46
    {
47
        $this->aliases = $aliases;
48
        $this->dbal = $dbal;
49
        $this->cache = $cache;
50
    }
51
52
    /**
53
     * @param string|string[] $paths
54
     */
55
    public function addEntityPaths($paths): void
56
    {
57
        $paths = (array)$paths;
58
        foreach ($paths as $path) {
59
            $this->entityPaths[] = $path;
60
        }
61
    }
62
63
    public function dropCurrentSchemaCache(): void
64
    {
65
        $this->cache->delete($this->cacheKey);
66
    }
67
68
    public function generateMigrations(Migrator $migrator, MigrationConfig $config): void
69
    {
70
        $classLocator = $this->getEntityClassLocator();
71
72
        // autoload annotations
73
        AnnotationRegistry::registerLoader('class_exists');
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...istry::registerLoader() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists') ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

73
        /** @scrutinizer ignore-deprecated */ AnnotationRegistry::registerLoader('class_exists');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
74
75
        (new Compiler())->compile(new Registry($this->dbal), [
76
            new Annotated\Embeddings($classLocator),   // register embeddable entities
77
            new Annotated\Entities($classLocator, null, $this->tableNaming), // register annotated entities
78
            new ResetTables(),                         // re-declared table schemas (remove columns)
79
            new GenerateRelations(),                   // generate entity relations
80
            new ValidateEntities(),                    // make sure all entity schemas are correct
81
            new RenderTables(),                        // declare table schemas
82
            new RenderRelations(),                     // declare relation keys and indexes
83
            new GenerateMigrations($migrator->getRepository(), $config), // generate migrations
84
            // new GenerateTypecast(),                    // typecast non string columns
85
        ]);
86
    }
87
88
    public function getCurrentSchemaArray($fromCache = true): array
89
    {
90
        $getSchemaArray = function () {
91
            $classLocator = $this->getEntityClassLocator();
92
            // autoload annotations
93
            AnnotationRegistry::registerLoader('class_exists');
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...istry::registerLoader() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists') ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

93
            /** @scrutinizer ignore-deprecated */ AnnotationRegistry::registerLoader('class_exists');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
94
95
            return (new Compiler())->compile(new Registry($this->dbal), [
96
                new Annotated\Embeddings($classLocator),    // register embeddable entities
97
                new Annotated\Entities($classLocator, null, $this->tableNaming), // register annotated entities
98
                new ResetTables(),                          // re-declared table schemas (remove columns)
99
                new GenerateRelations(),                    // generate entity relations
100
                new ValidateEntities(),                     // make sure all entity schemas are correct
101
                new RenderTables(),                         // declare table schemas
102
                new RenderRelations(),                      // declare relation keys and indexes
103
                new SyncTables(),                           // sync table changes to database
104
                new GenerateTypecast(),                     // typecast non string columns
105
            ]);
106
        };
107
108
        if ($fromCache) {
109
            $schema = $this->cache->get($this->cacheKey);
110
            if (is_array($schema)) {
111
                return $schema;
112
            }
113
        }
114
        $schema = $getSchemaArray();
115
        $this->cache->set($this->cacheKey, $schema);
116
        return $schema;
117
    }
118
119
    private function getEntityClassLocator(): ClassLocator
120
    {
121
        $list = [];
122
        foreach ($this->entityPaths as $path) {
123
            $list[] = $this->aliases->get($path);
124
        }
125
        $finder = (new Finder())
126
            ->files()
127
            ->in($list);
128
129
        return new ClassLocator($finder);
130
    }
131
}
132