confirmcomposerpackage/src/Plugin.php

170 lines
7.2 KiB
PHP

<?php
/**
* Copyright 2018 D3 Data Development (Inh. Thomas Dartsch)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
* @link http://www.oxidmodule.com
*/
namespace D3\confirmComposerPackage;
use Composer\Command\RemoveCommand;
use Composer\Composer;
use Composer\Config\JsonConfigSource;
use Composer\DependencyResolver\Operation\InstallOperation;
use Composer\EventDispatcher\EventSubscriberInterface;
use Composer\Factory;
use Composer\Installer;
use Composer\Installer\PackageEvent;
use Composer\Installer\PackageEvents;
use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
use Composer\Json\JsonManipulator;
use Composer\Plugin\CommandEvent;
use Composer\Plugin\PluginEvents;
use Composer\Plugin\PluginInterface;
use OxidEsales\ComposerPlugin\Installer\Package\ShopPackageInstaller;
use Symfony\Component\Console\Application as SymphonyApplication;
use Symfony\Component\Console\Input\ArgvInput;
use Webmozart\PathUtil\Path;
class Plugin implements PluginInterface, EventSubscriberInterface
{
/** @var Composer */
protected $composer;
/** @var IOInterface */
protected $io;
public function activate(Composer $composer, IOInterface $io)
{
$this->composer = $composer;
$this->io = $io;
}
/**
* Register events.
*
* @return array
*/
public static function getSubscribedEvents()
{
return [
PackageEvents::POST_PACKAGE_INSTALL => [['onPostPackageInstall', 1]],
];
}
/**
* @param PackageEvent $event
* @throws \Exception
*/
public function onPostPackageInstall(PackageEvent $event)
{
/** @var InstallOperation $operation */
$operation = $event->getOperation();
if ($operation->getJobType() == 'install') {
$aExtra = $operation->getPackage()->getExtra();
if (is_array($aExtra) && isset($aExtra['packageConfirmation']) && isset($aExtra['packageConfirmation']['question'])) {
if (false == in_array(
trim(strtolower($this->io->ask($aExtra['packageConfirmation']['question']))),
array_map('strtolower', $aExtra['packageConfirmation']['acceptedanswers'])
)) {
$this->io->write("You didn't accept the necessary license. The package will be uninstalled. This may take a moment. Please wait.");
$app = new SymphonyApplication;
$definition = $app->getDefinition();
$input = new ArgvInput();
$output = Factory::createOutput();
$removeCommand = new RemoveCommand();
$removeCommand->getDefinition()->setOptions(
(array_merge($removeCommand->getDefinition()->getOptions(), $definition->getOptions()))
);
$input->bind($removeCommand->getDefinition());
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'remove', $input, $output);
$event->getComposer()->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);
$install = Installer::create($this->io, $event->getComposer());
$updateDevMode = !$input->getOption('update-no-dev');
$optimize = $input->getOption('optimize-autoloader') || $event->getComposer()->getConfig()->get('optimize-autoloader');
$authoritative = $input->getOption('classmap-authoritative') || $event->getComposer()->getConfig()->get('classmap-authoritative');
$apcu = $input->getOption('apcu-autoloader') || $event->getComposer()->getConfig()->get('apcu-autoloader');
$package = $operation->getPackage()->getName();
$packages = array(strtolower($package));
$install
->setVerbose($input->getOption('verbose'))
->setDevMode($updateDevMode)
->setOptimizeAutoloader($optimize)
->setClassMapAuthoritative($authoritative)
->setApcuAutoloader($apcu)
->setUpdate(false)
->setUpdateWhitelist($packages)
->setWhitelistTransitiveDependencies(!$input->getOption('no-update-with-dependencies'))
->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs'))
->setRunScripts(false);
$install->run();
$file = Factory::getComposerFile();
$jsonfile = new JsonFile($file);
$json = new JsonConfigSource($jsonfile);
$jsonarray = $jsonfile->read();
$jsoncontent = file_get_contents($file);
$type = $input->getOption('dev') ? 'require-dev' : 'require';
$altType = !$input->getOption('dev') ? 'require-dev' : 'require';
if (isset($jsonarray[$type][$package])) {
// $json->removeLink($type, $package);
$manipulator = new JsonManipulator($jsoncontent);
if ($manipulator->removeSubNode($type, $package)) {
file_put_contents($file, $manipulator->getContents());
}
} elseif (isset($jsonarray[$altType][$package])) {
$this->io->writeError('<warning>'.$package.' could not be found in '.$type.' but it is present in '.$altType.'</warning>');
if ($this->io->isInteractive()) {
if ($this->io->askConfirmation('Do you want to remove it from '.$altType.' [<comment>yes</comment>]? ', true)) {
//$json->removeLink($altType, $package);
$manipulator = new JsonManipulator($jsoncontent);
if ($manipulator->removeSubNode($altType, $package)) {
file_put_contents($file, $manipulator->getContents());
}
}
}
} else {
$this->io->writeError('<warning>'.$package.' is not required in your composer.json and has not been removed</warning>');
}
}
}
}
}
/**
* Get the path to shop's source directory.
*
* @return string
*/
public function getShopSourcePath()
{
return Path::join(getcwd(), ShopPackageInstaller::SHOP_SOURCE_DIRECTORY);
}
}