This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace ConsoleTools\Controller; |
||
4 | |||
5 | use Zend\Db\Adapter\Adapter; |
||
6 | use Zend\Mvc\Controller\AbstractActionController; |
||
7 | use Zend\Console\ColorInterface as Color; |
||
8 | use Zend\Console\Adapter\AdapterInterface as Console; |
||
9 | use Zend\Console\Exception\RuntimeException; |
||
10 | use ConsoleTools\Model\Migration; |
||
11 | use Zend\Console\Prompt\Char; |
||
12 | |||
13 | /** |
||
14 | * Controller for console operations as create, upgrate and current migrations |
||
15 | * |
||
16 | * @author V.Leontiev <[email protected]> |
||
17 | * @license http://opensource.org/licenses/MIT MIT |
||
18 | * @since php 5.6 or higher |
||
19 | * @see https://github.com/newage/console-tools |
||
20 | */ |
||
21 | class MigrationController extends AbstractActionController |
||
22 | { |
||
23 | const UPGRADE_KEY = 'up'; |
||
24 | const DOWNGRADE_KEY = 'down'; |
||
25 | |||
26 | /** |
||
27 | * Destination to folder with migration files |
||
28 | * |
||
29 | * @var string |
||
30 | */ |
||
31 | protected $migrationFolder = null; |
||
32 | |||
33 | /** |
||
34 | * Execute one migration |
||
35 | * |
||
36 | */ |
||
37 | public function executeAction() |
||
38 | { |
||
39 | /* @var $console Console */ |
||
40 | $console = $this->getServiceLocator()->get('console'); |
||
41 | $request = $this->getRequest(); |
||
42 | $migration = $request->getParam('number'); |
||
43 | $percona = $request->getParam('percona'); |
||
44 | $port = $request->getParam('port'); |
||
45 | |||
46 | $migrationPath = $this->getMigrationFolder(); |
||
47 | $filePath = $migrationPath . $migration . '.php'; |
||
48 | |||
49 | if (!file_exists($filePath)) { |
||
50 | $console->writeLine('Migration does not exists: ' . $filePath, Color::RED); |
||
51 | } else { |
||
52 | if (!$this->isApplySchema($console)) { |
||
53 | false; |
||
54 | } |
||
55 | |||
56 | $migrationArray = $this->includeMigration($filePath); |
||
57 | |||
58 | if ($request->getParam(self::UPGRADE_KEY)) { |
||
59 | $this->applyMigration(self::UPGRADE_KEY, $migration, $migrationArray, $percona, $port); |
||
60 | } elseif ($request->getParam(self::DOWNGRADE_KEY)) { |
||
61 | $this->applyMigration(self::DOWNGRADE_KEY, $migration, $migrationArray, $percona, $port); |
||
62 | } |
||
63 | } |
||
64 | } |
||
65 | |||
66 | /** |
||
67 | * Show confirm for migration |
||
68 | * |
||
69 | * @param string $action |
||
70 | * @param string $migration |
||
71 | * @param array $migrationArray |
||
72 | * @return bool |
||
73 | */ |
||
74 | protected function applyMigration($action, $migration, $migrationArray, $percona, $port) |
||
75 | { |
||
76 | /* @var $adapter \Zend\Db\Adapter\Adapter */ |
||
77 | /* @var $console Console */ |
||
78 | $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); |
||
79 | $console = $this->getServiceLocator()->get('console'); |
||
80 | $model = new Migration($adapter, $this->getServiceLocator(), $percona, $port); |
||
0 ignored issues
–
show
|
|||
81 | $methodName = $action == self::UPGRADE_KEY ? 'upgrade' : 'downgrade'; |
||
82 | |||
83 | $console->writeLine(); |
||
84 | $console->write('Current migration: '); |
||
85 | $console->writeLine($this->getMigrationFolder() . $migration . '.php', Color::YELLOW); |
||
86 | $console->writeLine($migrationArray[$action], Color::BLUE); |
||
87 | $exist = $model->get(array('migration' => $migration)); |
||
88 | $doNotSaveAsExecuted = false; |
||
89 | if (!empty($exist) && empty($exist['ignored'])) { |
||
90 | $console->writeLine('This migration was already executed', Color::YELLOW); |
||
91 | $doNotSaveAsExecuted = true; |
||
92 | } elseif (!empty($exist) && !empty($exist['ignored'])) { |
||
93 | $console->writeLine('This migration was already pseudo-executed (ignored)', Color::LIGHT_CYAN); |
||
94 | } |
||
95 | $answer = Char::prompt('Apply this migration (Yes / no / ignore forever)? [y/n/i]', 'yni'); |
||
96 | switch ($answer) { |
||
97 | case 'y': |
||
98 | if ($action == self::UPGRADE_KEY) { |
||
99 | $model->$methodName($migration, $migrationArray, $ignore = false, $doNotSaveAsExecuted); |
||
100 | $console->writeLine('This migration successful upgraded', Color::GREEN); |
||
101 | } else { |
||
102 | $model->$methodName($migration, $migrationArray, $ignore = false); |
||
103 | $console->writeLine('This migration successful downgraded', Color::GREEN); |
||
104 | } |
||
105 | break; |
||
106 | case 'i': |
||
107 | $model->$methodName($migration, $migrationArray, $ignore = true); |
||
108 | if ($action == self::UPGRADE_KEY) { |
||
109 | $console->writeLine('This migration pseudo-upgraded', Color::LIGHT_CYAN); |
||
110 | } else { |
||
111 | $console->writeLine('This migration pseudo-downgraded', Color::LIGHT_CYAN); |
||
112 | } |
||
113 | break; |
||
114 | case 'n': |
||
115 | default: |
||
116 | $console->writeLine('This migration discarded', Color::RED); |
||
117 | return false; |
||
118 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
119 | } |
||
120 | |||
121 | return true; |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * Create new migration file |
||
126 | * |
||
127 | * @throws RuntimeException |
||
128 | */ |
||
129 | public function createAction() |
||
130 | { |
||
131 | $console = $this->getServiceLocator()->get('console'); |
||
132 | |||
133 | if (!$console instanceof Console) { |
||
134 | throw new RuntimeException('Cannot obtain console adapter. Are we running in a console?'); |
||
135 | } |
||
136 | $request = $this->getRequest(); |
||
137 | $short_name = $request->getParam('short_name', ''); |
||
138 | |||
139 | $config = $this->getServiceLocator()->get('Config'); |
||
140 | if (isset($config['console-tools']['migration_template'])) { |
||
141 | $dateTemplate = $config['console-tools']['migration_template']; |
||
142 | } else { |
||
143 | $dateTemplate = 'YmdHis'; |
||
144 | } |
||
145 | |||
146 | $migrationPath = $this->getMigrationFolder(); |
||
147 | if (!is_dir($migrationPath)) { |
||
148 | mkdir($migrationPath, 0777); |
||
149 | } |
||
150 | |||
151 | $date = new \DateTime(); |
||
152 | if ($short_name) { |
||
153 | $short_name = '_' . $short_name; |
||
154 | } |
||
155 | |||
156 | $migrationName = $date->format($dateTemplate) . $short_name . '.php'; |
||
157 | |||
158 | $migrationContent = <<<EOD |
||
159 | <?php |
||
160 | |||
161 | return [ |
||
162 | 'up' => "", |
||
163 | 'down' => "" |
||
164 | ]; |
||
165 | |||
166 | EOD; |
||
167 | |||
168 | file_put_contents($migrationPath . $migrationName, $migrationContent); |
||
169 | |||
170 | $console->writeLine('Created migration file: ' . $migrationPath . $migrationName, Color::GREEN); |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * Upgrade/downgrade to migration |
||
175 | * |
||
176 | * @throws RuntimeException |
||
177 | */ |
||
178 | public function upgradeAction() |
||
179 | { |
||
180 | $console = $this->getServiceLocator()->get('console'); |
||
181 | if (!$console instanceof Console) { |
||
182 | throw new RuntimeException('Cannot obtain console adapter. Are we running in a console?'); |
||
183 | } |
||
184 | |||
185 | $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); |
||
186 | $request = $this->getRequest(); |
||
187 | $toMigration = $request->getParam('number', 'all'); |
||
188 | $percona = $request->getParam('percona'); |
||
189 | $port = $request->getParam('port'); |
||
190 | $model = new Migration($adapter, $this->getServiceLocator(), $percona, $port); |
||
0 ignored issues
–
show
$adapter is of type object|array , but the function expects a object<Zend\Db\Adapter\Adapter>|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
191 | $migrationsFromBase = $model->applied(); |
||
192 | $migrationFolderPath = $this->getMigrationFolder(); |
||
193 | $files = array(); |
||
194 | |||
195 | if (!$this->isApplySchema($console, $adapter)) { |
||
0 ignored issues
–
show
$adapter is of type object|array , but the function expects a null|object<Zend\Db\Adapter\Adapter> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
196 | false; |
||
197 | } |
||
198 | |||
199 | if ($toMigration == 'all') { |
||
200 | $filesDirty = scandir($migrationFolderPath); |
||
201 | for ($i=0; $i<count($filesDirty); $i++) { |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
202 | if (substr($filesDirty[$i], 0, 1) != '.') { |
||
203 | array_push($files, substr($filesDirty[$i], 0, -4)); |
||
204 | } |
||
205 | } |
||
206 | $filesFromDrive = array_diff($files, $migrationsFromBase); |
||
207 | asort($files, SORT_NATURAL); |
||
208 | $files = array_diff($filesFromDrive, $migrationsFromBase); |
||
209 | asort($files, SORT_NATURAL); |
||
210 | $upgradeAction = self::UPGRADE_KEY; |
||
211 | } elseif (in_array($toMigration, $migrationsFromBase)) { |
||
212 | $key = array_search($toMigration, $migrationsFromBase); |
||
213 | $files = array_slice($migrationsFromBase, $key); |
||
214 | rsort($files, SORT_NATURAL); |
||
215 | $upgradeAction = self::DOWNGRADE_KEY; |
||
216 | } else { |
||
217 | $console->writeLine('Did not apply the migration: ' . $toMigration, Color::RED); |
||
218 | return false; |
||
219 | } |
||
220 | |||
221 | if (!count($files)) { |
||
222 | $console->writeLine('You have last version of database', Color::GREEN); |
||
223 | return false; |
||
224 | } |
||
225 | |||
226 | foreach ($files as $migration) { |
||
227 | $migrationPath = $migrationFolderPath . |
||
228 | DIRECTORY_SEPARATOR . $migration . '.php'; |
||
229 | |||
230 | $migrationArray = $this->includeMigration($migrationPath); |
||
231 | |||
232 | try { |
||
233 | switch ($upgradeAction) { |
||
234 | case self::DOWNGRADE_KEY: |
||
235 | //downgrade action |
||
236 | $this->applyMigration(self::DOWNGRADE_KEY, $migration, $migrationArray, $percona, $port); |
||
237 | break; |
||
238 | case self::UPGRADE_KEY: |
||
239 | //upgrade action |
||
240 | $this->applyMigration(self::UPGRADE_KEY, $migration, $migrationArray, $percona, $port); |
||
241 | break; |
||
242 | default: |
||
243 | throw new \Exception('Not set action'); |
||
244 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
245 | } |
||
246 | continue; |
||
247 | } catch (\Exception $err) { |
||
248 | $console->writeLine('Current migration failed commit', Color::RED); |
||
249 | $console->writeLine($err->getMessage(), Color::RED); |
||
250 | return false; |
||
251 | } |
||
252 | } |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Show last applied migration number |
||
257 | * |
||
258 | */ |
||
259 | public function lastAction() |
||
260 | { |
||
261 | $console = $this->getServiceLocator()->get('console'); |
||
262 | if (!$console instanceof Console) { |
||
263 | throw new RuntimeException('Cannot obtain console adapter. Are we running in a console?'); |
||
264 | } |
||
265 | |||
266 | $request = $this->getRequest(); |
||
267 | $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); |
||
268 | $model = new Migration($adapter, $this->getServiceLocator()); |
||
0 ignored issues
–
show
$adapter is of type object|array , but the function expects a object<Zend\Db\Adapter\Adapter>|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
269 | $lastMigration = $model->last(); |
||
270 | |||
271 | $migrationName = $this->getMigrationFolder() . $lastMigration->last . '.php'; |
||
272 | if ($request->getParam('show')) { |
||
273 | $console->writeLine('Last applied the migration: ' . $migrationName, Color::GREEN); |
||
274 | $console->writeLine('=== Up SQL ===', Color::YELLOW); |
||
275 | $console->writeLine($lastMigration->up, Color::GREEN); |
||
276 | $console->writeLine('=== Down SQL ===', Color::YELLOW); |
||
277 | $console->writeLine($lastMigration->down, Color::GREEN); |
||
278 | } else { |
||
279 | $console->writeLine('Last applied the migration: ' . $migrationName, Color::GREEN); |
||
280 | } |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * @param Console|null $console |
||
285 | * @param Adapter|null $adapter |
||
286 | * @return bool |
||
287 | */ |
||
288 | protected function isApplySchema(Console $console = null, Adapter $adapter = null) |
||
289 | { |
||
290 | if ($console === null) { |
||
291 | $console = $this->getServiceLocator()->get('console'); |
||
292 | } |
||
293 | if ($adapter === null) { |
||
294 | $adapter = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter'); |
||
295 | } |
||
296 | |||
297 | $console->writeLine('Current DSN: ' . $adapter->getDriver()->getConnection()->getDsn(), Color::GREEN); |
||
298 | $answer = Char::prompt('The schema is correct (Yes/No)? [y/n]', 'yn'); |
||
299 | if ($answer == 'n') { |
||
300 | return false; |
||
301 | } |
||
302 | return true; |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * Get migration folder from config file |
||
307 | * |
||
308 | * @return string |
||
309 | */ |
||
310 | protected function getMigrationFolder() |
||
311 | { |
||
312 | if ($this->migrationFolder === null) { |
||
313 | $config = $this->getServiceLocator()->get('config'); |
||
314 | $this->migrationFolder = getcwd() . '/' . $config['console-tools']['migration_folder'] . '/'; |
||
315 | } |
||
316 | |||
317 | return $this->migrationFolder; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * @param $migrationPath |
||
322 | * @return mixed |
||
323 | */ |
||
324 | protected function includeMigration($migrationPath) |
||
325 | { |
||
326 | $migrationArray = include $migrationPath; |
||
327 | |||
328 | return $migrationArray; |
||
329 | } |
||
330 | } |
||
331 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: