Completed
Push — master ( f5fb34...c0a0d3 )
by mark
02:30 queued 01:05
created

Util::isUniqueMigrationClassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 1
cts 1
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 * Phinx
4
 *
5
 * (The MIT license)
6
 * Copyright (c) 2015 Rob Morgan
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a copy
9
 * of this software and associated * documentation files (the "Software"), to
10
 * deal in the Software without restriction, including without limitation the
11
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
12
 * sell copies of the Software, and to permit persons to whom the Software is
13
 * furnished to do so, subject to the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be included in
16
 * all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
 * IN THE SOFTWARE.
25
 *
26
 * @package    Phinx
27
 * @subpackage Phinx\Util
28
 */
29
namespace Phinx\Util;
30
31
class Util
32
{
33
    /**
34
     * @var string
35
     */
36
    const DATE_FORMAT = 'YmdHis';
37
38
    /**
39
     * @var string
40
     */
41
    const MIGRATION_FILE_NAME_PATTERN = '/^\d+_([\w_]+).php$/i';
42
43
    /**
44
     * @var string
45
     */
46
    const SEED_FILE_NAME_PATTERN = '/^([A-Z][a-z0-9]+).php$/i';
47
48
    /**
49
     * Gets the current timestamp string, in UTC.
50
     *
51
     * @return string
52
     */
53 15
    public static function getCurrentTimestamp()
54
    {
55 15
        $dt = new \DateTime('now', new \DateTimeZone('UTC'));
56 15
57
        return $dt->format(static::DATE_FORMAT);
58
    }
59
60
    /**
61
     * Gets an array of all the existing migration class names.
62
     *
63
     * @return string[]
64 15
     */
65
    public static function getExistingMigrationClassNames($path)
66 15
    {
67
        $classNames = [];
68 15
69 1
        if (!is_dir($path)) {
70
            return $classNames;
71
        }
72
73 14
        // filter the files to only get the ones that match our naming scheme
74
        $phpFiles = glob($path . DIRECTORY_SEPARATOR . '*.php');
75 14
76 3
        foreach ($phpFiles as $filePath) {
77 3
            if (preg_match('/([0-9]+)_([_a-z0-9]*).php/', basename($filePath))) {
78 3
                $classNames[] = static::mapFileNameToClassName(basename($filePath));
79 14
            }
80
        }
81 14
82
        return $classNames;
83
    }
84
85
    /**
86
     * Get the version from the beginning of a file name.
87
     *
88
     * @param string $fileName File Name
89
     * @return string
90 395
     */
91
    public static function getVersionFromFileName($fileName)
92 395
    {
93 395
        $matches = [];
94 395
        preg_match('/^[0-9]+/', basename($fileName), $matches);
95
96
        return $matches[0];
97
    }
98
99
    /**
100
     * Turn migration names like 'CreateUserTable' into file names like
101
     * '12345678901234_create_user_table.php' or 'LimitResourceNamesTo30Chars' into
102
     * '12345678901234_limit_resource_names_to_30_chars.php'.
103
     *
104
     * @param string $className Class Name
105 14
     * @return string
106
     */
107 14
    public static function mapClassNameToFileName($className)
108 14
    {
109 14
        $arr = preg_split('/(?=[A-Z])/', $className);
110 14
        unset($arr[0]); // remove the first element ('')
111
        $fileName = static::getCurrentTimestamp() . '_' . strtolower(implode('_', $arr)) . '.php';
112
113
        return $fileName;
114
    }
115
116
    /**
117
     * Turn file names like '12345678901234_create_user_table.php' into class
118
     * names like 'CreateUserTable'.
119
     *
120 391
     * @param string $fileName File Name
121
     * @return string
122 391
     */
123 391
    public static function mapFileNameToClassName($fileName)
124 391
    {
125 391
        $matches = [];
126
        if (preg_match(static::MIGRATION_FILE_NAME_PATTERN, $fileName, $matches)) {
127 391
            $fileName = $matches[1];
128
        }
129
130
        return str_replace(' ', '', ucwords(str_replace('_', ' ', $fileName)));
131
    }
132
133
    /**
134
     * Check if a migration class name is unique regardless of the
135
     * timestamp.
136
     *
137
     * This method takes a class name and a path to a migrations directory.
138
     *
139
     * Migration class names must be in CamelCase format.
140
     * e.g: CreateUserTable or AddIndexToPostsTable.
141
     *
142
     * Single words are not allowed on their own.
143
     *
144
     * @param string $className Class Name
145 13
     * @param string $path Path
146
     * @return bool
147 13
     */
148 13
    public static function isUniqueMigrationClassName($className, $path)
149
    {
150
        $existingClassNames = static::getExistingMigrationClassNames($path);
151
152
        return !(in_array($className, $existingClassNames));
153
    }
154
155
    /**
156
     * Check if a migration/seed class name is valid.
157
     *
158
     * Migration & Seed class names must be in CamelCase format.
159
     * e.g: CreateUserTable, AddIndexToPostsTable or UserSeeder.
160
     *
161
     * Single words are not allowed on their own.
162 16
     *
163
     * @param string $className Class Name
164 16
     * @return bool
165
     */
166
    public static function isValidPhinxClassName($className)
167
    {
168
        return (bool)preg_match('/^([A-Z][a-z0-9]+)+$/', $className);
169
    }
170
171
    /**
172
     * Check if a migration file name is valid.
173 387
     *
174
     * @param string $fileName File Name
175 387
     * @return bool
176 387
     */
177
    public static function isValidMigrationFileName($fileName)
178
    {
179
        $matches = [];
180
181
        return preg_match(static::MIGRATION_FILE_NAME_PATTERN, $fileName, $matches);
182
    }
183
184
    /**
185 11
     * Check if a seed file name is valid.
186
     *
187 11
     * @param string $fileName File Name
188 11
     * @return bool
189
     */
190
    public static function isValidSeedFileName($fileName)
191
    {
192
        $matches = [];
193
194
        return preg_match(static::SEED_FILE_NAME_PATTERN, $fileName, $matches);
195
    }
196
197 33
    /**
198
     * Expands a set of paths with curly braces (if supported by the OS).
199 33
     *
200
     * @param array $paths
201 33
     * @return array
202 33
     */
203 33
    public static function globAll(array $paths)
204
    {
205 33
        $result = [];
206
207
        foreach ($paths as $path) {
208
            $result = array_merge($result, static::glob($path));
209
        }
210
211
        return $result;
212
    }
213
214 431
    /**
215
     * Expands a path with curly braces (if supported by the OS).
216 431
     *
217
     * @param string $path
218
     * @return array
219
     */
220
    public static function glob($path)
221
    {
222
        return glob($path, defined('GLOB_BRACE') ? GLOB_BRACE : 0);
223
    }
224
225
    /**
226
     * Takes the path to a php file and attempts to include it if readable
227
     *
228
     * @return string
229
     */
230
    public static function loadPhpFile($filename)
231
    {
232
        $filePath = realpath($filename);
233
234
        /**
235
         * I lifed this from phpunits FileLoader class
236
         *
237
         * @see https://github.com/sebastianbergmann/phpunit/pull/2751
238
         */
239
        $isReadable = @\fopen($filePath, 'r') !== false;
240
241
        if (!$filePath || !$isReadable) {
242
            throw new \Exception(sprintf("Cannot open file %s \n", $filename));
243
        }
244
245
        include_once $filePath;
246
247
        return $filePath;
248
    }
249
250
    /**
251
     * Given an array of paths, return all unique PHP files that are in them
252
     *
253
     * @param string[] $paths array of paths to get php files
254
     * @return string[]
255
     */
256
    public static function getFiles($paths)
257
    {
258
        $files = static::globAll(array_map(function ($path) {
259
            return $path . DIRECTORY_SEPARATOR . "*.php";
260
        }, $paths));
261
        // glob() can return the same file multiple times
262
        // This will cause the migration to fail with a
263
        // false assumption of duplicate migrations
264
        // http://php.net/manual/en/function.glob.php#110340
265
        $files = array_unique($files);
266
267
        return $files;
268
    }
269
}
270