default services conflit ?

This commit is contained in:
armansansd
2022-04-27 11:30:43 +02:00
parent 28190a5749
commit 8bb1064a3b
8132 changed files with 900138 additions and 426 deletions

View File

@@ -0,0 +1,36 @@
<?php
/**
* @file
* Contains \Drupal\Console\Annotations\DrupalCommand.
*/
namespace Drupal\Console\Annotations;
use Doctrine\Common\Annotations\Annotation;
/**
* @Annotation
* @Target("CLASS")
*/
class DrupalCommand
{
/**
* @var string
*/
public $extension;
/**
* @Enum({"module", "theme", "profile", "library"})
*/
public $extensionType;
/**
* @var array
*/
public $dependencies;
/**
* @Enum({"none", "site", "install"})
*/
public $bootstrap;
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Drupal\Console\Annotations;
use Doctrine\Common\Annotations\AnnotationReader;
/**
* Class DrupalCommandReader
*
* @package Drupal\Console\Annotations
*/
class DrupalCommandAnnotationReader
{
/**
* @param $class
* @return array
*/
public function readAnnotation($class)
{
$annotation = [
'extension' => null,
'extensionType' => null,
'dependencies' => [],
'bootstrap' => 'installed'
];
$reader = new AnnotationReader();
$drupalCommandAnnotation = $reader->getClassAnnotation(
new \ReflectionClass($class),
'Drupal\\Console\\Annotations\\DrupalCommand'
);
if ($drupalCommandAnnotation) {
$annotation['extension'] = $drupalCommandAnnotation->extension?:null;
$annotation['extensionType'] = $drupalCommandAnnotation->extensionType?:null;
$annotation['dependencies'] = $drupalCommandAnnotation->dependencies?:[];
$annotation['bootstrap'] = $drupalCommandAnnotation->bootstrap?:'install';
}
return $annotation;
}
}

View File

@@ -0,0 +1,148 @@
<?php
namespace Drupal\Console;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Console\Annotations\DrupalCommandAnnotationReader;
use Drupal\Console\Utils\AnnotationValidator;
use Drupal\Console\Core\Application as BaseApplication;
/**
* Class Application
*
* @package Drupal\Console
*/
class Application extends BaseApplication
{
/**
* @var string
*/
const NAME = 'Drupal Console';
/**
* @var string
*/
const VERSION = '1.9.8';
public function __construct(ContainerInterface $container)
{
parent::__construct($container, $this::NAME, $this::VERSION);
}
/**
* Returns the long version of the application.
*
* @return string The long application version
*/
public function getLongVersion()
{
$output = '';
if ('UNKNOWN' !== $this->getName()) {
if ('UNKNOWN' !== $this->getVersion()) {
$output .= sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());
} else {
$output .= sprintf('<info>%s</info>', $this->getName());
}
} else {
$output .= '<info>Drupal Console</info>';
}
return $output;
}
/**
* {@inheritdoc}
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
$this->validateCommands();
return parent::doRun($input, $output);
}
public function validateCommands()
{
$consoleCommands = $this->container
->findTaggedServiceIds('drupal.command');
if (!$consoleCommands) {
return;
}
$serviceDefinitions = $this->container->getDefinitions();
if (!$serviceDefinitions) {
return;
}
if (!$this->container->has('console.annotation_command_reader')) {
return;
}
/**
* @var DrupalCommandAnnotationReader $annotationCommandReader
*/
$annotationCommandReader = $this->container
->get('console.annotation_command_reader');
if (!$this->container->has('console.annotation_validator')) {
return;
}
/**
* @var AnnotationValidator $annotationValidator
*/
$annotationValidator = $this->container
->get('console.annotation_validator');
$invalidCommands = [];
foreach ($consoleCommands as $name => $tags) {
AnnotationRegistry::reset();
AnnotationRegistry::registerLoader(
[
$this->container->get('class_loader'),
"loadClass"
]
);
if (!$this->container->has($name)) {
$invalidCommands[] = $name;
continue;
}
if (!$serviceDefinition = $serviceDefinitions[$name]) {
$invalidCommands[] = $name;
continue;
}
if (!$annotationValidator->isValidCommand(
$serviceDefinition->getClass()
)
) {
$invalidCommands[] = $name;
continue;
}
$annotation = $annotationCommandReader
->readAnnotation($serviceDefinition->getClass());
if ($annotation) {
$this->container->get('console.translator_manager')
->addResourceTranslationsByExtension(
$annotation['extension'],
$annotation['extensionType']
);
}
}
$this->container
->get('console.key_value_storage')
->set('invalid_commands', $invalidCommands);
return;
}
}

View File

@@ -0,0 +1,306 @@
<?php
namespace Drupal\Console\Bootstrap;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Component\FileCache\FileCacheFactory;
use Drupal\Core\Database\Database;
use Drupal\Console\Core\Style\DrupalStyle;
use Drupal\Console\Core\Utils\ArgvInputReader;
use Drupal\Console\Core\Bootstrap\DrupalConsoleCore;
use Drupal\Console\Core\Utils\DrupalFinder;
use Drupal\Console\Core\Bootstrap\DrupalInterface;
use Drupal\Console\Core\Utils\ConfigurationManager;
class Drupal implements DrupalInterface
{
protected $autoload;
/**
* @var DrupalFinder
*/
protected $drupalFinder;
/**
* @var ConfigurationManager
*/
protected $configurationManager;
/**
* Drupal constructor.
*
* @param $autoload
* @param $drupalFinder
* @param $configurationManager
*/
public function __construct(
$autoload,
DrupalFinder $drupalFinder,
ConfigurationManager $configurationManager
) {
$this->autoload = $autoload;
$this->drupalFinder = $drupalFinder;
$this->configurationManager = $configurationManager;
}
/**
* Boot the Drupal object
*
* @return \Symfony\Component\DependencyInjection\ContainerBuilder
*/
public function boot()
{
$output = new ConsoleOutput();
$input = new ArrayInput([]);
$io = new DrupalStyle($input, $output);
$argvInputReader = new ArgvInputReader();
$command = $argvInputReader->get('command');
$uri = $argvInputReader->get('uri');
$debug = $argvInputReader->get('debug', false);
if ($debug) {
$binaryPath = $this->drupalFinder->getVendorDir() .
'/drupal/console/bin/drupal';
$io->writeln("<info>Per-Site path:</info> <comment>$binaryPath</comment>");
$io->newLine();
}
if (!class_exists('Drupal\Core\DrupalKernel')) {
$io->error('Class Drupal\Core\DrupalKernel does not exist.');
return $this->bootDrupalConsoleCore();
}
try {
// Add support for Acquia Dev Desktop sites.
// Try both Mac and Windows home locations.
$home = getenv('HOME');
if (empty($home)) {
$home = getenv('USERPROFILE');
}
if (!empty($home)) {
$devDesktopSettingsDir = $home . "/.acquia/DevDesktop/DrupalSettings";
if (file_exists($devDesktopSettingsDir)) {
$_SERVER['DEVDESKTOP_DRUPAL_SETTINGS_DIR'] = $devDesktopSettingsDir;
}
}
if ($debug) {
$io->writeln('➤ Creating request');
}
$parsed_url = parse_url($uri);
if($parsed_url['scheme'] == 'https') {
$_SERVER['HTTPS'] = 'on';
}
$path = '/';
if(isset($parsed_url['path'])) {
$path = $parsed_url['path'] . $path;
}
$_SERVER['HTTP_HOST'] = parse_url($uri, PHP_URL_HOST);
$_SERVER['SERVER_PORT'] = null;
$_SERVER['REQUEST_URI'] = $path;
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$_SERVER['REQUEST_METHOD'] = 'GET';
$_SERVER['SERVER_SOFTWARE'] = null;
$_SERVER['HTTP_USER_AGENT'] = null;
$_SERVER['PHP_SELF'] = $_SERVER['REQUEST_URI'] . 'index.php';
$_SERVER['SCRIPT_NAME'] = $_SERVER['PHP_SELF'];
$_SERVER['SCRIPT_FILENAME'] = $this->drupalFinder->getDrupalRoot() . '/index.php';
$request = Request::createFromGlobals();
if ($debug) {
$io->writeln("\r\033[K\033[1A\r<info>✔</info>");
$io->writeln('➤ Creating Drupal kernel');
}
$updateCommands = [
'update:execute',
'upex',
'updb',
'update:entities',
'upe'
];
if (!in_array($command, $updateCommands)) {
$drupalKernel = DrupalKernel::createFromRequest(
$request,
$this->autoload,
'prod',
false,
$this->drupalFinder->getDrupalRoot()
);
} else {
$drupalKernel = DrupalUpdateKernel::createFromRequest(
$request,
$this->autoload,
'prod',
false,
$this->drupalFinder->getDrupalRoot()
);
}
if ($debug) {
$io->writeln("\r\033[K\033[1A\r<info>✔</info>");
$io->writeln('➤ Registering dynamic services');
}
$configuration = $this->configurationManager->getConfiguration();
$drupalKernel->addServiceModifier(
new DrupalServiceModifier(
$this->drupalFinder->getComposerRoot(),
'drupal.command',
'drupal.generator',
$configuration
)
);
if ($debug) {
$io->writeln("\r\033[K\033[1A\r<info>✔</info>");
$io->writeln('➤ Rebuilding container');
}
// Fix an exception of FileCacheFactory not prefix not set when
// container is build and looks that as we depend on cache for
// AddServicesCompilerPass but container is not ready this prefix
// needs to be set manually to allow use of the cache files.
FileCacheFactory::setPrefix($this->drupalFinder->getDrupalRoot());
// Invalidate container to ensure rebuild of any cached state
// when boot is processed.
$drupalKernel->invalidateContainer();
// Load legacy libraries, modules, register stream wrapper, and push
// request to request stack but without trigger processing of '/'
// request that invokes hooks like hook_page_attachments().
$drupalKernel->boot();
$drupalKernel->preHandle($request);
if ($debug) {
$io->writeln("\r\033[K\033[1A\r<info>✔</info>");
}
$container = $drupalKernel->getContainer();
if ($this->shouldRedirectToDrupalCore($container)) {
$container = $this->bootDrupalConsoleCore();
$container->set('class_loader', $this->autoload);
return $container;
}
$container->set(
'console.root',
$this->drupalFinder->getComposerRoot()
);
AnnotationRegistry::registerLoader([$this->autoload, "loadClass"]);
$container->set(
'console.configuration_manager',
$this->configurationManager
);
$container->get('console.translator_manager')
->loadCoreLanguage(
$configuration->get('application.language'),
$this->drupalFinder->getComposerRoot()
);
$container->get('console.renderer')
->setSkeletonDirs(
[
$this->drupalFinder->getComposerRoot().DRUPAL_CONSOLE.'/templates/',
$this->drupalFinder->getComposerRoot().DRUPAL_CONSOLE_CORE.'/templates/'
]
);
$container->set(
'console.drupal_finder',
$this->drupalFinder
);
$container->set(
'console.cache_key',
$drupalKernel->getContainerKey()
);
return $container;
} catch (\Exception $e) {
$container = $this->bootDrupalConsoleCore();
$container->set('class_loader', $this->autoload);
$container->get('console.renderer')
->setSkeletonDirs(
[
$this->drupalFinder->getComposerRoot().DRUPAL_CONSOLE.'/templates/',
$this->drupalFinder->getComposerRoot().DRUPAL_CONSOLE_CORE.'/templates/'
]
);
$notifyErrorCodes = [
0,
1045,
1049,
2002,
];
if (in_array($e->getCode(), $notifyErrorCodes)) {
/**
* @var \Drupal\Console\Core\Utils\MessageManager $messageManager
*/
$messageManager = $container->get('console.message_manager');
$messageManager->error(
$e->getMessage(),
$e->getCode(),
'list',
'site:install'
);
}
return $container;
}
}
/**
* Builds and boot a DrupalConsoleCore object
*
* @return \Symfony\Component\DependencyInjection\ContainerBuilder
*/
protected function bootDrupalConsoleCore()
{
$drupal = new DrupalConsoleCore(
$this->drupalFinder->getComposerRoot(),
$this->drupalFinder->getDrupalRoot(),
$this->drupalFinder
);
return $drupal->boot();
}
/**
* Validate if flow should redirect to DrupalCore
*
* @param $container
* @return bool
*/
protected function shouldRedirectToDrupalCore($container)
{
if (!Database::getConnectionInfo()) {
return true;
}
if (!$container->has('database')) {
return true;
}
return !$container->get('database')->schema()->tableExists('sessions');
}
}

View File

