MigrationsManager::search()   B
last analyzed

Complexity

Conditions 9
Paths 12

Size

Total Lines 34
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 16
c 1
b 0
f 0
nc 12
nop 2
dl 0
loc 34
rs 8.0555
1
<?php
2
3
namespace Ffcms\Core\Managers;
4
5
use Apps\ActiveRecord\Migration;
0 ignored issues
show
Bug introduced by
The type Apps\ActiveRecord\Migration 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...
6
use Ffcms\Core\Helper\FileSystem\File;
7
use Ffcms\Core\Helper\FileSystem\Normalize;
8
use Ffcms\Core\Helper\Type\Any;
9
use Ffcms\Core\Helper\Type\Arr;
10
use Ffcms\Core\Helper\Type\Obj;
11
use Ffcms\Core\Helper\Type\Str;
12
13
/**
14
 * Class MigrationsManager. Manage migration files and database.
15
 * @package Ffcms\Core\Managers
16
 */
17
class MigrationsManager
18
{
19
    const DEFAULT_DIR = '/Private/Migrations';
20
21
    private $dir;
22
    private $connection;
23
    private $customDir = false;
24
25
    /**
26
     * MigrationsManager constructor. Pass directory inside or use default
27
     * @param string|null $dir
28
     * @param string|null $connectionName
29
     */
30
    public function __construct(?string $dir = null, ?string $connectionName = null)
31
    {
32
        if ($dir === null) {
33
            $dir = static::DEFAULT_DIR;
34
        }
35
36
        $this->dir = rtrim($dir, '/');
37
        $this->connection = $connectionName;
38
39
        if ($this->dir !== static::DEFAULT_DIR) {
40
            $this->customDir = true;
41
        }
42
    }
43
44
    /**
45
     * Search migration files. If $exists = false search only not installed files, if true - only installed
46
     * @param string|null $query
47
     * @param bool $exist
48
     * @return array|false
49
     */
50
    public function search(?string $query = null, bool $exist = false)
51
    {
52
        // initialize db migration record
53
        $records = new Migration();
54
        if ($this->connection !== null) {
55
            $records->setConnection($this->connection);
56
        }
57
58
        // get installed migrations
59
        $dbmigrations = Arr::pluck('migration', $records->get()->toArray());
60
61
        // list migrations
62
        $migrations = File::listFiles($this->dir, ['.php'], true);
63
        if (!Any::isArray($migrations) || count($migrations) < 1) {
64
            return false;
65
        }
66
67
        $found = false;
68
        foreach ($migrations as $migration) {
69
            // parse migration fullname
70
            $fullName = Str::cleanExtension($migration);
71
            // check if name contains search query conditions
72
            if (!Str::likeEmpty($query) && !Str::contains($query, $fullName)) {
0 ignored issues
show
Bug introduced by
It seems like $query can also be of type null; however, parameter $what of Ffcms\Core\Helper\Type\Str::contains() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

72
            if (!Str::likeEmpty($query) && !Str::contains(/** @scrutinizer ignore-type */ $query, $fullName)) {
Loading history...
Bug introduced by
It seems like $fullName can also be of type null; however, parameter $where of Ffcms\Core\Helper\Type\Str::contains() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

72
            if (!Str::likeEmpty($query) && !Str::contains($query, /** @scrutinizer ignore-type */ $fullName)) {
Loading history...
73
                continue;
74
            }
75
            // check initialize conditions (equals to $exist)
76
            if (File::exist($this->dir . '/' . $migration)) {
77
                if (Arr::in($fullName, $dbmigrations) === $exist) {
78
                    $found[] = $migration;
79
                }
80
            }
81
        }
82
83
        return $found;
84
    }
85
86
    /**
87
     * Run migration up
88
     * @param string|array $file
89
     * @return bool
90
     */
91
    public function makeUp($file)
92
    {
93
        // check if argument is array of files and run recursion
94
        if (Any::isArray($file)) {
95
            $success = true;
96
            foreach ($file as $single) {
97
                $exec = $this->makeUp($single);
98
                if (!$exec) {
99
                    $success = false;
100
                }
101
            }
102
            return $success;
103
        }
104
105
        // check if migration file is exists
106
        if (!File::exist($this->dir . '/' . $file)) {
0 ignored issues
show
Bug introduced by
Are you sure $file of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

106
        if (!File::exist($this->dir . '/' . /** @scrutinizer ignore-type */ $file)) {
Loading history...
107
            return false;
108
        }
109
110
        // check if migration file located in extend directory and copy to default
111
        if (Normalize::diskFullPath($this->dir) !== Normalize::diskFullPath(static::DEFAULT_DIR)) {
112
            File::copy($this->dir . DIRECTORY_SEPARATOR . $file, static::DEFAULT_DIR . DIRECTORY_SEPARATOR . $file);
113
        }
114
115
        // include migration and get class name
116
        File::inc($this->dir . '/' . $file, false, false);
117
        $fullName = Str::cleanExtension($file);
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type array; however, parameter $string of Ffcms\Core\Helper\Type\Str::cleanExtension() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

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

117
        $fullName = Str::cleanExtension(/** @scrutinizer ignore-type */ $file);
Loading history...
118
        $class = Str::firstIn($fullName, '-');
119
120
        // check if class is instance of migration interface
121
        if (!class_exists($class) || !is_a($class, 'Ffcms\Core\Migrations\MigrationInterface', true)) {
122
            return false;
123
        }
124
125
        // implement migration
126
        $init = new $class($fullName, $this->connection);
127
        $init->up();
128
        $init->seed();
129
130
        return true;
131
    }
132
133
    /**
134
     * Make migration down
135
     * @param array|string $file
136
     * @return bool
137
     */
138
    public function makeDown($file)
139
    {
140
        if (Any::isArray($file)) {
141
            $success = true;
142
            foreach ($file as $item) {
143
                $exec = $this->makeDown($file);
144
                if (!$exec) {
145
                    $success = false;
146
                }
147
                return $success;
148
            }
149
        }
150
151
        // check if exists
152
        if (!File::exist($this->dir . '/' . $file)) {
0 ignored issues
show
Bug introduced by
Are you sure $file of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

152
        if (!File::exist($this->dir . '/' . /** @scrutinizer ignore-type */ $file)) {
Loading history...
153
            return false;
154
        }
155
156
        File::inc($this->dir . '/' . $file, false, false);
157
        $fullName = Str::cleanExtension($file);
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type array; however, parameter $string of Ffcms\Core\Helper\Type\Str::cleanExtension() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

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

157
        $fullName = Str::cleanExtension(/** @scrutinizer ignore-type */ $file);
Loading history...
158
        $class = Str::firstIn($fullName, '-');
159
160
        // check if class is instance of migration interface
161
        if (!class_exists($class) || !is_a($class, 'Ffcms\Core\Migrations\MigrationInterface', true)) {
162
            return false;
163
        }
164
165
        // init migration and execute down method
166
        $init = new $class($fullName, $this->connection);
167
        $init->down();
168
169
        return true;
170
    }
171
}
172