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 Modera\UpgradeBundle\Command; |
||
4 | |||
5 | use Modera\UpgradeBundle\Json\JsonFile; |
||
6 | use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; |
||
7 | use Symfony\Component\Console\Input\InputArgument; |
||
8 | use Symfony\Component\Console\Input\InputInterface; |
||
9 | use Symfony\Component\Console\Output\OutputInterface; |
||
10 | use Symfony\Component\Console\Input\StringInput; |
||
11 | use Symfony\Component\Console\Input\InputOption; |
||
12 | use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; |
||
13 | |||
14 | /** |
||
15 | * @author Sergei Vizel <[email protected]> |
||
16 | * @copyright 2014 Modera Foundation |
||
17 | */ |
||
18 | class UpgradeCommand extends ContainerAwareCommand |
||
19 | { |
||
20 | /** |
||
21 | * {@inheritdoc} |
||
22 | */ |
||
23 | protected function configure() |
||
24 | { |
||
25 | $this |
||
26 | ->setName('modera:upgrade') |
||
27 | ->setDescription('Updates dependencies in "composer.json" and runs required commands to upgrade MF') |
||
28 | ->setDefinition([ |
||
29 | new InputOption('dependencies', null, InputOption::VALUE_NONE, 'Update dependencies in "composer.json"'), |
||
30 | new InputOption('run-commands', null, InputOption::VALUE_NONE, 'Run commands'), |
||
31 | new InputArgument('versions-path', InputArgument::OPTIONAL, 'versions.json path', getcwd().'/versions.json'), |
||
32 | ]) |
||
33 | ; |
||
34 | } |
||
35 | |||
36 | /** |
||
37 | * {@inheritdoc} |
||
38 | */ |
||
39 | protected function execute(InputInterface $input, OutputInterface $output) |
||
40 | { |
||
41 | /* @var DialogHelper $dialog */ |
||
42 | $dialog = $this->getHelperSet()->get('dialog'); |
||
43 | |||
44 | $dependenciesOption = $input->getOption('dependencies'); |
||
45 | $runCommandsOption = $input->getOption('run-commands'); |
||
46 | |||
47 | $versionsPathArg = $input->getArgument('versions-path'); |
||
48 | $versionJsonPath = getcwd().'/modera-version.txt'; |
||
49 | |||
50 | $output->writeln(''); |
||
51 | |||
52 | if (!$dependenciesOption && !$runCommandsOption) { |
||
53 | $msg = [ |
||
54 | 'If you want to update dependencies then please use <info>--dependencies</info> option for the command, ', |
||
55 | 'if you need to have commands executed when a version is upgraded then use <info>--run-commands</info> option instead.', |
||
56 | ]; |
||
57 | $output->writeln(implode('', $msg)); |
||
58 | $output->writeln(''); |
||
59 | |||
60 | return; |
||
61 | } |
||
62 | |||
63 | $output->writeln("Reading upgrade instructions from '<info>$versionsPathArg</info>'."); |
||
64 | |||
65 | $basePath = dirname($this->getContainer()->get('kernel')->getRootdir()); |
||
66 | $composerFile = new JsonFile($basePath.'/composer.json'); |
||
67 | $versionsFile = new JsonFile($versionsPathArg); |
||
68 | |||
69 | $composerFileContents = $composerFile->read(); |
||
70 | $versionsFileContents = $versionsFile->read(); |
||
71 | |||
72 | $currentVersion = @file_get_contents($versionJsonPath); |
||
73 | |||
74 | if ($dependenciesOption) { |
||
75 | $newVersion = null; |
||
76 | $versions = array_keys($versionsFileContents); |
||
77 | |||
78 | if ($currentVersion && $currentVersion == $versions[count($versions) - 1]) { |
||
79 | $output->writeln("<info>You have the latest version $currentVersion</info>"); |
||
80 | $output->writeln(''); |
||
81 | |||
82 | return; |
||
83 | } |
||
84 | |||
85 | // backup composer.json |
||
86 | file_put_contents( |
||
87 | $basePath.'/composer'.($currentVersion ? '.v'.$currentVersion : '').'.backup.json', |
||
88 | file_get_contents($basePath.'/composer.json') |
||
89 | ); |
||
90 | |||
91 | // manage dependencies |
||
92 | $oldDependencies = $newDependencies = array(); |
||
93 | if (!$currentVersion) { |
||
94 | $newVersion = $versions[0]; |
||
95 | $newDependencies = $this->getArrayValue( |
||
96 | $versionsFileContents[$newVersion], 'dependencies', array() |
||
97 | ); |
||
98 | } else { |
||
99 | foreach (array_keys($versions) as $k) { |
||
100 | if ($versions[$k] == $currentVersion) { |
||
101 | $key = $k; |
||
102 | while ($key >= 0) { |
||
103 | $oldDependencies = $this->getArrayValue( |
||
104 | $versionsFileContents[$versions[$key]], 'dependencies' |
||
105 | ); |
||
106 | if (is_array($oldDependencies)) { |
||
107 | break; |
||
108 | } |
||
109 | $oldDependencies = array(); |
||
110 | --$key; |
||
111 | } |
||
112 | |||
113 | $newVersion = $versions[$k + 1]; |
||
114 | $newDependencies = $this->getArrayValue( |
||
115 | $versionsFileContents[$newVersion], 'dependencies', $oldDependencies |
||
116 | ); |
||
117 | break; |
||
118 | } |
||
119 | } |
||
120 | } |
||
121 | $dependenciesDiff = $this->diffDependencies($oldDependencies, $newDependencies); |
||
122 | $output->writeln(sprintf('<info>Upgrading from %s to %s</info>', $currentVersion ?: '-', $newVersion)); |
||
123 | |||
124 | $dependenciesOption = $composerFileContents['require']; |
||
125 | View Code Duplication | foreach ($dependenciesDiff['added'] as $name => $ver) { |
|
0 ignored issues
–
show
|
|||
126 | if (!isset($dependenciesOption[$name])) { |
||
127 | $dependenciesOption[$name] = $ver; |
||
128 | } else { |
||
129 | if ($ver !== $dependenciesOption[$name]) { |
||
130 | $msg = sprintf(implode('', [ |
||
131 | '<question>', |
||
132 | 'Dependency "%s:%s" already exists. ', |
||
133 | 'Would you like to change it to "%s:%s"? (Y/n)', |
||
134 | '</question>', |
||
135 | ]), $name, $dependenciesOption[$name], $name, $ver); |
||
136 | |||
137 | if ($dialog->askConfirmation($output, $msg)) { |
||
138 | $dependenciesOption[$name] = $ver; |
||
139 | } |
||
140 | } |
||
141 | } |
||
142 | } |
||
143 | foreach ($dependenciesDiff['changed'] as $name => $ver) { |
||
144 | if ( |
||
145 | !isset($dependenciesOption[$name]) |
||
146 | || $oldDependencies[$name] == $dependenciesOption[$name] |
||
147 | || $ver == $dependenciesOption[$name] |
||
148 | ) { |
||
149 | $dependenciesOption[$name] = $ver; |
||
150 | } else { |
||
151 | $msg = sprintf(implode('', [ |
||
152 | '<question>', |
||
153 | 'Dependency "%s:%s" already changed. ', |
||
154 | 'Would you like to change it to "%s:%s"? (Y/n)', |
||
155 | '</question>', |
||
156 | ]), $name, $dependenciesOption[$name], $name, $ver); |
||
157 | |||
158 | if ($dialog->askConfirmation($output, $msg)) { |
||
159 | $dependenciesOption[$name] = $ver; |
||
160 | } |
||
161 | } |
||
162 | } |
||
163 | foreach ($dependenciesDiff['removed'] as $name => $ver) { |
||
164 | if (isset($dependenciesOption[$name])) { |
||
165 | $msg = sprintf(implode('', [ |
||
166 | '<question>', |
||
167 | 'Dependency "%s" has been removed. ', |
||
168 | 'Would you like to remove it? (Y/n)', |
||
169 | '</question>', |
||
170 | ]), $name); |
||
171 | |||
172 | if ($dialog->askConfirmation($output, $msg)) { |
||
173 | unset($dependenciesOption[$name]); |
||
174 | } |
||
175 | } |
||
176 | } |
||
177 | View Code Duplication | foreach ($dependenciesDiff['same'] as $name => $ver) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
178 | if (!isset($dependenciesOption[$name])) { |
||
179 | $dependenciesOption[$name] = $ver; |
||
180 | } elseif ($ver !== $dependenciesOption[$name]) { |
||
181 | $msg = sprintf(implode('', [ |
||
182 | '<question>', |
||
183 | 'Dependency "%s:%s" has been manually changed. ', |
||
184 | 'Would you like to restore it to "%s:%s"? (Y/n)', |
||
185 | '</question>', |
||
186 | ]), $name, $dependenciesOption[$name], $name, $ver); |
||
187 | |||
188 | if ($dialog->askConfirmation($output, $msg)) { |
||
189 | $dependenciesOption[$name] = $ver; |
||
190 | } |
||
191 | } |
||
192 | } |
||
193 | $composerFileContents['require'] = $dependenciesOption; |
||
194 | |||
195 | // manage repositories |
||
196 | $repositories = $this->getArrayValue( |
||
197 | $composerFileContents, 'repositories', array() |
||
198 | ); |
||
199 | $addRepositories = $this->getArrayValue( |
||
200 | $versionsFileContents[$newVersion], 'add-repositories' |
||
201 | ); |
||
202 | $rmRepositories = $this->getArrayValue( |
||
203 | $versionsFileContents[$newVersion], 'rm-repositories' |
||
204 | ); |
||
205 | if ($addRepositories) { |
||
206 | foreach ($addRepositories as $repo) { |
||
207 | if (false === array_search($repo, $repositories)) { |
||
208 | $repositories[] = $repo; |
||
209 | } |
||
210 | } |
||
211 | } |
||
212 | if ($rmRepositories) { |
||
213 | foreach ($rmRepositories as $repo) { |
||
214 | if (false !== ($key = array_search($repo, $repositories))) { |
||
215 | unset($repositories[$key]); |
||
216 | } |
||
217 | } |
||
218 | $repositories = array_values($repositories); |
||
219 | } |
||
220 | $composerFileContents['repositories'] = $repositories; |
||
221 | |||
222 | // write modera-version.txt |
||
223 | file_put_contents($versionJsonPath, $newVersion); |
||
224 | |||
225 | // write composer.json |
||
226 | $composerFile->write($composerFileContents); |
||
227 | |||
228 | // interactions |
||
229 | $output->writeln("<info>composer.json 'requires' section has been updated to version $newVersion</info>"); |
||
230 | |||
231 | View Code Duplication | if (count($this->getArrayValue($versionsFileContents[$newVersion], 'add-bundles'))) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
232 | $output->writeln('<comment>Add bundle(s) to app/AppKernel.php</comment>'); |
||
233 | foreach ($versionsFileContents[$newVersion]['add-bundles'] as $bundle) { |
||
234 | $output->writeln(' '.$bundle); |
||
235 | } |
||
236 | } |
||
237 | View Code Duplication | if (count($this->getArrayValue($versionsFileContents[$newVersion], 'rm-bundles'))) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
238 | $output->writeln('<comment>Remove bundle(s) from app/AppKernel.php</comment>'); |
||
239 | foreach ($versionsFileContents[$newVersion]['rm-bundles'] as $bundle) { |
||
240 | $output->writeln(' '.$bundle); |
||
241 | } |
||
242 | } |
||
243 | |||
244 | View Code Duplication | if (count($this->getArrayValue($versionsFileContents[$newVersion], 'instructions'))) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
245 | foreach ($versionsFileContents[$newVersion]['instructions'] as $instruction) { |
||
246 | $output->writeln(sprintf('<comment>%s</comment>', $instruction)); |
||
247 | } |
||
248 | } |
||
249 | |||
250 | if (count($this->getArrayValue($versionsFileContents[$newVersion], 'commands'))) { |
||
251 | $output->writeln('After composer update run:'); |
||
252 | $output->writeln('<info>php app/console '.$this->getName().' --run-commands</info>'); |
||
253 | } |
||
254 | } elseif ($runCommandsOption) { |
||
255 | if ($currentVersion) { |
||
256 | $versionData = $this->getArrayValue( |
||
257 | $versionsFileContents, $currentVersion, array() |
||
258 | ); |
||
259 | $commands = $this->getArrayValue( |
||
260 | $versionData, 'commands', array() |
||
261 | ); |
||
262 | |||
263 | if (count($commands) > 0) { |
||
264 | $this->getApplication()->setAutoExit(false); |
||
265 | foreach ($commands as $command) { |
||
266 | $output->writeln(''); |
||
267 | $output->writeln("<comment>$command</comment>"); |
||
268 | $this->getApplication()->run(new StringInput($command), $output); |
||
269 | } |
||
270 | } else { |
||
271 | $output->writeln('<comment>No commands need to be run! Aborting ...</comment>'); |
||
272 | } |
||
273 | } |
||
274 | } |
||
275 | |||
276 | $output->writeln(''); |
||
277 | } |
||
278 | |||
279 | /** |
||
280 | * @param array $arr |
||
281 | * @param $key |
||
282 | * @param null $default |
||
283 | * |
||
284 | * @return mixed |
||
285 | */ |
||
286 | private function getArrayValue(array $arr, $key, $default = null) |
||
287 | { |
||
288 | if (isset($arr[$key])) { |
||
289 | return $arr[$key]; |
||
290 | } |
||
291 | |||
292 | return $default; |
||
293 | } |
||
294 | |||
295 | /** |
||
296 | * @param array $arr1 |
||
297 | * @param array $arr2 |
||
298 | * |
||
299 | * @return array |
||
300 | */ |
||
301 | private function diffDependencies(array $arr1, array $arr2) |
||
302 | { |
||
303 | $diff1 = array_diff_assoc($arr1, $arr2); |
||
304 | $diff2 = array_diff_assoc($arr2, $arr1); |
||
305 | $added = array_diff_key($diff2, $diff1); |
||
306 | $changed = array_diff_key($diff2, $added); |
||
307 | $removed = array_diff_key($diff1, $diff2); |
||
308 | $same = array_diff_key($arr1, $diff1); |
||
309 | |||
310 | return array( |
||
311 | 'added' => $added, |
||
312 | 'changed' => $changed, |
||
313 | 'removed' => $removed, |
||
314 | 'same' => $same, |
||
315 | ); |
||
316 | } |
||
317 | } |
||
318 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.