@@ -0,0 +1,67 @@
<?php
namespace Drupal\Console\Bootstrap;
use Dflydev\DotAccessConfiguration\ConfigurationInterface;
use Drupal\Console\Override\ConfigSubscriber;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Drupal\Console\Utils\TranslatorManager;
use Drupal\Core\Cache\ListCacheBinsPass;
/**
* DrupalCompilerPass
*/
class DrupalCompilerPass implements CompilerPassInterface
{
protected $configuration;
/**
* DrupalCompilerPass constructor.
*
* @param ConfigurationInterface $configuration
*/
public function __construct(ConfigurationInterface $configuration)
{
$this->configuration = $configuration;
}
/**
* @inheritdoc
*/
public function process(ContainerBuilder $container)
{
// The AddServicesCompilerPass cache pass is executed before the
// ListCacheBinsPass causing exception: ParameterNotFoundException: You
// have requested a non-existent parameter "cache_default_bin_backends"
$cache_pass = new ListCacheBinsPass();
$cache_pass->process($container);
// Override TranslatorManager service definition
$container
->getDefinition('console.translator_manager')
->setClass(TranslatorManager::class);
$skipValidateSiteUuid = $this->configuration
->get('application.overrides.config.skip-validate-site-uuid');
if ($skipValidateSiteUuid) {
// override system.config_subscriber
if ($container->has('system.config_subscriber')) {
$container->getDefinition('system.config_subscriber')
->setClass(ConfigSubscriber::class);
}
}
// Set console.invalid_commands service
$container
->get('console.key_value_storage')
->set('invalid_commands', null);
// Set console.cache_key service
$container->set(
'console.cache_key',
null
);
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Drupal\Console\Bootstrap;
use Drupal\Core\DrupalKernel as DrupalKernelBase;
/**
* Class DrupalKernel
*
* @package Drupal\Console\Bootstrap
*/
class DrupalKernel extends DrupalKernelBase
{
use DrupalKernelTrait;
}

View File

@@ -0,0 +1,179 @@
<?php
namespace Drupal\Console\Bootstrap;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\Request;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Console\Core\Utils\DrupalFinder;
/**
* Trait DrupalKernelTrait
*
* @package Drupal\Console\Bootstrap
*/
trait DrupalKernelTrait
{
/**
* @var ServiceModifierInterface[]
*/
protected $serviceModifiers = [];
/**
* @inheritdoc
*/
public static function createFromRequest(Request $request, $class_loader, $environment, $allow_dumping = true, $app_root = null)
{
$kernel = new static($environment, $class_loader, $allow_dumping, $app_root);
static::bootEnvironment($app_root);
$kernel->initializeSettings($request);
return $kernel;
}
/**
* @param \Drupal\Core\DependencyInjection\ServiceModifierInterface $serviceModifier
*/
public function addServiceModifier(ServiceModifierInterface $serviceModifier)
{
$this->serviceModifiers[] = $serviceModifier;
}
/**
* @inheritdoc
*/
protected function getContainerBuilder()
{
$container = parent::getContainerBuilder();
foreach ($this->serviceModifiers as $serviceModifier) {
$serviceModifier->alter($container);
}
return $container;
}
/**
* {@inheritdoc}
*/
public function discoverServiceProviders()
{
// Discover Drupal service providers
parent::discoverServiceProviders();
// Discover Drupal Console service providers
$this->discoverDrupalConsoleServiceProviders();
}
public function getContainerKey()
{
return hash("sha256", $this->getContainerCacheKey());
}
public function discoverDrupalConsoleServiceProviders()
{
$drupalFinder = new DrupalFinder();
$drupalFinder->locateRoot(getcwd());
// Load DrupalConsole services
$this->addDrupalConsoleServices($drupalFinder->getComposerRoot());
// Load DrupalConsole services
$this->addDrupalConsoleConfigServices($drupalFinder->getComposerRoot());
// Load DrupalConsole extended services
$this->addDrupalConsoleExtendedServices($drupalFinder->getComposerRoot());
// Add DrupalConsole module(s) services
$this->addDrupalConsoleModuleServices($drupalFinder->getDrupalRoot());
// Add DrupalConsole theme(s) services
$this->addDrupalConsoleThemeServices($drupalFinder->getDrupalRoot());
}
protected function addDrupalConsoleServices($root)
{
$servicesFiles = array_filter(
[
$root. DRUPAL_CONSOLE_CORE . 'services.yml',
$root. DRUPAL_CONSOLE . 'uninstall.services.yml',
$root. DRUPAL_CONSOLE . 'services.yml'
],
function ($file) {
return file_exists($file);
}
);
$this->addDrupalServiceFiles($servicesFiles);
}
protected function addDrupalConsoleConfigServices($root)
{
$finder = new Finder();
$finder->files()
->name('*.yml')
->in(
sprintf(
'%s/config/services',
$root.DRUPAL_CONSOLE
)
);
$servicesFiles = [];
foreach ($finder as $file) {
$servicesFiles[] = $file->getPathname();
}
$this->addDrupalServiceFiles($servicesFiles);
}
protected function addDrupalConsoleExtendedServices($root)
{
$servicesFiles = array_filter(
[
$root . DRUPAL_CONSOLE . 'extend.console.services.yml',
$root . DRUPAL_CONSOLE . 'extend.console.uninstall.services.yml',
],
function ($file) {
return file_exists($file);
}
);
$this->addDrupalServiceFiles($servicesFiles);
}
protected function addDrupalConsoleModuleServices($root)
{
$servicesFiles = [];
$moduleFileNames = $this->getModuleFileNames();
foreach ($moduleFileNames as $module => $filename) {
$servicesFile = $root . '/' .
dirname($filename) .
"/console.services.yml";
if (file_exists($servicesFile)) {
$servicesFiles[] = $servicesFile;
}
}
$this->addDrupalServiceFiles($servicesFiles);
}
public function addDrupalServiceFiles($servicesFiles)
{
$this->serviceYamls['site'] = array_merge(
$this->serviceYamls['site'],
$servicesFiles
);
}
protected function addDrupalConsoleThemeServices($root)
{
$themes = $this->getThemeFileNames();
}
private function getThemeFileNames()
{
$extensions = $this->getConfigStorage()->read('core.extension');
return isset($extensions['theme']) ? $extensions['theme'] : [];
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Drupal\Console\Bootstrap;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Dflydev\DotAccessConfiguration\ConfigurationInterface;
/**
* Class DrupalServiceModifier
*
* @package Drupal\Console\Bootstrap
*/
class DrupalServiceModifier implements ServiceModifierInterface
{
/**
* @var string
*/
protected $root;
/**
* @var string
*/
protected $commandTag;
/**
* @var string
*/
protected $generatorTag;
protected $configuration;
/**
* DrupalServiceModifier constructor.
*
* @param string $root
* @param string $serviceTag
* @param string $generatorTag
* @param ConfigurationInterface $configuration
*/
public function __construct(
$root = null,
$serviceTag,
$generatorTag,
$configuration
) {
$this->root = $root;
$this->commandTag = $serviceTag;
$this->generatorTag = $generatorTag;
$this->configuration = $configuration;
}
/**
* @inheritdoc
*/
public function alter(ContainerBuilder $container)
{
$container->addCompilerPass(
new DrupalCompilerPass($this->configuration)
);
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace Drupal\Console\Bootstrap;
use Drupal\Core\Update\UpdateKernel as DrupalKernelBase;
/**
* Class DrupalUpdateKernel
*
* @package Drupal\Console\Bootstrap
*/
class DrupalUpdateKernel extends DrupalKernelBase
{
use DrupalKernelTrait;
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Drupal\Console\Bootstrap;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* FindCommandsCompilerPass
*/
class FindCommandsCompilerPass implements CompilerPassInterface
{
/**
* @var string
*/
protected $serviceTag;
/**
* FindCommandsCompilerPass constructor.
*
* @param $serviceTag
*/
public function __construct($serviceTag)
{
$this->serviceTag = $serviceTag;
}
/**
* @inheritdoc
*/
public function process(ContainerBuilder $container)
{
$taggedServices = $container->findTaggedServiceIds(
$this->serviceTag
);
foreach ($taggedServices as $id => $tags) {
$container->getDefinition($id)
->addTag('persist');
}
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Drupal\Console\Bootstrap;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
/**
* FindGeneratorsCompilerPass
*/
class FindGeneratorsCompilerPass implements CompilerPassInterface
{
/**
* @var string
*/
protected $serviceTag;
/**
* FindCommandsCompilerPass constructor.
*
* @param $serviceTag
*/
public function __construct($serviceTag)
{
$this->serviceTag = $serviceTag;
}
/**
* @inheritdoc
*/
public function process(ContainerBuilder $container)
{
$taggedServices = $container->findTaggedServiceIds(
$this->serviceTag
);
$generators = [];
foreach ($taggedServices as $id => $tags) {
$generators[] = $id;
}
$container->setParameter('drupal.generators', $generators);
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Cache\RebuildCommand.
*/
namespace Drupal\Console\Command\Cache;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Utils\DrupalApi;
use Drupal\Console\Utils\Site;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Class RebuildCommand
*
* @package Drupal\Console\Command\Cache
*/
class RebuildCommand extends Command
{
/**
* @var DrupalApi
*/
protected $drupalApi;
/**
* @var Site
*/
protected $site;
protected $classLoader;
/**
* @var RequestStack
*/
protected $requestStack;
/**
* RebuildCommand constructor.
*
* @param DrupalApi $drupalApi
* @param Site $site
* @param $classLoader
* @param RequestStack $requestStack
*/
public function __construct(
DrupalApi $drupalApi,
Site $site,
$classLoader,
RequestStack $requestStack
) {
$this->drupalApi = $drupalApi;
$this->site = $site;
$this->classLoader = $classLoader;
$this->requestStack = $requestStack;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('cache:rebuild')
->setDescription($this->trans('commands.cache.rebuild.description'))
->addArgument(
'cache',
InputArgument::OPTIONAL,
$this->trans('commands.cache.rebuild.options.cache'),
'all'
)->setAliases(['cr']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$cache = $input->getArgument('cache')?:'all';
$this->site->loadLegacyFile('/core/includes/utility.inc');
if ($cache && !$this->drupalApi->isValidCache($cache)) {
$this->getIo()->error(
sprintf(
$this->trans('commands.cache.rebuild.messages.invalid-cache'),
$cache
)
);
return 1;
}
$this->getIo()->newLine();
$this->getIo()->comment($this->trans('commands.cache.rebuild.messages.rebuild'));
if ($cache === 'all') {
$this->drupalApi->drupal_rebuild(
$this->classLoader,
$this->requestStack->getCurrentRequest()
);
} else {
$caches = $this->drupalApi->getCaches();
$caches[$cache]->deleteAll();
}
$this->getIo()->success($this->trans('commands.cache.rebuild.messages.completed'));
return 0;
}
}

View File

@@ -0,0 +1,67 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Cache\TagInvalidateCommand.
*/
namespace Drupal\Console\Command\Cache;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class TagInvalidateCommand extends Command
{
/**
* @var CacheTagsInvalidatorInterface
*/
protected $invalidator;
/**
* TagInvalidateCommand constructor.
*
* @param CacheTagsInvalidatorInterface $invalidator
*/
public function __construct(CacheTagsInvalidatorInterface $invalidator)
{
parent::__construct();
$this->invalidator = $invalidator;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('cache:tag:invalidate')
->setDescription($this->trans('commands.cache.tag.invalidate.description'))
->addArgument(
'tag',
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
$this->trans('commands.cache.tag.invalidate.options.tag')
)
->setAliases(['cti']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$tags = $input->getArgument('tag');
$this->getIo()->comment(
sprintf(
$this->trans('commands.cache.tag.invalidate.messages.start'),
implode(', ', $tags)
)
);
$this->invalidator->invalidateTags($tags);
$this->getIo()->success($this->trans('commands.cache.tag.invalidate.messages.completed'));
}
}

View File

@@ -0,0 +1,374 @@
<?php
namespace Drupal\Console\Command;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Core\Utils\DrupalFinder;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\Component\Serialization\Json;
/**
* Class ComposerizeCommand
*
* @package Drupal\Console\Command
*/
class ComposerizeCommand extends ContainerAwareCommand
{
/**
* @var array
*/
protected $corePackages = [];
/**
* @var array
*/
protected $packages = [];
/**
* @var array
*/
protected $dependencies = [];
/**
* @var DrupalFinder
*/
protected $drupalFinder = null;
/**
* @var Manager $extensionManager
*/
protected $extensionManager = null;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('composerize')
->setDescription(
$this->trans('commands.composerize.description')
)
->addOption(
'show-packages',
null,
InputOption::VALUE_NONE,
$this->trans('commands.composerize.options.show-packages')
)
->addOption(
'include-version',
null,
InputOption::VALUE_NONE,
$this->trans('commands.composerize.options.include-version')
)
->setHelp($this->trans('commands.composerize.description'));
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$includeVersion = $input->getOption('include-version');
$showPackages = $input->getOption('show-packages')?:false;
$this->drupalFinder = $this->get('console.drupal_finder');
$this->extensionManager = $this->get('console.extension_manager');
$this->extractCorePackages();
$this->processProfiles();
$this->processModules();
$this->processThemes();
$types = [
'profile',
'module',
'theme'
];
$composerCommand = 'composer require ';
foreach ($types as $type) {
$packages = $this->packages[$type];
if (!$packages) {
continue;
}
if ($showPackages) {
$this->getIo()->comment($this->trans('commands.composerize.messages.'.$type));
$tableHeader = [
$this->trans('commands.composerize.messages.name'),
$this->trans('commands.composerize.messages.version'),
$this->trans('commands.composerize.messages.dependencies')
];
$this->getIo()->table($tableHeader, $packages);
}
foreach ($packages as $package) {
$module = str_replace('drupal/', '', $package['name']);
if (array_key_exists($module, $this->dependencies)) {
continue;
}
$composerCommand .= $package['name'];
if ($includeVersion) {
$composerCommand .= ':' . $package['version'];
}
$composerCommand .= ' ';
}
}
$this->getIo()->comment($this->trans('commands.composerize.messages.from'));
$this->getIo()->simple($this->drupalFinder->getComposerRoot());
$this->getIo()->newLine();
$this->getIo()->comment($this->trans('commands.composerize.messages.execute'));
$this->getIo()->simple($composerCommand);
$this->getIo()->newLine();
$this->getIo()->comment($this->trans('commands.composerize.messages.ignore'));
$webRoot = str_replace(
$this->drupalFinder->getComposerRoot() . '/',
'',
$this->drupalFinder->getDrupalRoot() . '/'
);
$this->getIo()->writeln(
[
' vendor/',
' '.$webRoot.'modules/contrib',
' '.$webRoot.'themes/contrib',
' '.$webRoot.'profiles/contrib'
]
);
}
private function extractCorePackages()
{
$this->corePackages['module'] = $this->extensionManager->discoverModules()
->showInstalled()
->showUninstalled()
->showCore()
->getList(true);
$this->corePackages['theme'] = $this->extensionManager->discoverThemes()
->showInstalled()
->showUninstalled()
->showCore()
->getList(true);
$this->corePackages['profile'] = $this->extensionManager->discoverProfiles()
->showInstalled()
->showUninstalled()
->showCore()
->getList(true);
}
private function processProfiles()
{
$type = 'profile';
$profiles = $this->extensionManager->discoverProfiles()
->showNoCore()
->showInstalled()
->getList();
/**
* @var \Drupal\Core\Extension\Extension[] $module
*/
foreach ($profiles as $profile) {
if (!$this->isValidModule($profile)) {
continue;
}
$dependencies = $this->extractDependencies(
$profile,
[]
);
$this->packages[$type][] = [
'name' => sprintf('drupal/%s', $profile->getName()),
'version' => $this->calculateVersion($profile->info['version']),
'dependencies' => implode(PHP_EOL, array_values($dependencies))
];
$this->dependencies = array_merge(
$this->dependencies,
$dependencies?$dependencies:[]
);
}
}
private function processModules()
{
$type = 'module';
$modules = $this->extensionManager->discoverModules()
->showInstalled()
->showNoCore()
->getList();
/**
* @var \Drupal\Core\Extension\Extension[] $module
*/
foreach ($modules as $module) {
if (!$this->isValidModule($module)) {
continue;
}
$dependencies = $this->extractDependencies(
$module,
array_keys($modules)
);
$this->packages[$type][] = [
'name' => sprintf('drupal/%s', $module->getName()),
'version' => $this->calculateVersion($module->info['version']),
'dependencies' => implode(PHP_EOL, array_values($dependencies))
];
$this->dependencies = array_merge(
$this->dependencies,
$dependencies?$dependencies:[]
);
}
}
private function processThemes()
{
$type = 'theme';
$themes = $this->extensionManager->discoverThemes()
->showInstalled()
->showNoCore()
->getList();
/**
* @var \Drupal\Core\Extension\Extension[] $module
*/
foreach ($themes as $theme) {
if (!$this->isValidTheme($theme)) {
continue;
}
$this->packages[$type][] = [
'name' => sprintf('drupal/%s', $theme->getName()),
'version' => $this->calculateVersion($theme->info['version']),
'dependencies' => ''
];
}
}
/**
* @param $module
* @return bool
*/
private function isValidModule($module)
{
if (strpos($module->getPath(), 'modules/custom') === 0) {
return false;
}
if (!array_key_exists('project', $module->info)) {
return true;
}
if (!array_key_exists('project', $module->info)) {
return true;
}
return $module->info['project'] === $module->getName();
}
/**
* @param $module
* @return bool
*/
private function isValidTheme($module)
{
if (strpos($module->getPath(), 'themes/custom') === 0) {
return false;
}
return true;
}
private function isValidDependency($moduleDependency, $extension, $extensions)
{
if (in_array($moduleDependency, $this->corePackages['module'])) {
return false;
}
if ($extensions && !in_array($moduleDependency, $extensions)) {
return false;
}
if ($moduleDependency !== $extension->getName()) {
return true;
}
}
/**
* @param $extension
* @param $extensions
* @return array
*/
private function extractDependencies($extension, $extensions)
{
if (!array_key_exists('dependencies', $extension->info)) {
return [];
}
$dependencies = [];
// Dependencies defined at info.yml
foreach ($extension->info['dependencies'] as $dependency) {
$dependencyExploded = explode(':', $dependency);
$moduleDependency = count($dependencyExploded)>1?$dependencyExploded[1]:$dependencyExploded[0];
if ($space = strpos($moduleDependency, ' ')) {
$moduleDependency = substr($moduleDependency, 0, $space);
}
if ($this->isValidDependency($moduleDependency, $extension, $extensions)) {
$dependencies[$moduleDependency] = 'drupal/'.$moduleDependency;
}
}
// Dependencies defined at composer.json
$composer = $this->readComposerFile($extension->getPath() . '/composer.json');
if (array_key_exists('require', $composer)) {
foreach (array_keys($composer['require']) as $package) {
if (strpos($package, 'drupal/') !== 0) {
continue;
}
$moduleDependency = str_replace('drupal/', '', $package);
if ($this->isValidDependency($moduleDependency, $extension, $extensions)) {
$dependencies[$moduleDependency] = $package;
}
}
}
return $dependencies;
}
protected function readComposerFile($file)
{
if (!file_exists($file)) {
return [];
}
return Json::decode(file_get_contents($file));
}
/**
* @param $version
* @return mixed
*/
private function calculateVersion($version)
{
$replaceKeys = [
'8.x-' => '',
'8.' => ''
];
return str_replace(
array_keys($replaceKeys),
array_values($replaceKeys),
$version
);
}
}

View File

@@ -0,0 +1,210 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\DeleteCommand.
*/
namespace Drupal\Console\Command\Config;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Exception\RuntimeException;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigFactory;
class DeleteCommand extends Command
{
protected $allConfig = [];
/**
* @var ConfigFactory
*/
protected $configFactory;
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var StorageInterface
*/
protected $configStorageSync;
/**
* DeleteCommand constructor.
*
* @param ConfigFactory $configFactory
* @param CachedStorage $configStorage
* @param StorageInterface $configStorageSync
*/
public function __construct(
ConfigFactory $configFactory,
CachedStorage $configStorage,
StorageInterface $configStorageSync
) {
$this->configFactory = $configFactory;
$this->configStorage = $configStorage;
$this->configStorageSync = $configStorageSync;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:delete')
->setDescription($this->trans('commands.config.delete.description'))
->addArgument(
'type',
InputArgument::OPTIONAL,
$this->trans('commands.config.delete.arguments.type')
)
->addArgument(
'name',
InputArgument::OPTIONAL,
$this->trans('commands.config.delete.arguments.name')
)->setAliases(['cd']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$type = $input->getArgument('type');
if (!$type) {
$type = $this->getIo()->choiceNoList(
$this->trans('commands.config.delete.arguments.type'),
['active', 'staging'],
'active'
);
$input->setArgument('type', $type);
}
$name = $input->getArgument('name');
if (!$name) {
$name = $this->getIo()->choiceNoList(
$this->trans('commands.config.delete.arguments.name'),
$this->getAllConfigNames(),
'all'
);
$input->setArgument('name', $name);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$type = $input->getArgument('type');
if (!$type) {
$this->getIo()->error($this->trans('commands.config.delete.errors.type'));
return 1;
}
$name = $input->getArgument('name');
if (!$name) {
$this->getIo()->error($this->trans('commands.config.delete.errors.name'));
return 1;
}
$configStorage = ('active' === $type) ? $this->configStorage : $this->configStorageSync;
if (!$configStorage) {
$this->getIo()->error($this->trans('commands.config.delete.errors.config-storage'));
return 1;
}
if ('all' === $name) {
$this->getIo()->commentBlock($this->trans('commands.config.delete.warnings.undo'));
if ($this->getIo()->confirm($this->trans('commands.config.delete.questions.sure'))) {
if ($configStorage instanceof FileStorage) {
$configStorage->deleteAll();
} else {
foreach ($this->yieldAllConfig() as $name) {
$this->removeConfig($name);
}
}
$this->getIo()->success($this->trans('commands.config.delete.messages.all'));
return 0;
}
}
if ($configStorage->exists($name)) {
if ($configStorage instanceof FileStorage) {
$configStorage->delete($name);
} else {
$this->removeConfig($name);
}
$this->getIo()->success(
sprintf(
$this->trans('commands.config.delete.messages.deleted'),
$name
)
);
return 0;
}
$message = sprintf($this->trans('commands.config.delete.errors.not-exists'), $name);
$this->getIo()->error($message);
return 1;
}
/**
* Retrieve configuration names form cache or service factory.
*
* @return array
* All configuration names.
*/
private function getAllConfigNames()
{
if ($this->allConfig) {
return $this->allConfig;
}
foreach ($this->configFactory->listAll() as $name) {
$this->allConfig[] = $name;
}
return $this->allConfig;
}
/**
* Yield configuration names.
*
* @return \Generator
* Yield generator with config name.
*/
private function yieldAllConfig()
{
$this->allConfig = $this->allConfig ?: $this->getAllConfigNames();
foreach ($this->allConfig as $name) {
yield $name;
}
}
/**
* Delete given config name.
*
* @param String $name Given config name.
*/
private function removeConfig($name)
{
try {
$this->configFactory->getEditable($name)->delete();
} catch (\Exception $e) {
throw new RuntimeException($e->getMessage());
}
}
}

View File

@@ -0,0 +1,134 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\DiffCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\StorageComparer;
use Drupal\Core\Site\Settings;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigManager;
class DiffCommand extends Command
{
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var ConfigManager
*/
protected $configManager;
/**
* DiffCommand constructor.
*
* @param CachedStorage $configStorage
* @param ConfigManager $configManager
*/
public function __construct(
CachedStorage $configStorage,
ConfigManager $configManager
) {
$this->configStorage = $configStorage;
$this->configManager = $configManager;
parent::__construct();
}
/**
* A static array map of operations -> color strings.
*
* @see http://symfony.com/doc/current/components/console/introduction.html#coloring-the-output
*
* @var array
*/
protected static $operationColours = [
'delete' => '<fg=red>%s</fg=red>',
'update' => '<fg=yellow>%s</fg=yellow>',
'create' => '<fg=green>%s</fg=green>',
'default' => '%s',
];
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:diff')
->setDescription($this->trans('commands.config.diff.description'))
->addArgument(
'directory',
InputArgument::OPTIONAL,
$this->trans('commands.config.diff.arguments.directory')
)
->addOption(
'reverse',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.diff.options.reverse')
)->setAliases(['cdi']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$config_directory = Settings::get('config_sync_directory');
$source_storage = new FileStorage($config_directory);
if ($input->getOption('reverse')) {
$config_comparer = new StorageComparer($source_storage, $this->configStorage, $this->configManager);
} else {
$config_comparer = new StorageComparer($this->configStorage, $source_storage, $this->configManager);
}
if (!$config_comparer->createChangelist()->hasChanges()) {
$output->writeln($this->trans('commands.config.diff.messages.no-changes'));
}
$change_list = [];
foreach ($config_comparer->getAllCollectionNames() as $collection) {
$change_list[$collection] = $config_comparer->getChangelist(null, $collection);
}
$this->outputDiffTable($change_list);
}
/**
* Ouputs a table of configuration changes.
*
* @param array $change_list
* The list of changes from the StorageComparer.
*/
protected function outputDiffTable(array $change_list)
{
$header = [
$this->trans('commands.config.diff.table.headers.collection'),
$this->trans('commands.config.diff.table.headers.config-name'),
$this->trans('commands.config.diff.table.headers.operation'),
];
$rows = [];
foreach ($change_list as $collection => $changes) {
foreach ($changes as $operation => $configs) {
foreach ($configs as $config) {
$rows[] = [
$collection,
$config,
sprintf(self::$operationColours[$operation], $operation),
];
}
}
}
$this->getIo()->table($header, $rows);
}
}

View File

@@ -0,0 +1,179 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\EditCommand.
*/
namespace Drupal\Console\Command\Config;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Process\ProcessBuilder;
use Symfony\Component\Yaml\Parser;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Core\Utils\ConfigurationManager;
class EditCommand extends Command
{
/**
* @var ConfigFactory
*/
protected $configFactory;
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var ConfigurationManager
*/
protected $configurationManager;
/**
* EditCommand constructor.
*
* @param ConfigFactory $configFactory
* @param CachedStorage $configStorage
* @param ConfigurationManager $configurationManager
*/
public function __construct(
ConfigFactory $configFactory,
CachedStorage $configStorage,
ConfigurationManager $configurationManager
) {
$this->configFactory = $configFactory;
$this->configStorage = $configStorage;
$this->configurationManager = $configurationManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:edit')
->setDescription($this->trans('commands.config.edit.description'))
->addArgument(
'config-name',
InputArgument::REQUIRED,
$this->trans('commands.config.edit.arguments.config-name')
)
->addArgument(
'editor',
InputArgument::OPTIONAL,
$this->trans('commands.config.edit.arguments.editor')
)
->setAliases(['ced']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$configName = $input->getArgument('config-name');
$editor = $input->getArgument('editor');
$config = $this->configFactory->getEditable($configName);
$configSystem = $this->configFactory->get('system.file');
$temporaryDirectory = $configSystem->get('path.temporary') ?: '/tmp';
$configFile = $temporaryDirectory.'/config-edit/'.$configName.'.yml';
$ymlFile = new Parser();
$fileSystem = new Filesystem();
if (!$configName) {
$this->getIo()->error($this->trans('commands.config.edit.messages.no-config'));
return 1;
}
try {
$fileSystem->mkdir($temporaryDirectory);
$fileSystem->dumpFile($configFile, $this->getYamlConfig($configName));
} catch (IOExceptionInterface $e) {
$this->getIo()->error($this->trans('commands.config.edit.messages.no-directory').' '.$e->getPath());
return 1;
}
if (!$editor) {
$editor = $this->getEditor();
}
$processBuilder = new ProcessBuilder([$editor, $configFile]);
$process = $processBuilder->getProcess();
$process->setTty('true');
$process->run();
if ($process->isSuccessful()) {
$value = $ymlFile->parse(file_get_contents($configFile));
$config->setData($value);
$config->save();
$fileSystem->remove($configFile);
}
if (!$process->isSuccessful()) {
$this->getIo()->error($process->getErrorOutput());
return 1;
}
return 0;
}
protected function interact(InputInterface $input, OutputInterface $output)
{
$configName = $input->getArgument('config-name');
if (!$configName) {
$configNames = $this->configFactory->listAll();
$configName = $this->getIo()->choice(
$this->trans('commands.config.edit.messages.choose-configuration'),
$configNames
);
$input->setArgument('config-name', $configName);
}
}
/**
* @param $config_name String
*
* @return array
*/
protected function getYamlConfig($config_name)
{
if ($this->configStorage->exists($config_name)) {
$configuration = $this->configStorage->read($config_name);
$configurationEncoded = Yaml::encode($configuration);
}
return $configurationEncoded;
}
/**
* @return string
*/
protected function getEditor()
{
$config = $this->configurationManager->getConfiguration();
$editor = $config->get('application.editor', '');
if ($editor != '') {
return trim($editor);
}
$processBuilder = new ProcessBuilder(['bash']);
$process = $processBuilder->getProcess();
$process->setCommandLine('echo ${EDITOR:-${VISUAL:-vi}}');
$process->run();
$editor = $process->getOutput();
$process->stop();
return trim($editor);
}
}

View File

@@ -0,0 +1,198 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ExportCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\Core\Archiver\ArchiveTar;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Site\Settings;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Filesystem\Filesystem;
use Drupal\Core\Config\ConfigManager;
class ExportCommand extends Command
{
/**
* @var ConfigManager
*/
protected $configManager;
/**
* @var StorageInterface
*/
protected $storage;
/**
* ExportCommand constructor.
*
* @param ConfigManagerInterface $configManager
* @param StorageInterface $storage
*/
public function __construct(ConfigManagerInterface $configManager, StorageInterface $storage)
{
parent::__construct();
$this->configManager = $configManager;
$this->storage = $storage;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:export')
->setDescription($this->trans('commands.config.export.description'))
->addOption(
'directory',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.export.options.directory')
)->addOption(
'remove-uuid',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.options.remove-uuid')
)->addOption(
'remove-config-hash',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.options.remove-config-hash')
)->addOption(
'tar',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.options.tar')
)
->setAliases(['ce']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
if (!$input->getOption('directory')) {
$directory = $this->getIo()->ask(
$this->trans('commands.config.export.questions.directory'),
Settings::get('config_sync_directory')
);
$input->setOption('directory', $directory);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$drupal_root = $this->drupalFinder->getComposerRoot();
$directory = $drupal_root.'/'.$input->getOption('directory');
$tar = $input->getOption('tar');
$removeUuid = $input->getOption('remove-uuid');
$removeHash = $input->getOption('remove-config-hash');
$drupal_root = $this->drupalFinder->getComposerRoot();
if (!$directory) {
$directory = Settings::get('config_sync_directory') ;
}
$fileSystem = new Filesystem();
try {
$fileSystem->mkdir($drupal_root."/".$directory);
} catch (IOExceptionInterface $e) {
$this->getIo()->error(
sprintf(
$this->trans('commands.config.export.messages.error'),
$e->getPath()
)
);
}
// Remove previous yaml files before creating new ones
foreach (glob($directory . '/*') as $item) {
$fileSystem->remove($item);
}
if ($tar) {
$dateTime = new \DateTime();
$archiveFile = sprintf(
'%s/config-%s.tar.gz',
$directory,
$dateTime->format('Y-m-d-H-i-s')
);
$archiveTar = new ArchiveTar($archiveFile, 'gz');
}
try {
// Get raw configuration data without overrides.
foreach ($this->configManager->getConfigFactory()->listAll() as $name) {
$configName = "$name.yml";
$configData = $this->configManager->getConfigFactory()->get($name)->getRawData();
if ($removeUuid) {
unset($configData['uuid']);
}
if ($removeHash) {
unset($configData['_core']['default_config_hash']);
if (empty($configData['_core'])) {
unset($configData['_core']);
}
}
$ymlData = Yaml::encode($configData);
if ($tar) {
$archiveTar->addString($configName, $ymlData);
} else {
file_put_contents("$directory/$configName", $ymlData);
}
}
// Get all override data from the remaining collections.
foreach ($this->storage->getAllCollectionNames() as $collection) {
$collection_storage = $this->storage->createCollection($collection);
$collection_path = str_replace('.', '/', $collection);
if (!$tar) {
$fileSystem->mkdir("$directory/$collection_path", 0755);
}
foreach ($collection_storage->listAll() as $name) {
$configName = "$collection_path/$name.yml";
$configData = $collection_storage->read($name);
if ($removeUuid) {
unset($configData['uuid']);
}
if ($removeHash) {
unset($configData['_core']['default_config_hash']);
if (empty($configData['_core'])) {
unset($configData['_core']);
}
}
$ymlData = Yaml::encode($configData);
if ($tar) {
$archiveTar->addString($configName, $ymlData);
} else {
file_put_contents("$directory/$configName", $ymlData);
}
}
}
} catch (\Exception $e) {
$this->getIo()->error($e->getMessage());
}
$this->getIo()->info(
sprintf(
$this->trans('commands.config.export.messages.directory'),
$directory
)
);
}
}

View File

@@ -0,0 +1,212 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ExportContentTypeCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\Console\Command\Shared\ExportTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Core\Config\CachedStorage;
class ExportContentTypeCommand extends Command
{
use ModuleTrait;
use ExportTrait;
const ALL = '-all-';
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var Validator
*/
protected $validator;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* ExportContentTypeCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param Validator $validator
* @param ChainQueue $chainQueue
* @param CachedStorage $configStorage,
*/
public function __construct(
Manager $extensionManager,
EntityTypeManagerInterface $entityTypeManager,
Validator $validator,
ChainQueue $chainQueue,
CachedStorage $configStorage
) {
$this->extensionManager = $extensionManager;
$this->entityTypeManager = $entityTypeManager;
$this->validator = $validator;
$this->chainQueue = $chainQueue;
$this->configStorage = $configStorage;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:export:content:type')
->setDescription($this->trans('commands.config.export.content.type.description'))
->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module'))
->addArgument(
'content-type',
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
$this->trans('commands.config.export.content.type.arguments.content-type')
)->addOption(
'optional-config',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.content.type.options.optional-config')
)->addOption(
'remove-uuid',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.content.type.options.remove-uuid')
)->addOption(
'remove-config-hash',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.content.type.options.remove-config-hash')
)
->addOption(
'include-module-dependencies',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.export.content.type.options.include-module-dependencies')
)
->setAliases(['cect']);
$this->configExport = [];
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$this->getModuleOption();
// --content-type argument
$contentType = $input->getArgument('content-type');
if (!$contentType) {
$bundles_entities = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
$bundles = [ExportContentTypeCommand::ALL => $this->trans('commands.config.export.content.type.questions.all')];
$bundles_ids = [];
foreach ($bundles_entities as $entity) {
$bundles[$entity->id()] = $entity->label();
$bundles_ids[] = $entity->id();
}
if (!$contentType) {
$contentType = $this->getIo()->choice(
$this->trans('commands.config.export.content.type.questions.content-type'),
$bundles
);
}
if ($contentType == ExportContentTypeCommand::ALL) {
$input->setArgument('content-type', $bundles_ids);
}else{
$input->setArgument('content-type', [$contentType]);
}
}
$optionalConfig = $input->getOption('optional-config');
if (!$optionalConfig) {
$optionalConfig = $this->getIo()->confirm(
$this->trans('commands.config.export.content.type.questions.optional-config'),
true
);
$input->setOption('optional-config', $optionalConfig);
}
if (!$input->getOption('remove-uuid')) {
$removeUuid = $this->getIo()->confirm(
$this->trans('commands.config.export.content.type.questions.remove-uuid'),
true
);
$input->setOption('remove-uuid', $removeUuid);
}
if (!$input->getOption('remove-config-hash')) {
$removeHash = $this->getIo()->confirm(
$this->trans('commands.config.export.content.type.questions.remove-config-hash'),
true
);
$input->setOption('remove-config-hash', $removeHash);
}
$includeModuleDependencies = $input->getOption('include-module-dependencies');
if (!$includeModuleDependencies) {
$includeModuleDependencies = $this->getIo()->confirm(
$this->trans('commands.config.export.content.type.questions.include-module-dependencies'),
true
);
$input->setOption('include-module-dependencies', $includeModuleDependencies);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$module = $input->getOption('module');
$contentTypes = $input->getArgument('content-type');
$optionalConfig = $input->getOption('optional-config');
$removeUuid = $input->getOption('remove-uuid');
$removeHash = $input->getOption('remove-config-hash');
$includeModuleDependencies = $input->getOption('include-module-dependencies');
$this->chainQueue->addCommand(
'config:export:entity', [
'entity-type' => 'node_type',
'bundle' => $contentTypes,
'--module' => $module,
'--optional-config' => $optionalConfig,
'--remove-uuid' => $removeUuid,
'--remove-config-hash' => $removeHash,
'--include-module-dependencies' => $includeModuleDependencies
]
);
}
}

View File

@@ -0,0 +1,271 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ExportEntityCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\Console\Command\Shared\ExportTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeRepositoryInterface;
use Symfony\Component\Console\Exception\InvalidOptionException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class ExportEntityCommand extends Command {
use ModuleTrait;
use ExportTrait;
const ALL = '-all-';
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var EntityTypeRepositoryInterface
*/
protected $entityTypeRepository;
protected $configExport;
/**
* @var Validator
*/
protected $validator;
/**
* @var StorageInterface
*/
protected $storage;
/**
* ExportContentTypeCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param CachedStorage $configStorage
* @param Manager $extensionManager
* @param Validator $validator
* @param EntityTypeRepositoryInterface $entityTypeRepository
* @param StorageInterface $storage
*/
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
CachedStorage $configStorage,
Manager $extensionManager,
Validator $validator,
EntityTypeRepositoryInterface $entityTypeRepository,
StorageInterface $storage
) {
$this->entityTypeManager = $entityTypeManager;
$this->configStorage = $configStorage;
$this->extensionManager = $extensionManager;
$this->validator = $validator;
$this->entityTypeRepository = $entityTypeRepository;
$this->storage = $storage;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure() {
$this
->setName('config:export:entity')
->setDescription($this->trans('commands.config.export.entity.description'))
->addOption('module', NULL, InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module'))
->addArgument(
'entity-type',
InputArgument::REQUIRED,
$this->trans('commands.config.export.entity.arguments.entity-type')
)
->addArgument(
'bundle',
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
$this->trans('commands.config.export.entity.arguments.bundle')
)->addOption(
'optional-config',
NULL,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.entity.options.optional-config')
)->addOption(
'remove-uuid',
NULL,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.entity.options.remove-uuid')
)->addOption(
'remove-config-hash',
NULL,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.entity.options.remove-config-hash')
)
->addOption(
'include-module-dependencies',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.export.entity.options.include-module-dependencies')
)
->setAliases(['cee']);
$this->configExport = [];
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output) {
// --module option
$this->getModuleOption();
$entity_types = $this->entityTypeRepository->getEntityTypeLabels(true);
ksort($entity_types['Configuration']);
// --content-type argument
$entityType = $input->getArgument('entity-type');
if (!$entityType) {
$entityType = $this->getIo()->choice(
$this->trans('commands.config.export.entity.questions.content-type'),
$entity_types['Configuration']
);
$input->setArgument('entity-type', $entityType);
}
// --bundle argument
$bundle = $input->getArgument('bundle');
if (!$bundle) {
$bundles_entities = $this->entityTypeManager->getStorage($entityType)
->loadMultiple();
$bundles = [ExportEntityCommand::ALL => $this->trans('commands.config.export.entity.questions.all')];
$bundles_ids = [];
foreach ($bundles_entities as $entity) {
$bundles[$entity->id()] = $entity->label();
$bundles_ids[] = $entity->id();
}
$bundle = $this->getIo()->choice(
$this->trans('commands.config.export.entity.questions.bundle'),
$bundles
);
if ($bundle == ExportEntityCommand::ALL) {
$input->setArgument('bundle', $bundles_ids);
} else {
$input->setArgument('bundle', [$bundle]);
}
}
$optionalConfig = $input->getOption('optional-config');
if (!$optionalConfig) {
$optionalConfig = $this->getIo()->confirm(
$this->trans('commands.config.export.entity.questions.optional-config'),
TRUE
);
$input->setOption('optional-config', $optionalConfig);
}
if (!$input->getOption('remove-uuid')) {
$removeUuid = $this->getIo()->confirm(
$this->trans('commands.config.export.entity.questions.remove-uuid'),
TRUE
);
$input->setOption('remove-uuid', $removeUuid);
}
if (!$input->getOption('remove-config-hash')) {
$removeHash = $this->getIo()->confirm(
$this->trans('commands.config.export.entity.questions.remove-config-hash'),
TRUE
);
$input->setOption('remove-config-hash', $removeHash);
}
$includeModuleDependencies = $input->getOption('include-module-dependencies');
if (!$includeModuleDependencies) {
$includeModuleDependencies = $this->getIo()->confirm(
$this->trans('commands.config.export.entity.questions.include-module-dependencies'),
true
);
$input->setOption('include-module-dependencies', $includeModuleDependencies);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output) {
$module = $this->validateModule($input->getOption('module'));
$entityType = $input->getArgument('entity-type');
$bundles = $input->getArgument('bundle');
$optionalConfig = $input->getOption('optional-config');
$removeUuid = $input->getOption('remove-uuid');
$removeHash = $input->getOption('remove-config-hash');
$includeModuleDependencies = $input->getOption('include-module-dependencies');
foreach ($bundles as $bundle) {
$bundleDefinition = $this->entityTypeManager->getDefinition($entityType);
$bundleName = "{$bundleDefinition->getConfigPrefix()}.{$bundle}";
$bundleNameConfig = $this->getConfiguration($bundleName,
$removeUuid, $removeHash);
if (empty($bundleNameConfig)) {
throw new InvalidOptionException(sprintf('The bundle %s does not exist.',
$bundle));
}
$this->configExport[$bundleName] = [
'data' => $bundleNameConfig,
'optional' => $optionalConfig,
];
$this->getBasefieldOverrideFields($bundle, $optionalConfig, $removeUuid, $removeHash);
$this->getFields($bundle, $optionalConfig, $removeUuid, $removeHash);
$this->getFormDisplays($bundle, $optionalConfig, $removeUuid,
$removeHash);
$this->getViewDisplays($bundle, $optionalConfig, $removeUuid,
$removeHash);
// Include module dependencies in export files if export is not optional
if ($includeModuleDependencies) {
if ($dependencies = $this->fetchDependencies($bundleNameConfig, 'module')) {
$this->exportModuleDependencies($module, $dependencies);
}
}
$this->exportConfigToModule($module,
sprintf(
$this->trans('commands.config.export.entity.messages.bundle-exported'),
$bundle
));
}
}
}

View File

@@ -0,0 +1,347 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ExportSingleCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Site\Settings;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Config\CachedStorage;
use Drupal\Console\Command\Shared\ExportTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Extension\Manager;
use Drupal\Core\Language\LanguageManagerInterface;
use Webmozart\PathUtil\Path;
class ExportSingleCommand extends Command
{
use ModuleTrait;
use ExportTrait;
/**
* @var []
*/
protected $definitions;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var Configuration.
*/
protected $configExport;
/**
* @var LanguageManagerInterface
*/
protected $languageManager;
/**
* @var Validator
*/
protected $validator;
/**
* ExportSingleCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param CachedStorage $configStorage
* @param Manager $extensionManager
* @param languageManager $languageManager
* @param Validator $validator
*/
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
CachedStorage $configStorage,
Manager $extensionManager,
LanguageManagerInterface $languageManager,
Validator $validator
) {
$this->entityTypeManager = $entityTypeManager;
$this->configStorage = $configStorage;
$this->extensionManager = $extensionManager;
$this->languageManager = $languageManager;
$this->validator = $validator;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:export:single')
->setDescription($this->trans('commands.config.export.single.description'))
->addOption(
'name',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.config.export.single.options.name')
)->addOption(
'directory',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.export.options.directory')
)->addOption(
'module',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.common.options.module')
)->addOption(
'include-dependencies',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.single.options.include-dependencies')
)->addOption(
'optional',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.single.options.optional')
)->addOption(
'remove-uuid',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.single.options.remove-uuid')
)->addOption(
'remove-config-hash',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.single.options.remove-config-hash')
)
->setAliases(['ces']);
}
/*
* Return config types
*/
protected function getConfigTypes()
{
foreach ($this->entityTypeManager->getDefinitions() as $entity_type => $definition) {
if ($definition->isSubclassOf('Drupal\Core\Config\Entity\ConfigEntityInterface')) {
$this->definitions[$entity_type] = $definition;
}
}
$entity_types = array_map(
function ($definition) {
return $definition->getLabel();
}, $this->definitions
);
uasort($entity_types, 'strnatcasecmp');
$config_types = [
'system.simple' => $this->trans('commands.config.export.single.options.simple-configuration'),
] + $entity_types;
return $config_types;
}
/*
* Return config types
*/
protected function getConfigNames($config_type)
{
$names = [];
// For a given entity type, load all entities.
if ($config_type && $config_type !== 'system.simple') {
$entity_storage = $this->entityTypeManager->getStorage($config_type);
foreach ($entity_storage->loadMultiple() as $entity) {
$entity_id = $entity->id();
$label = $entity->label() ?: $entity_id;
$names[$entity_id] = $label;
}
}
// Handle simple configuration.
else {
// Gather the config entity prefixes.
$config_prefixes = array_map(
function ($definition) {
return $definition->getConfigPrefix() . '.';
}, $this->definitions
);
// Find all config, and then filter our anything matching a config prefix.
$names = $this->configStorage->listAll();
$names = array_combine($names, $names);
foreach ($names as $config_name) {
foreach ($config_prefixes as $config_prefix) {
if (strpos($config_name, $config_prefix) === 0) {
unset($names[$config_name]);
}
}
}
}
return $names;
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$config_types = $this->getConfigTypes();
$name = $input->getOption('name');
if (!$name) {
$type = $this->getIo()->choiceNoList(
$this->trans('commands.config.export.single.questions.config-type'),
array_keys($config_types),
'system.simple'
);
$names = $this->getConfigNames($type);
$name = $this->getIo()->choiceNoList(
$this->trans('commands.config.export.single.questions.name'),
array_keys($names)
);
if ($type !== 'system.simple') {
$definition = $this->entityTypeManager->getDefinition($type);
$name = $definition->getConfigPrefix() . '.' . $name;
}
$input->setOption('name', [$name]);
}
// --module option
$module = $this->getModuleOption();
if ($module) {
$optionalConfig = $input->getOption('optional');
if (!$optionalConfig) {
$optionalConfig = $this->getIo()->confirm(
$this->trans('commands.config.export.single.questions.optional'),
true
);
$input->setOption('optional', $optionalConfig);
}
}
if (!$input->getOption('remove-uuid')) {
$removeUuid = $this->getIo()->confirm(
$this->trans('commands.config.export.single.questions.remove-uuid'),
true
);
$input->setOption('remove-uuid', $removeUuid);
}
if (!$input->getOption('remove-config-hash')) {
$removeHash = $this->getIo()->confirm(
$this->trans('commands.config.export.single.questions.remove-config-hash'),
true
);
$input->setOption('remove-config-hash', $removeHash);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$directory = $input->getOption('directory');
$module = $this->validateModule($input->getOption('module'));
$name = $input->getOption('name');
$optional = $input->getOption('optional');
$removeUuid = $input->getOption('remove-uuid');
$removeHash = $input->getOption('remove-config-hash');
$includeDependencies = $input->getOption('include-dependencies');
foreach ($this->getLanguage() as $value) {
foreach ($name as $nameItem) {
$config = $this->getConfiguration(
$nameItem,
$removeUuid,
$removeHash,
$value
);
if ($config) {
$this->configExport[$nameItem] = [
'data' => $config,
'optional' => $optional
];
if ($includeDependencies) {
// Include config dependencies in export files
if ($dependencies = $this->fetchDependencies($config, 'config')) {
$this->resolveDependencies($dependencies, $optional);
}
}
} else {
$this->getIo()->error($this->trans('commands.config.export.single.messages.config-not-found'));
}
}
if ($module) {
$this->exportConfigToModule(
$module,
$this->trans(
'commands.config.export.single.messages.config-exported'
)
);
return 0;
}
$directory = $directory_copy = Settings::get('config_sync_directory') ;
if (!is_dir($directory)) {
if ($value) {
$directory = $directory_copy .'/' . str_replace('.', '/', $value);
}
} else {
$directory = $directory_copy .'/' . str_replace('.', '/', $value);
$directory = Path::canonicalize($directory);
if (!file_exists($directory)) {
mkdir($directory, 0755, true);
}
}
$this->exportConfig(
$directory,
$this->trans('commands.config.export.single.messages.config-exported')
);
}
return 0;
}
/**
* Get the languague enable.
*/
protected function getLanguage()
{
$output = [];
// Get the language that be for default.
$default_id = $this->languageManager->getDefaultLanguage()->getId();
foreach ($this->languageManager->getLanguages() as $key => $value) {
if ($default_id == $key) {
$output[] = '';
} else {
$output[] = 'language.' . $value->getId();
}
}
return $output;
}
}

View File

@@ -0,0 +1,201 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ExportViewCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Command\Shared\ExportTrait;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class ExportViewCommand extends Command
{
use ModuleTrait;
use ExportTrait;
protected $configExport;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var Validator
*/
protected $validator;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* ExportViewCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param CachedStorage $configStorage
* @param Manager $extensionManager
*/
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
CachedStorage $configStorage,
Manager $extensionManager,
Validator $validator,
ChainQueue $chainQueue
) {
$this->entityTypeManager = $entityTypeManager;
$this->configStorage = $configStorage;
$this->extensionManager = $extensionManager;
$this->validator = $validator;
$this->chainQueue = $chainQueue;
parent::__construct();
}
protected function configure()
{
$this
->setName('config:export:view')
->setDescription($this->trans('commands.config.export.view.description'))
->addOption(
'module', null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addArgument(
'view-id',
InputArgument::OPTIONAL,
$this->trans('commands.config.export.view.arguments.view-id')
)
->addOption(
'optional-config',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.export.view.options.optional-config')
)
->addOption(
'include-module-dependencies',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.export.view.options.include-module-dependencies')
)
->addOption(
'remove-uuid',
NULL,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.entity.options.remove-uuid')
)->addOption(
'remove-config-hash',
NULL,
InputOption::VALUE_NONE,
$this->trans('commands.config.export.entity.options.remove-config-hash')
)
->setAliases(['cev']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$this->getModuleOption();
// view-id argument
$viewId = $input->getArgument('view-id');
if (!$viewId) {
$views = $this->entityTypeManager->getStorage('view')->loadMultiple();
$viewList = [];
foreach ($views as $view) {
$viewList[$view->get('id')] = $view->get('label');
}
$viewId = $this->getIo()->choiceNoList(
$this->trans('commands.config.export.view.questions.view'),
$viewList
);
$input->setArgument('view-id', $viewId);
}
$optionalConfig = $input->getOption('optional-config');
if (!$optionalConfig) {
$optionalConfig = $this->getIo()->confirm(
$this->trans('commands.config.export.view.questions.optional-config'),
true
);
$input->setOption('optional-config', $optionalConfig);
}
$includeModuleDependencies = $input->getOption('include-module-dependencies');
if (!$includeModuleDependencies) {
$includeModuleDependencies = $this->getIo()->confirm(
$this->trans('commands.config.export.view.questions.include-module-dependencies'),
true
);
$input->setOption('include-module-dependencies', $includeModuleDependencies);
}
if (!$input->getOption('remove-uuid')) {
$removeUuid = $this->getIo()->confirm(
$this->trans('commands.config.export.entity.questions.remove-uuid'),
TRUE
);
$input->setOption('remove-uuid', $removeUuid);
}
if (!$input->getOption('remove-config-hash')) {
$removeHash = $this->getIo()->confirm(
$this->trans('commands.config.export.entity.questions.remove-config-hash'),
TRUE
);
$input->setOption('remove-config-hash', $removeHash);
}
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$module = $this->validateModule($input->getOption('module'));
$viewId = $input->getArgument('view-id');
$optionalConfig = $input->getOption('optional-config');
$includeModuleDependencies = $input->getOption('include-module-dependencies');
$removeUuid = $input->getOption('remove-uuid');
$removeHash = $input->getOption('remove-config-hash');
$this->chainQueue->addCommand(
'config:export:entity', [
'entity-type' => 'view',
'bundle' => [$viewId],
'--module' => $module,
'--optional-config' => $optionalConfig,
'--remove-uuid' => $removeUuid,
'--remove-config-hash' => $removeHash,
'--include-module-dependencies' => $includeModuleDependencies
]
);
}
}

View File

@@ -0,0 +1,173 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ImportCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\Core\Site\Settings;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigManager;
use Drupal\Core\Config\ConfigImporterException;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\StorageComparerInterface;
class ImportCommand extends Command
{
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var ConfigManager
*/
protected $configManager;
/**
* ImportCommand constructor.
*
* @param CachedStorage $configStorage
* @param ConfigManager $configManager
*/
public function __construct(
CachedStorage $configStorage,
ConfigManager $configManager
) {
$this->configStorage = $configStorage;
$this->configManager = $configManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:import')
->setDescription($this->trans('commands.config.import.description'))
->addOption(
'file',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.import.options.file')
)
->addOption(
'directory',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.import.options.directory')
)
->addOption(
'remove-files',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.import.options.remove-files')
)
->addOption(
'skip-uuid',
null,
InputOption::VALUE_NONE,
$this->trans('commands.config.import.options.skip-uuid')
)
->setAliases(['ci']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
if (!$input->getOption('directory')) {
$directory = $this->getIo()->ask(
$this->trans('commands.config.import.questions.directory'),
Settings::get('config_sync_directory')
);
$input->setOption('directory', $directory);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$directory = $input->getOption('directory');
$skipUuid = $input->getOption('skip-uuid');
if ($directory) {
$source_storage = new FileStorage($directory);
} else {
$source_storage = \Drupal::service('config.storage.sync');
}
$storageComparer = '\Drupal\Core\Config\StorageComparer';
if ($skipUuid) {
$storageComparer = '\Drupal\Console\Override\StorageComparer';
}
$storage_comparer = new $storageComparer(
$source_storage,
$this->configStorage,
$this->configManager
);
if (!$storage_comparer->createChangelist()->hasChanges()) {
$this->getIo()->success($this->trans('commands.config.import.messages.nothing-to-do'));
}
if ($this->configImport($storage_comparer)) {
$this->getIo()->success($this->trans('commands.config.import.messages.imported'));
} else {
return 1;
}
}
private function configImport(StorageComparerInterface $storage_comparer)
{
$config_importer = new ConfigImporter(
$storage_comparer,
\Drupal::service('event_dispatcher'),
\Drupal::service('config.manager'),
\Drupal::lock(),
\Drupal::service('config.typed'),
\Drupal::moduleHandler(),
\Drupal::service('module_installer'),
\Drupal::service('theme_handler'),
\Drupal::service('string_translation'),
\Drupal::service('extension.list.module')
);
if ($config_importer->alreadyImporting()) {
$this->getIo()->success($this->trans('commands.config.import.messages.already-imported'));
} else {
try {
$this->getIo()->info($this->trans('commands.config.import.messages.importing'));
$config_importer->import();
return true;
} catch (ConfigImporterException $e) {
$this->getIo()->error(
sprintf(
$this->trans('commands.site.import.local.messages.error-writing'),
implode("\n", $config_importer->getErrors())
)
);
} catch (\Exception $e) {
$this->getIo()->error(
sprintf(
$this->trans('commands.site.import.local.messages.error-writing'),
$e->getMessage()
)
);
}
}
}
}

View File

@@ -0,0 +1,212 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ImportSingleCommand.
*/
namespace Drupal\Console\Command\Config;
use Drupal\config\StorageReplaceDataWrapper;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigImporter;
use Drupal\Core\Config\ConfigImporterException;
use Drupal\Core\Config\ConfigManager;
use Drupal\Core\Config\StorageComparer;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Parser;
use Webmozart\PathUtil\Path;
class ImportSingleCommand extends Command
{
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var ConfigManager
*/
protected $configManager;
/**
* ImportSingleCommand constructor.
*
* @param CachedStorage $configStorage
* @param ConfigManager $configManager
*/
public function __construct(
CachedStorage $configStorage,
ConfigManager $configManager
) {
$this->configStorage = $configStorage;
$this->configManager = $configManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:import:single')
->setDescription($this->trans('commands.config.import.single.description'))
->addOption(
'file',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.config.import.single.options.file')
)->addOption(
'directory',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.config.import.options.directory')
)
->setAliases(['cis']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$file = $input->getOption('file');
$directory = $input->getOption('directory');
if (!$file) {
$this->getIo()->error($this->trans('commands.config.import.single..message.missing-file'));
return 1;
}
if ($directory) {
$directory = Path::canonicalize($directory);
}
$names = [];
try {
$source_storage = new StorageReplaceDataWrapper(
$this->configStorage
);
foreach ($file as $fileItem) {
$configFile = $fileItem;
if ($directory) {
$configFile = Path::canonicalize($directory) . '/' . $fileItem;
}
if (file_exists($configFile)) {
$name = Path::getFilenameWithoutExtension($configFile);
$ymlFile = new Parser();
$value = $ymlFile->parse(file_get_contents($configFile));
$source_storage->delete($name);
$source_storage->write($name, $value);
$names[] = $name;
continue;
}
$this->getIo()->error($this->trans('commands.config.import.single.messages.empty-value'));
return 1;
}
$storageComparer = new StorageComparer(
$source_storage,
$this->configStorage,
$this->configManager
);
if ($this->configImport($storageComparer)) {
$this->getIo()->success(
sprintf(
$this->trans(
'commands.config.import.single.messages.success'
),
implode(',', $names)
)
);
}
} catch (\Exception $e) {
$this->getIo()->error($e->getMessage());
return 1;
}
}
private function configImport(StorageComparer $storageComparer)
{
$configImporter = new ConfigImporter(
$storageComparer,
\Drupal::service('event_dispatcher'),
\Drupal::service('config.manager'),
\Drupal::lock(),
\Drupal::service('config.typed'),
\Drupal::moduleHandler(),
\Drupal::service('module_installer'),
\Drupal::service('theme_handler'),
\Drupal::service('string_translation'),
\Drupal::service('extension.list.module')
);
if ($configImporter->alreadyImporting()) {
$this->getIo()->success($this->trans('commands.config.import.messages.already-imported'));
} else {
try {
if ($configImporter->validate()) {
$sync_steps = $configImporter->initialize();
foreach ($sync_steps as $step) {
$context = [];
do {
$configImporter->doSyncStep($step, $context);
} while ($context['finished'] < 1);
}
return true;
}
} catch (ConfigImporterException $e) {
$message = $this->trans('commands.config.import.messages.import-fail') . "\n";
$message .= implode("\n", $configImporter->getErrors());
$this->getIo()->error(
sprintf(
$this->trans('commands.site.import.local.messages.error-writing'),
$message
)
);
} catch (\Exception $e) {
$this->getIo()->error(
sprintf(
$this->trans('commands.site.import.local.messages.error-writing'),
$e->getMessage()
)
);
}
}
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$file = $input->getOption('file');
$directory = $input->getOption('directory');
if (!$file) {
$file = $this->getIo()->ask(
$this->trans('commands.config.import.single.questions.file')
);
$input->setOption('file', [$file]);
if (!$directory && !Path::isAbsolute($file)) {
$directory = $this->getIo()->ask(
$this->trans('commands.config.import.single.questions.directory')
);
$input->setOption('directory', $directory);
}
}
}
}

View File

@@ -0,0 +1,195 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\OverrideCommand.
*/
namespace Drupal\Console\Command\Config;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigFactory;
class OverrideCommand extends Command
{
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* @var ConfigFactory
*/
protected $configFactory;
/**
* OverrideCommand constructor.
*
* @param CachedStorage $configStorage
* @param ConfigFactory $configFactory
*/
public function __construct(
CachedStorage $configStorage,
ConfigFactory $configFactory
) {
$this->configStorage = $configStorage;
$this->configFactory = $configFactory;
parent::__construct();
}
protected function configure()
{
$this
->setName('config:override')
->setDescription($this->trans('commands.config.override.description'))
->addArgument(
'name',
InputArgument::REQUIRED,
$this->trans('commands.config.override.arguments.name')
)
->addOption(
'key',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.config.override.options.key')
)
->addOption(
'value',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.config.override.options.value')
)
->setAliases(['co']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('name');
$names = $this->configFactory->listAll();
if ($name) {
if (!in_array($name, $names)) {
$this->getIo()->warning(
sprintf(
$this->trans('commands.config.override.messages.invalid-name'),
$name
)
);
$name = null;
}
}
if (!$name) {
$name = $this->getIo()->choiceNoList(
$this->trans('commands.config.override.questions.name'),
$names
);
$input->setArgument('name', $name);
}
$key = $input->getOption('key');
if (!$key) {
if (!$this->configStorage->exists($name)) {
$this->getIo()->newLine();
$this->getIo()->errorLite($this->trans('commands.config.override.messages.invalid-config-file'));
$this->getIo()->newLine();
return 0;
}
$configuration = $this->configStorage->read($name);
$input->setOption('key', $this->getKeysFromConfig($configuration));
}
$value = $input->getOption('value');
if (!$value) {
foreach ($input->getOption('key') as $name) {
$value[] = $this->getIo()->ask(
sprintf(
$this->trans('commands.config.override.questions.value'),
$name
)
);
}
$input->setOption('value', $value);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$configName = $input->getArgument('name');
$keys = $input->getOption('key');
$values = $input->getOption('value');
if(empty($keys)) {
return 1;
}
$config = $this->configFactory->getEditable($configName);
$configurationOverrideResult = [];
foreach ($keys as $index => $key) {
$result = $this->overrideConfiguration(
$config,
$key,
$values[$index]
);
$configurationOverrideResult = array_merge($configurationOverrideResult, $result);
}
$config->save();
$this->getIo()->info($this->trans('commands.config.override.messages.configuration'), false);
$this->getIo()->comment($configName);
$tableHeader = [
$this->trans('commands.config.override.messages.configuration-key'),
$this->trans('commands.config.override.messages.original'),
$this->trans('commands.config.override.messages.updated'),
];
$tableRows = $configurationOverrideResult;
$this->getIo()->table($tableHeader, $tableRows);
}
protected function overrideConfiguration($config, $key, $value)
{
$result[] = [
'configuration' => $key,
'original' => $config->get($key),
'updated' => $value,
];
$config->set($key, $value);
return $result;
}
/**
* Allow to search a specific key to override.
*
* @param $configuration
* @param null $key
*
* @return array
*/
private function getKeysFromConfig($configuration, $key = null)
{
$choiceKey = $this->getIo()->choiceNoList(
$this->trans('commands.config.override.questions.key'),
array_keys($configuration)
);
$key = is_null($key) ? $choiceKey:$key.'.'.$choiceKey;
if(is_array($configuration[$choiceKey])){
return $this->getKeysFromConfig($configuration[$choiceKey], $key);
}
return [$key];
}
}

View File

@@ -0,0 +1,24 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\PrintConfigValidationTrait.
*/
namespace Drupal\Console\Command\Config;
trait PrintConfigValidationTrait
{
protected function printResults($valid)
{
if ($valid === true) {
$this->getIo()->info($this->trans('commands.config.validate.messages.success'));
return 0;
}
foreach ($valid as $key => $error) {
$this->getIo()->warning($key . ': ' . $error);
}
return 1;
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Config\ValidateCommand.
*/
namespace Drupal\Console\Command\Config;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Drupal\Core\Config\Schema\SchemaCheckTrait;
/**
* Class ValidateCommand.
*
* @package Drupal\Console\Command\Config
*/
class ValidateCommand extends ContainerAwareCommand
{
use SchemaCheckTrait;
use PrintConfigValidationTrait;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('config:validate')
->setDescription($this->trans('commands.config.validate.description'))
->addArgument(
'name',
InputArgument::REQUIRED
)->setAliases(['cv']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
/**
* @var TypedConfigManagerInterface $typedConfigManager
*/
$typedConfigManager = $this->get('config.typed');
//Test the config name and see if a schema exists, if not it will fail
$name = $input->getArgument('name');
if (!$typedConfigManager->hasConfigSchema($name)) {
$this->getIo()->warning($this->trans('commands.config.validate.messages.no-conf'));
return 1;
}
//Get the config data from the factory
$configFactory = $this->get('config.factory');
$config_data = $configFactory->get($name)->get();
return $this->printResults($this->checkConfigSchema($typedConfigManager, $name, $config_data));
}
}

View File

@@ -0,0 +1,184 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Create\CommentsCommand.
*/
namespace Drupal\Console\Command\Create;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Console\Command\Shared\CreateTrait;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Utils\Create\CommentData;
use Drupal\node\Entity\Node;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class CommentsCommand
*
* @package Drupal\Console\Command\Generate
*
* @DrupalCommand(
* extension = "comment",
* extensionType = "module"
* )
*/
class CommentsCommand extends Command
{
use CreateTrait;
/**
* @var CommentData
*/
protected $createCommentData;
/**
* CommentsCommand constructor.
*
* @param CommentData $createCommentData
*/
public function __construct(CommentData $createCommentData)
{
$this->createCommentData = $createCommentData;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('create:comments')
->setDescription($this->trans('commands.create.comments.description'))
->addArgument(
'node-id',
InputOption::VALUE_REQUIRED,
$this->trans('commands.create.comments.arguments.node-id'),
null
)
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.comments.options.limit')
)
->addOption(
'title-words',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.comments.options.title-words')
)
->addOption(
'time-range',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.comments.options.time-range')
)->setAliases(['crc']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$nodeId = $input->getArgument('node-id');
if (!$nodeId) {
$nodeId = $this->getIo()->ask(
$this->trans('commands.create.comments.questions.node-id')
);
$input->setArgument('node-id', $nodeId);
}
$limit = $input->getOption('limit');
if (!$limit) {
$limit = $this->getIo()->ask(
$this->trans('commands.create.comments.questions.limit'),
25
);
$input->setOption('limit', $limit);
}
$titleWords = $input->getOption('title-words');
if (!$titleWords) {
$titleWords = $this->getIo()->ask(
$this->trans('commands.create.comments.questions.title-words'),
5
);
$input->setOption('title-words', $titleWords);
}
$timeRange = $input->getOption('time-range');
if (!$timeRange) {
$timeRanges = $this->getTimeRange();
$timeRange = $this->getIo()->choice(
$this->trans('commands.create.comments.questions.time-range'),
array_values($timeRanges)
);
$input->setOption('time-range', array_search($timeRange, $timeRanges));
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$nodeId = $input->getArgument('node-id')?:1;
$node = Node::load($nodeId);
if (empty($node)) {
throw new \InvalidArgumentException(
$this->trans(
'commands.generate.controller.messages.node-id-invalid'
)
);
}
$limit = $input->getOption('limit')?:25;
$titleWords = $input->getOption('title-words')?:5;
$timeRange = $input->getOption('time-range')?:31536000;
$result = $this->createCommentData->create(
$nodeId,
$limit,
$titleWords,
$timeRange
);
if ($result['success']) {
$tableHeader = [
$this->trans('commands.create.comments.messages.node-id'),
$this->trans('commands.create.comments.messages.comment-id'),
$this->trans('commands.create.comments.messages.title'),
$this->trans('commands.create.comments.messages.created'),
];
$this->getIo()->table($tableHeader, $result['success']);
$this->getIo()->success(
sprintf(
$this->trans('commands.create.comments.messages.created-comments'),
count($result['success'])
)
);
}
if (isset($result['error'])) {
foreach ($result['error'] as $error) {
$this->getIo()->error(
sprintf(
$this->trans('commands.create.comments.messages.error'),
$error
)
);
}
}
return 0;
}
}

View File

@@ -0,0 +1,265 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Create\NodesCommand.
*/
namespace Drupal\Console\Command\Create;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Console\Command\Shared\CreateTrait;
use Drupal\Console\Utils\Create\NodeData;
use Drupal\Console\Utils\DrupalApi;
use Drupal\Core\Language\LanguageInterface;
/**
* Class NodesCommand
*
* @package Drupal\Console\Command\Generate
*
* @DrupalCommand(
* extension = "node",
* extensionType = "module"
* )
*/
class NodesCommand extends Command
{
use CreateTrait;
/**
* @var DrupalApi
*/
protected $drupalApi;
/**
* @var NodeData
*/
protected $createNodeData;
/**
* NodesCommand constructor.
*
* @param DrupalApi $drupalApi
* @param NodeData $createNodeData
*/
public function __construct(
DrupalApi $drupalApi,
NodeData $createNodeData
) {
$this->drupalApi = $drupalApi;
$this->createNodeData = $createNodeData;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('create:nodes')
->setDescription($this->trans('commands.create.nodes.description'))
->addArgument(
'content-types',
InputArgument::IS_ARRAY,
$this->trans('commands.create.nodes.arguments.content-types')
)
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.nodes.options.limit')
)
->addOption(
'title-words',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.nodes.options.title-words')
)
->addOption(
'time-range',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.nodes.options.time-range')
)
->addOption(
'revision',
null,
InputOption::VALUE_NONE,
$this->trans('commands.create.nodes.options.revision')
)
->addOption(
'language',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.nodes.options.language')
)->setAliases(['crn']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$contentTypes = $input->getArgument('content-types');
if (!$contentTypes) {
$bundles = $this->drupalApi->getBundles();
$contentTypes = $this->getIo()->choice(
$this->trans('commands.create.nodes.questions.content-type'),
array_values($bundles),
null,
true
);
$contentTypes = array_map(
function ($contentType) use ($bundles) {
return array_search($contentType, $bundles);
},
$contentTypes
);
$input->setArgument('content-types', $contentTypes);
}
$limit = $input->getOption('limit');
if (!$limit) {
$limit = $this->getIo()->ask(
$this->trans('commands.create.nodes.questions.limit'),
25
);
$input->setOption('limit', $limit);
}
$titleWords = $input->getOption('title-words');
if (!$titleWords) {
$titleWords = $this->getIo()->ask(
$this->trans('commands.create.nodes.questions.title-words'),
5
);
$input->setOption('title-words', $titleWords);
}
$timeRange = $input->getOption('time-range');
if (!$timeRange) {
$timeRanges = $this->getTimeRange();
$timeRange = $this->getIo()->choice(
$this->trans('commands.create.nodes.questions.time-range'),
array_values($timeRanges)
);
$input->setOption('time-range', array_search($timeRange, $timeRanges));
}
$revision = is_null($input->getOption('revision'));
if (!$revision) {
$revision = $this->getIo()->confirm(
$this->trans('commands.create.nodes.questions.revision')
);
$input->setOption('revision', $revision);
}
// Language module is enabled or not.
$languageModuleEnabled = \Drupal::moduleHandler()
->moduleExists('language');
// If language module is enabled.
if ($languageModuleEnabled) {
// Get available languages on site.
$languages = \Drupal::languageManager()->getLanguages();
// Holds the available languages.
$language_list = [];
foreach ($languages as $lang) {
$language_list[$lang->getId()] = $lang->getName();
}
$language = $input->getOption('language');
// If no language option or invalid language code in option.
if (!$language || !array_key_exists($language, $language_list)) {
$language = $this->getIo()->choice(
$this->trans('commands.create.nodes.questions.language'),
$language_list
);
}
$input->setOption('language', $language);
} else {
// If 'language' module is not enabled.
$input->setOption(
'language',
\Drupal::languageManager()->getDefaultLanguage()->getId()
);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$contentTypes = $input->getArgument('content-types');
$limit = $input->getOption('limit')?:25;
$titleWords = $input->getOption('title-words')?:5;
$timeRange = $input->getOption('time-range')?:31536000;
$revision = $input->getOption('revision');
$available_types = array_keys($this->drupalApi->getBundles());
$language = $input->getOption('language')?:'und';
foreach ($contentTypes as $type) {
if (!in_array($type, $available_types)) {
throw new \Exception('Invalid content type name given.');
}
}
if (!$contentTypes) {
$contentTypes = $available_types;
}
$result = $this->createNodeData->create(
$contentTypes,
$limit,
$titleWords,
$timeRange,
$revision,
$language
);
if ($result['success']) {
$tableHeader = [
$this->trans('commands.create.nodes.messages.node-id'),
$this->trans('commands.create.nodes.messages.content-type'),
$this->trans('commands.create.nodes.messages.title'),
$this->trans('commands.create.nodes.messages.created'),
];
$this->getIo()->table($tableHeader, $result['success']);
$this->getIo()->success(
sprintf(
$this->trans('commands.create.nodes.messages.created-nodes'),
count($result['success'])
)
);
}
if (isset($result['error'])) {
foreach ($result['error'] as $error) {
$this->getIo()->error(
sprintf(
$this->trans('commands.create.nodes.messages.error'),
$error
)
);
}
}
return 0;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Create\RolesCommand.
*/
namespace Drupal\Console\Command\Create;
use Drupal\Console\Utils\Create\RoleData;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
/**
* Class RolesCommand
*
* @package Drupal\Console\Command\Create
*/
class RolesCommand extends Command
{
/**
* @var RoleData
*/
protected $createRoleData;
/**
* RolesCommand constructor.
*
* @param RoleData $createRoleData
*/
public function __construct(
RoleData $createRoleData
) {
$this->createRoleData = $createRoleData;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('create:roles')
->setDescription($this->trans('commands.create.roles.description'))
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.roles.options.limit')
)
->setAliases(['crr']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$limit = $input->getOption('limit');
if (!$limit) {
$limit = $this->getIo()->ask(
$this->trans('commands.create.roles.questions.limit'),
5
);
$input->setOption('limit', $limit);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$limit = $input->getOption('limit')?:5;
$result = $this->createRoleData->create(
$limit
);
$tableHeader = [
$this->trans('commands.create.roles.messages.role-id'),
$this->trans('commands.create.roles.messages.role-name'),
];
if ($result['success']) {
$this->getIo()->table($tableHeader, $result['success']);
$this->getIo()->success(
sprintf(
$this->trans('commands.create.roles.messages.created-roles'),
count($result['success'])
)
);
}
if (isset($result['error'])) {
foreach ($result['error'] as $error) {
$this->getIo()->error(
sprintf(
$this->trans('commands.create.roles.messages.error'),
$error
)
);
}
}
return 0;
}
}

View File

@@ -0,0 +1,176 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Create\TermsCommand.
*/
namespace Drupal\Console\Command\Create;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Console\Utils\Create\TermData;
use Drupal\Console\Utils\DrupalApi;
/**
* Class TermsCommand
*
* @package Drupal\Console\Command\Generate
*
* @DrupalCommand(
* extension = "taxonomy",
* extensionType = "module"
* )
*/
class TermsCommand extends Command
{
/**
* @var DrupalApi
*/
protected $drupalApi;
/**
* @var TermData
*/
protected $createTermData;
/**
* TermsCommand constructor.
*
* @param DrupalApi $drupalApi
* @param TermData $createTermData
*/
public function __construct(
DrupalApi $drupalApi,
TermData $createTermData
) {
$this->drupalApi = $drupalApi;
$this->createTermData = $createTermData;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('create:terms')
->setDescription($this->trans('commands.create.terms.description'))
->addArgument(
'vocabularies',
InputArgument::IS_ARRAY,
$this->trans('commands.create.terms.arguments.vocabularies')
)
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.terms.options.limit')
)
->addOption(
'name-words',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.terms.options.name-words')
)->setAliases(['crt']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$vocabularies = $input->getArgument('vocabularies');
if (!$vocabularies) {
$vocabularies = $this->drupalApi->getVocabularies();
$vids = $this->getIo()->choice(
$this->trans('commands.create.terms.questions.vocabularies'),
array_values($vocabularies),
null,
true
);
$vids = array_map(
function ($vid) use ($vocabularies) {
return array_search($vid, $vocabularies);
},
$vids
);
$input->setArgument('vocabularies', $vids);
}
$limit = $input->getOption('limit');
if (!$limit) {
$limit = $this->getIo()->ask(
$this->trans('commands.create.terms.questions.limit'),
25
);
$input->setOption('limit', $limit);
}
$nameWords = $input->getOption('name-words');
if (!$nameWords) {
$nameWords = $this->getIo()->ask(
$this->trans('commands.create.terms.questions.name-words'),
5
);
$input->setOption('name-words', $nameWords);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$vocabularies = $input->getArgument('vocabularies');
$limit = $input->getOption('limit')?:25;
$nameWords = $input->getOption('name-words')?:5;
if (!$vocabularies) {
$vocabularies = array_keys($this->drupalApi->getVocabularies());
}
$result = $this->createTermData->create(
$vocabularies,
$limit,
$nameWords
);
$tableHeader = [
$this->trans('commands.create.terms.messages.term-id'),
$this->trans('commands.create.terms.messages.vocabulary'),
$this->trans('commands.create.terms.messages.name'),
];
if ($result['success']) {
$this->getIo()->table($tableHeader, $result['success']);
$this->getIo()->success(
sprintf(
$this->trans('commands.create.terms.messages.created-terms'),
count($result['success'])
)
);
}
if (isset($result['error'])) {
foreach ($result['error'] as $error) {
$this->getIo()->error(
sprintf(
$this->trans('commands.create.terms.messages.error'),
$error
)
);
}
}
return 0;
}
}

View File

@@ -0,0 +1,194 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Create\UsersCommand.
*/
namespace Drupal\Console\Command\Create;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\CreateTrait;
use Drupal\Console\Utils\Create\UserData;
use Drupal\Console\Utils\DrupalApi;
/**
* Class UsersCommand
*
* @package Drupal\Console\Command\Create
*/
class UsersCommand extends Command
{
use CreateTrait;
/**
* @var DrupalApi
*/
protected $drupalApi;
/**
* @var UserData
*/
protected $createUserData;
/**
* UsersCommand constructor.
*
* @param DrupalApi $drupalApi
* @param UserData $createUserData
*/
public function __construct(
DrupalApi $drupalApi,
UserData $createUserData
) {
$this->drupalApi = $drupalApi;
$this->createUserData = $createUserData;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('create:users')
->setDescription($this->trans('commands.create.users.description'))
->addArgument(
'roles',
InputArgument::IS_ARRAY,
$this->trans('commands.create.users.arguments.roles')
)
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.users.options.limit')
)
->addOption(
'password',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.users.options.password')
)
->addOption(
'time-range',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.users.options.time-range')
)->setAliases(['cru']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$rids = $input->getArgument('roles');
if (!$rids) {
$roles = $this->drupalApi->getRoles(true, true);
$rids = $this->getIo()->choice(
$this->trans('commands.create.users.questions.roles'),
array_values($roles),
null,
true
);
$rids = array_map(
function ($role) use ($roles) {
return array_search($role, $roles);
},
$rids
);
$input->setArgument('roles', $rids);
}
$limit = $input->getOption('limit');
if (!$limit) {
$limit = $this->getIo()->ask(
$this->trans('commands.create.users.questions.limit'),
10
);
$input->setOption('limit', $limit);
}
$password = $input->getOption('password');
if (!$password) {
$password = $this->getIo()->ask(
$this->trans('commands.create.users.questions.password'),
5
);
$input->setOption('password', $password);
}
$timeRange = $input->getOption('time-range');
if (!$timeRange) {
$timeRanges = $this->getTimeRange();
$timeRange = $this->getIo()->choice(
$this->trans('commands.create.users.questions.time-range'),
array_values($timeRanges)
);
$input->setOption('time-range', array_search($timeRange, $timeRanges));
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$roles = $input->getArgument('roles');
$limit = $input->getOption('limit')?:25;
$password = $input->getOption('password');
$timeRange = $input->getOption('time-range')?:31536000;
if (!$roles) {
$roles = $this->drupalApi->getRoles();
}
$result = $this->createUserData->create(
$roles,
$limit,
$password,
$timeRange
);
$tableHeader = [
$this->trans('commands.create.users.messages.user-id'),
$this->trans('commands.create.users.messages.username'),
$this->trans('commands.create.users.messages.roles'),
$this->trans('commands.create.users.messages.created'),
];
if ($result['success']) {
$this->getIo()->table($tableHeader, $result['success']);
$this->getIo()->success(
sprintf(
$this->trans('commands.create.users.messages.created-users'),
count($result['success'])
)
);
}
if (isset($result['error'])) {
foreach ($result['error'] as $error) {
$this->getIo()->error(
sprintf(
$this->trans('commands.create.users.messages.error'),
$error
)
);
}
}
return 0;
}
}

View File

@@ -0,0 +1,128 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Create\TermsCommand.
*/
namespace Drupal\Console\Command\Create;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Utils\Create\VocabularyData;
/**
* Class VocabulariesCommand
*
* @package Drupal\Console\Command\Generate
*/
class VocabulariesCommand extends Command
{
/**
* @var VocabularyData
*/
protected $vocabularyData;
/**
* UsersCommand constructor.
*
* @param $vocabularyData
*/
public function __construct(VocabularyData $vocabularyData)
{
$this->vocabularyData = $vocabularyData;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('create:vocabularies')
->setDescription($this->trans('commands.create.vocabularies.description'))
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.vocabularies.options.limit')
)
->addOption(
'name-words',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.create.vocabularies.options.name-words')
)->setAliases(['crv']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$limit = $input->getOption('limit');
if (!$limit) {
$limit = $this->getIo()->ask(
$this->trans('commands.create.vocabularies.questions.limit'),
25
);
$input->setOption('limit', $limit);
}
$nameWords = $input->getOption('name-words');
if (!$nameWords) {
$nameWords = $this->getIo()->ask(
$this->trans('commands.create.vocabularies.questions.name-words'),
5
);
$input->setOption('name-words', $nameWords);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$limit = $input->getOption('limit')?:25;
$nameWords = $input->getOption('name-words')?:5;
$result = $this->vocabularyData->create(
$limit,
$nameWords
);
$tableHeader = [
$this->trans('commands.create.vocabularies.messages.vocabulary-id'),
$this->trans('commands.create.vocabularies.messages.name'),
];
if (isset($result['success'])) {
$this->getIo()->table($tableHeader, $result['success']);
$this->getIo()->success(
sprintf(
$this->trans('commands.create.vocabularies.messages.created-terms'),
count($result['success'])
)
);
}
if (isset($result['error'])) {
foreach ($result['error'] as $error) {
$this->getIo()->error(
sprintf(
$this->trans('commands.create.vocabularies.messages.error'),
$error
)
);
}
}
return 0;
}
}

View File

@@ -0,0 +1,118 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Cron\ExecuteCommand.
*/
namespace Drupal\Console\Command\Cron;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Core\State\StateInterface;
class ExecuteCommand extends Command
{
/**
* @var ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* @var LockBackendInterface
*/
protected $lock;
/**
* @var StateInterface
*/
protected $state;
/**
* DebugCommand constructor.
*
* @param ModuleHandlerInterface $moduleHandler
* @param LockBackendInterface $lock
* @param StateInterface $state
*/
public function __construct(
ModuleHandlerInterface $moduleHandler,
LockBackendInterface $lock,
StateInterface $state
) {
$this->moduleHandler = $moduleHandler;
$this->lock = $lock;
$this->state = $state;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('cron:execute')
->setDescription($this->trans('commands.cron.execute.description'))
->addArgument(
'module',
InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
$this->trans('commands.common.options.module'),
['all']
)
->setAliases(['croe']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$modules = $input->getArgument('module');
if (!$this->lock->acquire('cron', 900.0)) {
$this->getIo()->warning($this->trans('commands.cron.execute.messages.lock'));
return 1;
}
if (in_array('all', $modules)) {
$modules = $this->moduleHandler->getImplementations('cron');
}
foreach ($modules as $module) {
if (!$this->moduleHandler->implementsHook($module, 'cron')) {
$this->getIo()->warning(
sprintf(
$this->trans('commands.cron.execute.messages.module-invalid'),
$module
)
);
continue;
}
try {
$this->getIo()->info(
sprintf(
$this->trans('commands.cron.execute.messages.executing-cron'),
$module
)
);
$this->moduleHandler->invoke($module, 'cron');
} catch (\Exception $e) {
watchdog_exception('cron', $e);
$this->getIo()->error($e->getMessage());
}
}
$this->state->set('system.cron_last', \Drupal::time()->getRequestTime());
$this->lock->release('cron');
$this->getIo()->success($this->trans('commands.cron.execute.messages.success'));
return 0;
}
}

View File

@@ -0,0 +1,74 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Cron\ReleaseCommand.
*/
namespace Drupal\Console\Command\Cron;
use Symfony\Component\Config\Definition\Exception\Exception;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Lock\LockBackendInterface;
use Drupal\Console\Core\Utils\ChainQueue;
class ReleaseCommand extends Command
{
/**
* @var LockBackendInterface
*/
protected $lock;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* ReleaseCommand constructor.
*
* @param LockBackendInterface $lock
* @param ChainQueue $chainQueue
*/
public function __construct(
LockBackendInterface $lock,
ChainQueue $chainQueue
) {
$this->lock = $lock;
$this->chainQueue = $chainQueue;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('cron:release')
->setDescription($this->trans('commands.cron.release.description'))
->setAliases(['cror']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
try {
$this->lock->release('cron');
$this->getIo()->info($this->trans('commands.cron.release.messages.released'));
} catch (Exception $e) {
$this->getIo()->error($e->getMessage());
return 1;
}
$this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']);
return 0;
}
}

View File

@@ -0,0 +1,169 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\ConnectCommand.
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Generator\DatabaseSettingsGenerator;
class AddCommand extends Command
{
/**
* @var DatabaseSettingsGenerator
*/
protected $generator;
/**
* FormCommand constructor.
*
* @param DatabaseSettingsGenerator $generator
*/
public function __construct(
DatabaseSettingsGenerator $generator
) {
$this->generator = $generator;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:add')
->setDescription($this->trans('commands.database.add.description'))
->addOption(
'database',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.database.add.options.database')
)
->addOption(
'username',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.database.add.options.username')
)
->addOption(
'password',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.add.options.password')
)
->addOption(
'prefix',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.add.options.prefix')
)
->addOption(
'host',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.add.options.host')
)
->addOption(
'port',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.add.options.port')
)
->addOption(
'driver',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.add.options.driver')
)
->addOption(
'default',
null,
InputOption::VALUE_NONE,
$this->trans('commands.database.query.options.default')
)
->setHelp($this->trans('commands.database.add.help'))
->setAliases(['dba']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$result = $this
->generator
->generate($input->getOptions());
if (!$result) {
$this->getIo()->error($this->trans('commands.database.add.error'));
}
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$database = $input->getOption('database');
if (!$database) {
$database = $this->getIo()->ask(
$this->trans('commands.database.add.questions.database'),
'migrate_db'
);
}
$input->setOption('database', $database);
$username = $input->getOption('username');
if (!$username) {
$username = $this->getIo()->ask(
$this->trans('commands.database.add.questions.username'),
''
);
}
$input->setOption('username', $username);
$password = $input->getOption('password');
if (!$password) {
$password = $this->getIo()->askHiddenEmpty(
$this->trans('commands.migrate.execute.questions.db-pass')
);
}
$input->setOption('password', $password);
$prefix = $input->getOption('prefix');
if (!$prefix) {
$prefix = $this->getIo()->ask(
$this->trans('commands.database.add.questions.prefix'),
false
);
}
$input->setOption('prefix', $prefix);
$host = $input->getOption('host');
if (!$host) {
$host = $this->getIo()->ask(
$this->trans('commands.database.add.questions.host'),
'localhost'
);
}
$input->setOption('host', $host);
$port = $input->getOption('port');
if (!$port) {
$port = $this->getIo()->ask(
$this->trans('commands.database.add.questions.port'),
3306
);
}
$input->setOption('port', $port);
$driver = $input->getOption('driver');
if (!$driver) {
$driver = $this->getIo()->ask(
$this->trans('commands.database.add.questions.driver'),
'mysql'
);
}
$input->setOption('driver', $driver);
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\ClientCommand.
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\ProcessBuilder;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\ConnectTrait;
class ClientCommand extends Command
{
use ConnectTrait;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:client')
->setDescription($this->trans('commands.database.client.description'))
->addArgument(
'database',
InputArgument::OPTIONAL,
$this->trans('commands.database.client.arguments.database'),
'default'
)
->addArgument(
'target',
InputArgument::OPTIONAL,
$this->trans('commands.database.client.arguments.target'),
'default'
)
->setHelp($this->trans('commands.database.client.help'))
->setAliases(['dbc']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$database = $input->getArgument('database');
$learning = $input->getOption('learning');
$target = $input->getArgument('target');
$databaseConnection = $this->resolveConnection($database, $target);
$connection = $this->getConnectionString($databaseConnection);
if ($learning) {
$this->getIo()->commentBlock(
sprintf(
$this->trans('commands.database.client.messages.connection'),
$connection
)
);
}
$processBuilder = new ProcessBuilder([]);
$processBuilder->setArguments(explode(' ', $connection));
$process = $processBuilder->getProcess();
$process->setTty('true');
$process->run();
if (!$process->isSuccessful()) {
throw new \RuntimeException($process->getErrorOutput());
}
return 0;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\ConnectCommand.
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\ConnectTrait;
class ConnectCommand extends Command
{
use ConnectTrait;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:connect')
->setDescription($this->trans('commands.database.connect.description'))
->addArgument(
'key',
InputArgument::OPTIONAL,
$this->trans('commands.database.connect.arguments.key'),
'default'
)
->addArgument(
'target',
InputArgument::OPTIONAL,
$this->trans('commands.database.connect.arguments.target'),
'default'
)
->setHelp($this->trans('commands.database.connect.help'))
->setAliases(['dbco']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
$target = $input->getArgument('target');
$databaseConnection = $this->resolveConnection($key, $target);
$this->getIo()->commentBlock(
sprintf(
$this->trans('commands.database.connect.messages.connection'),
escapeshellcmd($this->getConnectionString($databaseConnection))
)
);
return 0;
}
}

View File

@@ -0,0 +1,284 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\DatabaseLogBase.
*/
namespace Drupal\Console\Command\Database;
use Drupal\Core\Database\Connection;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\user\UserStorageInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Logger\RfcLogLevel;
use Drupal\user\Entity\User;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\Html;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
/**
* Class DatabaseLogBase
*
* @package Drupal\Console\Command\Database
*/
abstract class DatabaseLogBase extends Command
{
/**
* @var Connection
*/
protected $database;
/**
* @var DateFormatterInterface
*/
protected $dateFormatter;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var TranslationInterface
*/
protected $stringTranslation;
/**
* @var UserStorageInterface
*/
protected $userStorage;
/**
* @var TranslatableMarkup[]
*/
protected $severityList;
/**
* @var null|string
*/
protected $eventType;
/**
* @var null|string
*/
protected $eventSeverity;
/**
* @var null|string
*/
protected $userId;
/**
* LogDebugCommand constructor.
*
* @param Connection $database
* @param DateFormatterInterface $dateFormatter
* @param EntityTypeManagerInterface $entityTypeManager
* @param TranslationInterface $stringTranslation
*/
public function __construct(
Connection $database,
DateFormatterInterface $dateFormatter,
EntityTypeManagerInterface $entityTypeManager,
TranslationInterface $stringTranslation
) {
$this->database = $database;
$this->dateFormatter = $dateFormatter;
$this->entityTypeManager = $entityTypeManager;
$this->stringTranslation = $stringTranslation;
$this->userStorage = $this->entityTypeManager->getStorage('user');
$this->severityList = RfcLogLevel::getLevels();
parent::__construct();
}
/**
* addDefaultLoggingOptions.
*/
protected function addDefaultLoggingOptions()
{
$this
->addOption(
'type',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.log.common.options.type')
)
->addOption(
'severity',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.log.common.options.severity')
)
->addOption(
'user-id',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.log.common.options.user-id')
);
}
/**
* @param InputInterface $input
*/
protected function getDefaultOptions(InputInterface $input)
{
$this->eventType = $input->getOption('type');
$this->eventSeverity = $input->getOption('severity');
$this->userId = $input->getOption('user-id');
}
/**
* @param null $offset
* @param int $range
* @return bool|\Drupal\Core\Database\Query\SelectInterface
*/
protected function makeQuery($offset = null, $range = 1000)
{
$query = $this->database->select('watchdog', 'w');
$query->fields(
'w',
[
'wid',
'uid',
'severity',
'type',
'timestamp',
'message',
'variables',
]
);
if ($this->eventType) {
$query->condition('type', $this->eventType);
}
if ($this->eventSeverity) {
if (!in_array($this->eventSeverity, $this->severityList)) {
$this->getIo()->error(
sprintf(
$this->trans('database.log.common.messages.invalid-severity'),
$this->eventSeverity
)
);
return false;
}
$query->condition(
'severity',
array_search(
$this->eventSeverity,
$this->severityList
)
);
}
if ($this->userId) {
$query->condition('uid', $this->userId);
}
$query->orderBy('wid', 'ASC');
if ($offset) {
$query->range($offset, $range);
}
return $query;
}
/**
* Generic logging table header
*
* @return array
*/
protected function createTableHeader()
{
return [
$this->trans('commands.database.log.common.messages.event-id'),
$this->trans('commands.database.log.common.messages.type'),
$this->trans('commands.database.log.common.messages.date'),
$this->trans('commands.database.log.common.messages.message'),
$this->trans('commands.database.log.common.messages.user'),
$this->trans('commands.database.log.common.messages.severity'),
];
}
/**
* @param \stdClass $dblog
* @return array
*/
protected function createTableRow(\stdClass $dblog)
{
/**
* @var User $user
*/
if ($user = $this->userStorage->load($dblog->uid)) {
$user_id = $user->id();
$user_name = $user->getUsername();
} else {
$user_id = $dblog->uid;
$user_name = $this->trans('commands.database.log.common.messages.user-deleted');
}
return [
$dblog->wid,
$dblog->type,
$this->dateFormatter->format($dblog->timestamp, 'short'),
Unicode::truncate(
Html::decodeEntities(strip_tags($this->formatMessage($dblog))),
500,
true,
true
),
$user_name . ' (' . $user_id . ')',
$this->severityList[$dblog->severity]->render(),
];
}
/**
* Formats a database log message.
*
* @param $event
* The record from the watchdog table. The object properties are: wid, uid,
* severity, type, timestamp, message, variables, link, name.
*
* @return string|false
* The formatted log message or FALSE if the message or variables properties
* are not set.
*/
protected function formatMessage(\stdClass $event)
{
$message = false;
// Check for required properties.
if (isset($event->message, $event->variables)) {
// Messages without variables or user specified text.
if ($event->variables === 'N;') {
return $event->message;
}
return $this->stringTranslation->translate(
$event->message,
unserialize($event->variables)
);
}
return $message;
}
/**
* @param $dblog
* @return array
*/
protected function formatSingle($dblog)
{
return array_combine(
$this->createTableHeader(),
$this->createTableRow($dblog)
);
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\DropCommand.
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Database\Connection;
use Drupal\Console\Command\Shared\ConnectTrait;
use Drupal\Core\Database\Database;
/**
* Class DropCommand
*
* @package Drupal\Console\Command\Database
*/
class DropCommand extends Command
{
use ConnectTrait;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:drop')
->setDescription($this->trans('commands.database.drop.description'))
->addArgument(
'database',
InputArgument::OPTIONAL,
$this->trans('commands.database.drop.arguments.database'),
'default'
)
->addArgument(
'target',
InputArgument::OPTIONAL,
$this->trans('commands.database.drop.arguments.target'),
'default'
)
->setHelp($this->trans('commands.database.drop.help'))
->setAliases(['dbd']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$database = $input->getArgument('database');
$target = $input->getArgument('target');
$yes = $input->getOption('yes');
$databaseConnection = $this->resolveConnection($database, $target);
if (!$yes) {
if (!$this->getIo()->confirm(
sprintf(
$this->trans('commands.database.drop.question.drop-tables'),
$databaseConnection['database']
),
true
)
) {
return 1;
}
}
$connection = Database::getConnection($target, $database);
$schema = $connection->schema();
$tables = $schema->findTables('%');
$tableRows = [];
foreach ($tables as $table) {
if ($schema->dropTable($table)) {
$tableRows['success'][] = [$table];
} else {
$tableRows['error'][] = [$table];
}
}
$this->getIo()->success(
sprintf(
$this->trans('commands.database.drop.messages.table-drop'),
count($tableRows['success'])
)
);
return 0;
}
}

View File

@@ -0,0 +1,246 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\DumpCommand.
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\ConnectTrait;
use Drupal\Console\Core\Utils\ShellProcess;
use Drupal\Core\Database\Connection;
use Symfony\Component\Process\Process;
class DumpCommand extends Command
{
use ConnectTrait;
protected $appRoot;
/**
* @var ShellProcess
*/
protected $shellProcess;
/**
* @var Connection
*/
protected $database;
/**
* DumpCommand constructor.
*
* @param $appRoot
* @param ShellProcess $shellProcess
* @param Connection $database
*/
public function __construct(
$appRoot,
ShellProcess $shellProcess,
Connection $database
) {
$this->appRoot = $appRoot;
$this->shellProcess = $shellProcess;
$this->database = $database;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:dump')
->setDescription($this->trans('commands.database.dump.description'))
->addArgument(
'database',
InputArgument::OPTIONAL,
$this->trans('commands.database.dump.arguments.database'),
'default'
)
->addArgument(
'target',
InputArgument::OPTIONAL,
$this->trans('commands.database.dump.arguments.target'),
'default'
)
->addOption(
'file',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.dump.options.file')
)
->addOption(
'gz',
null,
InputOption::VALUE_NONE,
$this->trans('commands.database.dump.options.gz')
)
->addOption(
'exclude-cache',
null,
InputOption::VALUE_NONE,
$this->trans('commands.database.dump.options.exclude.cache')
)
->setHelp($this->trans('commands.database.dump.help'))
->setAliases(['dbdu']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$database = $input->getArgument('database');
$target = $input->getArgument('target');
$file = $input->getOption('file');
$learning = $input->getOption('learning');
$gz = $input->getOption('gz');
$excludeCache = $input->getOption('exclude-cache');
$databaseConnection = $this->escapeConnection($this->resolveConnection($database, $target));
if ($excludeCache) {
$query = '';
if ($databaseConnection['driver'] == 'mysql') {
$query = "SHOW TABLES LIKE 'cache_%'";
} elseif ($databaseConnection['driver'] == 'pgsql') {
$query = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema' AND tablename LIKE 'cache_%'";
}
$result = $this->database
->query($query)
->fetchAll();
$excludeTables = [];
foreach ($result as $record) {
$table = array_values(json_decode(json_encode($record), true));
if ($databaseConnection['driver'] == 'mysql') {
$excludeTables[] = $databaseConnection['database'] . '.' . $table[0];
} elseif ($databaseConnection['driver'] == 'pgsql') {
$excludeTables[] = 'public' . '.' . $table[0];
}
}
}
if (!$file) {
$date = new \DateTime();
$file = sprintf(
'%s/%s-%s.sql',
$this->appRoot,
$databaseConnection['database'],
$date->format('Y-m-d-H-i-s')
);
}
$command = null;
if ($databaseConnection['driver'] == 'mysql') {
$command = sprintf(
"mysqldump --user='%s' --password='%s' --host='%s' --port='%s' '%s' > '%s'",
$databaseConnection['username'],
$databaseConnection['password'],
$databaseConnection['host'],
$databaseConnection['port'],
$databaseConnection['database'],
$file
);
if ($excludeCache) {
$ignoreTable = '';
foreach ($excludeTables as $table) {
$ignoreTable .= "--ignore-table=\"{$table}\" ";
}
$command = sprintf(
"mysqldump --user='%s' --password='%s' --host='%s' --port='%s' %s '%s'> '%s'",
$databaseConnection['username'],
$databaseConnection['password'],
$databaseConnection['host'],
$databaseConnection['port'],
$ignoreTable,
$databaseConnection['database'],
$file
);
}
} elseif ($databaseConnection['driver'] == 'pgsql') {
$command = sprintf(
"PGPASSWORD='%s' pg_dumpall -w -U '%s' -h '%s' -p '%s' -l '%s' -f '%s'",
$databaseConnection['password'],
$databaseConnection['username'],
$databaseConnection['host'],
$databaseConnection['port'],
$databaseConnection['database'],
$file
);
if ($excludeCache) {
$ignoreTable = '';
foreach ($excludeTables as $table) {
$ignoreTable .= "-T \"{$table}\" ";
}
$command = sprintf(
"PGPASSWORD='%s' pg_dump -w -U '%s' -h '%s' -p '%s' -f '%s' %s-d '%s'",
$databaseConnection['password'],
$databaseConnection['username'],
$databaseConnection['host'],
$databaseConnection['port'],
$file,
$ignoreTable,
$databaseConnection['database']
);
}
}
if ($learning) {
$this->getIo()->commentBlock($command);
}
try {
$process = new Process($command);
$process->setTimeout(null);
$process->setWorkingDirectory($this->appRoot);
$process->run();
if($process->isSuccessful()) {
$resultFile = $file;
if ($gz) {
if (substr($file, -3) != '.gz') {
$resultFile = $file . '.gz';
}
file_put_contents(
$resultFile,
gzencode(
file_get_contents(
$file
)
)
);
if ($resultFile != $file) {
unlink($file);
}
}
$this->getIo()->success(
sprintf(
'%s %s',
$this->trans('commands.database.dump.messages.success'),
$resultFile
)
);
}
return 0;
} catch (\Exception $e) {
return 1;
}
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\LogClearCommand.
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Database\Connection;
use Drupal\Core\Logger\RfcLogLevel;
class LogClearCommand extends Command
{
/**
* @var Connection
*/
protected $database;
/**
* LogClearCommand constructor.
*
* @param Connection $database
*/
public function __construct(Connection $database)
{
$this->database = $database;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:log:clear')
->setDescription($this->trans('commands.database.log.clear.description'))
->addArgument(
'event-id',
InputArgument::OPTIONAL,
$this->trans('commands.database.log.clear.arguments.event-id')
)
->addOption(
'type',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.log.clear.options.type')
)
->addOption(
'severity',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.log.clear.options.severity')
)
->addOption(
'user-id',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.database.log.clear.options.user-id')
)
->setAliases(['dblc']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$eventId = $input->getArgument('event-id');
$eventType = $input->getOption('type');
$eventSeverity = $input->getOption('severity');
$userId = $input->getOption('user-id');
if ($eventId) {
$this->clearEvent($eventId);
} else {
$this->clearEvents($eventType, $eventSeverity, $userId);
}
return 0;
}
/**
* @param $eventId
* @return bool
*/
private function clearEvent($eventId)
{
$result = $this->database->delete('watchdog')->condition('wid', $eventId)->execute();
if (!$result) {
$this->getIo()->error(
sprintf(
$this->trans('commands.database.log.clear.messages.not-found'),
$eventId
)
);
return false;
}
$this->getIo()->success(
sprintf(
$this->trans('commands.database.log.clear.messages.event-deleted'),
$eventId
)
);
return true;
}
/**
* @param $eventType
* @param $eventSeverity
* @param $userId
* @return bool
*/
protected function clearEvents($eventType, $eventSeverity, $userId)
{
$severity = RfcLogLevel::getLevels();
$query = $this->database->delete('watchdog');
if ($eventType) {
$query->condition('type', $eventType);
}
if ($eventSeverity) {
if (!in_array($eventSeverity, $severity)) {
$this->getIo()->error(
sprintf(
$this->trans('commands.database.log.clear.messages.invalid-severity'),
$eventSeverity
)
);
return false;
}
$query->condition('severity', array_search($eventSeverity, $severity));
}
if ($userId) {
$query->condition('uid', $userId);
}
$result = $query->execute();
if (!$result) {
$this->getIo()->error(
$this->trans('commands.database.log.clear.messages.clear-error')
);
return false;
}
$this->getIo()->success(
$this->trans('commands.database.log.clear.messages.clear-sucess')
);
return true;
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class LogPollCommand
*
* @package Drupal\Console\Command\Database
*/
class LogPollCommand extends DatabaseLogBase
{
/**
* @var
*/
protected $duration;
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->getIo()->note($this->trans('commands.database.log.poll.messages.warning'));
$this->getDefaultOptions($input);
$this->duration = $input->getArgument('duration');
$this->pollForEvents();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:log:poll')
->setDescription($this->trans('commands.database.log.poll.description'));
$this->addDefaultLoggingOptions();
$this->addArgument(
'duration',
InputArgument::OPTIONAL,
$this->trans('commands.database.log.poll.arguments.duration'),
'10'
)->setAliases(['dblp']);
}
protected function pollForEvents()
{
$query = $this->makeQuery()->countQuery();
$results = $query->execute()->fetchAssoc();
$count = $results['expression'] - 1;//minus 1 so the newest message always prints
$tableHeader = $this->createTableHeader();
//Poll, force no wait on first loop
$lastExec = time() - $this->duration;
while (1) {
if (time() > $lastExec + $this->duration) {
//Print out any new db logs
$query = $this->makeQuery($count);
$results = $query->execute()->fetchAll();
$count += count($results);
$tableRows = [];
foreach ($results as $r) {
$tableRows[] = $this->createTableRow($r);
}
if (!empty($tableRows)) {
$this->getIo()->table($tableHeader, $tableRows);
}
//update the last exec time
$lastExec = time();
}
}
}
}

View File

@@ -0,0 +1,138 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\QueryCommand.
*
*
* @TODO:
* - mysql -H option for html
* - mysql -X option for xml
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\ProcessBuilder;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\ConnectTrait;
class QueryCommand extends Command
{
use ConnectTrait;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:query')
->setDescription($this->trans('commands.database.query.description'))
->addArgument(
'query',
InputArgument::REQUIRED,
$this->trans('commands.database.query.arguments.query')
)
->addArgument(
'database',
InputArgument::OPTIONAL,
$this->trans('commands.database.query.arguments.database'),
'default'
)
->addArgument(
'target',
InputArgument::OPTIONAL,
$this->trans('commands.database.connect.arguments.target'),
'default'
)
->addOption('quick', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.quick'))
->addOption('debug', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.debug'))
->addOption('html', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.html'))
->addOption('xml', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.xml'))
->addOption('raw', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.raw'))
->addOption('vertical', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.vertical'))
->addOption('batch', null, InputOption::VALUE_NONE, $this->trans('commands.database.query.options.batch'))
->setHelp($this->trans('commands.database.query.help'))
->setAliases(['dbq']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$query = $input->getArgument('query');
$database = $input->getArgument('database');
$target = $input->getArgument('target');
$learning = $input->getOption('learning');
$databaseConnection = $this->resolveConnection($database, $target);
$connection = sprintf(
'%s -A --database=%s --user=%s --password=%s --host=%s --port=%s',
$databaseConnection['driver'],
$databaseConnection['database'],
$databaseConnection['username'],
$databaseConnection['password'],
$databaseConnection['host'],
$databaseConnection['port']
);
$args = explode(' ', $connection);
$args[] = sprintf('--execute=%s', $query);
$opts = ['quick', 'debug', 'html', 'xml', 'raw', 'vertical', 'batch'];
array_walk(
$opts, function ($opt) use ($input, &$args) {
if ($input->getOption($opt)) {
switch ($opt) {
case 'quick':
$args[] = '--quick';
break;
case 'debug':
$args[] = '-T';
break;
case 'html':
$args[] = '-H';
break;
case 'xml':
$args[] = '-X';
break;
case 'raw':
$args[] = '--raw';
break;
case 'vertical':
$args[] = '-E';
break;
case 'batch':
$args[] = '--batch';
break;
}
}
}
);
if ($learning) {
$this->getIo()->commentBlock(
implode(' ', $args)
);
}
$processBuilder = new ProcessBuilder();
$processBuilder->setArguments($args);
$process = $processBuilder->getProcess();
$process->setTty('true');
$process->run();
if (!$process->isSuccessful()) {
throw new \RuntimeException($process->getErrorOutput());
}
return 0;
}
}

View File

@@ -0,0 +1,163 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Database\RestoreCommand.
*/
namespace Drupal\Console\Command\Database;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\ConnectTrait;
class RestoreCommand extends Command
{
use ConnectTrait;
/**
* @var string
*/
protected $appRoot;
/**
* RestoreCommand constructor.
*
* @param string $appRoot
*/
public function __construct($appRoot)
{
$this->appRoot = $appRoot;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('database:restore')
->setDescription($this->trans('commands.database.restore.description'))
->addArgument(
'database',
InputArgument::OPTIONAL,
$this->trans('commands.database.restore.arguments.database'),
'default'
)
->addArgument(
'target',
InputArgument::OPTIONAL,
$this->trans('commands.database.restore.arguments.target'),
'default'
)
->addOption(
'file',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.database.restore.options.file')
)
->setHelp($this->trans('commands.database.restore.help'))
->setAliases(['dbr'])
->enableMaintenance();
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$database = $input->getArgument('database');
$target = $input->getArgument('target');
$file = $input->getOption('file');
$learning = $input->getOption('learning');
$databaseConnection = $this->escapeConnection($this->resolveConnection($database, $target));
if (!$file || !file_exists($file)) {
$this->getIo()->error(
$this->trans('commands.database.restore.messages.no-file')
);
return 1;
}
if (strpos($file, '.sql.gz') !== false) {
$catCommand = 'gunzip -c %s | ';
} else {
$catCommand = 'cat %s | ';
}
$commands = array();
if ($databaseConnection['driver'] == 'mysql') {
// Drop database first.
$commands[] = sprintf(
"mysql --user='%s' --password='%s' --host='%s' --port='%s' -e'DROP DATABASE IF EXISTS %s'",
$databaseConnection['username'],
$databaseConnection['password'],
$databaseConnection['host'],
$databaseConnection['port'],
$databaseConnection['database']
);
// Recreate database.
$commands[] = sprintf(
"mysql --user='%s' --password='%s' --host='%s' --port='%s' -e'CREATE DATABASE %s'",
$databaseConnection['username'],
$databaseConnection['password'],
$databaseConnection['host'],
$databaseConnection['port'],
$databaseConnection['database']
);
// Import dump.
$commands[] = sprintf(
$catCommand . "mysql --user='%s' --password='%s' --host='%s' --port='%s' %s",
$file,
$databaseConnection['username'],
$databaseConnection['password'],
$databaseConnection['host'],
$databaseConnection['port'],
$databaseConnection['database']
);
} elseif ($databaseConnection['driver'] == 'pgsql') {
$commands[] = sprintf(
"PGPASSWORD='%s' " . $catCommand . "psql -w -U '%s' -h '%s' -p '%s' -d '%s'",
$file,
$databaseConnection['password'],
$databaseConnection['username'],
$databaseConnection['host'],
$databaseConnection['port'],
$databaseConnection['database']
);
}
foreach ($commands as $command) {
if ($learning) {
$this->getIo()->commentBlock($command);
}
$process = new Process($command);
$process->setTimeout(null);
$process->setWorkingDirectory($this->appRoot);
$process->setTty($input->isInteractive());
$process->run();
if (!$process->isSuccessful()) {
throw new \RuntimeException($process->getErrorOutput());
}
}
$this->getIo()->success(
sprintf(
'%s %s',
$this->trans('commands.database.restore.messages.success'),
$file
)
);
return 0;
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\BreakpointsCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\breakpoint\BreakpointManagerInterface;
use Symfony\Component\Yaml\Yaml;
use Drupal\Console\Annotations\DrupalCommand;
/**
* @DrupalCommand(
* extension = "breakpoint",
* extensionType = "module"
* )
*/
class BreakpointsCommand extends Command
{
/**
* @var BreakpointManagerInterface
*/
protected $breakpointManager;
/**
* @var string
*/
protected $appRoot;
/**
* BreakpointsCommand constructor.
*
* @param BreakpointManagerInterface $breakpointManager
* @param string $appRoot
*/
public function __construct(
BreakpointManagerInterface $breakpointManager = null,
$appRoot
) {
$this->breakpointManager = $breakpointManager;
$this->appRoot = $appRoot;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:breakpoints')
->setDescription($this->trans('commands.debug.breakpoints.description'))
->addArgument(
'group',
InputArgument::OPTIONAL,
$this->trans('commands.debug.breakpoints.options.group-name')
)->setAliases(['dbre']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$group = $input->getArgument('group');
if ($group) {
$breakPointData = $this->getBreakpointByName($group);
foreach ($breakPointData as $key => $breakPoint) {
$this->getIo()->comment($key, false);
$this->getIo()->block(Yaml::dump($breakPoint));
}
return 0;
}
$groups = array_keys($this->breakpointManager->getGroups());
$tableHeader = [
$this->trans('commands.debug.breakpoints.messages.name'),
];
$this->getIo()->table($tableHeader, $groups, 'compact');
return 0;
}
/**
* @param $group String
* @return mixed
*/
private function getBreakpointByName($group)
{
$typeExtension = implode(
',',
array_values($this->breakpointManager->getGroupProviders($group))
);
$projectPath = drupal_get_path($typeExtension, $group);
$extensionFile = sprintf(
'%s/%s/%s.breakpoints.yml',
$this->appRoot,
$projectPath,
$group
);
return Yaml::parse(
file_get_contents($extensionFile)
);
}
}

View File

@@ -0,0 +1,60 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\CacheContextCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\ContainerAwareCommand;
/**
* Class CacheContextCommand.
*
* @package Drupal\Console\Command\Debug
*/
class CacheContextCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:cache:context')
->setDescription($this->trans('commands.debug.cache.context.description'))
->setAliases(['dcc']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$contextManager = $this->get('cache_contexts_manager');
$tableHeader = [
$this->trans('commands.debug.cache.context.messages.code'),
$this->trans('commands.debug.cache.context.messages.label'),
$this->trans('commands.debug.cache.context.messages.class'),
];
$tableRows = [];
foreach ($contextManager->getAll() as $code) {
$context = $this->get('cache_context.'.$code);
$tableRows[] = [
$code,
$context->getLabel()->render(),
get_class($context),
];
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
return 0;
}
}

View File

@@ -0,0 +1,132 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ConfigCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Console\Core\Command\Command;
class ConfigCommand extends Command
{
/**
* @var ConfigFactory
*/
protected $configFactory;
/**
* @var CachedStorage
*/
protected $configStorage;
/**
* ConfigCommand constructor.
*
* @param ConfigFactory $configFactory
* @param CachedStorage $configStorage
*/
public function __construct(
ConfigFactory $configFactory,
CachedStorage $configStorage
) {
$this->configFactory = $configFactory;
$this->configStorage = $configStorage;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:config')
->setDescription($this->trans('commands.debug.config.description'))
->addArgument(
'name',
InputArgument::OPTIONAL,
$this->trans('commands.debug.config.arguments.name')
)
->addOption(
'show-overridden',
null,
InputOption::VALUE_NONE,
$this->trans('commands.debug.config.options.show-overridden')
)
->setAliases(['dc']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$configName = $input->getArgument('name');
$showOverridden = $input->getOption('show-overridden');
if (!$configName) {
$this->getAllConfigurations();
} else {
$this->getConfigurationByName($configName, $showOverridden);
}
}
private function getAllConfigurations()
{
$names = $this->configFactory->listAll();
$tableHeader = [
$this->trans('commands.debug.config.arguments.name'),
];
$tableRows = [];
foreach ($names as $name) {
$tableRows[] = [
$name,
];
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
/**
* @param $config_name String
* @param $showOverridden bool
*/
private function getConfigurationByName($config_name, $showOverridden = false)
{
if ($this->configStorage->exists($config_name)) {
$tableHeader = [
$config_name,
];
$configuration = $this->configStorage->read($config_name);
if ($showOverridden) {
$configurationKeys = array_keys($configuration);
foreach ($configurationKeys as $configurationKey) {
$configuration[$configurationKey] = $this->configFactory
->get($config_name)
->get($configurationKey);
}
}
$configurationEncoded = Yaml::encode($configuration);
$tableRows = [];
$tableRows[] = [
$configurationEncoded,
];
$this->getIo()->table($tableHeader, $tableRows, 'compact');
} else {
$this->getIo()->error(
sprintf($this->trans('commands.debug.config.errors.not-exists'), $config_name)
);
}
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ConfigSettingsCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Site\Settings;
/**
* Class DebugCommand
*
* @package Drupal\Console\Command\Debug
*/
class ConfigSettingsCommand extends Command
{
/**
* @var Settings
*/
protected $settings;
/**
* ConfigSettingsCommand constructor.
*
* @param Settings $settings
*/
public function __construct(Settings $settings)
{
$this->settings = $settings;
;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:config:settings')
->setDescription($this->trans('commands.debug.config.settings.description'))
->setHelp($this->trans('commands.debug.config.settings.help'))
->setAliases(['dcs']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$settingKeys = array_keys($this->settings->getAll());
$this->getIo()->newLine();
$this->getIo()->info($this->trans('commands.debug.config.settings.messages.current'));
$this->getIo()->newLine();
foreach ($settingKeys as $settingKey) {
$settingValue = $this->settings->get($settingKey);
$this->getIo()->comment($settingKey . ': ', is_array($settingValue));
$this->getIo()->write(Yaml::encode($settingValue));
if (!is_array($settingValue)) {
$this->getIo()->newLine();
}
}
$this->getIo()->newLine();
}
}

View File

@@ -0,0 +1,114 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ConfigValidateCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Core\Config\Schema\SchemaCheckTrait;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Serialization\Yaml;
use Drupal\Console\Command\Config\PrintConfigValidationTrait;
/**
* Class ConfigValidateCommand.
*
*@package Drupal\Console\Command\Debug
*/
class ConfigValidateCommand extends ContainerAwareCommand
{
use SchemaCheckTrait;
use PrintConfigValidationTrait;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:config:validate')
->setDescription($this->trans('commands.debug.config.validate.description'))
->addArgument(
'filepath',
InputArgument::REQUIRED
)
->addArgument(
'schema-filepath',
InputArgument::REQUIRED
)
->addOption(
'schema-name',
'sch',
InputOption::VALUE_REQUIRED
)->setAliases(['dcv']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
/**
* @var TypedConfigManagerInterface $typedConfigManager
*/
$typedConfigManager = $this->get('config.typed');
//Validate config file path
$configFilePath = $input->getArgument('filepath');
if (!file_exists($configFilePath)) {
$this->getIo()->info($this->trans('commands.debug.config.validate.messages.noConfFile'));
return 1;
}
//Validate schema path
$configSchemaFilePath = $input->getArgument('schema-filepath');
if (!file_exists($configSchemaFilePath)) {
$this->getIo()->info($this->trans('commands.debug.config.validate.messages.noConfSchema'));
return 1;
}
$config = Yaml::decode(file_get_contents($configFilePath));
$schema = Yaml::decode(file_get_contents($configSchemaFilePath));
//Get the schema name and check it exists in the schema array
$schemaName = $this->getSchemaName($configFilePath);
if (!array_key_exists($schemaName, $schema)) {
$this->getIo()->warning($this->trans('commands.debug.config.validate.messages.noSchemaName') . $schemaName);
return 1;
}
return $this->printResults($this->manualCheckConfigSchema($typedConfigManager, $config, $schema[$schemaName]));
}
private function getSchemaName($configFilePath)
{
$schemaName = $this->getIo()->getInput()->getOption('schema-name');
if ($schemaName === null) {
$schema_name = end(explode('/', $configFilePath));
$schemaName = substr($schema_name, 0, -4);
}
return $schemaName;
}
private function manualCheckConfigSchema(TypedConfigManagerInterface $typed_config, $config_data, $config_schema)
{
$data_definition = $typed_config->buildDataDefinition($config_schema, $config_data);
$this->schema = $typed_config->create($data_definition, $config_data);
$errors = [];
foreach ($config_data as $key => $value) {
$errors = array_merge($errors, $this->checkValue($key, $value));
}
if (empty($errors)) {
return true;
}
return $errors;
}
}

View File

@@ -0,0 +1,403 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\ContainerDebugCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Yaml;
/**
* Class ContainerCommand
*
* @package Drupal\Console\Command\Debug
*/
class ContainerCommand extends ContainerAwareCommand
{
const BLUE = 'blue';
const CYAN = 'cyan';
const GREEN = 'green';
const MAGENTA = 'magenta';
const RED = 'red';
const YELLOW = 'yellow';
const WHITE = 'white';
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:container')
->setDescription($this->trans('commands.debug.container.description'))
->addOption(
'parameters',
null,
InputOption::VALUE_NONE,
$this->trans('commands.debug.container.arguments.service')
)
->addArgument(
'service',
InputArgument::OPTIONAL,
$this->trans('commands.debug.container.arguments.service')
)->addArgument(
'method',
InputArgument::OPTIONAL,
$this->trans('commands.debug.container.arguments.method')
)->addArgument(
'arguments',
InputArgument::OPTIONAL,
$this->trans('commands.debug.container.arguments.arguments')
)->addOption(
'tag',
null,
InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.container.options.tag')
)
->setAliases(['dco']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$service = $input->getArgument('service');
$parameters = $input->getOption('parameters');
$tag = $input->getOption('tag');
$method = $input->getArgument('method');
$args = $input->getArgument('arguments');
if ($parameters) {
$parameterList = $this->getParameterList();
ksort($parameterList);
$this->getIo()->write(Yaml::dump(['parameters' => $parameterList], 4, 2));
return 0;
}
if ($method) {
$tableHeader = [];
$callbackRow = $this->getCallbackReturnList($service, $method, $args);
$this->getIo()->table($tableHeader, $callbackRow, 'compact');
return 0;
} else {
$tableHeader = [];
if ($service) {
$tableRows = $this->getServiceDetail($service);
$this->getIo()->table($tableHeader, $tableRows, 'compact');
return 0;
}
$tableHeader = [
$this->trans('commands.debug.container.messages.service-id'),
$this->trans('commands.debug.container.messages.class-name')
];
$tableRows = $this->getServiceList($tag);
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
return 0;
}
/**
* Get callback list.
*
* @param string $service
* Service name.
* @param string $method
* Methods name.
* @param array $args
* Arguments.
*
* @return array
* List of callbacks.
*/
private function getCallbackReturnList($service, $method, $args)
{
if ($args != null) {
$parsedArgs = json_decode($args, true);
if (!is_array($parsedArgs)) {
$parsedArgs = explode(',', $args);
}
} else {
$parsedArgs = null;
}
$serviceInstance = \Drupal::service($service);
if (!method_exists($serviceInstance, $method)) {
throw new \Symfony\Component\DependencyInjection\Exception\BadMethodCallException($this->trans('commands.debug.container.errors.method-not-exists'));
return $serviceDetail;
}
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.service'),
$this->addWrapper($service),
];
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.class'),
$this->addWrapper(get_class($serviceInstance)),
];
$methods = [$method];
$this->extendArgumentList($serviceInstance, $methods);
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.method'),
$this->addWrapper($methods[0]),
];
if ($parsedArgs) {
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.arguments'),
$this->addWrapper(json_encode($parsedArgs, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)),
];
}
$return = call_user_func_array([$serviceInstance,$method], $parsedArgs);
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.return'),
$this->addWrapper(json_encode($return, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)),
];
return $serviceDetail;
}
/**
* Get service list.
*
* @param string $tag
* Tag.
*
* @return array
* Array of services.
*/
private function getServiceList($tag = null)
{
if ($tag) {
return $this->getServiceListByTag($tag);
}
$services = [];
$serviceDefinitions = $this->container->getDefinitions();
foreach ($serviceDefinitions as $serviceId => $serviceDefinition) {
$services[] = [$serviceId, $serviceDefinition->getClass()];
}
usort($services, [$this, 'compareService']);
return $services;
}
/**
* Get service list by a tag.
*
* @param string $tag
* Tag.
*
* @return array
* Array of services.
*/
private function getServiceListByTag($tag)
{
$services = [];
$serviceIds = [];
$serviceDefinitions = $this->container->getDefinitions();
foreach ($tag as $tagId) {
$serviceIds = array_merge(
$serviceIds,
array_keys($this->container->findTaggedServiceIds($tagId))
);
}
foreach ($serviceIds as $serviceId) {
$serviceDefinition = $serviceDefinitions[$serviceId];
if ($serviceDefinition) {
$services[] = [$serviceId, $serviceDefinition->getClass()];
}
}
usort($services, [$this, 'compareService']);
return $services;
}
/**
* Compares the values.
*
* @param string $a
* First value.
* @param string $b
* Second value.
*
* @return int
* Result.
*/
private function compareService($a, $b)
{
return strcmp($a[0], $b[0]);
}
private function getServiceDetail($service)
{
$serviceInstance = $this->get($service);
$serviceDetail = [];
$class_name = get_class($serviceInstance);
if ($serviceInstance) {
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.service'),
$this->addTranslationWrapper('commands.debug.container.messages.service'),
];
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.class'),
$this->addTranslationWrapper('commands.debug.container.messages.class'),
];
$interface = str_replace('{ }', '', Yaml::dump(class_implements($serviceInstance)));
if (!empty($interface)) {
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.interface'),
$this->addWrapper($interface),
];
}
if ($parent = get_parent_class($serviceInstance)) {
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.parent'),
$this->addWrapper($parent),
];
}
if ($vars = get_class_vars($class_name)) {
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.variables'),
$this->addWrapper(Yaml::dump($vars)),
];
}
if ($methods = get_class_methods($class_name)) {
sort($methods);
$this->extendArgumentList($serviceInstance, $methods);
$serviceDetail[] = [
$this->addGreenTranslationWrapper('commands.debug.container.messages.methods'),
$this->addWrapper(implode("\n", $methods)),
];
}
} else {
throw new \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException($service);
return $serviceDetail;
}
return $serviceDetail;
}
/**
* Adds a wrapper with a color
*
* @param string $text
* Text.
* @param string $color
* Color.
*
* @return string
* Result of the wrapping.
*/
private function addWrapper($text, $color = ContainerCommand::YELLOW)
{
return "<fg=$color>$text</>";
}
/**
* Adds green color wrapper.
*
* @param string $translationString
* Translation string.
*
* @return string
* Result of the wrapping.
*/
private function addGreenTranslationWrapper($translationString)
{
return $this->addTranslationWrapper($translationString, ContainerCommand::GREEN);
}
/**
* Adds green color wrapper.
*
* @param string $translationString
* Translation string.
*
* @return string
* Result of the wrapping.
*/
private function addTranslationWrapper($translationString, $color = ContainerCommand::YELLOW) {
return $this->addWrapper($this->trans($translationString), $color);
}
private function extendArgumentList($serviceInstance, &$methods)
{
foreach ($methods as $k => $m) {
$reflection = new \ReflectionMethod($serviceInstance, $m);
$params = $reflection->getParameters();
$p = [];
for ($i = 0; $i < count($params); $i++) {
if ($params[$i]->isDefaultValueAvailable()) {
$defaultVar = $params[$i]->getDefaultValue();
$defaultVar = ' = ' . $this->addWrapper(str_replace(["\n",'array ('], ['', 'array('], var_export($defaultVar, true)), ContainerCommand::MAGENTA);
} else {
$defaultVar = '';
}
if (method_exists($params[$i], 'hasType') && method_exists($params[$i], 'getType')) {
if ($params[$i]->hasType()) {
$defaultType = $this->addWrapper( strval($params[$i]->getType()), ContainerCommand::WHITE) . ' ';
} else {
$defaultType = '';
}
} else {
$defaultType = '';
}
if ($params[$i]->isPassedByReference()) {
$parameterReference = $this->addWrapper('&');
} else {
$parameterReference = '';
}
$p[] = $defaultType . $parameterReference . $this->addWrapper('$' . $params[$i]->getName(), ContainerCommand::RED) . $defaultVar;
}
if ($reflection->isPublic()) {
$methods[$k] = $this->addWrapper($methods[$k], ContainerCommand::CYAN) . $this->addWrapper('(', ContainerCommand::BLUE) . implode(', ', $p) . $this->addWrapper(')', ContainerCommand::BLUE);
}
}
}
/**
* Get parameter list.
*
* @return array
* Array with parameter.
*/
private function getParameterList()
{
return array_filter(
$this->container->getParameterBag()->all(), function ($name) {
if (preg_match('/^container\./', $name)) {
return false;
}
if (preg_match('/^drupal\./', $name)) {
return false;
}
if (preg_match('/^console\./', $name)) {
return false;
}
return true;
}, ARRAY_FILTER_USE_KEY
);
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\CronCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Extension\ModuleHandlerInterface;
class CronCommand extends Command
{
/**
* @var ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* CronCommand constructor.
*
* @param ModuleHandlerInterface $moduleHandler
*/
public function __construct(ModuleHandlerInterface $moduleHandler)
{
$this->moduleHandler = $moduleHandler;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:cron')
->setDescription($this->trans('commands.debug.cron.description'))
->setAliases(['dcr']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->getIo()->section(
$this->trans('commands.debug.cron.messages.module-list')
);
$this->getIo()->table(
[ $this->trans('commands.debug.cron.messages.module') ],
$this->moduleHandler->getImplementations('cron'),
'compact'
);
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\DatabaseLogCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\Console\Command\Database\DatabaseLogBase;
/**
* Class DatabaseLogCommand
*
* @package Drupal\Console\Command\Debug
*/
class DatabaseLogCommand extends DatabaseLogBase
{
/**
* @var
*/
protected $eventId;
/**
* @var
*/
protected $asc;
/**
* @var
*/
protected $limit;
/**
* @var
*/
protected $offset;
/**
* Print in yml style if true
*
* @var bool
*/
protected $ymlStyle;
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:database:log')
->setDescription($this->trans('commands.debug.database.log.description'));
$this->addDefaultLoggingOptions();
$this
->addArgument(
'event-id',
InputArgument::OPTIONAL,
$this->trans('commands.debug.database.log.arguments.event-id')
)
->addOption(
'asc',
null,
InputOption::VALUE_NONE,
$this->trans('commands.debug.database.log.options.asc')
)
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.database.log.options.limit')
)
->addOption(
'offset',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.database.log.options.offset'),
0
)
->addOption(
'yml',
null,
InputOption::VALUE_NONE,
$this->trans('commands.debug.database.log.options.yml'),
null
)
->setAliases(['dbb']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->getDefaultOptions($input);
$this->eventId = $input->getArgument('event-id');
$this->asc = $input->getOption('asc');
$this->limit = $input->getOption('limit');
$this->offset = $input->getOption('offset');
$this->ymlStyle = $input->getOption('yml');
if ($this->eventId) {
return $this->getEventDetails();
} else {
return $this->getAllEvents();
}
}
/**
* @param $eventId
* @return bool
*/
private function getEventDetails()
{
$dblog = $this->database
->query(
'SELECT w.*, u.uid FROM {watchdog} w LEFT JOIN {users} u ON u.uid = w.uid WHERE w.wid = :id',
[':id' => $this->eventId]
)
->fetchObject();
if (!$dblog) {
$this->getIo()->error(
sprintf(
$this->trans('commands.debug.database.log.messages.not-found'),
$this->eventId
)
);
return 1;
}
if ($this->ymlStyle) {
$this->getIo()->writeln(Yaml::encode($this->formatSingle($dblog)));
} else {
$this->getIo()->table(
$this->createTableHeader(),
[$this->createTableRow($dblog)]
);
}
}
/**
* @return bool
*/
private function getAllEvents()
{
$query = $this->makeQuery();
$result = $query->execute();
$tableRows = [];
foreach ($result as $dblog) {
$tableRows[] = $this->createTableRow($dblog);
}
$this->getIo()->table(
$this->createTableHeader(),
$tableRows
);
return true;
}
}

View File

@@ -0,0 +1,131 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\DatabaseTableCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use RedBeanPHP\R;
use Drupal\Core\Database\Connection;
use Drupal\Console\Command\Shared\ConnectTrait;
/**
* Class DatabaseTableCommand
*
* @package Drupal\Console\Command\Database
*/
class DatabaseTableCommand extends Command
{
use ConnectTrait;
/**
* @var Connection
*/
protected $database;
/**
* DatabaseTableCommand constructor.
*
* @param Connection $database
*/
public function __construct(
Connection $database
) {
$this->database = $database;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:database:table')
->setDescription($this->trans('commands.debug.database.table.description'))
->addOption(
'database',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.database.table.options.database'),
'default'
)
->addArgument(
'table',
InputArgument::OPTIONAL,
$this->trans('commands.debug.database.table.arguments.table'),
null
)
->setHelp($this->trans('commands.debug.database.table.help'))
->setAliases(['ddt']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$database = $input->getOption('database');
$table = $input->getArgument('table');
$databaseConnection = $this->resolveConnection($database);
if ($table) {
$result = $databaseConnection['driver'] == 'sqlite' ? $this->database->query('PRAGMA table_info('.$table.');') :
$this->database
->query('DESCRIBE ' . $table . ';')
->fetchAll();
if (!$result) {
throw new \Exception(
sprintf(
$this->trans('commands.debug.database.table.messages.no-connection'),
$database
)
);
}
$tableHeader = [
$this->trans('commands.debug.database.table.messages.column'),
$this->trans('commands.debug.database.table.messages.type')
];
$tableRows = [];
foreach ($result as $record) {
$column = json_decode(json_encode($record), true);
$tableRows[] = [
'column' => $column[$databaseConnection['driver'] == 'sqlite' ? 'name': 'Field'],
'type' => $column[$databaseConnection['driver'] == 'sqlite' ? 'type': 'Type'],
];
}
$this->getIo()->table($tableHeader, $tableRows);
return 0;
}
$schema = $this->database->schema();
$tables = $databaseConnection['driver'] == 'sqlite' ? array_keys($this->database->query('SELECT name FROM sqlite_master WHERE type = "table" AND name NOT LIKE "sqlite_%";')
->fetchAllAssoc('name')) : $schema->findTables('%');
$this->getIo()->comment(
sprintf(
$this->trans('commands.debug.database.table.messages.table-show'),
$databaseConnection['database']
)
);
$this->getIo()->table(
[$this->trans('commands.debug.database.table.messages.table')],
$tables
);
return 0;
}
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Filesystem\Filesystem;
use Drupal\Console\Core\Utils\DrupalFinder;
/**
* Class DebugCommand
*
* @package Drupal\Console\Command\Debug
*/
class DotenvCommand extends Command
{
/**
* @var DrupalFinder
*/
protected $drupalFinder;
/**
* InitCommand constructor.
*
* @param DrupalFinder $drupalFinder
*/
public function __construct(
DrupalFinder $drupalFinder
) {
$this->drupalFinder = $drupalFinder;
parent::__construct();
}
protected function configure()
{
$this->setName('debug:dotenv')
->setDescription('Debug Dotenv debug values.');
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$fs = new Filesystem();
$envFile = $this->drupalFinder->getComposerRoot() . '/.env';
if (!$fs->exists($envFile)) {
$this->getIo()->warning('File '. $envFile . ' not found.');
return 1;
}
$fileContent = file_get_contents($envFile);
$this->getIo()->writeln($fileContent);
$this->getIo()->warning('This command is deprecated use instead: `cat .env`');
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\EntityCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Entity\EntityTypeRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
class EntityCommand extends Command
{
/**
* @var EntityTypeRepositoryInterface
*/
protected $entityTypeRepository;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* EntityCommand constructor.
*
* @param EntityTypeRepositoryInterface $entityTypeRepository
* @param EntityTypeManagerInterface $entityTypeManager
*/
public function __construct(
EntityTypeRepositoryInterface $entityTypeRepository,
EntityTypeManagerInterface $entityTypeManager
) {
$this->entityTypeRepository = $entityTypeRepository;
$this->entityTypeManager = $entityTypeManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:entity')
->setDescription($this->trans('commands.debug.entity.description'))
->addArgument(
'entity-type',
InputArgument::OPTIONAL,
$this->trans('commands.debug.entity.arguments.entity-type')
)->setAliases(['de']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$entityType = $input->getArgument('entity-type');
$tableHeader = [
$this->trans('commands.debug.entity.table-headers.entity-name'),
$this->trans('commands.debug.entity.table-headers.entity-type')
];
$tableRows = [];
$entityTypesLabels = $this->entityTypeRepository->getEntityTypeLabels(true);
if ($entityType) {
$entityTypes = [$entityType => $entityType];
} else {
$entityTypes = array_keys($entityTypesLabels);
}
foreach ($entityTypes as $entityTypeId) {
$entities = array_keys($entityTypesLabels[$entityTypeId]);
foreach ($entities as $entity) {
$tableRows[$entity] = [
$entity,
$entityTypeId
];
}
}
$this->getIo()->table($tableHeader, array_values($tableRows));
}
}

View File

@@ -0,0 +1,139 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\EventCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Yaml\Yaml;
/**
* Class EventCommand
*
* @package Drupal\Console\Command\Debug
*/
class EventCommand extends Command
{
protected $eventDispatcher;
/**
* EventDebugCommand constructor.
*
* @param $eventDispatcher
*/
public function __construct($eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:event')
->setDescription($this->trans('commands.debug.event.description'))
->addArgument(
'event',
InputArgument::OPTIONAL,
$this->trans('commands.debug.event.arguments.event'),
null
)
->setHelp($this->trans('commands.debug.event.blerp'))
->setAliases(['dev']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$events = array_keys($this->eventDispatcher->getListeners());
$event = $input->getArgument('event');
if ($event) {
if (!in_array($event, $events)) {
throw new \Exception(
sprintf(
$this->trans('commands.debug.event.messages.no-events'),
$event
)
);
}
$dispatcher = $this->eventDispatcher->getListeners($event);
$listeners = [];
foreach ($dispatcher as $key => $value) {
$reflection = new \ReflectionClass(get_class($value[0]));
$className = $reflection->getName();
if (!$reflection->hasMethod('getSubscribedEvents')) {
$reflection = new \ReflectionClass($reflection->getParentClass());
}
$eventObject = $reflection->newInstanceWithoutConstructor();
$reflectionMethod = new \ReflectionMethod(
$reflection->getName(),
'getSubscribedEvents'
);
$subscribedEvents = $reflectionMethod->invoke(
$eventObject
);
if (!is_array($subscribedEvents[$event])) {
$subscribedEvents[$event] = [$subscribedEvents[$event]];
}
$subscribedEventData = [];
foreach ($subscribedEvents[$event] as $subscribedEvent) {
if (!is_array($subscribedEvent)) {
$subscribedEvent = [$subscribedEvent, 0];
}
if ($subscribedEvent[0] == $value[1]) {
$subscribedEventData = [
$subscribedEvent[0] => isset($subscribedEvent[1])?$subscribedEvent[1]:0
];
}
}
$listeners[] = [
'class' => $className,
'method' => $value[1],
'events' => rtrim(Yaml::dump($subscribedEventData, 4, 2))
];
}
$tableHeader = [
$this->trans('commands.debug.event.messages.class'),
$this->trans('commands.debug.event.messages.method'),
];
$tableRows = [];
foreach ($listeners as $key => $element) {
$tableRows[] = [
'class' => $element['class'],
'events' => $element['events']
];
}
$this->getIo()->table($tableHeader, $tableRows);
return 0;
}
$this->getIo()->table(
[$this->trans('commands.debug.event.messages.event')],
$events
);
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\FeaturesCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Command\Shared\FeatureTrait;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Console\Core\Command\Command;
/**
* @DrupalCommand(
* extension = "features",
* extensionType = "module"
* )
*/
class FeaturesCommand extends Command
{
use FeatureTrait;
protected function configure()
{
$this
->setName('debug:features')
->setDescription($this->trans('commands.debug.features.description'))
->addArgument(
'bundle',
InputArgument::OPTIONAL,
$this->trans('commands.debug.features.arguments.bundle')
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$bundle= $input->getArgument('bundle');
$tableHeader = [
$this->trans('commands.debug.features.messages.bundle'),
$this->trans('commands.debug.features.messages.name'),
$this->trans('commands.debug.features.messages.machine-name'),
$this->trans('commands.debug.features.messages.status'),
$this->trans('commands.debug.features.messages.state'),
];
$tableRows = [];
$features = $this->getFeatureList($bundle);
foreach ($features as $feature) {
$tableRows[] = [$feature['bundle_name'],$feature['name'], $feature['machine_name'], $feature['status'],$feature['state']];
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
}

View File

@@ -0,0 +1,198 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\HookCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Extension\Manager;
use Drupal\Component\Utility;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Finder\Finder;
/**
* Class HookCommand.
*
* @package Drupal\Console\Command\Debug
*/
class HookCommand extends Command
{
/**
* @var Manager $extensionManager
*/
protected $extensionManager = null;
/**
* @var ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* @var array
*/
protected $hooks = [];
/**
* HookCommand constructor.
*
* @param Manager $extensionManager
* @param ModuleHandlerInterface $moduleHandler
*
*/
public function __construct(
Manager $extensionManager,
ModuleHandlerInterface $moduleHandler
) {
$this->extensionManager = $extensionManager;
$this->moduleHandler = $moduleHandler;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:hook')
->setDescription($this->trans('commands.debug.hook.description'))
->setAliases(['dbh']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->findHooks();
$tableHeader = [
$this->trans('commands.debug.hook.messages.name'),
];
$this->getIo()->table($tableHeader, $this->getHooks(), 'compact');
return 0;
}
protected function findHooks()
{
$modules = $this->getAllModules();
$moduleInstances = [];
foreach ($modules as $module) {
$moduleInstance = $this->extensionManager->getModule($module);
if (empty($moduleInstance)) {
continue;
}
$moduleInstances[$module] = $moduleInstance;
$this->moduleHandler->setModuleList([$module => $moduleInstance]);
$this->findHooksInApiFile($moduleInstance);
}
$this->getHooksFromHookInfo($moduleInstances);
}
/**
* Get module of all modules in the system.
*
* @return array
* Module list.
*/
protected function getAllModules()
{
return $this->extensionManager->discoverModules()
->showInstalled()
->showUninstalled()
->showNoCore()
->showCore()
->getList(true);
}
/**
* Gets gooks from api file of the module.
*
* @param $moduleInstance
* Module instance.
*/
protected function findHooksInApiFile($moduleInstance)
{
$finder = new Finder();
$files = $finder->files()
->name("{$moduleInstance->info['name']}.api.php")
->in($moduleInstance->getPath());
foreach ($files as $file) {
$functions = $this->getFileFunctions($file->getPathname());
foreach ($functions as $function) {
if (Unicode::strpos($function, 'hook')) {
$this->addHook($function);
}
}
}
}
/**
* Get names of all functions from file.
*
* @param string $filePath
* File path
* @return array
* Functions list.
*/
protected function getFileFunctions($filePath)
{
$source = file_get_contents($filePath);
$tokens = token_get_all($source);
$functions = [];
$nextStringIsFunc = false;
foreach($tokens as $token) {
switch($token[0]) {
case T_FUNCTION:
$nextStringIsFunc = true;
break;
case T_STRING:
if ($nextStringIsFunc) {
$nextStringIsFunc = false;
$functions[] = $token[1];
}
break;
}
}
return $functions;
}
/**
* @param $modules
*/
protected function getHooksFromHookInfo($modules)
{
$this->moduleHandler->setModuleList($modules);
foreach(array_keys($this->moduleHandler->getHookInfo()) as $hook) {
$this->addHook('hook_' . $hook);
}
}
/**
* Add hook.
*
* @param string $value
* Hook name.
*/
protected function addHook($value)
{
$this->hooks[] = $value;
}
protected function getHooks()
{
return $this->hooks;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ImageStylesCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* Class StylesDebugCommand
*
* @package Drupal\Console\Command\Debug
*/
class ImageStylesCommand extends Command
{
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* ImageStylesCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager)
{
$this->entityTypeManager = $entityTypeManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:image:styles')
->setDescription($this->trans('commands.debug.image.styles.description'))
->setAliases(['dis']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$imageStyle = $this->entityTypeManager->getStorage('image_style');
$this->getIo()->newLine();
$this->getIo()->comment(
$this->trans('commands.debug.image.styles.messages.styles-list')
);
if ($imageStyle) {
$this->imageStyleList($imageStyle);
}
return 0;
}
/**
* @param $imageStyle
*/
protected function imageStyleList($imageStyle)
{
$tableHeader = [
$this->trans('commands.debug.image.styles.messages.styles-name'),
$this->trans('commands.debug.image.styles.messages.styles-label')
];
$tableRows = [];
foreach ($imageStyle->loadMultiple() as $styles) {
$tableRows[] = [
$styles->get('name'),
$styles->get('label')
];
}
$this->getIo()->table(
$tableHeader,
$tableRows
);
}
}

View File

@@ -0,0 +1,155 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\LibrariesCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Extension\ThemeHandlerInterface;
use Drupal\Core\Asset\LibraryDiscoveryInterface;
use Drupal\Component\Serialization\Yaml;
class LibrariesCommand extends Command
{
/**
* @var ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* @var ThemeHandlerInterface;
*/
protected $themeHandler;
/**
* @var LibraryDiscoveryInterface
*/
protected $libraryDiscovery;
/**
* @var string
*/
protected $appRoot;
/**
* DebugCommand constructor.
*
* @param ModuleHandlerInterface $moduleHandler
* @param ThemeHandlerInterface $themeHandler
* @param LibraryDiscoveryInterface $libraryDiscovery
* @param string $appRoot
*/
public function __construct(
ModuleHandlerInterface $moduleHandler,
ThemeHandlerInterface $themeHandler,
LibraryDiscoveryInterface $libraryDiscovery,
$appRoot
) {
$this->moduleHandler = $moduleHandler;
$this->themeHandler = $themeHandler;
$this->libraryDiscovery = $libraryDiscovery;
$this->appRoot = $appRoot;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:libraries')
->setDescription($this->trans('commands.debug.libraries.description'))
->addArgument(
'group',
InputArgument::OPTIONAL,
$this->trans('commands.debug.libraries.options.name')
)->setAliases(['dl']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$extension = $input->getArgument('group');
if (!$extension) {
$groups = $this->getAllLibraries();
$tableRow = [];
$tableHeader = [
$this->trans('commands.debug.libraries.messages.extension'),
$this->trans('commands.debug.libraries.messages.library'),
];
foreach ($groups as $extension) {
$library = $this->libraryDiscovery
->getLibrariesByExtension($extension);
if (!$library) {
continue;
}
if ($libraryKeys = array_keys($library)) {
$libraryKeys = array_map(
function ($value) use ($extension) {
return $extension . '/' . $value;
},
$libraryKeys
);
$tableRow[] = [
$extension,
$libraryKeys = implode("\n", $libraryKeys) . "\n"
];
}
}
$this->getIo()->table($tableHeader, $tableRow, 'default');
} else {
$libraryName = null;
if ($library = explode('/', $extension)) {
$extension = $library[0];
$libraryName = $library[1];
}
$librariesData = $this->libraryDiscovery
->getLibrariesByExtension($extension);
foreach ($librariesData as $key => $libraries) {
if ($libraryName && $libraryName != $key) {
continue;
}
$this->getIo()->writeln('<info>'.$extension.'/'.$key.'</info>');
$this->getIo()->writeln(Yaml::encode($libraries));
}
}
}
private function getAllLibraries()
{
$modules = $this->moduleHandler->getModuleList();
$themes = $this->themeHandler->rebuildThemeData();
$extensions = array_merge($modules, $themes);
$libraries = [];
foreach ($extensions as $extensionName => $extension) {
$libraryFile = $extension->getPath() . '/' . $extensionName . '.libraries.yml';
if (is_file($this->appRoot . '/' . $libraryFile)) {
$libraries[$extensionName] = $this->libraryDiscovery->getLibrariesByExtension($extensionName);
}
}
return array_keys($libraries);
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\MigrateCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Command\Shared\MigrationTrait;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Console\Core\Command\Command;
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
/**
* @DrupalCommand(
* extension = "migrate",
* extensionType = "module"
* )
*/
class MigrateCommand extends Command
{
use MigrationTrait;
/**
* @var MigrationPluginManagerInterface $pluginManagerMigration
*/
protected $pluginManagerMigration;
/**
* MigrateCommand constructor.
*
* @param MigrationPluginManagerInterface $pluginManagerMigration
*/
public function __construct(
MigrationPluginManagerInterface $pluginManagerMigration
) {
$this->pluginManagerMigration = $pluginManagerMigration;
parent::__construct();
}
protected function configure()
{
$this
->setName('debug:migrate')
->setDescription($this->trans('commands.debug.migrate.description'))
->addArgument(
'tag',
InputArgument::OPTIONAL,
$this->trans('commands.debug.migrate.arguments.tag')
)
->setAliases(['mid']);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$drupal_version = 'Drupal ' . $input->getArgument('tag');
$migrations = $this->getMigrations($drupal_version);
$tableHeader = [
$this->trans('commands.debug.migrate.messages.id'),
$this->trans('commands.debug.migrate.messages.description'),
$this->trans('commands.debug.migrate.messages.tags'),
];
$tableRows = [];
if (empty($migrations)) {
$this->getIo()->error(
sprintf(
$this->trans('commands.debug.migrate.messages.no-migrations'),
count($migrations)
)
);
}
foreach ($migrations as $migration_id => $migration) {
$tableRows[] = [$migration_id, $migration['description'], $migration['tags']];
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
}

View File

@@ -0,0 +1,172 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ModuleCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Utils\Site;
use Drupal\Console\Core\Utils\ConfigurationManager;
use Drupal\Core\Extension\ModuleExtensionList;
class ModuleCommand extends Command
{
/**
* @var ConfigurationManager
*/
protected $configurationManager;
/**
* @var Site
*/
protected $site;
/**
* @var Site
*/
protected $module;
/**
* @var Drupal\Core\Extension\ModuleExtensionList
*/
protected $extensionList;
/**
* ChainDebugCommand constructor.
*
* @param ConfigurationManager $configurationManager
* @param Site $site
* @param ModuleExtensionList $extensionList
*/
public function __construct(
ConfigurationManager $configurationManager,
Site $site,
ModuleExtensionList $extensionList
) {
$this->configurationManager = $configurationManager;
$this->site = $site;
$this->extensionList = $extensionList;
parent::__construct();
}
protected function configure()
{
$this
->setName('debug:module')
->setDescription($this->trans('commands.debug.module.description'))
->addArgument(
'module',
InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
$this->trans('commands.debug.module.module')
)
->addOption(
'status',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.module.options.status')
)
->addOption(
'type',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.module.options.type')
)
->setAliases(['dm']);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->site->loadLegacyFile('/core/modules/system/system.module');
$status = strtolower($input->getOption('status'));
$type = strtolower($input->getOption('type'));
$modules = $input->getArgument('module');
if ($status == 'installed') {
$status = 1;
} elseif ($status == 'uninstalled') {
$status = 0;
} else {
$status = -1;
}
if ($type == 'core') {
$type = 'core';
} elseif ($type == 'no-core') {
$type = '';
} else {
$type = null;
}
$tableHeader = [
$this->trans('commands.debug.module.messages.id'),
$this->trans('commands.debug.module.messages.name'),
$this->trans('commands.debug.module.messages.package'),
$this->trans('commands.debug.module.messages.version'),
$this->trans('commands.debug.module.messages.schema-version'),
$this->trans('commands.debug.module.messages.status'),
$this->trans('commands.debug.module.messages.origin'),
];
$tableRows = $this->getModules($status, $type, $modules);
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
/**
* Get the module info
* @param $status
* @param $type
* @param $modules
*
* @return array
*/
private function getModules($status, $type, $modules) {
$result = [];
$modulesData = $this->extensionList->reset()->getList();
if(!$modules) {
$modules = array_keys($modulesData) ;
}
foreach ($modules as $module) {
$moduleData = $modulesData[strtolower($module)];
if(!$moduleData) {
continue;
}
if ($status >= 0 && $status != $moduleData->status) {
continue;
}
if ($type !== null && $type !== $moduleData->origin) {
continue;
}
$module_status = ($moduleData->status) ? $this->trans('commands.debug.module.messages.installed') : $this->trans('commands.debug.module.messages.uninstalled');
$module_origin = ($moduleData->origin) ? $moduleData->origin : 'no core';
$schema_version = (drupal_get_installed_schema_version($module)!= -1?drupal_get_installed_schema_version($module): '');
$result [] = [
$module,
$moduleData->info['name'],
$moduleData->info['package'],
$moduleData->info['version'],
$schema_version,
$module_status,
$module_origin,
];
}
return $result;
}
}

View File

@@ -0,0 +1,92 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\MultisiteCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
/**
* Class MultisiteCommand
*
* @package Drupal\Console\Command\Debug
*/
class MultisiteCommand extends Command
{
protected $appRoot;
/**
* MultisiteCommand constructor.
*
* @param $appRoot
*/
public function __construct($appRoot)
{
$this->appRoot = $appRoot;
parent::__construct();
}
/**
* {@inheritdoc}
*/
public function configure()
{
$this
->setName('debug:multisite')
->setDescription($this->trans('commands.debug.multisite.description'))
->setHelp($this->trans('commands.debug.multisite.help'))
->setAliases(['dmu']);
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$sites = [];
$multiSiteFile = sprintf(
'%s/sites/sites.php',
$this->appRoot
);
if (file_exists($multiSiteFile)) {
include $multiSiteFile;
}
if (!$sites) {
$this->getIo()->error(
$this->trans('commands.debug.multisite.messages.no-multisites')
);
return 1;
}
$this->getIo()->info(
$this->trans('commands.debug.multisite.messages.site-format')
);
$tableHeader = [
$this->trans('commands.debug.multisite.messages.site'),
$this->trans('commands.debug.multisite.messages.directory'),
];
$tableRows = [];
foreach ($sites as $site => $directory) {
$tableRows[] = [
$site,
$this->appRoot . '/sites/' . $directory
];
}
$this->getIo()->table($tableHeader, $tableRows);
return 0;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\PermissionCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
/**
* Class DebugCommand
*
* @package Drupal\Console\Command\Debug
*/
class PermissionCommand extends Command
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setName('debug:permission')
->setDescription($this->trans('commands.debug.permission.description'))
->setHelp($this->trans('commands.debug.permission.help'))
->addArgument(
'role',
InputArgument::OPTIONAL,
$this->trans('commands.debug.permission.arguments.role')
)->setAliases(['dp']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$role = $input->getArgument('role');
// No role specified, show a list of ALL permissions.
if (!$role) {
$tableHeader = [
$this->trans('commands.debug.permission.table-headers.permission-name'),
$this->trans('commands.debug.permission.table-headers.permission-label'),
$this->trans('commands.debug.permission.table-headers.permission-role')
];
$tableRows = [];
$permissions = \Drupal::service('user.permissions')->getPermissions();
foreach ($permissions as $permission_name => $permission) {
$tableRows[$permission_name] = [
$permission_name,
strip_tags($permission['title']->__toString()),
implode(', ', $this->getRolesAssignedByPermission($permission_name))
];
}
ksort($tableRows);
$this->getIo()->table($tableHeader, array_values($tableRows));
return true;
} else {
$tableHeader = [
$this->trans('commands.debug.permission.table-headers.permission-name'),
$this->trans('commands.debug.permission.table-headers.permission-label')
];
$tableRows = [];
$permissions = \Drupal::service('user.permissions')->getPermissions();
$roles = user_roles();
if (empty($roles[$role])) {
$message = sprintf($this->trans('commands.debug.permission.messages.role-error'), $role);
$this->getIo()->error($message);
return true;
}
$user_permission = $roles[$role]->getPermissions();
foreach ($permissions as $permission_name => $permission) {
if (in_array($permission_name, $user_permission)) {
$tableRows[$permission_name] = [
$permission_name,
strip_tags($permission['title']->__toString())
];
}
}
ksort($tableRows);
$this->getIo()->table($tableHeader, array_values($tableRows));
return true;
}
}
/**
* Get user roles Assigned by Permission.
*
* @param string $permission_name
* Permission Name.
*
* @return array
* User roles filtered by permission else empty array.
*/
public function getRolesAssignedByPermission($permission_name)
{
$roles = user_roles();
$roles_found = [];
foreach ($roles as $role) {
if ($role->hasPermission($permission_name)) {
$roles_found[] = $role->getOriginalId();
}
}
return $roles_found;
}
}

View File

@@ -0,0 +1,223 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\PluginDebugCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Symfony\Component\Yaml\Yaml;
/**
* Class DebugCommand
*
* @package Drupal\Console\Command\Debug
*/
class PluginCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setName('debug:plugin')
->setDescription($this->trans('commands.debug.plugin.description'))
->setHelp($this->trans('commands.debug.plugin.help'))
->addArgument(
'type',
InputArgument::OPTIONAL,
$this->trans('commands.debug.plugin.arguments.type')
)
->addArgument(
'id',
InputArgument::OPTIONAL,
$this->trans('commands.debug.plugin.arguments.id')
)->setAliases(['dpl']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$pluginType = $input->getArgument('type');
$pluginId = $input->getArgument('id');
// No plugin type specified, show a list of plugin types.
if (!$pluginType) {
$tableHeader = [
$this->trans('commands.debug.plugin.table-headers.plugin-type-name'),
$this->trans('commands.debug.plugin.table-headers.plugin-type-class')
];
$tableRows = [];
$serviceDefinitions = $this->container->getDefinitions();
foreach ($serviceDefinitions as $serviceId => $serviceDefinition) {
if (strpos($serviceId, 'plugin.manager.') === 0) {
$serviceName = substr($serviceId, 15);
$tableRows[$serviceName] = [
$serviceName,
$serviceDefinition->getClass()
];
}
}
ksort($tableRows);
$this->getIo()->table($tableHeader, array_values($tableRows));
return true;
}
$service = $this->container->get('plugin.manager.' . $pluginType);
if (!$service) {
$this->getIo()->error(
sprintf(
$this->trans('commands.debug.plugin.errors.plugin-type-not-found'),
$pluginType
)
);
return false;
}
// Valid plugin type specified, no ID specified, show list of instances.
if (!$pluginId) {
$tableHeader = [
$this->trans('commands.debug.plugin.table-headers.plugin-id'),
$this->trans('commands.debug.plugin.table-headers.plugin-class')
];
$tableRows = [];
foreach ($service->getDefinitions() as $definition) {
$pluginId = $definition['id'];
$className = $definition['class'];
$tableRows[$pluginId] = [$pluginId, $className];
}
ksort($tableRows);
$this->getIo()->table($tableHeader, array_values($tableRows));
return true;
}
// Valid plugin type specified, ID specified, show the definition.
$definition = $service->getDefinition($pluginId);
$tableHeader = [
$this->trans('commands.debug.plugin.table-headers.definition-key'),
$this->trans('commands.debug.plugin.table-headers.definition-value')
];
$tableRows = $this->prepareTableRows($definition);
ksort($tableRows);
$this->getIo()->table($tableHeader, array_values($tableRows));
$this->displayPluginData($pluginType, $pluginId);
return true;
}
/**
* Displays additional plugin data.
*
* @param string $pluginType
* Plugin type.
* @param $pluginId
* Plugin ID.
*/
protected function displayPluginData($pluginType, $pluginId) {
switch ($pluginType) {
case 'field.field_type':
$this->getFieldTypeData($pluginId);
break;
case 'field.formatter':
$this->getFieldFormatterData($pluginId);
break;
case 'field.widget':
$this->getFieldWidgetData($pluginId);
break;
}
}
/**
* Get field type plugin additional data.
*
* @param string $pluginId
* Plugin ID.
*/
protected function getFieldTypeData($pluginId) {
$settings = $this->container->get('plugin.manager.field.field_type')->getDefaultFieldSettings($pluginId);
$this->displaySettingsTable($settings);
}
/**
* Get field formatter plugin additional data.
*
* @param string $pluginId
* Plugin ID.
*/
protected function getFieldFormatterData($pluginId) {
$settings = $this->container->get('plugin.manager.field.formatter')->getDefaultSettings($pluginId);
$this->displaySettingsTable($settings);
}
/**
* Get field widget plugin additional data.
*
* @param string $pluginId
* Plugin ID.
*/
protected function getFieldWidgetData($pluginId) {
$settings = $this->container->get('plugin.manager.field.widget')->getDefaultSettings($pluginId);
$this->displaySettingsTable($settings);
}
/**
* Displays settings table.
*
* @param array $settings
* Settings array.
*/
protected function displaySettingsTable($settings) {
$tableHeader = [
$this->trans('commands.debug.plugin.table-headers.setting'),
$this->trans('commands.debug.plugin.table-headers.definition-value')
];
$tableRows = $this->prepareTableRows($settings);
if (count($tableRows) > 0) {
$this->getIo()->newLine(1);
$this->getIo()->info(
$this->trans('commands.debug.plugin.messages.plugin-info')
);
$this->getIo()->table($tableHeader, array_values($tableRows));
}
}
/**
* Prepare table rows.
*
* @param array $items
* Data array.
*
* @return array
* Table rows.
*/
protected function prepareTableRows($items) {
$tableRows = [];
foreach ($items as $key => $value) {
if (is_object($value) && method_exists($value, '__toString')) {
$value = (string) $value;
} elseif (is_array($value) || is_object($value)) {
$value = Yaml::dump($value);
} elseif (is_bool($value)) {
$value = ($value) ? 'TRUE' : 'FALSE';
}
$tableRows[] = [$key, $value];
}
return $tableRows;
}
}

View File

@@ -0,0 +1,101 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\QueueCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueWorkerManagerInterface;
/**
* Class DebugCommand
*
* @package Drupal\Console\Command\Debug
*/
class QueueCommand extends Command
{
/**
* @var QueueFactory
*/
protected $queueFactory;
/**
* @var QueueWorkerManagerInterface
*/
protected $queueWorker;
/**
* DebugCommand constructor.
*
* @param QueueWorkerManagerInterface $queueWorker
*/
public function __construct(QueueFactory $queueFactory, QueueWorkerManagerInterface $queueWorker)
{
$this->queueFactory = $queueFactory;
$this->queueWorker = $queueWorker;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:queue')
->setDescription($this->trans('commands.debug.queue.description'))
->setAliases(['dq']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$tableHeader = [
$this->trans('commands.debug.queue.messages.queue'),
$this->trans('commands.debug.queue.messages.items'),
$this->trans('commands.debug.queue.messages.class')
];
$tableBody = $this->listQueues();
$this->getIo()->table($tableHeader, $tableBody);
return 0;
}
/**
* listQueues.
*/
private function listQueues()
{
$queues = [];
foreach ($this->queueWorker->getDefinitions() as $name => $info) {
$queues[$name] = $this->formatQueue($name);
}
return $queues;
}
/**
* @param $name
* @return array
*/
private function formatQueue($name)
{
$q = $this->queueFactory->get($name);
return [
$name,
$q->numberOfItems(),
get_class($q)
];
}
}

View File

@@ -0,0 +1,181 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\RestCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Console\Command\Shared\RestTrait;
use Drupal\rest\Plugin\Type\ResourcePluginManager;
use Drupal\Core\Entity\EntityTypeManagerInterface;
/**
* @DrupalCommand(
* extension = "rest",
* extensionType = "module"
* )
*/
class RestCommand extends Command
{
use RestTrait;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var ResourcePluginManager $pluginManagerRest
*/
protected $pluginManagerRest;
/**
* RestCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param ResourcePluginManager $pluginManagerRest
*/
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
ResourcePluginManager $pluginManagerRest
) {
$this->entityTypeManager = $entityTypeManager;
$this->pluginManagerRest = $pluginManagerRest;
parent::__construct();
}
protected function configure()
{
$this
->setName('debug:rest')
->setDescription($this->trans('commands.debug.rest.description'))
->addArgument(
'resource-id',
InputArgument::OPTIONAL,
$this->trans('commands.debug.rest.arguments.resource-id')
)
->addOption(
'authorization',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.rest.options.status')
)
->setAliases(['rede']);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$resource_id = $input->getArgument('resource-id');
$status = $input->getOption('authorization');
if ($resource_id) {
$this->restDetail($resource_id);
} else {
$this->restList($status);
}
return 0;
}
private function restDetail($resource_id)
{
$config = $this->getRestDrupalConfig();
$plugin = $this->pluginManagerRest->createInstance($resource_id);
if (empty($plugin)) {
$this->getIo()->error(
sprintf(
$this->trans('commands.debug.rest.messages.not-found'),
$resource_id
)
);
return false;
}
$resource = $plugin->getPluginDefinition();
$configuration = [];
$configuration[] = [
$this->trans('commands.debug.rest.messages.id'),
$resource['id']
];
$configuration[] = [
$this->trans('commands.debug.rest.messages.label'),
(string) $resource['label']
];
$configuration[] = [
$this->trans('commands.debug.rest.messages.canonical-url'),
$resource['uri_paths']['canonical']
];
$configuration[] = [
$this->trans('commands.debug.rest.messages.status'),
(isset($config[$resource['id']])) ? $this->trans('commands.debug.rest.messages.enabled') : $this->trans('commands.debug.rest.messages.disabled')];
$configuration[] = [
$this->trans(
sprintf(
'commands.debug.rest.messages.provider',
$resource['provider']
)
)
];
$this->getIo()->comment($resource_id);
$this->getIo()->newLine();
$this->getIo()->table([], $configuration, 'compact');
$tableHeader = [
$this->trans('commands.debug.rest.messages.rest-state'),
$this->trans('commands.debug.rest.messages.supported-formats'),
$this->trans('commands.debug.rest.messages.supported-auth'),
];
$tableRows = [];
foreach ($config[$resource['id']] as $method => $settings) {
$tableRows[] = [
$method,
implode(', ', $settings['supported_formats']),
implode(', ', $settings['supported-auth']),
];
}
$this->getIo()->table($tableHeader, $tableRows);
}
protected function restList($status)
{
$rest_resources = $this->getRestResources($status);
$tableHeader = [
$this->trans('commands.debug.rest.messages.id'),
$this->trans('commands.debug.rest.messages.label'),
$this->trans('commands.debug.rest.messages.canonical-url'),
$this->trans('commands.debug.rest.messages.status'),
$this->trans('commands.debug.rest.messages.provider'),
];
$tableRows = [];
foreach ($rest_resources as $status => $resources) {
foreach ($resources as $id => $resource) {
$tableRows[] =[
$id,
$resource['label'],
$resource['uri_paths']['canonical'],
$status,
$resource['provider'],
];
}
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
}

View File

@@ -0,0 +1,72 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Roles\DebugCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Utils\DrupalApi;
/**
* Class RolesCommand
*
* @package Drupal\Console\Command\Debug
*/
class RolesCommand extends Command
{
/**
* @var DrupalApi
*/
protected $drupalApi;
/**
* DebugCommand constructor.
*
* @param DrupalApi $drupalApi
*/
public function __construct(
DrupalApi $drupalApi
) {
$this->drupalApi = $drupalApi;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:roles')
->setDescription($this->trans('commands.debug.roles.description'))
->setAliases(['dusr']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$roles = $this->drupalApi->getRoles();
$tableHeader = [
$this->trans('commands.debug.roles.messages.role-id'),
$this->trans('commands.debug.roles.messages.role-name'),
];
$tableRows = [];
foreach ($roles as $roleId => $role) {
$tableRows[] = [
$roleId,
$role
];
}
$this->getIo()->table($tableHeader, $tableRows);
}
}

View File

@@ -0,0 +1,142 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\RouterCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Core\Command\Command;
use Drupal\Component\Serialization\Yaml;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class RouterCommand extends Command
{
/**
* @var RouteProviderInterface
*/
protected $routeProvider;
/**
* DebugCommand constructor.
*
* @param RouteProviderInterface $routeProvider
*/
public function __construct(RouteProviderInterface $routeProvider)
{
$this->routeProvider = $routeProvider;
parent::__construct();
}
protected function configure()
{
$this
->setName('debug:router')
->setDescription($this->trans('commands.debug.router.description'))
->addArgument(
'route-name',
InputArgument::OPTIONAL | InputArgument::IS_ARRAY,
$this->trans('commands.debug.router.arguments.route-name')
)
->addOption(
'pattern',
null,
InputArgument::OPTIONAL,
$this->trans('commands.debug.router.options.pattern')
)
->setAliases(['dr']);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$route_name = $input->getArgument('route-name');
$pattern = $input->getOption('pattern');
if (!empty($route_name)) {
$this->getRoutesTables($this->routeProvider->getRoutesByNames($route_name));
} elseif (!empty($pattern)) {
$this->getRoutesTables($this->routeProvider->getRoutesByPattern($pattern));
} else {
$this->getAllRoutes();
}
}
protected function getAllRoutes()
{
$routes = $this->routeProvider->getAllRoutes();
$tableHeader = [
$this->trans('commands.debug.router.messages.name'),
$this->trans('commands.debug.router.messages.path'),
];
$tableRows = [];
foreach ($routes as $route_name => $route) {
$tableRows[] = [$route_name, $route->getPath()];
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
protected function getRoutesTables($routes)
{
foreach ($routes as $name => $route) {
$tableHeader = [
$this->trans('commands.debug.router.messages.route'),
'<info>' . $name . '</info>'
];
$tableRows = [];
$tableRows[] = [
'<comment>' . $this->trans('commands.debug.router.messages.path') . '</comment>',
$route->getPath(),
];
$tableRows[] = ['<comment>' . $this->trans('commands.debug.router.messages.defaults') . '</comment>'];
$attributes = $this->addRouteAttributes($route->getDefaults());
foreach ($attributes as $attribute) {
$tableRows[] = $attribute;
}
$tableRows[] = ['<comment>' . $this->trans('commands.debug.router.messages.requirements') . '</comment>'];
$requirements = $this->addRouteAttributes($route->getRequirements());
foreach ($requirements as $requirement) {
$tableRows[] = $requirement;
}
$tableRows[] = ['<comment>' . $this->trans('commands.debug.router.messages.options') . '</comment>'];
$options = $this->addRouteAttributes($route->getOptions());
foreach ($options as $option) {
$tableRows[] = $option;
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
}
protected function addRouteAttributes($attr, $attributes = null)
{
foreach ($attr as $key => $value) {
if (is_array($value)) {
$attributes[] = [
' ' . $key,
str_replace(
'- ',
'',
Yaml::encode($value)
)
];
} else {
$attributes[] = [' ' . $key, $value];
}
}
return $attributes;
}
}

View File

@@ -0,0 +1,87 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\DebugCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Component\Serialization\Yaml;
/**
* Class DebugCommand
*
* @package Drupal\Console\Command\Debug
*/
class StateCommand extends Command
{
/**
* @var StateInterface
*/
protected $state;
/**
* @var KeyValueFactoryInterface
*/
protected $keyValue;
/**
* DebugCommand constructor.
*
* @param StateInterface $state
* @param KeyValueFactoryInterface $keyValue
*/
public function __construct(
StateInterface $state,
KeyValueFactoryInterface $keyValue
) {
$this->state = $state;
$this->keyValue = $keyValue;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:state')
->setDescription($this->trans('commands.debug.state.description'))
->addArgument(
'key',
InputArgument::OPTIONAL,
$this->trans('commands.debug.state.arguments.key')
)
->setHelp($this->trans('commands.debug.state.help'))
->setAliases(['dst']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
if ($key) {
$this->getIo()->info($key);
$this->getIo()->writeln(Yaml::encode($this->state->get($key)));
return 0;
}
$tableHeader = [$this->trans('commands.debug.state.messages.key')];
$keyStoreStates = array_keys($this->keyValue->get('state')->getAll());
$this->getIo()->table($tableHeader, $keyStoreStates);
return 0;
}
}

View File

@@ -0,0 +1,194 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\TestCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Component\Serialization\Yaml;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Core\Test\TestDiscovery;
/**
* @DrupalCommand(
* extension = "simpletest",
* extensionType = "module",
* )
*/
class TestCommand extends Command
{
/**
* @var TestDiscovery
*/
protected $test_discovery;
/**
* TestCommand constructor.
*
* @param TestDiscovery $test_discovery
*/
public function __construct(
TestDiscovery $test_discovery
) {
$this->test_discovery = $test_discovery;
parent::__construct();
}
protected function configure()
{
$this
->setName('debug:test')
->setDescription($this->trans('commands.debug.test.description'))
->addArgument(
'group',
InputArgument::OPTIONAL,
$this->trans('commands.debug.test.options.group'),
null
)
->addOption(
'test-class',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.test.arguments.test-class')
)
->setAliases(['td']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
//Registers namespaces for disabled modules.
$this->test_discovery->registerTestNamespaces();
$testClass = $input->getOption('test-class');
$group = $input->getArgument('group');
if ($testClass) {
$this->testDetail($testClass);
} else {
$this->testList($group);
}
}
private function testDetail($test_class)
{
$testingGroups = $this->test_discovery->getTestClasses(null);
$testDetails = null;
foreach ($testingGroups as $testing_group => $tests) {
foreach ($tests as $key => $test) {
if ($test['name'] == $test_class) {
$testDetails = $test;
break;
}
}
if ($testDetails !== null) {
break;
}
}
$class = null;
if ($testDetails) {
$class = new \ReflectionClass($test['name']);
if (is_subclass_of($testDetails['name'], 'PHPUnit_Framework_TestCase')) {
$testDetails['type'] = 'phpunit';
} else {
$testDetails = $this->test_discovery
->getTestInfo($testDetails['name']);
$testDetails['type'] = 'simpletest';
}
$this->getIo()->comment($testDetails['name']);
$testInfo = [];
foreach ($testDetails as $key => $value) {
$testInfo [] = [$key, $value];
}
$this->getIo()->table([], $testInfo);
if ($class) {
$methods = $class->getMethods(\ReflectionMethod::IS_PUBLIC);
$this->getIo()->info($this->trans('commands.debug.test.messages.methods'));
foreach ($methods as $method) {
if ($method->class == $testDetails['name'] && strpos($method->name, 'test') === 0) {
$this->getIo()->simple($method->name);
}
}
}
} else {
$this->getIo()->error($this->trans('commands.debug.test.messages.not-found'));
}
}
protected function testList($group)
{
$testingGroups = $this->test_discovery
->getTestClasses(null);
if (empty($group)) {
$tableHeader = [$this->trans('commands.debug.test.messages.group')];
} else {
$tableHeader = [
$this->trans('commands.debug.test.messages.class'),
$this->trans('commands.debug.test.messages.type')
];
$this->getIo()->writeln(
sprintf(
'%s: %s',
$this->trans('commands.debug.test.messages.group'),
$group
)
);
}
$tableRows = [];
foreach ($testingGroups as $testing_group => $tests) {
if (empty($group)) {
$tableRows[] =[$testing_group];
continue;
}
if (!empty($group) && $group != $testing_group) {
continue;
}
foreach ($tests as $test) {
if (is_subclass_of($test['name'], 'PHPUnit_Framework_TestCase')) {
$test['type'] = 'phpunit';
} else {
$test['type'] = 'simpletest';
}
$tableRows[] =[
$test['name'],
$test['type']
];
}
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
if ($group) {
$this->getIo()->success(
sprintf(
$this->trans('commands.debug.test.messages.success-group'),
$group
)
);
} else {
$this->getIo()->success(
$this->trans('commands.debug.test.messages.success-groups')
);
}
}
}

View File

@@ -0,0 +1,170 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ThemeCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Extension\ThemeHandler;
class ThemeCommand extends Command
{
/**
* @var ConfigFactory
*/
protected $configFactory;
/**
* @var ThemeHandler
*/
protected $themeHandler;
/**
* DebugCommand constructor.
*
* @param ConfigFactory $configFactory
* @param ThemeHandler $themeHandler
*/
public function __construct(
ConfigFactory $configFactory,
ThemeHandler $themeHandler
) {
$this->configFactory = $configFactory;
$this->themeHandler = $themeHandler;
parent::__construct();
}
protected function configure()
{
$this
->setName('debug:theme')
->setDescription($this->trans('commands.debug.theme.description'))
->addArgument(
'theme',
InputArgument::OPTIONAL,
$this->trans('commands.debug.theme.arguments.theme')
)
->setAliases(['dt']);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$theme = $input->getArgument('theme');
if ($theme) {
$this->themeDetail($theme);
} else {
$this->themeList();
}
}
protected function themeList()
{
$tableHeader = [
$this->trans('commands.debug.theme.messages.theme-id'),
$this->trans('commands.debug.theme.messages.theme-name'),
$this->trans('commands.debug.theme.messages.status'),
$this->trans('commands.debug.theme.messages.version'),
];
$themes = $this->themeHandler->rebuildThemeData();
$tableRows = [];
foreach ($themes as $themeId => $theme) {
$status = $this->getThemeStatus($theme);
$tableRows[] = [
$themeId,
$theme->info['name'],
$status,
(isset($theme->info['version'])) ? $theme->info['version'] : '',
];
}
$this->getIo()->table($tableHeader, $tableRows);
}
protected function themeDetail($themeId)
{
$theme = null;
$themes = $this->themeHandler->rebuildThemeData();
if (isset($themes[$themeId])) {
$theme = $themes[$themeId];
} else {
foreach ($themes as $themeAvailableId => $themeAvailable) {
if ($themeAvailable->info['name'] == $themeId) {
$themeId = $themeAvailableId;
$theme = $themeAvailable;
break;
}
}
}
if ($theme) {
$theme = $themes[$themeId];
$status = $this->getThemeStatus($themeId);
$this->getIo()->info($theme->info['name']);
$this->getIo()->comment(
sprintf(
'%s : ',
$this->trans('commands.debug.theme.messages.status')
),
false
);
$this->getIo()->writeln($status);
$this->getIo()->comment(
sprintf(
'%s : ',
$this->trans('commands.debug.theme.messages.version')
),
false
);
$this->getIo()->writeln($theme->info['version']);
$this->getIo()->comment($this->trans('commands.debug.theme.messages.regions'));
$tableRows = $this->addThemeAttributes($theme->info['regions'], $tableRows);
$this->getIo()->table([], $tableRows);
} else {
$this->getIo()->error(
sprintf(
$this->trans('commands.debug.theme.messages.invalid-theme'),
$themeId
)
);
}
}
protected function getThemeStatus($theme)
{
$defaultTheme = $this->configFactory->get('system.theme')->get('default');
$status = ($theme->status)?$this->trans('commands.debug.theme.messages.installed'):$this->trans('commands.debug.theme.messages.uninstalled');
if ($defaultTheme == $theme) {
$status = $this->trans('commands.debug.theme.messages.default-theme');
}
return $status;
}
protected function addThemeAttributes($attr, $tableRows = [])
{
foreach ($attr as $key => $value) {
if (is_array($value)) {
$tableRows = $this->addThemeAttributes($value, $tableRows);
} else {
$tableRows[] = [
$key,
$value,
];
}
}
return $tableRows;
}
}

View File

@@ -0,0 +1,110 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Theme\DebugKeysCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Yaml\Yaml;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Core\Command\Shared\CommandTrait;
use Drupal\Core\Theme\Registry;
class ThemeKeysCommand extends Command
{
use CommandTrait;
/**
* @var Registry
*/
protected $themeRegistry;
/**
* DebugCommand constructor.
*
* @param \Drupal\Core\Theme\Registry $themeRegistry
* The theme registry service.
*/
public function __construct(Registry $themeRegistry)
{
$this->themeRegistry = $themeRegistry;
parent::__construct();
}
protected function configure()
{
$this
->setName('debug:theme:keys')
->setDescription($this->trans('commands.debug.theme.keys.description'))
->setHelp($this->trans('commands.debug.theme.keys.help'))
->addArgument(
'key',
InputArgument::OPTIONAL,
$this->trans('commands.debug.theme.keys.arguments.key')
)
->setAliases(['dtk']);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$key = $input->getArgument('key');
if (!$key) {
$this->themeKeysList();
} else {
$this->themeKeysDetail($key);
}
}
protected function themeKeysList()
{
$tableHeader = [
$this->trans('commands.debug.theme.keys.table-headers.key'),
$this->trans('commands.debug.theme.keys.table-headers.provider-type'),
$this->trans('commands.debug.theme.keys.table-headers.provider'),
];
$tableRows = [];
$keys = $this->themeRegistry->get();
foreach ($keys as $key => $definition) {
$tableRows[] = [
$key,
$this->trans('commands.debug.theme.keys.provider-types.' . strtr($definition['type'], '_', '-')),
basename($definition['theme path']),
];
}
array_multisort($tableRows, array_column($tableRows, 0));
$this->getIo()->table($tableHeader, $tableRows);
}
protected function themeKeysDetail($key)
{
$tableHeader = [
$this->trans('commands.debug.theme.keys.table-headers.key'),
$this->trans('commands.debug.theme.keys.table-headers.value')
];
$keys = $this->themeRegistry->get();
$definition = $keys[$key];
$tableRows = [];
foreach ($definition as $key => $value) {
if (is_object($value) && method_exists($value, '__toString')) {
$value = (string) $value;
} elseif (is_array($value) || is_object($value)) {
$value = Yaml::dump($value);
} elseif (is_bool($value)) {
$value = ($value) ? 'TRUE' : 'FALSE';
}
$tableRows[$key] = [$key, $value];
}
ksort($tableRows);
$this->getIo()->table($tableHeader, array_values($tableRows));
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\UpdateCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Command\Shared\UpdateTrait;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Update\UpdateRegistry;
use Drupal\Console\Utils\Site;
class UpdateCommand extends Command
{
use UpdateTrait;
/**
* @var Site
*/
protected $site;
/**
* @var UpdateRegistry
*/
protected $postUpdateRegistry;
/**
* DebugCommand constructor.
*
* @param Site $site
* @param UpdateRegistry $postUpdateRegistry
*/
public function __construct(
Site $site,
UpdateRegistry $postUpdateRegistry
) {
$this->site = $site;
$this->postUpdateRegistry = $postUpdateRegistry;
parent::__construct();
}
/**
* @inheritdoc
*/
protected function configure()
{
$this
->setName('debug:update')
->setDescription($this->trans('commands.debug.update.description'))
->setAliases(['du']);
}
/**
* @inheritdoc
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->site->loadLegacyFile('/core/includes/update.inc');
$this->site->loadLegacyFile('/core/includes/install.inc');
drupal_load_updates();
$requirements = update_check_requirements();
$severity = drupal_requirements_severity($requirements);
$updates = update_get_update_list();
$postUpdates = $this->postUpdateRegistry->getPendingUpdateInformation();
$this->getIo()->newLine();
if ($severity == REQUIREMENT_ERROR || ($severity == REQUIREMENT_WARNING)) {
$this->populateRequirements($requirements);
} elseif (empty($updates) && empty($postUpdates)) {
$this->getIo()->info($this->trans('commands.debug.update.messages.no-updates'));
} else {
$this->showUpdateTable($updates, $this->trans('commands.debug.update.messages.module-list'));
$this->showPostUpdateTable($postUpdates, $this->trans('commands.debug.update.messages.module-list-post-update'));
}
}
/**
* @param $requirements
*/
private function populateRequirements($requirements)
{
$this->getIo()->info($this->trans('commands.debug.update.messages.requirements-error'));
$tableHeader = [
$this->trans('commands.debug.update.messages.severity'),
$this->trans('commands.debug.update.messages.title'),
$this->trans('commands.debug.update.messages.value'),
$this->trans('commands.debug.update.messages.description'),
];
$tableRows = [];
foreach ($requirements as $requirement) {
$minimum = in_array(
$requirement['minimum schema'],
[REQUIREMENT_ERROR, REQUIREMENT_WARNING]
);
if ((isset($requirement['minimum schema'])) && ($minimum)) {
$tableRows[] = [
$requirement['severity'],
$requirement['title'],
$requirement['value'],
$requirement['description'],
];
}
}
$this->getIo()->table($tableHeader, $tableRows);
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\UpdateComposerCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Command\Shared\UpdateTrait;
use Drupal\Console\Core\Utils\DrupalFinder;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Process\Process;
class UpdateComposerCommand extends Command
{
use UpdateTrait;
/**
* @var DrupalFinder
*/
protected $drupalFinder;
/**
* DebugComposerCommand constructor.
*
* @param DrupalFinder $drupalFinder
*/
public function __construct(DrupalFinder $drupalFinder) {
$this->drupalFinder = $drupalFinder;
parent::__construct();
}
/**
* @inheritdoc
*/
protected function configure()
{
$this
->setName('debug:update:composer')
->setDescription($this->trans('commands.debug.update.composer.description'))
->addOption(
'only-drupal',
null,
InputOption::VALUE_NONE,
$this->trans('commands.debug.update.composer.options.only-drupal')
)
->setAliases(['duc']);
}
/**
* @inheritdoc
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$onlyDrupal = $input->getOption('only-drupal');
$process = new Process("composer show --outdated --format=json");
$process->setTimeout(null);
$process->setWorkingDirectory($this->drupalFinder->getComposerRoot());
$process->run();
if($process->isSuccessful()){
$jsonData = json_decode($process->getOutput());
$this->showComposerUpdateTable($jsonData->installed, $onlyDrupal, $this->trans('commands.debug.update.composer.messages.composer-list'));
}
}
}

View File

@@ -0,0 +1,178 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\User\DebugCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Console\Utils\DrupalApi;
/**
* Class UserCommand
*
* @package Drupal\Console\Command\Debug
*/
class UserCommand extends Command
{
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var DrupalApi
*/
protected $drupalApi;
/**
* DebugCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param DrupalApi $drupalApi
*/
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
DrupalApi $drupalApi
) {
$this->entityTypeManager = $entityTypeManager;
$this->drupalApi = $drupalApi;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:user')
->setDescription($this->trans('commands.debug.user.description'))
->addOption(
'uid',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.debug.user.options.uid')
)
->addOption(
'username',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.debug.user.options.username')
)
->addOption(
'mail',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.debug.user.options.mail')
)
->addOption(
'roles',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.user.options.roles')
)
->addOption(
'limit',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.user.options.limit')
)->setAliases(['dus']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$roles = $input->getOption('roles');
$limit = $input->getOption('limit');
$uids = $this->splitOption($input->getOption('uid'));
$usernames = $this->splitOption($input->getOption('username'));
$mails = $this->splitOption($input->getOption('mail'));
$userStorage = $this->entityTypeManager->getStorage('user');
$systemRoles = $this->drupalApi->getRoles();
$query = $this->entityTypeManager->getStorage('user')->getQuery();
$query->condition('uid', 0, '>');
$query->sort('uid');
// uid as option
if (is_array($uids) && $uids) {
$group = $query->andConditionGroup()
->condition('uid', $uids, 'IN');
$query->condition($group);
}
// username as option
if (is_array($usernames) && $usernames) {
$group = $query->andConditionGroup()
->condition('name', $usernames, 'IN');
$query->condition($group);
}
// mail as option
if (is_array($mails) && $mails) {
$group = $query->andConditionGroup()
->condition('mail', $mails, 'IN');
$query->condition($group);
}
if ($roles) {
$query->condition('roles', is_array($roles)?$roles:[$roles], 'IN');
}
if ($limit) {
$query->range(0, $limit);
}
$results = $query->execute();
$users = $userStorage->loadMultiple($results);
$tableHeader = [
$this->trans('commands.debug.user.messages.user-id'),
$this->trans('commands.debug.user.messages.username'),
$this->trans('commands.debug.user.messages.roles'),
$this->trans('commands.debug.user.messages.status'),
];
$tableRows = [];
foreach ($users as $userId => $user) {
$userRoles = [];
foreach ($user->getRoles() as $userRole) {
if ($systemRoles[$userRole]) {
$userRoles[] = $systemRoles[$userRole];
}
}
$status = $user->isActive()?$this->trans('commands.common.status.enabled'):$this->trans('commands.common.status.disabled');
$tableRows[] = [
$userId,
$user->getUsername(),
implode(', ', $userRoles),
$status
];
}
$this->getIo()->table($tableHeader, $tableRows);
}
//@TODO: this should be in src/Command/Shared/CommandTrait.php
public function splitOption($option)
{
if (1 == count($option) && strpos($option[0], " ") >= 1) {
return explode(" ", $option[0]);
} else {
return $option;
}
}
}

View File

@@ -0,0 +1,240 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ViewsCommand.
*/
namespace Drupal\Console\Command\Debug;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\views\Entity\View;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Console\Annotations\DrupalCommand;
/**
* Class ViewsCommand
*
* @DrupalCommand(
* extension = "views",
* extensionType = "module"
* )
*
* @package Drupal\Console\Command\Debug
*/
class ViewsCommand extends Command
{
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var PluginManagerInterface
*/
protected $viewsDisplayManager;
/**
* DebugCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param PluginManagerInterface $viewsDisplayManager
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, PluginManagerInterface $viewsDisplayManager)
{
$this->entityTypeManager = $entityTypeManager;
$this->viewsDisplayManager = $viewsDisplayManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:views')
->setDescription($this->trans('commands.debug.views.description'))
->addArgument(
'view-id',
InputArgument::OPTIONAL,
$this->trans('commands.debug.views.arguments.view-id')
)
->addOption(
'tag',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.views.arguments.view-tag')
)->addOption(
'status',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.debug.views.arguments.view-status')
)
->setAliases(['vde']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$view_id = $input->getArgument('view-id');
$view_tag = $input->getOption('tag');
$view_status = $input->getOption('status');
if ($view_status == $this->trans('commands.common.status.enabled')) {
$view_status = 1;
} elseif ($view_status == $this->trans('commands.common.status.disabled')) {
$view_status = 0;
} else {
$view_status = -1;
}
if ($view_id) {
$this->viewDetail($view_id);
} else {
$this->viewList($view_tag, $view_status);
}
}
/**
* @param $view_id
* @return bool
*/
private function viewDetail($view_id)
{
$view = $this->entityTypeManager->getStorage('view')->load($view_id);
if (empty($view)) {
$this->getIo()->error(sprintf($this->trans('commands.debug.views.messages.not-found'), $view_id));
return false;
}
$configuration = [];
$configuration [] = [$this->trans('commands.debug.views.messages.view-id'), $view->get('id')];
$configuration [] = [$this->trans('commands.debug.views.messages.view-name'), (string) $view->get('label')];
$configuration [] = [$this->trans('commands.debug.views.messages.tag'), $view->get('tag')];
$configuration [] = [$this->trans('commands.debug.views.messages.status'), $view->status() ? $this->trans('commands.common.status.enabled') : $this->trans('commands.common.status.disabled')];
$configuration [] = [$this->trans('commands.debug.views.messages.description'), $view->get('description')];
$this->getIo()->comment($view_id);
$this->getIo()->table([], $configuration);
$tableHeader = [
$this->trans('commands.debug.views.messages.display-id'),
$this->trans('commands.debug.views.messages.display-name'),
$this->trans('commands.debug.views.messages.display-description'),
$this->trans('commands.debug.views.messages.display-paths'),
];
$displays = $this->viewDisplayList($view);
$this->getIo()->info(sprintf($this->trans('commands.debug.views.messages.display-list'), $view_id));
$tableRows = [];
foreach ($displays as $display_id => $display) {
$tableRows[] = [
$display_id,
$display['name'],
$display['description'],
$this->viewDisplayPaths($view, $display_id),
];
}
$this->getIo()->table($tableHeader, $tableRows);
}
/**
* @param $tag
* @param $status
*/
protected function viewList($tag, $status)
{
$views = $this->entityTypeManager->getStorage('view')->loadMultiple();
$tableHeader = [
$this->trans('commands.debug.views.messages.view-id'),
$this->trans('commands.debug.views.messages.view-name'),
$this->trans('commands.debug.views.messages.tag'),
$this->trans('commands.debug.views.messages.status'),
$this->trans('commands.debug.views.messages.path')
];
$tableRows = [];
foreach ($views as $view) {
if ($status != -1 && $view->status() != $status) {
continue;
}
if (isset($tag) && $view->get('tag') != $tag) {
continue;
}
$tableRows[] = [
$view->get('id'),
$view->get('label'),
$view->get('tag'),
$view->status() ? $this->trans('commands.common.status.enabled') : $this->trans('commands.common.status.disabled'),
$this->viewDisplayPaths($view),
];
}
$this->getIo()->table($tableHeader, $tableRows, 'compact');
}
/**
* @param \Drupal\views\Entity\View $view
* @param null $display_id
* @return string
*/
protected function viewDisplayPaths(View $view, $display_id = null)
{
$all_paths = [];
$executable = $view->getExecutable();
$executable->initDisplay();
foreach ($executable->displayHandlers as $display) {
if ($display->hasPath()) {
$path = $display->getPath();
if (strpos($path, '%') === false) {
// @see Views should expect and store a leading /. See:
// https://www.drupal.org/node/2423913
$all_paths[] = '/'.$path;
} else {
$all_paths[] = '/'.$path;
}
if ($display_id !== null && $display_id == $display->getBaseId()) {
return '/'.$path;
}
}
}
return implode(', ', array_unique($all_paths));
}
/**
* @param \Drupal\views\Entity\View $view
* @return array
*/
protected function viewDisplayList(View $view)
{
$displays = [];
foreach ($view->get('display') as $display) {
$definition = $this->viewsDisplayManager->getDefinition($display['display_plugin']);
if (!empty($definition['admin'])) {
// Cast the admin label to a string since it is an object.
$displays[$definition['id']]['name'] = (string) $definition['admin'];
$displays[$definition['id']]['description'] = (string) $definition['help'];
}
}
asort($displays);
return $displays;
}
}

View File

@@ -0,0 +1,82 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Debug\ViewsPluginsCommand.
*/
namespace Drupal\Console\Command\Debug;
use Drupal\Console\Core\Command\Command;
use Drupal\views\Views;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class ViewsPluginsCommand
*
* @package Drupal\Console\Command\Debug
*/
class ViewsPluginsCommand extends Command
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('debug:views:plugins')
->setDescription($this->trans('commands.debug.views.plugins.description'))
->addArgument(
'type',
InputArgument::OPTIONAL,
$this->trans('commands.debug.views.plugins.arguments.type')
)->setAliases(['dvp']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$type = $input->getArgument('type');
$this->pluginList($type);
}
/**
* @param $type
*/
protected function pluginList($type)
{
$plugins = Views::pluginList();
$rows = [];
foreach ($plugins as &$plugin) {
if ($type && $plugin['type'] != $type) {
continue;
}
$views = [];
// Link each view name to the view itself.
foreach ($plugin['views'] as $plugin_name => $view) {
$views[] = $view;
}
$rows[] = [$plugin['type'], $plugin['title'], $plugin['provider'], implode(',', $views)];
}
// Sort rows by field name.
ksort($rows);
$tableHeader = [
$this->trans('commands.debug.views.plugins.messages.type'),
$this->trans('commands.debug.views.plugins.messages.name'),
$this->trans('commands.debug.views.plugins.messages.provider'),
$this->trans('commands.debug.views.plugins.messages.views'),
];
$this->getIo()->table($tableHeader, $rows, 'compact');
}
}

View File

@@ -0,0 +1,116 @@
<?php
namespace Drupal\Console\Command;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactory;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\devel\DevelDumperPluginManager;
use Drupal\devel\DevelDumperManager;
/**
* Class DevelDumperCommand.
* Command to quickly change between devel dumpers from the command line
*
* @package Drupal\Console\Command
*
* @todo Inject services using \Drupal
* @todo Move to namespace Devel
* @todo Load devel.module legacy file
*/
class DevelDumperCommand extends ContainerAwareCommand
{
/**
* @var DevelDumperPluginManager
*/
protected $develDumperPluginManager;
/**
* DevelDumperCommand constructor.
*/
public function __construct(
DevelDumperPluginManager $develDumperPluginManager = null
) {
$this->develDumperPluginManager = $develDumperPluginManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('devel:dumper')
->setDescription($this->trans('commands.devel.dumper.messages.change-devel-dumper-plugin'))
->addArgument(
'dumper',
InputArgument::OPTIONAL,
$this->trans('commands.devel.dumper.messages.name-devel-dumper-plugin')
)->setAliases(['dd']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
if (!\Drupal::moduleHandler()->moduleExists('devel')) {
$this->getIo()->error($this->trans('commands.devel.dumper.messages.devel-must-be-installed'));
return 1;
}
$dumper = $input->getArgument('dumper');
if (!$dumper) {
/* @var string[] $dumpKeys */
$dumpKeys = $this->getDumperKeys();
$dumper = $this->getIo()->choice(
$this->trans('commands.devel.dumper.messages.select-debug-dumper'),
$dumpKeys,
'kint', //Make kint the default for quick 'switchback'
false
);
$input->setArgument('dumper', $dumper);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
//Check the dumper actually exists
$dumper = $input->getArgument('dumper');
$dumpKeys = $this->getDumperKeys();
if (!in_array($dumper, $dumpKeys)) {
$this->getIo()->error($this->trans('commands.devel.dumper.messages.dumper-not-exist'));
return 1;
}
/* @var ConfigFactory $configFactory */
$configFactory = \Drupal::configFactory();
/* @var Config $develSettings */
$develSettings = $configFactory->getEditable('devel.settings');
$develSettings->set('devel_dumper', $dumper)->save();
$this->getIo()->info(
sprintf(
$this->trans('commands.devel.dumper.messages.devel-dumper-set'),
$configFactory->get('devel.settings')->get('devel_dumper')
)
);
}
protected function getDumperKeys()
{
/* @var DevelDumperPluginManager $manager */
$plugins = $this->develDumperPluginManager->getDefinitions();
return array_keys($plugins);
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Drupal\Console\Command;
use Drupal\Console\Core\Style\DrupalStyle;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\GenerateCommand;
use Drupal\Console\Generator\DockerInitGenerator;
use Symfony\Component\Filesystem\Filesystem;
/**
* Class DockerInitCommand
*
* @package Drupal\Console\Command
*/
class DockerInitCommand extends GenerateCommand
{
/**
* @var DockerInitGenerator
*/
protected $generator;
/**
* InitCommand constructor.
*
* @param DockerInitGenerator $generator
*/
public function __construct(
DockerInitGenerator $generator
) {
$this->generator = $generator;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('docker:init')
->setDescription(
$this->trans('commands.docker.init.description')
)
->setHelp($this->trans('commands.docker.init.description'));
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new DrupalStyle($input, $output);
$fs = new Filesystem();
$dockerComposeFiles = [
$this->drupalFinder->getComposerRoot() . '/docker-compose.yml',
$this->drupalFinder->getComposerRoot() . '/docker-compose.yaml'
];
$dockerComposeFile = $this->validateFileExists(
$fs,
$dockerComposeFiles,
false
);
if (!$dockerComposeFile) {
$dockerComposeFile = $this->drupalFinder->getComposerRoot() . '/docker-compose.yml';
}
$this->backUpFile($fs, $dockerComposeFile);
$parameters = [
'docker_compose_file' => $dockerComposeFile
];
$this->generator->setIo($io);
$this->generator->generate($parameters);
}
}

View File

@@ -0,0 +1,189 @@
<?php
namespace Drupal\Console\Command;
use Drupal\Core\Site\Settings;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\GenerateCommand;
use Symfony\Component\Filesystem\Filesystem;
use Drupal\Component\Utility\Crypt;
use Drupal\Console\Generator\DotenvInitGenerator;
use Webmozart\PathUtil\Path;
/**
* Class InitCommand
*
* @package Drupal\Console\Command\Dotenv
*/
class DotenvInitCommand extends GenerateCommand
{
/**
* @var DotenvInitGenerator
*/
protected $generator;
private $envParameters = [
'environment' => 'develop',
'database_name' => 'drupal',
'database_user' => 'drupal',
'database_password' => 'drupal',
'database_host' => 'mariadb',
'database_port' => '3306',
'host_name' => 'drupal.develop',
'host_port' => '80',
'drupal_root' => '/var/www/html',
'server_root' => '/var/www/html/web'
];
/**
* InitCommand constructor.
*
* @param DotenvInitGenerator $generator
*/
public function __construct(
DotenvInitGenerator $generator
) {
$this->generator = $generator;
parent::__construct();
}
protected function configure()
{
$this->setName('dotenv:init')
->setDescription($this->trans('commands.dotenv.init.description'))
->addOption(
'load-from-env',
null,
InputOption::VALUE_NONE,
$this->trans('commands.dotenv.init.options.load-from-env')
)
->addOption(
'load-settings',
null,
InputOption::VALUE_NONE,
$this->trans('commands.dotenv.init.options.load-settings')
);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
foreach ($this->envParameters as $key => $value) {
$this->envParameters[$key] = $this->getIo()->ask(
'Enter value for ' . strtoupper($key),
$value
);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$fs = new Filesystem();
$loadFromEnv = $input->getOption('load-from-env');
$loadSettings = $input->getOption('load-settings');
if ($loadFromEnv) {
$this->envParameters['load_from_env'] = $loadFromEnv;
}
if ($loadSettings) {
$this->envParameters['load_settings'] = $loadSettings;
}
$this->copySettingsFile($fs);
$this->copyEnvFile($fs);
$this->generator->setIo($this->getIo());
$this->generator->generate($this->envParameters);
}
protected function copySettingsFile(Filesystem $fs)
{
$sourceFile = $this->drupalFinder
->getDrupalRoot() . '/sites/default/default.settings.php';
$destinationFile = $this->drupalFinder
->getDrupalRoot() . '/sites/default/settings.php';
$directory = dirname($sourceFile);
$permissions = fileperms($directory);
$fs->chmod($directory, 0755);
$this->validateFileExists($fs, $sourceFile);
$this->backUpFile($fs, $destinationFile);
$fs->copy(
$sourceFile,
$destinationFile
);
$this->validateFileExists($fs, $destinationFile);
include_once $this->drupalFinder->getDrupalRoot() . '/core/includes/bootstrap.inc';
include_once $this->drupalFinder->getDrupalRoot() . '/core/includes/install.inc';
$settings['config_directories'] = [
Settings::get('config_sync_directory') => (object) [
'value' => Path::makeRelative(
$this->drupalFinder->getComposerRoot() . '/config/sync',
$this->drupalFinder->getDrupalRoot()
),
'required' => true,
],
];
$settings['settings']['hash_salt'] = (object) [
'value' => Crypt::randomBytesBase64(55),
'required' => true,
];
drupal_rewrite_settings($settings, $destinationFile);
$this->showFileCreatedMessage($destinationFile);
$fs->chmod($directory, $permissions);
}
private function copyEnvFile(Filesystem $fs)
{
$sourceFiles = [
$this->drupalFinder->getComposerRoot() . '/example.gitignore',
$this->drupalFinder->getComposerRoot() . '/.gitignore'
];
$sourceFile = $this->validateFileExists($fs, $sourceFiles);
$destinationFile = $this->drupalFinder
->getComposerRoot() . '/.gitignore';
if ($sourceFile !== $destinationFile) {
$this->backUpFile($fs, $destinationFile);
}
$fs->copy(
$sourceFile,
$destinationFile
);
$this->validateFileExists($fs, $destinationFile);
$gitIgnoreContent = file_get_contents($destinationFile);
$gitIgnoreDistFile = $this->drupalFinder->getComposerRoot() .
$this->drupalFinder->getConsolePath() .
'templates/files/.gitignore.dist';
$gitIgnoreDistContent = file_get_contents($gitIgnoreDistFile);
if (strpos($gitIgnoreContent, '.env') === false) {
file_put_contents(
$destinationFile,
$gitIgnoreContent .
$gitIgnoreDistContent
);
}
$this->showFileCreatedMessage($destinationFile);
}
}

View File

@@ -0,0 +1,150 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Entity\DeleteCommand.
*/
namespace Drupal\Console\Command\Entity;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Entity\EntityTypeRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
class DeleteCommand extends Command
{
/**
* @var EntityTypeRepositoryInterface
*/
protected $entityTypeRepository;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* DeleteCommand constructor.
*
* @param EntityTypeRepositoryInterface $entityTypeRepository
* @param EntityTypeManagerInterface $entityTypeManager
*/
public function __construct(
EntityTypeRepositoryInterface $entityTypeRepository,
EntityTypeManagerInterface $entityTypeManager
) {
$this->entityTypeRepository = $entityTypeRepository;
$this->entityTypeManager = $entityTypeManager;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('entity:delete')
->setDescription($this->trans('commands.entity.delete.description'))
->addOption(
'all',
null,
InputOption::VALUE_NONE,
$this->trans('commands.entity.delete.options.all')
)
->addArgument(
'entity-definition-id',
InputArgument::REQUIRED,
$this->trans('commands.entity.delete.arguments.entity-definition-id')
)
->addArgument(
'entity-id',
InputArgument::REQUIRED,
$this->trans('commands.entity.delete.arguments.entity-id')
)->setAliases(['ed']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$entityDefinitionID = $input->getArgument('entity-definition-id');
$entityID = $input->getArgument('entity-id');
$all = $input->getOption('all');
if (!$entityDefinitionID) {
$entityTypes = $this->entityTypeRepository->getEntityTypeLabels(true);
$entityType = $this->getIo()->choice(
$this->trans('commands.entity.delete.questions.entity-type'),
array_keys($entityTypes)
);
$entityDefinitionID = $this->getIo()->choice(
$this->trans('commands.entity.delete.questions.entity-definition-id'),
array_keys($entityTypes[$entityType])
);
$input->setArgument('entity-definition-id', $entityDefinitionID);
}
if ($all) {
$input->setArgument('entity-id', '-');
} elseif (!$entityID) {
$entityID = $this->getIo()->ask(
$this->trans('commands.entity.delete.questions.entity-id')
);
$input->setArgument('entity-id', $entityID);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$entityDefinitionID = $input->getArgument('entity-definition-id');
try {
$storage = $this->entityTypeManager->getStorage($entityDefinitionID);
if ($input->getOption('all')) {
$entities = $storage->loadMultiple();
if ($this->getIo()->confirm(
sprintf(
$this->trans('commands.entity.delete.messages.confirm-delete-all'),
$entityDefinitionID,
count($entities)
)
)
) {
$storage->delete($entities);
$this->getIo()->success(
sprintf(
$this->trans('commands.entity.delete.messages.deleted-all'),
$entityDefinitionID,
count($entities)
)
);
}
} else {
$entityID = $input->getArgument('entity-id');
$storage->load($entityID)->delete();
$this->getIo()->success(
sprintf(
$this->trans('commands.entity.delete.messages.deleted'),
$entityDefinitionID,
$entityID
)
);
}
} catch (\Exception $e) {
$this->getIo()->error($e->getMessage());
return 1;
}
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Features\ImportCommand.
*/
namespace Drupal\Console\Command\Features;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Command\Shared\FeatureTrait;
use Drupal\Console\Annotations\DrupalCommand;
use Drupal\Console\Core\Command\Command;
/**
* @DrupalCommand(
* extension = "features",
* extensionType = "module"
* )
*/
class ImportCommand extends Command
{
use FeatureTrait;
public function __construct()
{
parent::__construct();
}
protected function configure()
{
$this
->setName('features:import')
->setDescription($this->trans('commands.features.import.description'))
->addOption(
'bundle',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.features.import.options.bundle')
)
->addArgument(
'packages',
InputArgument::IS_ARRAY,
$this->trans('commands.features.import.arguments.packages')
)->setAliases(['fei']);
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$packages = $input->getArgument('packages');
$bundle = $input->getOption('bundle');
if ($bundle) {
$packages = $this->getPackagesByBundle($bundle);
}
$this->getAssigner($bundle);
$this->importFeature($packages);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$packages = $input->getArgument('packages');
$bundle = $input->getOption('bundle');
if (!$packages) {
// @see Drupal\Console\Command\Shared\FeatureTrait::packageQuestion
$package = $this->packageQuestion($bundle);
$input->setArgument('packages', $package);
}
}
}

View File

@@ -0,0 +1,287 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Field\InfoCommand.
*/
namespace Drupal\Console\Command\Field;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\field\FieldConfigInterface;
/**
* Class InfoCommand.
*/
class InfoCommand extends Command
{
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* InfoCommand constructor.
*
* @param EntityTypeManagerInterface $entityTypeManager
* @param EntityFieldManagerInterface $entityFieldManager
*/
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
EntityFieldManagerInterface $entityFieldManager
) {
$this->entityTypeManager = $entityTypeManager;
$this->entityFieldManager = $entityFieldManager;
parent::__construct();
}
/**
* @{@inheritdoc}
*/
public function configure()
{
$this
->setName('field:info')
->setDescription($this->trans('commands.field.info.description'))
->setHelp($this->trans('commands.field.info.help'))
->addOption(
'detailed',
null,
InputOption::VALUE_NONE,
$this->trans('commands.field.info.options.detailed')
)
->addOption(
'entity',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.field.info.options.entity')
)
->addOption(
'bundle',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.field.info.options.bundle')
)->setAliases(['fii']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// Retrieve whether detailed option has been selected.
$detailedOutput = $input->getOption('detailed');
// Retrieve whether an entity type has been specified.
$entityTypeOption = $input->getOption('entity');
// Retrieve whether a specific bundle type has been specified.
$bundleTypeOption = $input->getOption('bundle');
$entityList = $this->entityTypeManager->getDefinitions();
$allFields = $this->entityFieldManager->getFieldMap();
// Set a flag so we can error if a specific entity type selected but not found.
$entityTypeOptionFound = false;
// Set a flag so we can error if a specific bundle type selected but not found.
$bundleTypeOptionFound = false;
// Let's count the fields found so we can display a message if none found.
$fieldCounter = 0;
foreach ($entityList as $entityTypeId => $entityValue) {
// If the Entity has bundleEntityType set we grab it.
$bundleEntityType = $entityValue->get('bundle_entity_type');
// Check to see if the entity has any bundle before continuing.
if (!empty($bundleEntityType)) {
$bundleTypes = $this->entityTypeManager
->getStorage($bundleEntityType)->loadMultiple();
// If a specific entity type has been selected and this is it then we continue else we skip.
if ((!empty($entityTypeOption) && ($entityTypeOption == $entityTypeId))| empty($entityTypeOption)
) {
// Store the fact that we found the entity type specified so we can error if not found.
$entityTypeOptionFound = true;
// Get the entity type label.
$bundleParent = $entityValue->get('label');
// Using counter to know whether to output header.
$bundleTypeCounter = 0;
foreach ($bundleTypes as $bundleType) {
// If a specific bundle type has been selected and this is it then we continue else we skip.
if ((!empty($bundleTypeOption) && ($bundleTypeOption == $bundleType->id()))| empty($bundleTypeOption)
) {
// Store the fact that we found the bundle type specified so we can error if not found.
$bundleTypeOptionFound = true;
// Increase the bundle type counter so we know whether to output header.
$bundleTypeCounter++;
if ($bundleTypeCounter == 1) {
// Output the Parent Entity label if we haven't already.
if ($detailedOutput) {
// If detailed output then display the id as well.
$this->getIo()->info(strtoupper($bundleParent) . ' (' . $entityTypeId . '):');
} else {
// otherwise just display the label for normal output.
$this->getIo()->info(strtoupper($bundleParent . ':'));
}
$this->getIo()->newLine();
}
// Load in the entityType fields.
$fields = $this->getBundleFields(
$entityTypeId,
$bundleType->id()
);
foreach ($fields as $field => $fieldArray) {
// We found a field so increase the field counter.
$fieldCounter++;
// Get the related / used in bundles from the field.
$relatedBundles = "";
$relatedBundlesArray = $allFields[$entityTypeId][$field]['bundles'];
// Turn those related / used in bundles array into a string.
foreach ($relatedBundlesArray as $relatedBundlesValue) {
if ($bundleTypes[$relatedBundlesValue]->id() != $bundleType->id()) {
if (!empty($relatedBundles)) {
$relatedBundles .= ', ' . $bundleTypes[$relatedBundlesValue]->label();
} else {
$relatedBundles = $bundleTypes[$relatedBundlesValue]->label();
}
}
}
// Build out our table for the fields.
$tableRows[] = $detailedOutput ? [
$fieldArray->get('label'),
$fieldArray->get('field_type'),
$fieldArray->get('description'),
$relatedBundles
] : [
$fieldArray->get('label'),
$fieldArray->get('field_type'),
$relatedBundles
];
// Clear the related bundles ready for the next field.
unset($relatedBundles);
}
// If detailed output then display bundle id and description.
if ($detailedOutput) {
// Output the bundle label and id.
$this->getIo()->info($bundleType->label() . ' (' . $bundleType->id() . ')');
$this->getIo()->info(strip_tags($bundleType->get('description')));
} else {
// Else just output the bundle label.
$this->getIo()->info($bundleType->label());
}
// Fill out our table header.
// If no rows exist for the fields then we display a no results message.
if (!empty($tableRows)) {
$tableHeader = $detailedOutput ? [
$this->trans('commands.field.info.table.header-name'),
$this->trans('commands.field.info.table.header-type'),
$this->trans('commands.field.info.table.header-desc'),
$this->trans('commands.field.info.table.header-usage')
] : [
$this->trans('commands.field.info.table.header-name'),
$this->trans('commands.field.info.table.header-type'),
$this->trans('commands.field.info.table.header-usage')
];
$this->getIo()->table($tableHeader, $tableRows);
} else {
$this->getIo()->comment(
$this->trans('commands.field.info.messages.fields-none')
. ' ' . $this->trans('commands.field.info.messages.in-bundle-type')
. " '" . $bundleType->label() . "'"
);
}
// Clear out the rows & headers arrays to start fresh.
unset($tableHeader, $tableRows);
// Create some space so the output looks nice.
$this->getIo()->newLine();
}
}
}
}
}
// If entity type was specified but not found then display error message.
if (!empty($entityTypeOption)) {
if (!$entityTypeOptionFound) {
$this->getIo()->comment(
$this->trans('commands.field.info.messages.entity-type') .
' ' . $entityTypeOption . ' ' .
$this->trans('commands.field.info.messages.not-found')
);
} elseif (!empty($bundleTypeOption) && !$bundleTypeOptionFound) {
// If specified entity type found and bundle type specified but not found then display error message.
$this->getIo()->comment(
$this->trans('commands.field.info.messages.bundle-type') .
' ' . $bundleTypeOption . ' ' .
$this->trans('commands.field.info.messages.not-found') .
' ' . $this->trans('commands.field.info.messages.in-entity-type') .
' ' . $entityTypeOption
);
}
} elseif (!empty($bundleTypeOption) && !$bundleTypeOptionFound) {
// If specified bundle type not found then display error message.
$this->getIo()->comment(
$this->trans('commands.field.info.messages.bundle-type') .
' ' . $bundleTypeOption . ' ' .
$this->trans('commands.field.info.messages.not-found')
);
} elseif ($fieldCounter == 0) {
// If no fields found then display appropriate message.
$this->getIo()->comment($this->trans('commands.field.info.messages.fields-none'));
}
return 0;
}
/**
* Helper function to get the field definitions.
*
* @param string $entityTypeId
* The entity type we want to inspect.
* @param string $bundle
* The bundle we want to discover the fields of.
* @return array
* An array of field storage definitions for the entity type,
* keyed by field name.
*/
private function getBundleFields($entityTypeId, $bundle)
{
$fields = [];
if (!empty($entityTypeId) && !empty($bundle)) {
$fields = array_filter(
$this->entityFieldManager->getFieldDefinitions($entityTypeId, $bundle),
function ($fieldDefinition) {
return $fieldDefinition instanceof FieldConfigInterface;
}
);
}
return $fields;
}
}

View File

@@ -0,0 +1,179 @@
<?php
/**
* @file
* Contains Drupal\Console\Command\Generate\ControllerCommand.
*/
namespace Drupal\Console\Command\Generate;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Generator\AjaxCommandGenerator;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
/**
* Class AjaxCommand
*
* @package Drupal\Console\Command\Generate
*/
class AjaxCommand extends Command
{
use ModuleTrait;
use ConfirmationTrait;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var AjaxCommandGenerator
*/
protected $generator;
/**
* @var Validator
*/
protected $validator;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* AjaxCommand constructor.
*
* @param Manager $extensionManager
* @param AjaxCommandGenerator $generator
* @param Validator $validator
* @param ChainQueue $chainQueue
*/
public function __construct(
Manager $extensionManager,
AjaxCommandGenerator $generator,
Validator $validator,
ChainQueue $chainQueue
) {
$this->extensionManager = $extensionManager;
$this->generator = $generator;
$this->validator = $validator;
$this->chainQueue = $chainQueue;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('generate:ajax:command')
->setDescription($this->trans('commands.generate.ajax.command.description'))
->setHelp($this->trans('commands.generate.ajax.command.help'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'class',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.ajax.command.options.class')
)
->addOption(
'method',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.ajax.command.options.method')
)
->addOption(
'js-name',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.ajax.command.options.js-name')
)
->setAliases(['gac']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$class = $this->validator->validateClassName($input->getOption('class'));
$method = $input->getOption('method');
$js_name = $input->getOption('js-name');
$this->generator->generate(
[
'module' => $module,
'class_name' => $class,
'method' => $method,
'js_name' => $js_name,
]
);
// Run cache rebuild to see changes in Web UI
$this->chainQueue->addCommand('router:rebuild', []);
return 0;
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$this->getModuleOption();
// --class option
$class = $input->getOption('class');
if (!$class) {
$class = $this->getIo()->ask(
$this->trans('commands.generate.ajax.command.questions.class'),
'AjaxCommand',
function ($class) {
return $this->validator->validateClassName($class);
}
);
$input->setOption('class', $class);
}
// --method option
$method = $input->getOption('method');
if (!$method) {
$method = $this->getIo()->ask(
$this->trans('commands.generate.ajax.command.questions.method'),
'hello'
);
$input->setOption('method', $method);
}
// --js-name option
$js_name = $input->getOption('js-name');
if (!$js_name) {
$js_name = $this->getIo()->ask(
$this->trans('commands.generate.ajax.command.questions.js-name'),
'script'
);
$input->setOption('js-name', $js_name);
}
}
}

View File

@@ -0,0 +1,150 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\AuthenticationProviderCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Utils\Validator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Generator\AuthenticationProviderGenerator;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Extension\Manager;
class AuthenticationProviderCommand extends Command
{
use ModuleTrait;
use ConfirmationTrait;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var AuthenticationProviderGenerator
*/
protected $generator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var Validator
*/
protected $validator;
/**
* AuthenticationProviderCommand constructor.
*
* @param Manager $extensionManager
* @param AuthenticationProviderGenerator $generator
* @param StringConverter $stringConverter
* @param Validator $validator
*/
public function __construct(
Manager $extensionManager,
AuthenticationProviderGenerator $generator,
StringConverter $stringConverter,
Validator $validator
) {
$this->extensionManager = $extensionManager;
$this->generator = $generator;
$this->stringConverter = $stringConverter;
$this->validator = $validator;
parent::__construct();
}
protected function configure()
{
$this
->setName('generate:authentication:provider')
->setDescription($this->trans('commands.generate.authentication.provider.description'))
->setHelp($this->trans('commands.generate.authentication.provider.help'))
->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module'))
->addOption(
'class',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.authentication.provider.options.class')
)
->addOption(
'provider-id',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.authentication.provider.options.provider-id')
)
->setAliases(['gap']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$class = $this->validator->validateClassName($input->getOption('class'));
$provider_id = $input->getOption('provider-id');
$this->generator->generate([
'module' => $module,
'class' => $class,
'provider_id' => $provider_id,
]);
return 0;
}
protected function interact(InputInterface $input, OutputInterface $output)
{
$stringUtils = $this->stringConverter;
// --module option
$this->getModuleOption();
// --class option
$class = $input->getOption('class');
if (!$class) {
$class = $this->getIo()->ask(
$this->trans(
'commands.generate.authentication.provider.questions.class'
),
'DefaultAuthenticationProvider',
function ($class) {
return $this->validator->validateClassName($class);
}
);
$input->setOption('class', $class);
}
// --provider-id option
$provider_id = $input->getOption('provider-id');
if (!$provider_id) {
$provider_id = $this->getIo()->ask(
$this->trans('commands.generate.authentication.provider.questions.provider-id'),
$stringUtils->camelCaseToUnderscore($class),
function ($value) use ($stringUtils) {
if (!strlen(trim($value))) {
throw new \Exception('The Class name can not be empty');
}
return $stringUtils->camelCaseToUnderscore($value);
}
);
$input->setOption('provider-id', $provider_id);
}
}
}

View File

@@ -0,0 +1,250 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\BlockTypeCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ArrayInputTrait;
use Drupal\Console\Command\Shared\FormTrait;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Command\Shared\ServicesTrait;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Generator\BlockTypeGenerator;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\block_content\Entity\BlockContent;
use Drupal\block\Entity\Block;
use Drupal\block_content\BlockContentTypeInterface;
use Drupal\block_content\Entity\BlockContentType;
class BlockTypeCommand extends ContainerAwareCommand
{
use ArrayInputTrait;
use ServicesTrait;
use ModuleTrait;
use FormTrait;
use ConfirmationTrait;
/**
* @var ConfigFactory
*/
protected $configFactory;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* @var BlockTypeGenerator
*/
protected $generator;
/**
* @var EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var Validator
*/
protected $validator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var ElementInfoManagerInterface
*/
protected $elementInfoManager;
/**
* BlockTypeCommand constructor.
*
* @param ConfigFactory $configFactory
* @param ChainQueue $chainQueue
* @param BlockTypeGenerator $generator
* @param EntityTypeManagerInterface $entityTypeManager
* @param Manager $extensionManager
* @param Validator $validator
* @param StringConverter $stringConverter
* @param ElementInfoManagerInterface $elementInfoManager
*/
public function __construct(
ConfigFactory $configFactory,
ChainQueue $chainQueue,
BlockTypeGenerator $generator,
EntityTypeManagerInterface $entityTypeManager,
Manager $extensionManager,
Validator $validator,
StringConverter $stringConverter,
ElementInfoManagerInterface $elementInfoManager
) {
$this->configFactory = $configFactory;
$this->chainQueue = $chainQueue;
$this->generator = $generator;
$this->entityTypeManager = $entityTypeManager;
$this->extensionManager = $extensionManager;
$this->validator = $validator;
$this->stringConverter = $stringConverter;
$this->elementInfoManager = $elementInfoManager;
parent::__construct();
}
protected function configure()
{
$this
->setName('generate:block:type')
->setDescription($this->trans('commands.generate.block.type.description'))
->setHelp($this->trans('commands.generate.block.type.help'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'class',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.block.type.options.class')
)
->addOption(
'block-label',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.block.type.options.block-label')
)
->addOption(
'block-description',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.block.type.options.block-description')
)
->addOption(
'block-id',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.block.type.options.block-id')
)
->setAliases(['gbt']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$class_name = $this->validator->validateClassName($input->getOption('class'));
$block_label = $input->getOption('block-label');
$block_description = $input->getOption('block-description');
$block_id = $input->getOption('block-id');
$theme_region = true;
$this->generator->generate([
'module' => $module,
'class_name' => $class_name,
'label' => $block_label,
'description' => $block_description,
'block_id' => $block_id,
]);
$this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']);
if ($theme_region) {
$block_content_type = BlockContentType::create([
'id' => $block_id,
'label' => $block_label,
'description' => $block_description,
]);
$block_content_type->save();
$block_content = BlockContent::create([
'info' => $block_label,
'type' => $block_id,
'body' => [
'value' => "<h1>Block's body</h1>",
'format' => 'full_html',
],
]);
$block_content->save();
}
}
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$this->getModuleOption();
// --class option
$class = $input->getOption('class');
if (!$class) {
$class = $this->getIo()->ask(
$this->trans('commands.generate.block.type.questions.class'),
'DefaultBlockContentType',
function ($class) {
return $this->validator->validateClassName($class);
}
);
$input->setOption('class', $class);
}
// --block-label option
$block_label = $input->getOption('block-label');
if (!$block_label) {
$block_label = $this->getIo()->ask(
$this->trans('commands.generate.block.type.questions.block-label'),
$this->stringConverter->camelCaseToHuman($class)
);
$input->setOption('block-label', $block_label);
}
// --block-id option
$blockId = $input->getOption('block-id');
if (!$blockId) {
$blockId = $this->getIo()->ask(
$this->trans('commands.generate.block.type.questions.block-id'),
$this->stringConverter->camelCaseToUnderscore($class)
);
$input->setOption('block-id', $blockId);
}
// --block-description option
$blockDesc = $input->getOption('block-description');
if (!$blockDesc) {
$blockDesc = $this->getIo()->ask(
$this->trans('commands.generate.block.type.questions.block-description'),
$this->stringConverter->camelCaseToUnderscore($class)
);
$input->setOption('block-description', $blockDesc);
}
}
}

View File

@@ -0,0 +1,172 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\BreakPointCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ArrayInputTrait;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ThemeBreakpointTrait;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Generator\BreakPointGenerator;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Extension\ThemeHandler;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Class BreakPointCommand
*
* @package Drupal\Console\Command\Generate
*/
class BreakPointCommand extends Command
{
use ArrayInputTrait;
use ConfirmationTrait;
use ThemeBreakpointTrait;
/**
* @var BreakPointGenerator
*/
protected $generator;
/**
* @var Site
*/
protected $site;
/**
* @var string
*/
protected $appRoot;
/**
* @var ThemeHandler
*/
protected $themeHandler;
/**
* @var Validator
*/
protected $validator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* BreakPointCommand constructor.
*
* @param BreakPointGenerator $generator
* @param string $appRoot
* @param ThemeHandler $themeHandler
* @param Validator $validator
* @param StringConverter $stringConverter
*/
public function __construct(
BreakPointGenerator $generator,
$appRoot,
ThemeHandler $themeHandler,
Validator $validator,
StringConverter $stringConverter
) {
$this->generator = $generator;
$this->appRoot = $appRoot;
$this->themeHandler = $themeHandler;
$this->validator = $validator;
$this->stringConverter = $stringConverter;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('generate:breakpoint')
->setDescription($this->trans('commands.generate.breakpoint.description'))
->setHelp($this->trans('commands.generate.breakpoint.help'))
->addOption(
'theme',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.generate.breakpoint.options.theme')
)
->addOption(
'breakpoints',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.generate.breakpoint.options.breakpoints')
)->setAliases(['gb']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$validators = $this->validator;
// we must to ensure theme exist
$machine_name = $validators->validateMachineName($input->getOption('theme'));
$theme = $input->getOption('theme');
$breakpoints = $input->getOption('breakpoints');
$noInteraction = $input->getOption('no-interaction');
// Parse nested data.
if ($noInteraction) {
$breakpoints = $this->explodeInlineArray($breakpoints);
}
$this->generator->generate([
'theme' => $theme,
'breakpoints' => $breakpoints,
'machine_name' => $machine_name,
]);
return 0;
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --theme option.
$theme = $input->getOption('theme');
if (!$theme) {
$themeHandler = $this->themeHandler;
$themes = $themeHandler->rebuildThemeData();
$themes['classy'] = '';
uasort($themes, 'system_sort_modules_by_info_name');
$theme = $this->getIo()->choiceNoList(
$this->trans('commands.generate.breakpoint.questions.theme'),
array_keys($themes)
);
$input->setOption('theme', $theme);
}
// --breakpoints option.
$breakpoints = $input->getOption('breakpoints');
if (!$breakpoints) {
$breakpoints = $this->breakpointQuestion();
$input->setOption('breakpoints', $breakpoints);
} else {
$breakpoints = $this->explodeInlineArray($breakpoints);
}
$input->setOption('breakpoints', $breakpoints);
}
}

View File

@@ -0,0 +1,180 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\CacheContextCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Command\Shared\ServicesTrait;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Generator\CacheContextGenerator;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class CacheContextCommand extends ContainerAwareCommand
{
use ModuleTrait;
use ConfirmationTrait;
use ServicesTrait;
/**
* @var CacheContextGenerator
*/
protected $generator;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var Validator
*/
protected $validator;
/**
* CacheContextCommand constructor.
*
* @param CacheContextGenerator $generator
* @param ChainQueue $chainQueue
* @param Manager $extensionManager
* @param StringConverter $stringConverter
* @param Validator $validator
*/
public function __construct(
CacheContextGenerator $generator,
ChainQueue $chainQueue,
Manager $extensionManager,
StringConverter $stringConverter,
Validator $validator
) {
$this->generator = $generator;
$this->chainQueue = $chainQueue;
$this->extensionManager = $extensionManager;
$this->stringConverter = $stringConverter;
$this->validator = $validator;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('generate:cache:context')
->setDescription($this->trans('commands.generate.cache.context.description'))
->setHelp($this->trans('commands.generate.cache.context.description'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'cache-context',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.cache.context.options.name')
)
->addOption(
'class',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.cache.context.options.class')
)
->addOption(
'services',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.common.options.services')
)->setAliases(['gcc']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$cache_context = $input->getOption('cache-context');
$class = $this->validator->validateClassName($input->getOption('class'));
$services = $input->getOption('services');
// @see Drupal\Console\Command\Shared\ServicesTrait::buildServices
$buildServices = $this->buildServices($services);
$this->generator->generate([
'module' => $module,
'cache_context' => $cache_context,
'class' => $class,
'services' => $buildServices,
]);
$this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$module = $this->getModuleOption();
// --cache_context option
$cache_context = $input->getOption('cache-context');
if (!$cache_context) {
$cache_context = $this->getIo()->ask(
$this->trans('commands.generate.cache.context.questions.name'),
sprintf('%s', $module)
);
$input->setOption('cache-context', $cache_context);
}
// --class option
$class = $input->getOption('class');
if (!$class) {
$class = $this->getIo()->ask(
$this->trans('commands.generate.cache.context.questions.class'),
'DefaultCacheContext',
function ($class) {
return $this->validator->validateClassName($class);
}
);
$input->setOption('class', $class);
}
// --services option
$services = $input->getOption('services');
if (!$services) {
// @see Drupal\Console\Command\Shared\ServicesTrait::servicesQuestion
$services = $this->servicesQuestion();
$input->setOption('services', $services);
}
}
}

View File

@@ -0,0 +1,273 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\CommandCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Command\Shared\ExtensionTrait;
use Drupal\Console\Command\Shared\ServicesTrait;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Generator\CommandGenerator;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Drupal\Console\Utils\Site;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class CommandCommand extends ContainerAwareCommand
{
use ConfirmationTrait;
use ServicesTrait;
use ModuleTrait;
use ExtensionTrait;
/**
* @var CommandGenerator
*/
protected $generator;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var Validator
*/
protected $validator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var Site
*/
protected $site;
/**
* CommandCommand constructor.
*
* @param CommandGenerator $generator
* @param Manager $extensionManager
* @param Validator $validator
* @param StringConverter $stringConverter
* @param Site $site
*/
public function __construct(
CommandGenerator $generator,
Manager $extensionManager,
Validator $validator,
StringConverter $stringConverter,
Site $site
) {
$this->generator = $generator;
$this->extensionManager = $extensionManager;
$this->validator = $validator;
$this->stringConverter = $stringConverter;
$this->site = $site;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('generate:command')
->setDescription($this->trans('commands.generate.command.description'))
->setHelp($this->trans('commands.generate.command.help'))
->addOption(
'extension',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.extension')
)
->addOption(
'extension-type',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.extension-type')
)
->addOption(
'class',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.generate.command.options.class')
)
->addOption(
'name',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.generate.command.options.name')
)
->addOption(
'initialize',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.command.options.initialize')
)
->addOption(
'interact',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.command.options.interact')
)
->addOption(
'container-aware',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.command.options.container-aware')
)
->addOption(
'services',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.common.options.services')
)
->addOption(
'generator',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.command.options.generator')
)
->setAliases(['gco']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$extension = $input->getOption('extension');
$extensionType = $input->getOption('extension-type');
$class = $this->validator->validateCommandName($input->getOption('class'));
$name = $input->getOption('name');
$initialize = $input->getOption('initialize');
$interact = $input->getOption('interact');
$containerAware = $input->getOption('container-aware');
$services = $input->getOption('services');
$generator = $input->getOption('generator');
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
// @see use Drupal\Console\Command\Shared\ServicesTrait::buildServices
$build_services = $this->buildServices($services);
$class_generator = null;
if ($generator) {
$class_generator = str_replace('Command', 'Generator', $class);
}
$this->generator->generate([
'extension' => $extension,
'extension_type' => $extensionType,
'name' => $name,
'initialize' => $initialize,
'interact' => $interact,
'class_name' => $class,
'container_aware' => $containerAware,
'services' => $build_services,
'class_generator' => $class_generator,
'generator' => $generator,
]);
$this->site->removeCachedServicesFile();
return 0;
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$extension = $input->getOption('extension');
if (!$extension) {
$extension = $this->extensionQuestion(true, true);
$input->setOption('extension', $extension->getName());
$input->setOption('extension-type', $extension->getType());
}
$extensionType = $input->getOption('extension-type');
if (!$extensionType) {
$extensionType = $this->extensionTypeQuestion();
$input->setOption('extension-type', $extensionType);
}
$name = $input->getOption('name');
if (!$name) {
$name = $this->getIo()->ask(
$this->trans('commands.generate.command.questions.name'),
sprintf('%s:default', $extension->getName())
);
$input->setOption('name', $name);
}
$initialize = $input->getOption('initialize');
if (!$initialize) {
$initialize = $this->getIo()->confirm(
$this->trans('commands.generate.command.questions.initialize'),
false
);
$input->setOption('initialize', $initialize);
}
$interact = $input->getOption('interact');
if (!$interact) {
$interact = $this->getIo()->confirm(
$this->trans('commands.generate.command.questions.interact'),
false
);
$input->setOption('interact', $interact);
}
$class = $input->getOption('class');
if (!$class) {
$class = $this->getIo()->ask(
$this->trans('commands.generate.command.questions.class'),
'DefaultCommand',
function ($class) {
return $this->validator->validateCommandName($class);
}
);
$input->setOption('class', $class);
}
$containerAware = $input->getOption('container-aware');
if (!$containerAware) {
$containerAware = $this->getIo()->confirm(
$this->trans('commands.generate.command.questions.container-aware'),
false
);
$input->setOption('container-aware', $containerAware);
}
if (!$containerAware) {
// @see use Drupal\Console\Command\Shared\ServicesTrait::servicesQuestion
$services = $this->servicesQuestion();
$input->setOption('services', $services);
}
$generator = $input->getOption('generator');
if (!$generator) {
$generator = $this->getIo()->confirm(
$this->trans('commands.generate.command.questions.generator'),
false
);
$input->setOption('generator', $generator);
}
}
}

View File

@@ -0,0 +1,417 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\ComposerCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ArrayInputTrait;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Generator\ComposerGenerator;
use Drupal\Console\Utils\Validator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class ComposerCommand extends Command
{
use ArrayInputTrait;
use ConfirmationTrait;
use ModuleTrait;
/**
* @var ComposerGenerator
*/
protected $generator;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var Validator
*/
protected $validator;
/**
* ComposerCommand constructor.
*
* @param ComposerGenerator $generator
* @param Manager $extensionManager
* @param Validator $validator
*/
public function __construct(
ComposerGenerator $generator,
Manager $extensionManager,
Validator $validator
) {
$this->generator = $generator;
$this->extensionManager = $extensionManager;
$this->validator = $validator;
parent::__construct();
}
protected function configure()
{
$this
->setName('generate:composer')
->setDescription($this->trans('commands.generate.composer.description'))
->setHelp($this->trans('commands.generate.composer.composer'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'name',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.generate.composer.options.name')
)
->addOption(
'type',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.generate.composer.options.type')
)
->addOption(
'description',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.generate.composer.options.description')
)
->addOption(
'keywords',
null,
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.generate.composer.options.keywords')
)
->addOption(
'license',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.composer.options.license')
)
->addOption(
'homepage',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.composer.options.homepage')
)
->addOption(
'minimum-stability',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.composer.options.minimum-stability')
)
->addOption(
'authors',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.generate.composer.options.authors')
)
->addOption(
'support',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.generate.composer.options.support')
)
->addOption(
'required',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.generate.composer.options.required')
)->setAliases(['gcom']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$module = $this->getModuleOption();
// --name option
$name = $input->getOption('name');
if (!$name) {
$name = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.name'),
'drupal/' . $module
);
$input->setOption('name', $name);
}
// --type option
$type = $input->getOption('type');
if (!$type) {
$type = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.type'),
'drupal-module'
);
$input->setOption('type', $type);
}
// --description option
$description = $input->getOption('description');
if (!$description) {
$description = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.description')
);
$input->setOption('description', $description);
}
// --keywords option
$keywords = $input->getOption('keywords');
if (!$keywords) {
if ($this->getIo()->confirm(
$this->trans('commands.generate.composer.questions.add-keywords'),
false
)) {
$keywords = [];
while (true) {
$keyword = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.keyword')
);
if (empty($keyword) || is_numeric($keyword)) {
break;
}
$keywords[] = $keyword;
}
$input->setOption('keywords', $keywords);
}
}
// --license option
$license = $input->getOption('license');
if (!$license) {
$license = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.license'),
'GPL-2.0+'
);
$input->setOption('license', $license);
}
// --homepage option
$homepage = $input->getOption('homepage');
if (!$homepage) {
$homepage = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.homepage'),
'https://www.drupal.org/project/' . $module
);
$input->setOption('homepage', $homepage);
}
// --minimum-stability option
$minimumStability = $input->getOption('minimum-stability');
if (!$minimumStability) {
$stabilityOptions = [
'stable',
'dev',
'alpha',
'beta',
'RC',
];
$minimumStability = $this->getIo()->choiceNoList(
$this->trans('commands.generate.composer.questions.minimum-stability'),
$stabilityOptions,
'',
true
);
$input->setOption('minimum-stability', $minimumStability);
}
// --authors option
$authors = $input->getOption('authors');
if (!$authors) {
if ($this->getIo()->confirm(
$this->trans('commands.generate.composer.questions.add-author'),
false
)) {
$authorItems = [];
while (true) {
$authorName = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.author-name')
);
$authorEmail = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.author-email')
);
$authorHomepage = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.author-homepage')
);
$authorRole = $this->getIo()->askEmpty(
$this->trans('commands.generate.composer.questions.author-role')
);
if (!empty($authorName) || !empty($authorEmail) || !empty($authorHomepage) || !empty($authorRole)) {
$authorItems[] = [
'name' => $authorName,
'email' => $authorEmail,
'homepage' => $authorHomepage,
'role' => $authorRole,
];
}
$this->getIo()->newLine();
if (!$this->getIo()->confirm(
$this->trans('commands.generate.composer.questions.add-another-author'),
false
)) {
break;
}
}
$this->getIo()->newLine(2);
$input->setOption('authors', $authorItems);
}
}
// --support option
$support = $input->getOption('support');
if (!$support) {
if ($this->getIo()->confirm(
$this->trans('commands.generate.composer.questions.add-support'),
false
)) {
$supportChannels = [
'email',
'issues',
'forum',
'wiki',
'irc',
'source',
'docs',
'rss',
];
$supportItems = [];
while (true) {
$supportChannel = $this->getIo()->choiceNoList(
$this->trans('commands.generate.composer.questions.support-channel'),
$supportChannels,
'',
true
);
$supportUrl = $this->getIo()->ask(
$this->trans('commands.generate.composer.questions.support-value')
);
$supportItems[] = [
'channel' => $supportChannel,
'url' => $supportUrl,
];
$this->getIo()->newLine();
if (!$this->getIo()->confirm(
$this->trans('commands.generate.composer.questions.add-another-support'),
false
)) {
break;
}
}
$this->getIo()->newLine(2);
$input->setOption('support', $supportItems);
}
}
// --required option
$required = $input->getOption('required');
if (!$required) {
if ($this->getIo()->confirm(
$this->trans('commands.generate.composer.questions.add-required'),
false
)) {
$requiredItems = [];
while (true) {
$requiredName = $this->getIo()->ask(
$this->trans('commands.generate.composer.questions.required-name')
);
$requiredVersion = $this->getIo()->ask(
$this->trans('commands.generate.composer.questions.required-version')
);
$requiredItems[] = [
'name' => $requiredName,
'version' => $requiredVersion,
];
$this->getIo()->newLine();
if (!$this->getIo()->confirm(
$this->trans('commands.generate.composer.questions.add-another-required'),
false
)) {
break;
}
}
$input->setOption('required', $requiredItems);
}
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $input->getOption('module');
$name = $input->getOption('name');
$type = $input->getOption('type');
$description = $input->getOption('description');
$keywords = $input->getOption('keywords');
$license = $input->getOption('license');
$homepage = $input->getOption('homepage');
$minimumStability = $input->getOption('minimum-stability');
$authors = $input->getOption('authors');
$support = $input->getOption('support');
$required = $input->getOption('required');
$noInteraction = $input->getOption('no-interaction');
// Parse nested data.
if ($noInteraction) {
$authors = $this->explodeInlineArray($authors);
$support = $this->explodeInlineArray($support);
$required = $this->explodeInlineArray($required);
}
$this->generator->generate([
'machine_name' => $module,
'name' => $name,
'type' => $type,
'description' => $description,
'keywords' => $keywords,
'license' => $license,
'homepage' => $homepage,
'minimum_stability' => $minimumStability,
'authors' => $authors,
'support_items' => $support,
'required_items' => $required,
]);
return 0;
}
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* @file
* Contains Drupal\Console\Command\Generate\ConfigFormBaseCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Generator\FormGenerator;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Utils\Validator;
use Drupal\Console\Utils\TranslatorManager;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Core\Render\ElementInfoManager;
class ConfigFormBaseCommand extends FormCommand
{
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var FormGenerator
*/
protected $generator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var Validator
*/
protected $validator;
/**
* @var RouteProviderInterface
*/
protected $routeProvider;
/**
* @var ElementInfoManager
*/
protected $elementInfoManager;
/**
* @var string
*/
protected $appRoot;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* ConfigFormBaseCommand constructor.
*
* @param TranslatorManager $translator
* @param Manager $extensionManager
* @param FormGenerator $generator
* @param StringConverter $stringConverter
* @param Validator $validator
* @param RouteProviderInterface $routeProvider
* @param ElementInfoManager $elementInfoManager
* @param $appRoot
* @param ChainQueue $chainQueue
*/
public function __construct(
TranslatorManager $translator,
Manager $extensionManager,
FormGenerator $generator,
StringConverter $stringConverter,
Validator $validator,
RouteProviderInterface $routeProvider,
ElementInfoManager $elementInfoManager,
$appRoot,
ChainQueue $chainQueue
) {
$this->extensionManager = $extensionManager;
$this->generator = $generator;
$this->stringConverter = $stringConverter;
$this->validator = $validator;
$this->routeProvider = $routeProvider;
$this->elementInfoManager = $elementInfoManager;
$this->appRoot = $appRoot;
$this->chainQueue = $chainQueue;
parent::__construct($translator, $extensionManager, $generator, $chainQueue, $stringConverter, $validator, $elementInfoManager, $routeProvider);
}
protected function configure()
{
$this->setFormType('ConfigFormBase');
$this->setCommandName('generate:form:config');
$this->setAliases(['gfc']);
parent::configure();
}
}

View File

@@ -0,0 +1,300 @@
<?php
/**
* @file
* Contains Drupal\Console\Command\Generate\ControllerCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Command\Shared\ServicesTrait;
use Drupal\Console\Generator\ControllerGenerator;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\Console\Core\Command\Shared\InputTrait;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Routing\RouteProviderInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class ControllerCommand extends ContainerAwareCommand
{
use ModuleTrait;
use ServicesTrait;
use ConfirmationTrait;
use InputTrait;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var ControllerGenerator
*/
protected $generator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var Validator
*/
protected $validator;
/**
* @var RouteProviderInterface
*/
protected $routeProvider;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* ControllerCommand constructor.
*
* @param Manager $extensionManager
* @param ControllerGenerator $generator
* @param StringConverter $stringConverter
* @param Validator $validator
* @param RouteProviderInterface $routeProvider
* @param ChainQueue $chainQueue
*/
public function __construct(
Manager $extensionManager,
ControllerGenerator $generator,
StringConverter $stringConverter,
Validator $validator,
RouteProviderInterface $routeProvider,
ChainQueue $chainQueue
) {
$this->extensionManager = $extensionManager;
$this->generator = $generator;
$this->stringConverter = $stringConverter;
$this->validator = $validator;
$this->routeProvider = $routeProvider;
$this->chainQueue = $chainQueue;
parent::__construct();
}
protected function configure()
{
$this
->setName('generate:controller')
->setDescription($this->trans('commands.generate.controller.description'))
->setHelp($this->trans('commands.generate.controller.help'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'class',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.controller.options.class')
)
->addOption(
'routes',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.generate.controller.options.routes')
)
->addOption(
'services',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.common.options.services')
)
->addOption(
'test',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.controller.options.test')
)
->setAliases(['gcon']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$class = $this->validator->validateControllerName($input->getOption('class'));
$routes = $input->getOption('routes');
$test = $input->getOption('test');
$services = $input->getOption('services');
$routes = $this->inlineValueAsArray($routes);
$input->setOption('routes', $routes);
// @see use Drupal\Console\Command\Shared\ServicesTrait::buildServices
$build_services = $this->buildServices($services);
//$this->generator->setLearning($learning);
$this->generator->generate([
'module' => $module,
'class_name' => $class,
'routes' => $routes,
'test' => $test,
'services' => $build_services
]);
// Run cache rebuild to see changes in Web UI
$this->chainQueue->addCommand('router:rebuild', []);
return 0;
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$module = $this->getModuleOption();
// --class option
$class = $input->getOption('class');
if (!$class) {
$class = $this->getIo()->ask(
$this->trans('commands.generate.controller.questions.class'),
'DefaultController',
function ($class) {
return $this->validator->validateControllerName($class);
}
);
$input->setOption('class', $class);
}
$routes = $input->getOption('routes');
if (!$routes) {
while (true) {
$title = $this->getIo()->askEmpty(
$this->trans('commands.generate.controller.questions.title'),
'',
function ($title) use ($routes) {
if ($routes && empty(trim($title))) {
return false;
}
if (!$routes && empty(trim($title))) {
throw new \InvalidArgumentException(
$this->trans(
'commands.generate.controller.messages.title-empty'
)
);
}
if (in_array($title, array_column($routes, 'title'))) {
throw new \InvalidArgumentException(
sprintf(
$this->trans(
'commands.generate.controller.messages.title-already-added'
),
$title
)
);
}
return $title;
}
);
if ($title === '') {
break;
}
$method = $this->getIo()->ask(
$this->trans('commands.generate.controller.questions.method'),
'hello',
function ($method) use ($routes) {
if (in_array($method, array_column($routes, 'method'))) {
throw new \InvalidArgumentException(
sprintf(
$this->trans(
'commands.generate.controller.messages.method-already-added'
),
$method
)
);
}
return $method;
}
);
$path = $this->getIo()->ask(
$this->trans('commands.generate.controller.questions.path'),
sprintf(
'/%s/'.($method!='hello'?$method:'hello/{name}'),
$module
),
function ($path) use ($routes) {
if (count($this->routeProvider->getRoutesByPattern($path)) > 0
|| in_array($path, array_column($routes, 'path'))
) {
throw new \InvalidArgumentException(
sprintf(
$this->trans(
'commands.generate.controller.messages.path-already-added'
),
$path
)
);
}
return $path;
}
);
$classMachineName = $this->stringConverter->camelCaseToMachineName($class);
$routeName = $module . '.' . $classMachineName . '_' . $method;
if ($this->routeProvider->getRoutesByNames([$routeName])
|| in_array($routeName, $routes)
) {
$routeName .= '_' . rand(0, 100);
}
$routes[] = [
'title' => $title,
'name' => $routeName,
'method' => $method,
'path' => $path
];
}
$input->setOption('routes', $routes);
}
// --test option
$test = $input->getOption('test');
if (!$test) {
$test = $this->getIo()->confirm(
$this->trans('commands.generate.controller.questions.test'),
true
);
$input->setOption('test', $test);
}
// --services option
// @see use Drupal\Console\Command\Shared\ServicesTrait::servicesQuestion
$services = $this->servicesQuestion();
$input->setOption('services', $services);
}
}

View File

@@ -0,0 +1,145 @@
<?php
/**
* @file
* Contains Drupal\Console\Command\Generate\EntityBundleCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Core\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Generator\EntityBundleGenerator;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
class EntityBundleCommand extends Command
{
use ModuleTrait;
use ConfirmationTrait;
/**
* @var Validator
*/
protected $validator;
/**
* @var EntityBundleGenerator
*/
protected $generator;
/**
* @var Manager
*/
protected $extensionManager;
/**
* EntityBundleCommand constructor.
*
* @param Validator $validator
* @param EntityBundleGenerator $generator
* @param Manager $extensionManager
*/
public function __construct(
Validator $validator,
EntityBundleGenerator $generator,
Manager $extensionManager
) {
$this->validator = $validator;
$this->generator = $generator;
$this->extensionManager = $extensionManager;
parent::__construct();
}
protected function configure()
{
$this
->setName('generate:entity:bundle')
->setDescription($this->trans('commands.generate.entity.bundle.description'))
->setHelp($this->trans('commands.generate.entity.bundle.help'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'bundle-name',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.entity.bundle.options.bundle-name')
)
->addOption(
'bundle-title',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.entity.bundle.options.bundle-title')
)
->setAliases(['geb']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$bundleName = $input->getOption('bundle-name');
$bundleTitle = $input->getOption('bundle-title');
//TODO:
// $generator->setLearning($learning);
$this->generator->generate([
'module' => $module,
'bundle_name' => $bundleName,
'bundle_title' => $bundleTitle,
]);
return 0;
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$this->getModuleOption();
// --bundle-name option
$bundleName = $input->getOption('bundle-name');
if (!$bundleName) {
$bundleName = $this->getIo()->ask(
$this->trans('commands.generate.entity.bundle.questions.bundle-name'),
'default',
function ($bundleName) {
return $this->validator->validateClassName($bundleName);
}
);
$input->setOption('bundle-name', $bundleName);
}
// --bundle-title option
$bundleTitle = $input->getOption('bundle-title');
if (!$bundleTitle) {
$bundleTitle = $this->getIo()->ask(
$this->trans('commands.generate.entity.bundle.questions.bundle-title'),
'default',
function ($bundle_title) {
return $this->validator->validateBundleTitle($bundle_title);
}
);
$input->setOption('bundle-title', $bundleTitle);
}
}
}

View File

@@ -0,0 +1,166 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\EntityCommand.
*/
namespace Drupal\Console\Command\Generate;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Command\Shared\ModuleTrait;
abstract class EntityCommand extends Command
{
use ModuleTrait;
private $entityType;
private $commandName;
/**
* @param $entityType
*/
protected function setEntityType($entityType)
{
$this->entityType = $entityType;
}
/**
* @param $commandName
*/
protected function setCommandName($commandName)
{
$this->commandName = $commandName;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$commandKey = str_replace(':', '.', $this->commandName);
$this
->setName($this->commandName)
->setDescription(
sprintf(
$this->trans('commands.'.$commandKey.'.description'),
$this->entityType
)
)
->setHelp(
sprintf(
$this->trans('commands.'.$commandKey.'.help'),
$this->commandName,
$this->entityType
)
)
->addOption('module', null, InputOption::VALUE_REQUIRED, $this->trans('commands.common.options.module'))
->addOption(
'entity-class',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.'.$commandKey.'.options.entity-class')
)
->addOption(
'entity-name',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.'.$commandKey.'.options.entity-name')
)
->addOption(
'base-path',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.' . $commandKey . '.options.base-path')
)
->addOption(
'label',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.'.$commandKey.'.options.label')
);
}
protected function execute(InputInterface $input, OutputInterface $output)
{
// Operations defined in EntityConfigCommand and EntityContentCommand.
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
$commandKey = str_replace(':', '.', $this->commandName);
$utils = $this->stringConverter;
// --module option
$this->getModuleOption();
// --entity-class option
$entityClass = $input->getOption('entity-class');
if (!$entityClass) {
$entityClass = $this->getIo()->ask(
$this->trans('commands.'.$commandKey.'.questions.entity-class'),
'DefaultEntity',
function ($entityClass) {
return $this->validator->validateSpaces($entityClass);
}
);
$input->setOption('entity-class', $entityClass);
}
// --entity-name option
$entityName = $input->getOption('entity-name');
if (!$entityName) {
$entityName = $this->getIo()->ask(
$this->trans('commands.'.$commandKey.'.questions.entity-name'),
$utils->camelCaseToMachineName($entityClass),
function ($entityName) {
return $this->validator->validateMachineName($entityName);
}
);
$input->setOption('entity-name', $entityName);
}
// --label option
$label = $input->getOption('label');
if (!$label) {
$label = $this->getIo()->ask(
$this->trans('commands.'.$commandKey.'.questions.label'),
$utils->camelCaseToHuman($entityClass)
);
$input->setOption('label', $label);
}
// --base-path option
$base_path = $input->getOption('base-path');
if (!$base_path) {
$base_path = $this->getDefaultBasePath();
}
$base_path = $this->getIo()->ask(
$this->trans('commands.'.$commandKey.'.questions.base-path'),
$base_path
);
if (substr($base_path, 0, 1) !== '/') {
// Base path must start with a leading '/'.
$base_path = '/' . $base_path;
}
$input->setOption('base-path', $base_path);
}
/**
* Gets default base path.
*
* @return string
* Default base path.
*/
protected function getDefaultBasePath()
{
return '/admin/structure';
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\EntityConfigCommand.
*/
namespace Drupal\Console\Command\Generate;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Generator\EntityConfigGenerator;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Utils\Validator;
use Drupal\Console\Core\Utils\StringConverter;
class EntityConfigCommand extends EntityCommand
{
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var EntityConfigGenerator
*/
protected $generator;
/**
* @var Validator
*/
protected $validator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* EntityConfigCommand constructor.
*
* @param Manager $extensionManager
* @param EntityConfigGenerator $generator
* @param Validator $validator
* @param StringConverter $stringConverter
*/
public function __construct(
Manager $extensionManager,
EntityConfigGenerator $generator,
Validator $validator,
StringConverter $stringConverter
) {
$this->extensionManager = $extensionManager;
$this->generator = $generator;
$this->validator = $validator;
$this->stringConverter = $stringConverter;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setEntityType('EntityConfig');
$this->setCommandName('generate:entity:config');
parent::configure();
$this->addOption(
'bundle-of',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.entity.config.options.bundle-of')
)
->setAliases(['gec']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
parent::interact($input, $output);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$module = $this->validateModule($input->getOption('module'));
$entity_class = $input->getOption('entity-class');
$entity_name = $this->validator->validateMachineName($input->getOption('entity-name'));
$label = $input->getOption('label');
$bundle_of = $input->getOption('bundle-of');
$base_path = $input->getOption('base-path');
$this->generator->generate([
'module' => $module,
'entity_name' => $entity_name,
'entity_class' => $entity_class,
'label' => $label,
'base_path' => $base_path,
'bundle_of' => $bundle_of,
]);
}
}

View File

@@ -0,0 +1,234 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\EntityContentCommand.
*/
namespace Drupal\Console\Command\Generate;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Generator\EntityContentGenerator;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Utils\Validator;
class EntityContentCommand extends EntityCommand
{
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* @var EntityContentGenerator
*/
protected $generator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var Validator
*/
protected $validator;
/**
* EntityContentCommand constructor.
*
* @param ChainQueue $chainQueue
* @param EntityContentGenerator $generator
* @param StringConverter $stringConverter
* @param Manager $extensionManager
* @param Validator $validator
*/
public function __construct(
ChainQueue $chainQueue,
EntityContentGenerator $generator,
StringConverter $stringConverter,
Manager $extensionManager,
Validator $validator
) {
$this->chainQueue = $chainQueue;
$this->generator = $generator;
$this->stringConverter = $stringConverter;
$this->extensionManager = $extensionManager;
$this->validator = $validator;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this->setEntityType('EntityContent');
$this->setCommandName('generate:entity:content');
parent::configure();
$this->addOption(
'has-bundles',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.entity.content.options.has-bundles')
);
$this->addOption(
'is-translatable',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.entity.content.options.is-translatable')
);
$this->addOption(
'revisionable',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.entity.content.options.revisionable')
);
$this->addOption(
'has-forms',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.entity.content.options.has-forms')
);
$this->addOption(
'has-owner',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.entity.content.options.has-owner')
);
$this->addOption(
'has-bundle-permissions',
null,
InputOption::VALUE_NONE,
$this->trans('commands.generate.entity.content.options.has-bundle-permissions')
);
$this->setAliases(['geco']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
parent::interact($input, $output);
// --bundle-of option
$bundle_of = $input->getOption('has-bundles');
if (!$bundle_of) {
$bundle_of = $this->getIo()->confirm(
$this->trans('commands.generate.entity.content.questions.has-bundles'),
false
);
$input->setOption('has-bundles', $bundle_of);
}
// --is-translatable option
$is_translatable = $this->getIo()->confirm(
$this->trans('commands.generate.entity.content.questions.is-translatable'),
true
);
$input->setOption('is-translatable', $is_translatable);
// --revisionable option
$revisionable = $this->getIo()->confirm(
$this->trans('commands.generate.entity.content.questions.revisionable'),
true
);
$input->setOption('revisionable', $revisionable);
// --has-forms option
$has_forms = $this->getIo()->confirm(
$this->trans('commands.generate.entity.content.questions.has-forms'),
true
);
$input->setOption('has-forms', $has_forms);
// --has-owner option
$has_owner = $this->getIo()->confirm(
$this->trans('commands.generate.entity.content.questions.has-owner'),
true
);
$input->setOption('has-owner', $has_owner);
// --has-bundle-permissions
if($bundle_of){
$has_bundle_permissions = $this->getIo()->confirm(
$this->trans('commands.generate.entity.content.questions.has-bundle-permissions'),
true
);
$input->setOption('has-bundle-permissions', $has_bundle_permissions);
}
else {
$input->setOption('has-bundle-permissions', false);
}
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$module = $this->validateModule($input->getOption('module'));
$entity_class = $input->getOption('entity-class')?:'DefaultEntity';
$entity_name = $this->validator->validateMachineName($input->getOption('entity-name'))?:'default_entity';
$label = $input->getOption('label')?:'Default Entity';
$has_bundles = $input->getOption('has-bundles')?:false;
$base_path = $input->getOption('base-path')?:'/admin/structure';
$learning = $input->getOption('learning')?:false;
$bundle_entity_type = $has_bundles ? $entity_name . '_type' : null;
$is_translatable = $input->getOption('is-translatable');
$revisionable = $input->getOption('revisionable');
$has_forms = $input->getOption('has-forms');
$has_owner = $input->getOption('has-owner');
$has_bundle_permissions = $input->getOption('has-bundle-permissions');
$generator = $this->generator;
$generator->setIo($this->getIo());
//@TODO:
//$generator->setLearning($learning);
$generator->generate([
'module' => $module,
'entity_name' => $entity_name,
'entity_class' => $entity_class,
'label' => $label,
'bundle_entity_type' => $bundle_entity_type,
'base_path' => $base_path,
'is_translatable' => $is_translatable,
'revisionable' => $revisionable,
'has_forms' => $has_forms,
'has_owner' => $has_owner,
'has_bundle_permissions' => $has_bundle_permissions,
]);
if ($has_bundles) {
$this->chainQueue->addCommand(
'generate:entity:config', [
'--module' => $module,
'--entity-class' => $entity_class . 'Type',
'--entity-name' => $entity_name . '_type',
'--label' => $label . ' type',
'--bundle-of' => $entity_name,
'--no-interaction'
]
);
}
}
}

View File

@@ -0,0 +1,208 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\EventSubscriberCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Command\Shared\EventsTrait;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Command\Shared\ServicesTrait;
use Drupal\Console\Core\Command\ContainerAwareCommand;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Extension\Manager;
use Drupal\Console\Generator\EventSubscriberGenerator;
use Drupal\Console\Utils\Validator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class EventSubscriberCommand extends ContainerAwareCommand
{
use EventsTrait;
use ServicesTrait;
use ModuleTrait;
use ConfirmationTrait;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var EventSubscriberGenerator
*/
protected $generator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var Validator
*/
protected $validator;
/**
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* EventSubscriberCommand constructor.
*
* @param Manager $extensionManager
* @param EventSubscriberGenerator $generator
* @param StringConverter $stringConverter
* @param Validator $validator
* @param EventDispatcherInterface $eventDispatcher
* @param ChainQueue $chainQueue
*/
public function __construct(
Manager $extensionManager,
EventSubscriberGenerator $generator,
StringConverter $stringConverter,
Validator $validator,
EventDispatcherInterface $eventDispatcher,
ChainQueue $chainQueue
) {
$this->extensionManager = $extensionManager;
$this->generator = $generator;
$this->stringConverter = $stringConverter;
$this->validator = $validator;
$this->eventDispatcher = $eventDispatcher;
$this->chainQueue = $chainQueue;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('generate:event:subscriber')
->setDescription($this->trans('commands.generate.event.subscriber.description'))
->setHelp($this->trans('commands.generate.event.subscriber.description'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'name',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.event.subscriber.options.name')
)
->addOption(
'class',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.event.subscriber.options.class')
)
->addOption(
'events',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.common.options.events')
)
->addOption(
'services',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.common.options.services')
)
->setAliases(['ges']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$name = $input->getOption('name');
$class = $this->validator->validateClassName($input->getOption('class'));
$events = $input->getOption('events');
$services = $input->getOption('services');
// @see Drupal\Console\Command\Shared\ServicesTrait::buildServices
$buildServices = $this->buildServices($services);
$this->generator->generate([
'module' => $module,
'name' => $name,
'class' => $class,
'events' => $events,
'services' => $buildServices,
]);
$this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']);
}
/**
* {@inheritdoc}
*/
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$module = $this->getModuleOption();
// --service-name option
$name = $input->getOption('name');
if (!$name) {
$name = $this->getIo()->ask(
$this->trans('commands.generate.service.questions.service-name'),
sprintf('%s.default', $module)
);
$input->setOption('name', $name);
}
// --class option
$class = $input->getOption('class');
if (!$class) {
$class = $this->getIo()->ask(
$this->trans('commands.generate.event.subscriber.questions.class'),
'DefaultSubscriber',
function ($class) {
return $this->validator->validateClassName($class);
}
);
$input->setOption('class', $class);
}
// --events option
$events = $input->getOption('events');
if (!$events) {
// @see Drupal\Console\Command\Shared\ServicesTrait::servicesQuestion
$events = $this->eventsQuestion();
$input->setOption('events', $events);
}
// --services option
$services = $input->getOption('services');
if (!$services) {
// @see Drupal\Console\Command\Shared\ServicesTrait::servicesQuestion
$services = $this->servicesQuestion();
$input->setOption('services', $services);
}
}
}

View File

@@ -0,0 +1,286 @@
<?php
/**
* @file
* Contains \Drupal\Console\Command\Generate\FormAlterCommand.
*/
namespace Drupal\Console\Command\Generate;
use Drupal\Console\Command\Shared\ArrayInputTrait;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Drupal\Console\Generator\FormAlterGenerator;
use Drupal\Console\Command\Shared\ModuleTrait;
use Drupal\Console\Command\Shared\FormTrait;
use Drupal\Console\Command\Shared\ConfirmationTrait;
use Drupal\Console\Core\Command\Command;
use Drupal\Console\Core\Utils\StringConverter;
use Drupal\Console\Extension\Manager;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\ElementInfoManager;
use Drupal\Console\Utils\Validator;
use Drupal\Core\Routing\RouteProviderInterface;
use Drupal\Console\Core\Utils\ChainQueue;
use Drupal\webprofiler\Profiler\Profiler;
class FormAlterCommand extends Command
{
use ConfirmationTrait;
use ArrayInputTrait;
use FormTrait;
use ModuleTrait;
/**
* @var Manager
*/
protected $extensionManager;
/**
* @var FormAlterGenerator
*/
protected $generator;
/**
* @var StringConverter
*/
protected $stringConverter;
/**
* @var ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* @var ElementInfoManager
*/
protected $elementInfoManager;
/**
* @var Validator
*/
protected $validator;
/**
* @var RouteProviderInterface
*/
protected $routeProvider;
/**
* @var Profiler
*/
protected $profiler;
/**
* @var string
*/
protected $appRoot;
/**
* @var ChainQueue
*/
protected $chainQueue;
/**
* FormAlterCommand constructor.
*
* @param Manager $extensionManager
* @param FormAlterGenerator $generator
* @param StringConverter $stringConverter
* @param ModuleHandlerInterface $moduleHandler
* @param ElementInfoManager $elementInfoManager
* @param Profiler $profiler
* @param $appRoot
* @param ChainQueue $chainQueue
*/
public function __construct(
Manager $extensionManager,
FormAlterGenerator $generator,
StringConverter $stringConverter,
ModuleHandlerInterface $moduleHandler,
ElementInfoManager $elementInfoManager,
Profiler $profiler = null,
$appRoot,
ChainQueue $chainQueue,
Validator $validator
) {
$this->extensionManager = $extensionManager;
$this->generator = $generator;
$this->stringConverter = $stringConverter;
$this->moduleHandler = $moduleHandler;
$this->elementInfoManager = $elementInfoManager;
$this->profiler = $profiler;
$this->appRoot = $appRoot;
$this->chainQueue = $chainQueue;
$this->validator = $validator;
parent::__construct();
}
protected $metadata = [
'class' => [],
'method'=> [],
'file'=> [],
'unset' => []
];
protected function configure()
{
$this
->setName('generate:form:alter')
->setDescription($this->trans('commands.generate.form.alter.description'))
->setHelp($this->trans('commands.generate.form.alter.help'))
->addOption(
'module',
null,
InputOption::VALUE_REQUIRED,
$this->trans('commands.common.options.module')
)
->addOption(
'form-id',
null,
InputOption::VALUE_OPTIONAL,
$this->trans('commands.generate.form.alter.options.form-id')
)
->addOption(
'inputs',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
$this->trans('commands.common.options.inputs')
)
->setAliases(['gfa']);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
// @see use Drupal\Console\Command\Shared\ConfirmationTrait::confirmOperation
if (!$this->confirmOperation()) {
return 1;
}
$module = $this->validateModule($input->getOption('module'));
$formId = $input->getOption('form-id');
$inputs = $input->getOption('inputs');
$noInteraction = $input->getOption('no-interaction');
// Parse nested data.
if ($noInteraction) {
$inputs = $this->explodeInlineArray($inputs);
}
$function = $module . '_form_' . $formId . '_alter';
if ($this->extensionManager->validateModuleFunctionExist($module, $function)) {
throw new \Exception(
sprintf(
$this->trans('commands.generate.form.alter.messages.help-already-implemented'),
$module
)
);
}
$this->generator->generate([
'module' => $module,
'form_id' => $formId,
'inputs' => $inputs,
'metadata' => $this->metadata,
]);
$this->chainQueue->addCommand('cache:rebuild', ['cache' => 'discovery']);
return 0;
}
protected function interact(InputInterface $input, OutputInterface $output)
{
// --module option
$this->getModuleOption();
// --form-id option
$formId = $input->getOption('form-id');
if (!$formId) {
$forms = [];
// Get form ids from webprofiler
if ($this->moduleHandler->moduleExists('webprofiler')) {
$this->getIo()->info(
$this->trans('commands.generate.form.alter.messages.loading-forms')
);
$forms = $this->getWebprofilerForms();
}
if (!empty($forms)) {
$formId = $this->getIo()->choiceNoList(
$this->trans('commands.generate.form.alter.questions.form-id'),
array_keys($forms)
);
}
}
if ($this->moduleHandler->moduleExists('webprofiler') && isset($forms[$formId])) {
$this->metadata['class'] = $forms[$formId]['class']['class'];
$this->metadata['method'] = $forms[$formId]['class']['method'];
$this->metadata['file'] = str_replace(
$this->appRoot,
'',
$forms[$formId]['class']['file']
);
foreach ($forms[$formId]['form'] as $itemKey => $item) {
if ($item['#type'] == 'hidden') {
unset($forms[$formId]['form'][$itemKey]);
}
}
unset($forms[$formId]['form']['form_build_id']);
unset($forms[$formId]['form']['form_token']);
unset($forms[$formId]['form']['form_id']);
unset($forms[$formId]['form']['actions']);
$formItems = array_keys($forms[$formId]['form']);
$formItemsToHide = $this->getIo()->choice(
$this->trans('commands.generate.form.alter.messages.hide-form-elements'),
$formItems,
null,
true
);
$this->metadata['unset'] = array_filter(array_map('trim', $formItemsToHide));
}
$input->setOption('form-id', $formId);
// @see Drupal\Console\Command\Shared\FormTrait::formQuestion
$inputs = $input->getOption('inputs');
if (empty($inputs)) {
$this->getIo()->writeln($this->trans('commands.generate.form.alter.messages.inputs'));
$inputs = $this->formQuestion();
} else {
$inputs= $this->explodeInlineArray($inputs);
}
$input->setOption('inputs', $inputs);
}
public function getWebprofilerForms()
{
$tokens = $this->profiler->find(null, null, 1000, null, '', '');
$forms = [];
foreach ($tokens as $token) {
$token = [$token['token']];
$profile = $this->profiler->loadProfile($token);
$formCollector = $profile->getCollector('forms');
$collectedForms = $formCollector->getForms();
if (empty($forms)) {
$forms = $collectedForms;
} elseif (!empty($collectedForms)) {
$forms = array_merge($forms, $collectedForms);
}
}
return $forms;
}
}

Some files were not shown because too many files have changed in this diff Show More