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 | /* |
||
| 4 | * This file is part of the composer-changelogs project. |
||
| 5 | * |
||
| 6 | * (c) Loïck Piera <[email protected]> |
||
| 7 | * |
||
| 8 | * For the full copyright and license information, please view the LICENSE |
||
| 9 | * file that was distributed with this source code. |
||
| 10 | */ |
||
| 11 | |||
| 12 | namespace Pyrech\ComposerChangelogs; |
||
| 13 | |||
| 14 | use Composer\Composer; |
||
| 15 | use Composer\EventDispatcher\EventSubscriberInterface; |
||
| 16 | use Composer\Installer\PackageEvent; |
||
| 17 | use Composer\Installer\PackageEvents; |
||
| 18 | use Composer\IO\IOInterface; |
||
| 19 | use Composer\Plugin\PluginInterface; |
||
| 20 | use Composer\Script\Event; |
||
| 21 | use Composer\Script\ScriptEvents; |
||
| 22 | use Pyrech\ComposerChangelogs\Config\Config; |
||
| 23 | use Pyrech\ComposerChangelogs\Config\ConfigBuilder; |
||
| 24 | use Pyrech\ComposerChangelogs\Config\ConfigLocator; |
||
| 25 | |||
| 26 | class ChangelogsPlugin implements PluginInterface, EventSubscriberInterface |
||
| 27 | { |
||
| 28 | const EXTRA_KEY = 'composer-changelogs'; |
||
| 29 | |||
| 30 | /** @var Composer */ |
||
| 31 | private $composer; |
||
| 32 | |||
| 33 | /** @var IOInterface */ |
||
| 34 | private $io; |
||
| 35 | |||
| 36 | /** @var Outputter */ |
||
| 37 | private $outputter; |
||
| 38 | |||
| 39 | /** @var ConfigLocator */ |
||
| 40 | private $configLocator; |
||
| 41 | |||
| 42 | /** @var Config */ |
||
| 43 | private $config; |
||
| 44 | |||
| 45 | /** @var int */ |
||
| 46 | private static $postUpdatePriority = -1; |
||
| 47 | |||
| 48 | /** |
||
| 49 | * {@inheritdoc} |
||
| 50 | */ |
||
| 51 | 14 | public function activate(Composer $composer, IOInterface $io) |
|
| 52 | { |
||
| 53 | 14 | $this->composer = $composer; |
|
| 54 | 14 | $this->io = $io; |
|
| 55 | 14 | $this->configLocator = new ConfigLocator($composer); |
|
| 56 | |||
| 57 | 14 | $this->setupConfig(); |
|
| 58 | 14 | $this->autoloadNeededClasses(); |
|
| 59 | |||
| 60 | 14 | $this->outputter = Factory::createOutputter($this->config->getGitlabHosts()); |
|
| 61 | 14 | } |
|
| 62 | |||
| 63 | /** |
||
| 64 | * {@inheritdoc} |
||
| 65 | */ |
||
| 66 | 6 | public static function getSubscribedEvents() |
|
| 67 | { |
||
| 68 | return [ |
||
| 69 | 6 | PackageEvents::POST_PACKAGE_UPDATE => [ |
|
| 70 | 6 | ['postPackageOperation'], |
|
| 71 | 6 | ], |
|
| 72 | 6 | PackageEvents::POST_PACKAGE_INSTALL => [ |
|
| 73 | 6 | ['postPackageOperation'], |
|
| 74 | 6 | ], |
|
| 75 | 6 | PackageEvents::POST_PACKAGE_UNINSTALL => [ |
|
| 76 | 6 | ['postPackageOperation'], |
|
| 77 | 6 | ], |
|
| 78 | 6 | ScriptEvents::POST_UPDATE_CMD => [ |
|
| 79 | 6 | ['postUpdate', static::$postUpdatePriority], |
|
|
0 ignored issues
–
show
|
|||
| 80 | 6 | ], |
|
| 81 | 6 | ]; |
|
| 82 | } |
||
| 83 | |||
| 84 | /** |
||
| 85 | * @param PackageEvent $event |
||
| 86 | */ |
||
| 87 | 10 | public function postPackageOperation(PackageEvent $event) |
|
| 88 | { |
||
| 89 | 10 | $operation = $event->getOperation(); |
|
| 90 | |||
| 91 | 10 | $this->outputter->addOperation($operation); |
|
| 92 | 10 | } |
|
| 93 | |||
| 94 | /** |
||
| 95 | * @param Event $event |
||
| 96 | */ |
||
| 97 | 10 | public function postUpdate(Event $event) |
|
| 98 | { |
||
| 99 | 10 | $this->io->write($this->outputter->getOutput()); |
|
| 100 | |||
| 101 | 10 | $this->handleCommit(); |
|
| 102 | 10 | } |
|
| 103 | |||
| 104 | /** |
||
| 105 | * This method ensures all the classes required to make the plugin working |
||
| 106 | * are loaded. |
||
| 107 | * |
||
| 108 | * It's required to avoid composer looking for classes no longer existing |
||
| 109 | * (after the plugin is updated or removed for example). |
||
| 110 | * |
||
| 111 | * Lot of classes (like operation handlers, url generators, Outputter, etc) |
||
| 112 | * do not need this because they are already autoloaded at the activation |
||
| 113 | * of the plugin. |
||
| 114 | */ |
||
| 115 | 14 | private function autoloadNeededClasses() |
|
| 116 | { |
||
| 117 | $classes = [ |
||
| 118 | 14 | 'Pyrech\ComposerChangelogs\Version', |
|
| 119 | 14 | ]; |
|
| 120 | |||
| 121 | 14 | foreach ($classes as $class) { |
|
| 122 | // Force the class to be autoloaded |
||
| 123 | 14 | class_exists($class, true); |
|
| 124 | 14 | } |
|
| 125 | 14 | } |
|
| 126 | |||
| 127 | 14 | private function setupConfig() |
|
| 128 | { |
||
| 129 | 14 | $builder = new ConfigBuilder(); |
|
| 130 | |||
| 131 | 14 | $this->config = $builder->build( |
|
| 132 | 14 | $this->configLocator->getConfig(self::EXTRA_KEY), |
|
| 133 | 14 | $this->configLocator->getPath(self::EXTRA_KEY) |
|
| 134 | 14 | ); |
|
| 135 | |||
| 136 | 14 | static::$postUpdatePriority = $this->config->getPostUpdatePriority(); |
|
|
0 ignored issues
–
show
Since
$postUpdatePriority is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $postUpdatePriority to at least protected.
Let’s assume you have a class which uses late-static binding: class YourClass
{
private static $someVariable;
public static function getSomeVariable()
{
return static::$someVariable;
}
}
The code above will run fine in your PHP runtime. However, if you now create a
sub-class and call the class YourSubClass extends YourClass { }
YourSubClass::getSomeVariable(); // Will cause an access error.
In the case above, it makes sense to update class SomeClass
{
private static $someVariable;
public static function getSomeVariable()
{
return self::$someVariable; // self works fine with private.
}
}
Loading history...
|
|||
| 137 | |||
| 138 | 14 | if (count($builder->getWarnings()) > 0) { |
|
| 139 | $this->io->writeError('<error>Invalid config for composer-changelogs plugin:</error>'); |
||
| 140 | foreach ($builder->getWarnings() as $warning) { |
||
| 141 | $this->io->write(' ' . $warning); |
||
| 142 | } |
||
| 143 | } |
||
| 144 | 14 | } |
|
| 145 | |||
| 146 | 10 | private function handleCommit() |
|
| 147 | { |
||
| 148 | 10 | if ($this->outputter->isEmpty()) { |
|
| 149 | return; |
||
| 150 | } |
||
| 151 | |||
| 152 | 10 | switch ($this->config->getCommitAuto()) { |
|
| 153 | 10 | case 'never': |
|
| 154 | 4 | return; |
|
| 155 | 6 | case 'ask': |
|
| 156 | if ($this->io->askConfirmation('<info>Would you like to commit the update? </info>[<comment>no</comment>]: ', false)) { |
||
| 157 | $this->doCommit(); |
||
| 158 | } |
||
| 159 | break; |
||
| 160 | 6 | case 'always': |
|
| 161 | 6 | $this->doCommit(); |
|
| 162 | 6 | } |
|
| 163 | 6 | } |
|
| 164 | |||
| 165 | 6 | private function doCommit() |
|
| 166 | { |
||
| 167 | 6 | if (!$this->config->getCommitBinFile()) { |
|
|
0 ignored issues
–
show
The expression
$this->config->getCommitBinFile() of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
Loading history...
|
|||
| 168 | $this->io->writeError('<error>No "commit-bin-file" for composer-changelogs plugin. Commit not done.</error>'); |
||
| 169 | |||
| 170 | return; |
||
| 171 | } |
||
| 172 | |||
| 173 | 6 | $workingDirectory = getcwd(); |
|
| 174 | 6 | $filename = tempnam(sys_get_temp_dir(), 'composer-changelogs-'); |
|
| 175 | 6 | $message = $this->config->getCommitMessage() . PHP_EOL . PHP_EOL . strip_tags($this->outputter->getOutput()); |
|
| 176 | |||
| 177 | 6 | file_put_contents($filename, $message); |
|
| 178 | |||
| 179 | 6 | $command = $this->config->getCommitBinFile() . ' ' . escapeshellarg($workingDirectory) . ' ' . escapeshellarg($filename); |
|
| 180 | |||
| 181 | 6 | $this->io->write(sprintf('Executing following command: %s', $command)); |
|
| 182 | 6 | exec($command); |
|
| 183 | 6 | } |
|
| 184 | } |
||
| 185 |
Let’s assume you have a class which uses late-static binding:
The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the
getSomeVariable()on that sub-class, you will receive a runtime error:In the case above, it makes sense to update
SomeClassto useselfinstead: