├── .gitignore ├── .php_cs ├── README.md ├── composer.json ├── config ├── aliases.yml ├── chain │ ├── develop-contribute.yml │ ├── quick-start.yml │ └── site-new.yml ├── config.yml ├── drush.yml ├── mappings.yml ├── phpcheck.yml ├── router.php └── site.mode.yml ├── dist ├── chain │ ├── build-install.yml │ ├── build.yml │ ├── create-data.yml │ ├── form-sample.yml │ ├── sample.yml │ ├── site-install-placeholers-env.yml │ ├── site-install-placeholers.yml │ ├── site-install.yml │ ├── site-update.yml │ ├── update-command-data.yml │ └── update-gitbook.yml ├── defaults.yml └── sites │ ├── docker.yml │ ├── local.yml │ ├── ssh.yml │ └── vagrant.yml ├── phpqa.yml ├── services.yml ├── src ├── Application.php ├── Bootstrap │ ├── DrupalConsoleCore.php │ └── DrupalInterface.php ├── Command │ ├── AboutCommand.php │ ├── Chain │ │ ├── BaseCommand.php │ │ ├── ChainCommand.php │ │ └── ChainCustomCommand.php │ ├── CheckCommand.php │ ├── Command.php │ ├── CompleteCommand.php │ ├── ContainerAwareCommand.php │ ├── Debug │ │ ├── ChainCommand.php │ │ ├── SettingsCommand.php │ │ └── SiteCommand.php │ ├── DrushCommand.php │ ├── Exclude │ │ ├── DrupliconCommand.php │ │ └── ElephpantCommand.php │ ├── Exec │ │ └── ExecCommand.php │ ├── Generate │ │ └── SiteAliasCommand.php │ ├── GenerateCommand.php │ ├── HelpCommand.php │ ├── InitCommand.php │ ├── ListCommand.php │ ├── Settings │ │ └── SetCommand.php │ └── Shared │ │ ├── CommandTrait.php │ │ ├── ContainerAwareCommandTrait.php │ │ └── InputTrait.php ├── Descriptor │ └── TextDescriptor.php ├── EventSubscriber │ ├── CallCommandListener.php │ ├── DefaultValueEventListener.php │ ├── MaintenanceModeListener.php │ ├── RemoveMessagesListener.php │ ├── SaveStatisticsListener.php │ ├── SendStatisticsListener.php │ ├── ShowGenerateChainListener.php │ ├── ShowGenerateCountCodeLinesListener.php │ ├── ShowGenerateInlineListener.php │ ├── ShowGeneratedFilesListener.php │ ├── ShowTipsListener.php │ ├── ShowWelcomeMessageListener.php │ └── ValidateExecutionListener.php ├── Generator │ ├── Generator.php │ ├── GeneratorInterface.php │ ├── InitGenerator.php │ └── SiteAliasGenerator.php ├── Helper │ ├── DescriptorHelper.php │ └── DrupalChoiceQuestionHelper.php ├── Style │ └── DrupalStyle.php ├── Utils │ ├── ArgvInputReader.php │ ├── ChainDiscovery.php │ ├── ChainQueue.php │ ├── ConfigurationManager.php │ ├── CountCodeLines.php │ ├── DrupalFinder.php │ ├── FileQueue.php │ ├── KeyValueStorage.php │ ├── MessageManager.php │ ├── NestedArray.php │ ├── RequirementChecker.php │ ├── ShellProcess.php │ ├── ShowFile.php │ ├── StringConverter.php │ ├── TranslatorManager.php │ ├── TranslatorManagerInterface.php │ └── TwigRenderer.php └── functions.php └── templates └── core ├── autocomplete ├── console.fish.twig └── console.rc.twig ├── druplicon ├── 1.twig └── 2.twig ├── elephpant ├── 1.twig ├── 2.twig ├── 3.twig └── 4.twig ├── init ├── config.yml.twig └── statistics.config.yml.twig └── sites └── alias.yml.twig /.gitignore: -------------------------------------------------------------------------------- 1 | # deprecation-detector 2 | /.rules 3 | 4 | # Composer 5 | composer.lock 6 | /vendor 7 | /bin/phpunit 8 | /bin/jsonlint 9 | /bin/phpcbf 10 | /bin/phpcs 11 | /bin/validate-json 12 | /bin/pdepend 13 | /bin/php-cs-fixer 14 | /bin/phpmd 15 | 16 | # Binaries 17 | /box.phar 18 | /console.phar 19 | /drupal.phar 20 | /drupal.phar.version 21 | 22 | # Test 23 | /phpunit.xml 24 | 25 | # Drupal 26 | /core 27 | -------------------------------------------------------------------------------- /.php_cs: -------------------------------------------------------------------------------- 1 | setRules( 5 | [ 6 | '@PSR2' => true, 7 | 'array_syntax' => ['syntax' => 'short'], 8 | ] 9 | ) 10 | ->setUsingCache(false); 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Drupal Console Core 2 | 3 | Drupal Console Core, this project contains commands and features to be shared across DrupalConsole projects. 4 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "drupal/console-core", 3 | "description": "Drupal Console Core", 4 | "keywords": [ 5 | "Drupal", 6 | "Console", 7 | "Development", 8 | "Symfony" 9 | ], 10 | "homepage": "http://drupalconsole.com/", 11 | "type": "library", 12 | "license": "GPL-2.0-or-later", 13 | "authors": [ 14 | { 15 | "name": "David Flores", 16 | "email": "dmousex@gmail.com", 17 | "homepage": "http://dmouse.net" 18 | }, 19 | { 20 | "name": "Jesus Manuel Olivas", 21 | "email": "jesus.olivas@gmail.com", 22 | "homepage": "http://jmolivas.com" 23 | }, 24 | { 25 | "name": "Eduardo Garcia", 26 | "email": "enzo@enzolutions.com", 27 | "homepage": "http://enzolutions.com/" 28 | }, 29 | { 30 | "name": "Omar Aguirre", 31 | "email": "omersguchigu@gmail.com" 32 | }, 33 | { 34 | "name": "Drupal Console Contributors", 35 | "homepage": "https://github.com/hechoendrupal/DrupalConsole/graphs/contributors" 36 | } 37 | ], 38 | "support": { 39 | "issues": "https://github.com/hechoendrupal/DrupalConsole/issues", 40 | "forum": "https://gitter.im/hechoendrupal/DrupalConsole", 41 | "docs": "http://docs.drupalconsole.com/" 42 | }, 43 | "require": { 44 | "php": ">=7.0.8", 45 | "dflydev/dot-access-configuration": "^1.0.4", 46 | "drupal/console-en": "1.9.7", 47 | "stecman/symfony-console-completion": "~0.7", 48 | "symfony/config": "~3.0|^4.4", 49 | "symfony/console": "~3.0|^4.4", 50 | "symfony/debug": "~3.0|^4.4", 51 | "symfony/dependency-injection": "~3.0|^4.4", 52 | "symfony/event-dispatcher": "~3.0|^4.4", 53 | "symfony/filesystem": "^4.4.9 || ^5 || ^6", 54 | "symfony/finder": "^4.4.9 || ^5 || ^6", 55 | "symfony/process": "~3.0|^4.4", 56 | "symfony/translation": "~3.0|^4.4", 57 | "symfony/yaml": "~3.0|^4.4", 58 | "twig/twig": "^2.15.3|^3.4.3", 59 | "webflo/drupal-finder": "^1.0", 60 | "webmozart/path-util": "^2.3", 61 | "guzzlehttp/guzzle": "^6.5.8|^7.4.5" 62 | }, 63 | "minimum-stability": "dev", 64 | "prefer-stable": true, 65 | "autoload": { 66 | "files": [ 67 | "src/functions.php" 68 | ], 69 | "psr-4": { 70 | "Drupal\\Console\\Core\\": "src" 71 | } 72 | }, 73 | "repositories": { 74 | "dot-access-configuration": { 75 | "url": "https://github.com/LOBsTerr/dflydev-dot-access-configuration.git", 76 | "type": "git" 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /config/aliases.yml: -------------------------------------------------------------------------------- 1 | aliases: 2 | debug:container: 3 | - cod 4 | config:edit: 5 | - cdit 6 | cron:execute: 7 | - cre 8 | database:connect: 9 | - sqlc 10 | database:query: 11 | - sqlq 12 | debug:database:log: 13 | - ws 14 | debug:multisite: 15 | - msd 16 | debug:router: 17 | - rod 18 | debug:theme: 19 | - tde 20 | debug:update: 21 | - upd 22 | multisite:new: 23 | - sn 24 | router:rebuild: 25 | - ror 26 | site:status: 27 | - st 28 | user:login:clear:attempts: 29 | - uslca 30 | user:login:url: 31 | - usli 32 | - uli 33 | user:password:hash: 34 | - usph 35 | user:password:reset: 36 | - upsr 37 | views:disable: 38 | - vdi 39 | cache:rebuild: 40 | - cc 41 | update:execute: 42 | - updb 43 | server: 44 | - rs 45 | -------------------------------------------------------------------------------- /config/chain/develop-contribute.yml: -------------------------------------------------------------------------------- 1 | # How to use 2 | # develop:contribute --drupal=/path/to/drupal-directory --code=/path/to/code-directory 3 | command: 4 | name: develop:contribute 5 | description: 'Download Drupal + Drupal Console to contribute.' 6 | vars: 7 | repository: drupal/recommended-project:9.x-dev 8 | commands: 9 | - command: exec 10 | arguments: 11 | bin: composer create-project {{repository}} {{drupal}} --prefer-dist --no-progress --no-interaction --no-install 12 | - command: exec 13 | arguments: 14 | bin: composer require drupal/features drupal/console-develop --dev --working-dir={{drupal}} --no-update 15 | - command: exec 16 | arguments: 17 | bin: composer install --working-dir={{drupal}} 18 | - command: exec 19 | arguments: 20 | bin: drupal site:install standard --root={{drupal}} --db-type="sqlite" --no-interaction 21 | - command: exec 22 | arguments: 23 | bin: drupal module:install --root={{drupal}} rest taxonomy locale migrate simpletest breakpoint node views features 24 | - command: exec 25 | arguments: 26 | bin: drupal develop:create:symlinks --root={{drupal}} --code-directory={{code}} 27 | -------------------------------------------------------------------------------- /config/chain/quick-start.yml: -------------------------------------------------------------------------------- 1 | # How to use 2 | # quick:start --directory=/path/to/drupal-project/ 3 | # quick:start --directory=/path/to/drupal-project/ --profile=minimal 4 | # quick:start --repository=weknowinc/drupal-project --directory=/path/to/drupal-project/ --profile=standard 5 | command: 6 | name: quick:start 7 | description: 'Download, install and serve a new Drupal project' 8 | vars: 9 | repository: 10 | - weknowinc/drupal-project 11 | - drupal/recommended-project:9.x-dev 12 | - acquia/lightning-project 13 | - acquia/reservoir-project 14 | profile: standard 15 | commands: 16 | # Create Drupal project using DrupalComposer 17 | - command: exec 18 | arguments: 19 | bin: composer create-project {{repository}} {{directory}} --prefer-dist --no-progress --no-interaction 20 | # Install Drupal 21 | - command: exec 22 | arguments: 23 | bin: drupal site:install {{profile}} --root={{directory}} --db-type="sqlite" --no-interaction 24 | # Start PHP built-in server 25 | - command: exec 26 | arguments: 27 | bin: drupal server --root={{directory}} 28 | -------------------------------------------------------------------------------- /config/chain/site-new.yml: -------------------------------------------------------------------------------- 1 | # How to use 2 | # site:new --directory=/path/to/drupal-project/ 3 | # site:new --repository=weknowinc/drupal-project --directory=/path/to/drupal-project/ 4 | command: 5 | name: site:new 6 | description: 'Download a new Drupal project' 7 | vars: 8 | repository: 9 | - weknowinc/drupal-project 10 | - drupal/recommended-project:9.x-dev 11 | - acquia/lightning-project 12 | - acquia/reservoir-project 13 | - drupal/drupal 14 | commands: 15 | # Create Drupal project using Composer 16 | - command: exec 17 | arguments: 18 | bin: composer create-project {{repository}} {{directory}} --stability dev --prefer-dist --no-progress --no-interaction 19 | -------------------------------------------------------------------------------- /config/config.yml: -------------------------------------------------------------------------------- 1 | application: 2 | statistics: 3 | enabled: false 4 | last-attempted: ~ 5 | times-attempted: 0 6 | language: 'en' 7 | autowire: 8 | commands: 9 | forced: 10 | _completion: 11 | class: '\Stecman\Component\Symfony\Console\BashCompletion\CompletionCommand' 12 | name: 13 | elephpant: 14 | class: '\Drupal\Console\Core\Command\Exclude\ElephpantCommand' 15 | arguments: ['@app.root', '@console.renderer', '@console.configuration_manager'] 16 | druplicon: 17 | class: '\Drupal\Console\Core\Command\Exclude\DrupliconCommand' 18 | arguments: ['@app.root', '@console.renderer', '@console.configuration_manager'] 19 | commands: 20 | aliases: ~ 21 | defaults: ~ 22 | mappings: ~ 23 | languages: 24 | ar: 'العَرَبِيَّة‎' 25 | en: 'English' 26 | es: 'Español' 27 | ca: 'Català' 28 | fa-ir: 'فارسی' 29 | fr: 'Français' 30 | ko: '한국어' 31 | he: 'בעברית' 32 | hi: 'हिन्दी' 33 | hu: 'Magyar' 34 | id: 'Bahasa Indonesia' 35 | ja: '日本語' 36 | mr: 'मराठी' 37 | pa: 'ਪੰਜਾਬੀ' 38 | pt-br: 'Português' 39 | ro: 'Romanian' 40 | ru: 'pусский язык' 41 | tl: 'Tagalog' 42 | vn: 'Tiếng Việt' 43 | ua: 'українська' 44 | ur: 'اُردُو' 45 | zh-hans: '简体中文' 46 | zh-hant: '繁體中文' 47 | -------------------------------------------------------------------------------- /config/drush.yml: -------------------------------------------------------------------------------- 1 | commands: 2 | config: 3 | config-delete: 'config:delete' 4 | config-edit: 'config:edit' 5 | config-export: 'config:export' 6 | config-get: 'debug:config CONFIG_NAME' 7 | config-import: 'config:import' 8 | config-list: 'debug:config' 9 | config-pull: ~ 10 | config-set: 'config:override' 11 | core: 12 | archive-dump: ~ 13 | archive-restore: ~ 14 | core-cli: 'shell' 15 | core-config: ~ 16 | core-cron: 'cron:execute' 17 | core-execute: 'exec' 18 | core-init: 'init' 19 | core-quick-drupal: 'quick:start' 20 | core-requirements: 'site:status' 21 | core-rsync: ~ 22 | core-status: 'site:status' 23 | core-topic: ~ 24 | drupal-directory: ~ 25 | entity-updates: 'update:entities' 26 | help: 'help' 27 | image-derive: ~ 28 | image-flush: 'image:styles:flush' 29 | php-eval: ~ 30 | php-script: ~ 31 | queue-list: 'debug:queue' 32 | queue-run: 'queue:run' 33 | shell-alias: ~ 34 | site-alias: 'debug:site' 35 | site-install: 'site:install' 36 | site-set: ~ 37 | site-ssh: ~ 38 | twig-compile: ~ 39 | updatedb: 'update:execute' 40 | updatedb-status: 'debug:update' 41 | version: '--version' 42 | field: 43 | field-clone: ~ 44 | field-create: ~ 45 | field-delete: ~ 46 | field-info: 'field:info' 47 | field-update: ~ 48 | language: 49 | language-add: 'locale:language:add' 50 | language-disable: 'locale:language:delete' 51 | make: 52 | make: ~ 53 | make-convert: ~ 54 | make-generate: ~ 55 | make-lock: ~ 56 | make-update: ~ 57 | other: 58 | registry-rebuild: 'cache:rebuild all' 59 | pm: 60 | pm-disable: 'module:uninstall, theme:uninstall' 61 | pm-download: 'module:download, theme:download' 62 | pm-enable: 'module:install, theme:install' 63 | pm-info: ~ 64 | pm-list: 'debug:module, debug:theme' 65 | pm-projectinfo: ~ 66 | pm-refresh: ~ 67 | pm-releasenotes: ~ 68 | pm-releases: ~ 69 | pm-uninstall: 'module:uninstall, theme:uninstall' 70 | pm-update: 'module:update, theme:update' 71 | pm-updatecode: ~ 72 | pm-updatestatus: ~ 73 | role: 74 | role-add-perm: ~ 75 | role-create: ~ 76 | role-delete: ~ 77 | role-list: ~ 78 | role-remove-perm: ~ 79 | runserver: 80 | runserver: 'server' 81 | sql: 82 | sql-cli: 'database:client' 83 | sql-connect: 'database:connect' 84 | sql-create: ~ 85 | sql-drop: 'database:drop' 86 | sql-dump: 'database:dump' 87 | sql-query: 'database:query' 88 | sql-sanitize: ~ 89 | sql-sync: ~ 90 | search: 91 | search-index: ~ 92 | search-reindex: ~ 93 | search-status: ~ 94 | site_audit: 95 | cache-clear: 'cache:rebuild' 96 | cache-get: ~ 97 | cache-rebuild: 'cache:rebuild' 98 | cache-set: ~ 99 | state: 100 | state-delete: 'state:delete' 101 | state-get: 'debug:state' 102 | state-set: 'state:override' 103 | user: 104 | user-add-role: 'user:role' 105 | user-block: ~ 106 | user-cancel: ~ 107 | user-create: 'user:create' 108 | user-information: ~ 109 | user-login: 'user:login:url' 110 | user-password: 'user:password:reset' 111 | user-remove-role: 'user:role' 112 | user-unblock: ~ 113 | watchdog: 114 | watchdog-delete: 'database:log:clear' 115 | watchdog-list: 'database:log:poll' 116 | watchdog-show: 'debug:database:log' 117 | -------------------------------------------------------------------------------- /config/mappings.yml: -------------------------------------------------------------------------------- 1 | mappings: 2 | breakpoints:debug: debug:breakpoints 3 | cache:context:debug: debug:cache:context 4 | chain:debug: debug:chain 5 | config:debug: debug:config 6 | config:settings:debug: debug:config:settings 7 | config:validate:debug: debug:config:validate 8 | container:debug: debug:container 9 | cron:debug: debug:cron 10 | database:log:debug: debug:database:log 11 | database:table:debug: debug:database:table 12 | entity:debug: debug:entity 13 | event:debug: debug:event 14 | image:styles:debug: debug:image:styles 15 | libraries:debug: debug:libraries 16 | module:debug: debug:module 17 | multisite:debug: debug:multisite 18 | permission:debug: debug:permission 19 | plugin:debug: debug:plugin 20 | queue:debug: debug:queue 21 | router:debug: debug:router 22 | settings:debug: debug:settings 23 | site:debug: debug:site 24 | state:debug: debug:state 25 | theme:debug: debug:theme 26 | update:debug: debug:update 27 | user:debug: debug:user 28 | views:debug: debug:views 29 | views:plugins:debug: debug:views:plugins 30 | -------------------------------------------------------------------------------- /config/phpcheck.yml: -------------------------------------------------------------------------------- 1 | requirements: 2 | php: 3 | required: 5.5.9 4 | configurations: 5 | required: 6 | - date.timezone: 'America/Tijuana' 7 | - memory_limit: 1024M 8 | recomended: {} 9 | extensions: 10 | required: 11 | - date 12 | - dom 13 | - filter 14 | - gd 15 | - hash 16 | - json 17 | - pcre 18 | - pdo 19 | - session 20 | - SimpleXML 21 | - SPL 22 | - tokenizer 23 | - xml 24 | - curl 25 | recommended: {} 26 | -------------------------------------------------------------------------------- /config/router.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | /* 11 | * This file implements rewrite rules for PHP built-in web server. 12 | * 13 | * See: http://www.php.net/manual/en/features.commandline.webserver.php 14 | * 15 | * If you have custom directory layout, then you have to write your own router 16 | * and pass it as a value to 'router' option of server:run command. 17 | * 18 | * @author: Michał Pipa 19 | * @author: Albert Jessurum 20 | */ 21 | 22 | // Workaround https://bugs.php.net/64566 23 | if (ini_get('auto_prepend_file') && !in_array(realpath(ini_get('auto_prepend_file')), get_included_files(), true)) { 24 | include ini_get('auto_prepend_file'); 25 | } 26 | 27 | if (is_file($_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.$_SERVER['SCRIPT_NAME'])) { 28 | return false; 29 | } 30 | 31 | $_SERVER = array_merge($_SERVER, $_ENV); 32 | $_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'].DIRECTORY_SEPARATOR.'index.php'; 33 | 34 | // Since we are rewriting to index.php, adjust SCRIPT_NAME and PHP_SELF accordingly 35 | $_SERVER['SCRIPT_NAME'] = DIRECTORY_SEPARATOR.'index.php'; 36 | $_SERVER['PHP_SELF'] = DIRECTORY_SEPARATOR.'index.php'; 37 | 38 | require 'index.php'; 39 | -------------------------------------------------------------------------------- /config/site.mode.yml: -------------------------------------------------------------------------------- 1 | configurations: 2 | system.performance: 3 | cache.page.use_internal: 4 | dev: false 5 | prod: true 6 | css.preprocess: 7 | dev: false 8 | prod: true 9 | css.gzip: 10 | dev: false 11 | prod: true 12 | js.preprocess: 13 | dev: false 14 | prod: true 15 | js.gzip: 16 | dev: false 17 | prod: true 18 | response.gzip: 19 | dev: false 20 | prod: true 21 | views.settings: 22 | ui.show.sql_query.enabled: 23 | dev: true 24 | prod: false 25 | ui.show.performance_statistics: 26 | dev: true 27 | prod: false 28 | system.logging: 29 | error_level: 30 | dev: all 31 | prod: none 32 | services: 33 | http.response.debug_cacheability_headers: 34 | dev: true 35 | prod: false 36 | twig.config: 37 | debug: 38 | dev: true 39 | prod: false 40 | auto_reload: 41 | dev: true 42 | prod: false 43 | cache: 44 | dev: false 45 | prod: true 46 | -------------------------------------------------------------------------------- /dist/chain/build-install.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: build:install 3 | description: 'Build site by installing and importing configuration' 4 | commands: 5 | # Install site 6 | - command: site:install 7 | options: 8 | force: true 9 | no-interaction: true 10 | arguments: 11 | profile: standard 12 | # Import configuration 13 | - command: build 14 | -------------------------------------------------------------------------------- /dist/chain/build.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: build 3 | description: 'Build site' 4 | commands: 5 | # Import configuration 6 | - command: config:import 7 | # Rebuild caches. 8 | - command: cache:rebuild 9 | arguments: 10 | cache: all 11 | -------------------------------------------------------------------------------- /dist/chain/create-data.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: create:data 3 | description: 'Create dummy data' 4 | commands: 5 | # Create dummy data 6 | - command: create:users 7 | options: 8 | limit: 5 9 | - command: create:vocabularies 10 | options: 11 | limit: 5 12 | name-words: 5 13 | learning: true 14 | - command: create:terms 15 | - command: create:nodes 16 | options: 17 | limit: 50 18 | -------------------------------------------------------------------------------- /dist/chain/form-sample.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: generate:example:form 3 | description: 'Generate form example' 4 | commands: 5 | - command: generate:form:config 6 | options: 7 | module: example 8 | class: ConfigForm 9 | form-id: config_form 10 | services: 11 | - state 12 | inputs: 13 | - name: email 14 | type: email 15 | label: Email 16 | description: 'Enter a valid email.' 17 | fieldset: '' 18 | - name: api_key 19 | type: textfield 20 | label: 'API Key' 21 | description: 'Enter API Key' 22 | maxlength: '64' 23 | size: '64' 24 | - name: number_field 25 | type: number 26 | label: 'Number field' 27 | description: 'Enter a valid number.' 28 | - name: big_text 29 | type: textarea 30 | label: 'Big text' 31 | description: 'Enter a big text, you can user key' 32 | path: '/admin/config/form' 33 | menu_link_gen: true 34 | menu_link_title: 'Example Config Form' 35 | menu_parent: system.admin_config_system 36 | menu_link_desc: 'A Example Config Form.' 37 | # Rebuild routes 38 | - command: router:rebuild 39 | -------------------------------------------------------------------------------- /dist/chain/sample.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: generate:example:module 3 | description: 'Generate example module' 4 | commands: 5 | - command: generate:module 6 | options: 7 | module: Example module 8 | machine-name: example 9 | module-path: /modules/custom/ 10 | description: My example module 11 | core: 8.x 12 | package: Custom 13 | dependencies: 14 | - command: generate:controller 15 | options: 16 | module: example 17 | class: HelloWorldController 18 | routes: 19 | - title: 'Hello World' 20 | name: 'example.hello_name' 21 | method: hello 22 | path: '/example/hello/{name}' 23 | services: 24 | - entity_field.manager 25 | - theme_handler 26 | - config.factory 27 | test: true 28 | - command: generate:form:config 29 | options: 30 | module: example 31 | class: SettingsForm 32 | form-id: settings_form 33 | inputs: 34 | - name: foo_field 35 | type: textfield 36 | label: 'Foo field' 37 | options: '' 38 | description: '' 39 | maxlength: '64' 40 | size: '64' 41 | default_value: '' 42 | weight: '0' 43 | fieldset: '' 44 | - name: bar_number 45 | type: number 46 | label: 'Bar number' 47 | options: '' 48 | description: '' 49 | maxlength: null 50 | size: null 51 | default_value: '' 52 | weight: '0' 53 | fieldset: '' 54 | path: '/admin/setting/form' 55 | menu_link_gen: true 56 | menu_link_title: SettingsForm 57 | menu_parent: system.admin_config_system 58 | menu_link_desc: 'A description for the menu entry' 59 | - command: generate:entity:content 60 | options: 61 | module: example 62 | entity-class: Foo 63 | entity-name: foo 64 | label: Foo 65 | - command: generate:entity:config 66 | options: 67 | module: example 68 | entity-class: Bar 69 | entity-name: bar 70 | label: Bar 71 | - command: generate:command 72 | options: 73 | module: example 74 | class: ExampleCommand 75 | name: example:command 76 | container-aware: false 77 | - command: generate:authentication:provider 78 | options: 79 | module: example 80 | class: ExampleAuthenticationProvider 81 | - command: generate:plugin:block 82 | options: 83 | module: example 84 | class: ExampleBlock 85 | label: Example plugin block 86 | plugin-id: example_block 87 | - command: generate:plugin:imageeffect 88 | options: 89 | module: example 90 | class: ExampleImageEffect 91 | plugin-id: example_image_effect 92 | label: Example image effect 93 | description: Example image effect 94 | - command: generate:plugin:rest:resource 95 | options: 96 | module: example 97 | class: ExampleRestResource 98 | plugin-id: example_rest_resource 99 | plugin-label: Example Rest Resource 100 | plugin-url: example_rest_resource 101 | plugin-states: 102 | - GET 103 | - PUT 104 | - POST 105 | - command: generate:service 106 | options: 107 | module: example 108 | class: ExampleService 109 | name: example.service 110 | interface: yes 111 | - command: module:install 112 | arguments: 113 | module: [example] 114 | -------------------------------------------------------------------------------- /dist/chain/site-install-placeholers-env.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: site:install:env 3 | description: 'Install site using environment placeholders' 4 | commands: 5 | # Install Drupal 6 | - command: site:install 7 | options: 8 | langcode: en 9 | db-type: '{{ env("DATABASE_TYPE") }}' 10 | db-host: '{{ env("DATABASE_HOST") }}' 11 | db-name: '{{ env("DATABASE_NAME") }}' 12 | db-user: '{{ env("DATABASE_USER") }}' 13 | db-pass: '{{ env("DATABASE_PASSWORD") }}' 14 | db-port: '{{ env("DATABASE_PORT") }}' 15 | site-name: 'Drupal 8 site' 16 | site-mail: admin@example.org # default email 17 | account-name: admin # default account 18 | account-mail: admin@example.org # default email 19 | account-pass: admin # default pass 20 | arguments: 21 | profile: 'standard' 22 | -------------------------------------------------------------------------------- /dist/chain/site-install-placeholers.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: site:install:inline 3 | description: 'Install site using inline placeholders' 4 | vars: 5 | db_type: mysql 6 | db_host: 127.0.0.1 7 | db_name: drupal 8 | db_port: 3306 9 | commands: 10 | # Install Drupal 11 | - command: site:install 12 | options: 13 | langcode: 'en' 14 | db-type: '{{db_type}}' 15 | db-host: '{{db_host}}' 16 | db-name: '{{db_name}}' 17 | db-user: '{{db_user}}' 18 | db-pass: '{{db_pass}}' 19 | db-port: '{{db_port}}' 20 | site-name: 'Drupal 8 site' 21 | site-mail: 'admin@example.org' # default email 22 | account-name: 'admin' # default account 23 | account-mail: 'admin@example.org' # default email 24 | account-pass: 'admin' # default pass 25 | arguments: 26 | profile: 'standard' 27 | -------------------------------------------------------------------------------- /dist/chain/site-install.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: site:install:sqlite 3 | description: 'Install site using sqlite' 4 | commands: 5 | # Install Drupal 6 | - command: site:install 7 | options: 8 | langcode: en 9 | db-type: sqlite 10 | db-file: sites/default/files/.ht.sqlite 11 | site-name: 'Drupal 8 Quick Start' 12 | site-mail: admin@example.com 13 | account-name: admin 14 | account-mail: admin@example.com 15 | account-pass: admin 16 | arguments: 17 | profile: standard 18 | -------------------------------------------------------------------------------- /dist/chain/site-update.yml: -------------------------------------------------------------------------------- 1 | command: 2 | name: site:update 3 | description: 'Execute update commands' 4 | commands: 5 | # Backup current database 6 | - command: database:dump 7 | arguments: 8 | database: 'default' 9 | # Import configurations 10 | - command: config:import 11 | # Run pending update hooks 12 | - command: update:execute 13 | arguments: 14 | module: 'all' 15 | # Run pending update entities 16 | - command: update:entities 17 | # Rebuild caches 18 | - command: cache:rebuild 19 | arguments: 20 | cache: 'all' 21 | -------------------------------------------------------------------------------- /dist/chain/update-command-data.yml: -------------------------------------------------------------------------------- 1 | # How to use 2 | # update:command:data --directory="/path/to/drupal-project/" 3 | command: 4 | name: update:command:data 5 | description: 'Update gitbook' 6 | commands: 7 | {% set languages = ['en', 'es', 'hi', 'hu', 'pt_br', 'ro', 'vn', 'zh_hans'] %} 8 | {% for language in languages %} 9 | - command: settings:set 10 | arguments: 11 | name: language 12 | value: {{ language }} 13 | - command: generate:doc:data 14 | options: 15 | file: '{{ directory }}/{{ language }}.json' 16 | {% endfor %} 17 | - command: settings:set 18 | arguments: 19 | name: language 20 | value: en 21 | -------------------------------------------------------------------------------- /dist/chain/update-gitbook.yml: -------------------------------------------------------------------------------- 1 | # How to use 2 | # update:gitbook --directory="/path/to/drupal-console/gitbook-repository/" 3 | command: 4 | name: update:gitbook 5 | description: 'Update gitbook' 6 | commands: 7 | - command: 'module:install' 8 | arguments: 9 | module: 10 | - rest 11 | - taxonomy 12 | - locale 13 | - migrate 14 | - simpletest 15 | - breakpoint 16 | - node 17 | - views 18 | - features 19 | - command: 'develop:translation:sync' 20 | {% set languages = ['en', 'ca', 'es', 'hi', 'hu', 'ja', 'mr', 'pt-br', 'ro', 'ru', 'vn' , 'zh-hans'] %} 21 | {% for language in languages %} 22 | - command: settings:set 23 | arguments: 24 | name: language 25 | value: {{ language }} 26 | - command: exec 27 | arguments: 28 | bin: 'rm -Rf {{ directory }}/{{ language }}/commands' 29 | - command: develop:doc:gitbook 30 | options: 31 | path: '{{ directory }}/{{ language }}' 32 | {% endfor %} 33 | - command: settings:set 34 | arguments: 35 | name: language 36 | value: en -------------------------------------------------------------------------------- /dist/defaults.yml: -------------------------------------------------------------------------------- 1 | #defaults: 2 | # cache: 3 | # rebuild: 4 | # arguments: 5 | # cache: all 6 | # config: 7 | # export: 8 | # options: 9 | # remove-uuid: true 10 | # remove-config-hash: true 11 | # generate: 12 | # controller: 13 | # options: 14 | # module: example 15 | -------------------------------------------------------------------------------- /dist/sites/docker.yml: -------------------------------------------------------------------------------- 1 | # Drupal4Docker example 2 | dev: 3 | root: /var/www/html 4 | extra-options: docker-compose exec --user=82 php 5 | type: container 6 | -------------------------------------------------------------------------------- /dist/sites/local.yml: -------------------------------------------------------------------------------- 1 | local: 2 | root: /var/www/drupal8.dev 3 | type: local 4 | -------------------------------------------------------------------------------- /dist/sites/ssh.yml: -------------------------------------------------------------------------------- 1 | dev: 2 | root: /var/www/html/drupal 3 | host: drupal.org 4 | user: drupal 5 | type: ssh 6 | -------------------------------------------------------------------------------- /dist/sites/vagrant.yml: -------------------------------------------------------------------------------- 1 | # DrupalVM Example 2 | dev: 3 | root: /var/www/drupalvm/drupal 4 | host: 192.168.88.88 5 | user: vagrant 6 | extra-options: '-o PasswordAuthentication=no -i ~/.vagrant.d/insecure_private_key' 7 | type: ssh 8 | -------------------------------------------------------------------------------- /phpqa.yml: -------------------------------------------------------------------------------- 1 | application: 2 | method: 3 | git: 4 | enabled: true 5 | exception: false 6 | composer: 7 | enabled: true 8 | exception: false 9 | analyzer: 10 | parallel-lint: 11 | enabled: true 12 | exception: true 13 | options: 14 | e: 'php' 15 | exclude: vendor/ 16 | arguments: 17 | php-cs-fixer: 18 | enabled: true 19 | exception: false 20 | options: 21 | level: psr2 22 | arguments: 23 | prefixes: 24 | - fix 25 | postfixes: 26 | phpcbf: 27 | enabled: true 28 | exception: false 29 | options: 30 | standard: PSR2 31 | severity: 0 32 | ignore: /vendor 33 | arguments: 34 | - '-n' 35 | phpcs: 36 | enabled: false 37 | exception: false 38 | options: 39 | standard: PSR2 40 | severity: 0 41 | ignore: /vendor 42 | arguments: 43 | - '-n' 44 | phpmd: 45 | enabled: false 46 | exception: false 47 | options: 48 | arguments: 49 | prefixes: 50 | postfixes: 51 | - 'text' 52 | - 'cleancode' 53 | phploc: 54 | enabled: false 55 | exception: false 56 | phpcpd: 57 | enabled: false 58 | exception: false 59 | phpdcd: 60 | enabled: false 61 | exception: false 62 | phpunit: 63 | enabled: false 64 | exception: true 65 | file: 66 | configuration: phpunit.xml.dist 67 | single-execution: true 68 | options: 69 | arguments: 70 | -------------------------------------------------------------------------------- /services.yml: -------------------------------------------------------------------------------- 1 | services: 2 | # DrupalConsoleCore Services 3 | console.translator_manager: 4 | class: Drupal\Console\Core\Utils\TranslatorManager 5 | console.configuration_manager: 6 | class: Drupal\Console\Core\Utils\ConfigurationManager 7 | console.requirement_checker: 8 | class: Drupal\Console\Core\Utils\RequirementChecker 9 | console.chain_queue: 10 | class: Drupal\Console\Core\Utils\ChainQueue 11 | console.nested_array: 12 | class: Drupal\Console\Core\Utils\NestedArray 13 | console.show_file: 14 | class: Drupal\Console\Core\Utils\ShowFile 15 | arguments: ['@app.root', '@console.translator_manager'] 16 | console.renderer: 17 | class: Drupal\Console\Core\Utils\TwigRenderer 18 | arguments: ['@console.translator_manager', '@console.string_converter'] 19 | console.file_queue: 20 | class: Drupal\Console\Core\Utils\FileQueue 21 | arguments: ['@app.root'] 22 | console.shell_process: 23 | class: Drupal\Console\Core\Utils\ShellProcess 24 | arguments: ['@app.root', '@console.translator_manager'] 25 | console.string_converter: 26 | class: Drupal\Console\Core\Utils\StringConverter 27 | console.chain_discovery: 28 | class: Drupal\Console\Core\Utils\ChainDiscovery 29 | arguments: ['@console.root', '@console.configuration_manager', '@console.message_manager', '@console.translator_manager'] 30 | console.count_code_lines: 31 | class: Drupal\Console\Core\Utils\CountCodeLines 32 | console.message_manager: 33 | class: Drupal\Console\Core\Utils\MessageManager 34 | console.drupal_finder: 35 | class: Drupal\Console\Core\Utils\DrupalFinder 36 | console.key_value_storage: 37 | class: Drupal\Console\Core\Utils\KeyValueStorage 38 | # DrupalConsoleCore Commands 39 | console.about: 40 | class: Drupal\Console\Core\Command\AboutCommand 41 | tags: 42 | - { name: drupal.command } 43 | console.list: 44 | class: Drupal\Console\Core\Command\ListCommand 45 | tags: 46 | - { name: drupal.command } 47 | console.help: 48 | class: Drupal\Console\Core\Command\HelpCommand 49 | tags: 50 | - { name: drupal.command } 51 | console.complete: 52 | class: Drupal\Console\Core\Command\CompleteCommand 53 | tags: 54 | - { name: drupal.command } 55 | console.check: 56 | class: Drupal\Console\Core\Command\CheckCommand 57 | arguments: ['@console.requirement_checker', '@console.chain_queue', '@console.configuration_manager'] 58 | tags: 59 | - { name: drupal.command } 60 | console.init: 61 | class: Drupal\Console\Core\Command\InitCommand 62 | arguments: ['@console.show_file', '@console.configuration_manager', '@console.init_generator', '@app.root', '@?console.root'] 63 | tags: 64 | - { name: drupal.command } 65 | console.settings_debug: 66 | class: Drupal\Console\Core\Command\Debug\SettingsCommand 67 | arguments: ['@console.configuration_manager'] 68 | tags: 69 | - { name: drupal.command } 70 | console.settings_set: 71 | class: Drupal\Console\Core\Command\Settings\SetCommand 72 | arguments: ['@console.configuration_manager', '@console.nested_array'] 73 | tags: 74 | - { name: drupal.command } 75 | console.exec: 76 | class: Drupal\Console\Core\Command\Exec\ExecCommand 77 | arguments: ['@console.shell_process'] 78 | tags: 79 | - { name: drupal.command } 80 | console.chain: 81 | class: Drupal\Console\Core\Command\Chain\ChainCommand 82 | arguments: ['@console.chain_queue', '@console.chain_discovery'] 83 | tags: 84 | - { name: drupal.command } 85 | console.chain_debug: 86 | class: Drupal\Console\Core\Command\Debug\ChainCommand 87 | arguments: ['@console.chain_discovery'] 88 | tags: 89 | - { name: drupal.command } 90 | console.site_debug: 91 | class: Drupal\Console\Core\Command\Debug\SiteCommand 92 | arguments: ['@console.configuration_manager'] 93 | tags: 94 | - { name: drupal.command } 95 | console.drush: 96 | class: Drupal\Console\Core\Command\DrushCommand 97 | arguments: ['@console.configuration_manager', '@console.chain_queue'] 98 | tags: 99 | - { name: drupal.command } 100 | console.generate_site_alias: 101 | class: Drupal\Console\Core\Command\Generate\SiteAliasCommand 102 | arguments: ['@console.site_alias_generator', '@console.configuration_manager', '@console.drupal_finder'] 103 | tags: 104 | - { name: drupal.command } 105 | # DrupalConsoleCore Generators 106 | console.init_generator: 107 | class: Drupal\Console\Core\Generator\InitGenerator 108 | arguments: ['@console.configuration_manager'] 109 | tags: 110 | - { name: drupal.generator } 111 | console.site_alias_generator: 112 | class: Drupal\Console\Core\Generator\SiteAliasGenerator 113 | tags: 114 | - { name: drupal.generator } 115 | -------------------------------------------------------------------------------- /src/Bootstrap/DrupalConsoleCore.php: -------------------------------------------------------------------------------- 1 | root = $root; 50 | $this->appRoot = $appRoot; 51 | $this->drupalFinder = $drupalFinder; 52 | } 53 | 54 | /** 55 | * @return ContainerBuilder 56 | */ 57 | public function boot() 58 | { 59 | $container = new ContainerBuilder(); 60 | $loader = new YamlFileLoader($container, new FileLocator($this->root)); 61 | 62 | if (substr($this->root, -1) === DIRECTORY_SEPARATOR) { 63 | $this->root = substr($this->root, 0, -1); 64 | } 65 | 66 | $servicesFiles = [ 67 | $this->root.DRUPAL_CONSOLE_CORE.'services.yml', 68 | $this->root.'/services.yml', 69 | $this->root.DRUPAL_CONSOLE.'uninstall.services.yml', 70 | $this->root.DRUPAL_CONSOLE.'extend.console.uninstall.services.yml' 71 | ]; 72 | 73 | foreach ($servicesFiles as $servicesFile) { 74 | if (file_exists($servicesFile)) { 75 | $loader->load($servicesFile); 76 | } 77 | } 78 | 79 | $container->get('console.configuration_manager') 80 | ->loadConfiguration($this->root) 81 | ->getConfiguration(); 82 | 83 | $container->get('console.translator_manager') 84 | ->loadCoreLanguage('en', $this->root); 85 | 86 | $appRoot = $this->appRoot?$this->appRoot:$this->root; 87 | $container->set( 88 | 'app.root', 89 | $appRoot 90 | ); 91 | $consoleRoot = $appRoot; 92 | if (stripos($this->root, '/bin/') <= 0) { 93 | $consoleRoot = $this->root; 94 | } 95 | $container->set( 96 | 'console.root', 97 | $consoleRoot 98 | ); 99 | 100 | $container->set( 101 | 'console.drupal_finder', 102 | $this->drupalFinder 103 | ); 104 | 105 | $configurationManager = $container->get('console.configuration_manager'); 106 | $directory = $configurationManager->getConsoleDirectory() . 'extend/'; 107 | $autoloadFile = $directory . 'vendor/autoload.php'; 108 | if (is_file($autoloadFile)) { 109 | include_once $autoloadFile; 110 | $extendServicesFile = $directory . 'extend.console.uninstall.services.yml'; 111 | if (is_file($extendServicesFile)) { 112 | $loader->load($extendServicesFile); 113 | } 114 | } 115 | 116 | $container->get('console.renderer') 117 | ->setSkeletonDirs( 118 | [ 119 | $this->root.'/templates/', 120 | $this->root.DRUPAL_CONSOLE_CORE.'/templates/' 121 | ] 122 | ); 123 | 124 | return $container; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/Bootstrap/DrupalInterface.php: -------------------------------------------------------------------------------- 1 | setName('about') 28 | ->setDescription($this->trans('commands.about.description')); 29 | } 30 | 31 | /** 32 | * {@inheritdoc} 33 | */ 34 | protected function execute(InputInterface $input, OutputInterface $output) 35 | { 36 | $application = $this->getApplication(); 37 | 38 | $aboutTitle = sprintf( 39 | '%s (%s)', 40 | $application->getName(), 41 | $application->getVersion() 42 | ); 43 | 44 | $this->getIo()->setDecorated(false); 45 | $this->getIo()->title($aboutTitle); 46 | $this->getIo()->setDecorated(true); 47 | 48 | $commands = [ 49 | 'init' => [ 50 | $this->trans('commands.init.description'), 51 | 'drupal init' 52 | ], 53 | 'quick-start' => [ 54 | $this->trans('commands.common.messages.quick-start'), 55 | 'drupal quick:start' 56 | ], 57 | 'site-new' => [ 58 | $this->trans('commands.site.new.description'), 59 | 'drupal site:new' 60 | ], 61 | 'site-install' => [ 62 | $this->trans('commands.site.install.description'), 63 | sprintf( 64 | 'drupal site:install' 65 | ) 66 | ], 67 | 'list' => [ 68 | $this->trans('commands.list.description'), 69 | 'drupal list', 70 | ] 71 | ]; 72 | 73 | foreach ($commands as $command => $commandInfo) { 74 | $this->getIo()->writeln($commandInfo[0]); 75 | $this->getIo()->comment(sprintf(' %s', $commandInfo[1])); 76 | $this->getIo()->newLine(); 77 | } 78 | 79 | $this->getIo()->writeln($this->trans('commands.self-update.description')); 80 | $this->getIo()->comment(' drupal self-update'); 81 | $this->getIo()->newLine(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/Command/Chain/BaseCommand.php: -------------------------------------------------------------------------------- 1 | chainDiscovery = $chainDiscovery; 33 | parent::__construct(); 34 | $this->ignoreValidationErrors(); 35 | } 36 | 37 | protected function initialize( 38 | InputInterface $input, 39 | OutputInterface $output 40 | ) { 41 | parent::initialize($input, $output); 42 | 43 | $options = []; 44 | foreach ($_SERVER['argv'] as $index => $element) { 45 | if ($index<2) { 46 | continue; 47 | } 48 | 49 | if (substr($element, 0, 2) !== "--") { 50 | continue; 51 | } 52 | 53 | $element = substr($element, 2); 54 | $exploded = explode("=", $element); 55 | 56 | if (!$exploded) { 57 | $exploded = explode(" ", $element); 58 | } 59 | 60 | if (count($exploded)>1) { 61 | $options[trim($exploded[0])] = trim($exploded[1]); 62 | } 63 | } 64 | 65 | $file = $input->getOption('file'); 66 | $file = calculateRealPath($file); 67 | $content = $this->chainDiscovery->getFileContents($file); 68 | $variables = $this->chainDiscovery->extractInlinePlaceHolderNames($content); 69 | 70 | foreach ($variables as $variable) { 71 | if (!array_key_exists($variable, $options)) { 72 | $options[$variable] = null; 73 | } 74 | } 75 | 76 | foreach ($options as $optionName => $optionValue) { 77 | if ($input->hasOption($optionName)) { 78 | continue; 79 | } 80 | 81 | $this->addOption( 82 | $optionName, 83 | null, 84 | InputOption::VALUE_OPTIONAL, 85 | $optionName, 86 | $optionValue 87 | ); 88 | } 89 | } 90 | 91 | protected function getFileOption() 92 | { 93 | $input = $this->getIo()->getInput(); 94 | $file = $input->getOption('file'); 95 | 96 | if (!$file) { 97 | $files = array_keys($this->chainDiscovery->getFiles()); 98 | 99 | $file = $this->getIo()->choice( 100 | $this->trans('commands.chain.questions.chain-file'), 101 | $files 102 | ); 103 | } 104 | 105 | $file = calculateRealPath($file); 106 | $input->setOption('file', $file); 107 | 108 | return $file; 109 | } 110 | 111 | protected function getOptionsAsArray() 112 | { 113 | $input = $this->getIo()->getInput(); 114 | $options = []; 115 | foreach ($input->getOptions() as $option => $value) { 116 | $options[$option] = $value; 117 | } 118 | 119 | return $options; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/Command/Chain/ChainCustomCommand.php: -------------------------------------------------------------------------------- 1 | name = $name; 55 | $this->description = $description; 56 | $this->file = $file; 57 | 58 | parent::__construct($chainDiscovery); 59 | $this->ignoreValidationErrors(); 60 | 61 | $this->addOption( 62 | 'file', 63 | null, 64 | InputOption::VALUE_OPTIONAL, 65 | "File", 66 | $file 67 | ); 68 | } 69 | 70 | /** 71 | * {@inheritdoc} 72 | */ 73 | protected function configure() 74 | { 75 | $this 76 | ->setName($this->name) 77 | ->setDescription($this->description); 78 | } 79 | 80 | /** 81 | * {@inheritdoc} 82 | */ 83 | protected function execute(InputInterface $input, OutputInterface $output) 84 | { 85 | $command = $this->getApplication()->find('chain'); 86 | 87 | $arguments = [ 88 | 'command' => 'chain', 89 | '--file' => $this->file, 90 | ]; 91 | 92 | foreach ($input->getOptions() as $option => $value) { 93 | if ($value) { 94 | $arguments['--' . $option] = $value; 95 | } 96 | } 97 | 98 | $commandInput = new ArrayInput($arguments); 99 | $commandInput->setInteractive(true); 100 | 101 | return $command->run($commandInput, $output); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/Command/CheckCommand.php: -------------------------------------------------------------------------------- 1 | requirementChecker = $requirementChecker; 51 | $this->chainQueue = $chainQueue; 52 | $this->configurationManager = $configurationManager; 53 | 54 | parent::__construct(); 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | protected function configure() 61 | { 62 | $this 63 | ->setName('check') 64 | ->setDescription($this->trans('commands.check.description')); 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | protected function execute(InputInterface $input, OutputInterface $output) 71 | { 72 | $checks = $this->requirementChecker->getCheckResult(); 73 | if (!$checks) { 74 | $phpCheckFile = $this->configurationManager 75 | ->getVendorCoreDirectory() . 'phpcheck.yml'; 76 | 77 | $checks = $this->requirementChecker->validate($phpCheckFile); 78 | } 79 | 80 | if (!$checks['php']['valid']) { 81 | $this->getIo()->error( 82 | sprintf( 83 | $this->trans('commands.check.messages.php-invalid'), 84 | $checks['php']['current'], 85 | $checks['php']['required'] 86 | ) 87 | ); 88 | 89 | return 1; 90 | } 91 | 92 | if ($extensions = $checks['extensions']['required']['missing']) { 93 | foreach ($extensions as $extension) { 94 | $this->getIo()->error( 95 | sprintf( 96 | $this->trans('commands.check.messages.extension-missing'), 97 | $extension 98 | ) 99 | ); 100 | } 101 | } 102 | 103 | if ($extensions = $checks['extensions']['recommended']['missing']) { 104 | foreach ($extensions as $extension) { 105 | $this->getIo()->commentBlock( 106 | sprintf( 107 | $this->trans( 108 | 'commands.check.messages.extension-recommended' 109 | ), 110 | $extension 111 | ) 112 | ); 113 | } 114 | } 115 | 116 | if ($configurations = $checks['configurations']['required']['missing']) { 117 | foreach ($configurations as $configuration) { 118 | $this->getIo()->error( 119 | sprintf( 120 | $this->trans('commands.check.messages.configuration-missing'), 121 | $configuration 122 | ) 123 | ); 124 | } 125 | } 126 | 127 | if ($configurations = $checks['configurations']['required']['overwritten']) { 128 | foreach ($configurations as $configuration => $overwritten) { 129 | $this->getIo()->commentBlock( 130 | sprintf( 131 | $this->trans( 132 | 'commands.check.messages.configuration-overwritten' 133 | ), 134 | $configuration, 135 | $overwritten 136 | ) 137 | ); 138 | } 139 | } 140 | 141 | if ($this->requirementChecker->isValid() && !$this->requirementChecker->isOverwritten()) { 142 | $this->getIo()->success( 143 | $this->trans('commands.check.messages.success') 144 | ); 145 | } 146 | 147 | return $this->requirementChecker->isValid(); 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/Command/Command.php: -------------------------------------------------------------------------------- 1 | io = new DrupalStyle($input, $output); 47 | } 48 | 49 | /** 50 | * @return \Drupal\Console\Core\Style\DrupalStyle 51 | */ 52 | public function getIo() 53 | { 54 | return $this->io; 55 | } 56 | 57 | /** 58 | * Check maintenance mode. 59 | * 60 | * @return bool 61 | */ 62 | public function isMaintenance() 63 | { 64 | return $this->maintenance; 65 | } 66 | 67 | /** 68 | * Enable maintenance mode. 69 | * 70 | * @return $this 71 | * Command. 72 | */ 73 | public function enableMaintenance() 74 | { 75 | $this->maintenance = true; 76 | return $this; 77 | } 78 | 79 | /** 80 | * Create Exception 81 | * 82 | * @return void 83 | * 84 | */ 85 | public function createException($message) { 86 | $this->getIo()->error($message); 87 | exit(1); 88 | } 89 | 90 | /** 91 | * @param \Drupal\Console\Core\Utils\DrupalFinder $drupalFinder 92 | */ 93 | public function setDrupalFinder($drupalFinder) { 94 | $this->drupalFinder = $drupalFinder; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/Command/CompleteCommand.php: -------------------------------------------------------------------------------- 1 | setName('complete') 22 | ->setDescription($this->trans('commands.complete.description')); 23 | } 24 | 25 | /** 26 | * {@inheritdoc} 27 | */ 28 | protected function execute(InputInterface $input, OutputInterface $output) 29 | { 30 | $commands = array_keys($this->getApplication()->all()); 31 | asort($commands); 32 | $output->writeln($commands); 33 | 34 | return 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Command/ContainerAwareCommand.php: -------------------------------------------------------------------------------- 1 | chainDiscovery = $chainDiscovery; 36 | 37 | parent::__construct(); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | protected function configure() 44 | { 45 | $this 46 | ->setName('debug:chain') 47 | ->setDescription($this->trans('commands.debug.chain.description')) 48 | ->setAliases(['dch']); 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | protected function execute(InputInterface $input, OutputInterface $output) 55 | { 56 | $files = $this->chainDiscovery->getFiles(); 57 | $filesPerDirectory = $this->chainDiscovery->getFilesPerDirectory(); 58 | 59 | if (!$files || !$filesPerDirectory) { 60 | $this->getIo()->warning($this->trans('commands.debug.chain.messages.no-files')); 61 | 62 | return 0; 63 | } 64 | 65 | foreach ($filesPerDirectory as $directory => $fileNames) { 66 | $this->getIo()->info(' ' . $this->trans('commands.debug.chain.messages.directory'), false); 67 | $this->getIo()->comment($directory); 68 | 69 | $tableHeader = [ 70 | $this->trans('commands.debug.chain.messages.file'), 71 | $this->trans('commands.debug.chain.messages.command') 72 | ]; 73 | 74 | $tableRows = []; 75 | foreach ($fileNames as $file) { 76 | $commandName = ''; 77 | if (array_key_exists('command', $files[$directory.$file])) { 78 | $commandName = $files[$directory.$file]['command']; 79 | } 80 | $tableRows[] = [ 81 | 'file' => $file, 82 | 'command' => $commandName 83 | ]; 84 | } 85 | 86 | $this->getIo()->table($tableHeader, $tableRows); 87 | } 88 | 89 | return 0; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Command/Debug/SettingsCommand.php: -------------------------------------------------------------------------------- 1 | configurationManager = $configurationManager; 37 | parent::__construct(); 38 | } 39 | 40 | /** 41 | * {@inheritdoc} 42 | */ 43 | protected function configure() 44 | { 45 | $this 46 | ->setName('debug:settings') 47 | ->setDescription($this->trans('commands.debug.settings.description')) 48 | ->setAliases(['dse']); 49 | ; 50 | } 51 | 52 | /** 53 | * {@inheritdoc} 54 | */ 55 | protected function execute(InputInterface $input, OutputInterface $output) 56 | { 57 | $configuration = $this->configurationManager->getConfiguration(); 58 | $configApplication['application'] = $configuration->getRaw('application'); 59 | 60 | unset($configApplication['application']['autowire']); 61 | unset($configApplication['application']['languages']); 62 | 63 | $this->getIo()->write(Yaml::dump($configApplication, 6, 2)); 64 | $this->getIo()->newLine(); 65 | 66 | return 0; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Command/Debug/SiteCommand.php: -------------------------------------------------------------------------------- 1 | configurationManager = $configurationManager; 38 | parent::__construct(); 39 | } 40 | 41 | /** 42 | * @{@inheritdoc} 43 | */ 44 | public function configure() 45 | { 46 | $this 47 | ->setName('debug:site') 48 | ->setDescription($this->trans('commands.debug.site.description')) 49 | ->addArgument( 50 | 'target', 51 | InputArgument::OPTIONAL, 52 | $this->trans('commands.debug.site.options.target'), 53 | null 54 | ) 55 | ->addArgument( 56 | 'property', 57 | InputArgument::OPTIONAL, 58 | $this->trans('commands.debug.site.options.property'), 59 | null 60 | ) 61 | ->setHelp($this->trans('commands.debug.site.help')) 62 | ->setAliases(['dsi']); 63 | } 64 | 65 | /** 66 | * {@inheritdoc} 67 | */ 68 | protected function execute(InputInterface $input, OutputInterface $output) 69 | { 70 | $sites = $this->configurationManager->getSites(); 71 | 72 | if (!$sites) { 73 | $this->getIo()->warning($this->trans('commands.debug.site.messages.invalid-sites')); 74 | 75 | return 0; 76 | } 77 | 78 | $target = $input->getArgument('target'); 79 | if (!$target) { 80 | foreach ($sites as $key => $site) { 81 | $environments = array_keys($site); 82 | unset($environments[0]); 83 | 84 | $environments = array_map( 85 | function ($element) use ($key) { 86 | return $key . '.' . $element; 87 | }, 88 | $environments 89 | ); 90 | 91 | $this->getIo()->info($key); 92 | $this->getIo()->listing($environments); 93 | } 94 | 95 | return 0; 96 | } 97 | 98 | $targetConfig = $this->configurationManager->readTarget($target); 99 | if (!$targetConfig) { 100 | $this->getIo()->error($this->trans('commands.debug.site.messages.invalid-site')); 101 | 102 | return 1; 103 | } 104 | 105 | // --property argument, allows the user to fetch specific properties of the selected site 106 | $property = $input->getArgument('property'); 107 | if ($property) { 108 | $property_keys = explode('.', $property); 109 | 110 | $val = $targetConfig; 111 | foreach ($property_keys as $property_key) { 112 | $val = &$val[$property_key]; 113 | } 114 | 115 | $this->getIo()->writeln($val); 116 | return 0; 117 | } 118 | 119 | $this->getIo()->info($target); 120 | $dumper = new Dumper(); 121 | $this->getIo()->writeln($dumper->dump($targetConfig, 4, 2)); 122 | 123 | return 0; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/Command/DrushCommand.php: -------------------------------------------------------------------------------- 1 | configurationManager = $configurationManager; 44 | $this->chainQueue = $chainQueue; 45 | parent::__construct(); 46 | } 47 | 48 | /** 49 | * {@inheritdoc} 50 | */ 51 | protected function configure() 52 | { 53 | $this 54 | ->setName('drush') 55 | ->setDescription($this->trans('commands.drush.description')) 56 | ->addArgument( 57 | 'command-name', 58 | InputArgument::OPTIONAL, 59 | $this->trans('commands.drush.arguments.command-name'), 60 | null 61 | ); 62 | } 63 | 64 | /** 65 | * {@inheritdoc} 66 | */ 67 | protected function execute(InputInterface $input, OutputInterface $output) 68 | { 69 | $commandName = $input->getArgument('command-name'); 70 | 71 | $alternative = $this->configurationManager->readDrushEquivalents($commandName); 72 | 73 | $this->getIo()->newLine(); 74 | $this->getIo()->info($this->trans('commands.drush.description')); 75 | $this->getIo()->newLine(); 76 | 77 | if (!$alternative) { 78 | $this->getIo()->error($this->trans('commands.drush.messages.not-found')); 79 | 80 | return 1; 81 | } 82 | 83 | $tableHeader = ['drush','drupal console']; 84 | if (is_array($alternative)) { 85 | $this->getIo()->table( 86 | $tableHeader, 87 | $alternative 88 | ); 89 | 90 | return 0; 91 | } 92 | 93 | $this->getIo()->table( 94 | $tableHeader, 95 | [[$commandName, $alternative]] 96 | ); 97 | 98 | if ($this->getApplication()->has($alternative)) { 99 | $this->chainQueue->addCommand( 100 | 'help', 101 | ['command_name' => $alternative] 102 | ); 103 | 104 | return 0; 105 | } 106 | 107 | return 0; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/Command/Exclude/DrupliconCommand.php: -------------------------------------------------------------------------------- 1 | appRoot = $appRoot; 52 | $this->renderer = $renderer; 53 | $this->configurationManager = $configurationManager; 54 | parent::__construct(); 55 | } 56 | 57 | /** 58 | * {@inheritdoc} 59 | */ 60 | protected function configure() 61 | { 62 | $this 63 | ->setName('druplicon') 64 | ->setDescription($this->trans('application.commands.druplicon.description')); 65 | } 66 | 67 | /** 68 | * {@inheritdoc} 69 | */ 70 | protected function execute(InputInterface $input, OutputInterface $output) 71 | { 72 | $directory = sprintf( 73 | '%s/templates/core/druplicon/', 74 | $this->configurationManager->getVendorCoreRoot() 75 | ); 76 | 77 | $finder = new Finder(); 78 | $finder->files() 79 | ->name('*.twig') 80 | ->in($directory); 81 | 82 | $templates = []; 83 | foreach ($finder as $template) { 84 | $templates[] = $template->getRelativePathname(); 85 | } 86 | 87 | $druplicon = $this->renderer->render( 88 | sprintf( 89 | 'core/druplicon/%s', 90 | $templates[array_rand($templates)] 91 | ) 92 | ); 93 | 94 | $this->getIo()->writeln($druplicon); 95 | return 0; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Command/Exclude/ElephpantCommand.php: -------------------------------------------------------------------------------- 1 | appRoot = $appRoot; 53 | $this->renderer = $renderer; 54 | $this->configurationManager = $configurationManager; 55 | parent::__construct(); 56 | } 57 | 58 | /** 59 | * {@inheritdoc} 60 | */ 61 | protected function configure() 62 | { 63 | $this 64 | ->setName('elephpant') 65 | ->setDescription($this->trans('application.commands.elephpant.description')); 66 | } 67 | 68 | /** 69 | * {@inheritdoc} 70 | */ 71 | protected function execute(InputInterface $input, OutputInterface $output) 72 | { 73 | $directory = sprintf( 74 | '%stemplates/core/elephpant/', 75 | $this->configurationManager->getVendorCoreRoot() 76 | ); 77 | 78 | $finder = new Finder(); 79 | $finder->files() 80 | ->name('*.twig') 81 | ->in($directory); 82 | 83 | $templates = []; 84 | 85 | foreach ($finder as $template) { 86 | $templates[] = $template->getRelativePathname(); 87 | } 88 | 89 | $elephpant = $this->renderer->render( 90 | sprintf( 91 | 'core/elephpant/%s', 92 | $templates[array_rand($templates)] 93 | ) 94 | ); 95 | 96 | $this->getIo()->writeln($elephpant); 97 | return 0; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/Command/Exec/ExecCommand.php: -------------------------------------------------------------------------------- 1 | shellProcess = $shellProcess; 38 | parent::__construct(); 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | protected function configure() 45 | { 46 | $this 47 | ->setName('exec') 48 | ->setDescription($this->trans('commands.exec.description')) 49 | ->addArgument( 50 | 'bin', 51 | InputArgument::REQUIRED, 52 | $this->trans('commands.exec.arguments.bin') 53 | )->addOption( 54 | 'working-directory', 55 | null, 56 | InputOption::VALUE_OPTIONAL, 57 | $this->trans('commands.exec.options.working-directory') 58 | ); 59 | } 60 | 61 | /** 62 | * {@inheritdoc} 63 | */ 64 | protected function execute(InputInterface $input, OutputInterface $output) 65 | { 66 | $bin = $input->getArgument('bin'); 67 | $workingDirectory = $input->getOption('working-directory'); 68 | 69 | if (!$bin) { 70 | $this->getIo()->error( 71 | $this->trans('commands.exec.messages.missing-bin') 72 | ); 73 | 74 | return 1; 75 | } 76 | 77 | $name = $bin; 78 | if ($index = stripos($name, " ")) { 79 | $name = substr($name, 0, $index); 80 | } 81 | 82 | $finder = new ExecutableFinder(); 83 | if (!$finder->find($name)) { 84 | $this->getIo()->error( 85 | sprintf( 86 | $this->trans('commands.exec.messages.binary-not-found'), 87 | $name 88 | ) 89 | ); 90 | 91 | return 1; 92 | } 93 | 94 | if (!$this->shellProcess->exec($bin, $workingDirectory)) { 95 | $this->getIo()->error( 96 | sprintf( 97 | $this->trans('commands.exec.messages.invalid-bin') 98 | ) 99 | ); 100 | 101 | $this->getIo()->writeln($this->shellProcess->getOutput()); 102 | 103 | return 1; 104 | } 105 | 106 | $this->getIo()->success( 107 | sprintf( 108 | $this->trans('commands.exec.messages.success'), 109 | $bin 110 | ) 111 | ); 112 | 113 | return 0; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/Command/GenerateCommand.php: -------------------------------------------------------------------------------- 1 | exists($sourceFile)) { 31 | return $sourceFile; 32 | } 33 | 34 | $notFound[] = Path::makeRelative( 35 | $sourceFile, 36 | $this->drupalFinder->getComposerRoot() 37 | ); 38 | } 39 | 40 | if ($stopOnException) { 41 | $this->createException( 42 | 'File(s): ' . implode(', ', $notFound) . ' not found.' 43 | ); 44 | } 45 | 46 | return null; 47 | } 48 | 49 | protected function backUpFile(Filesystem $fs, $fileName) 50 | { 51 | $fileNameBackup = $fileName.'.original'; 52 | if ($fs->exists($fileName)) { 53 | if ($fs->exists($fileNameBackup)) { 54 | $fs->remove($fileName); 55 | return; 56 | } 57 | 58 | $fs->rename( 59 | $fileName, 60 | $fileNameBackup, 61 | TRUE 62 | ); 63 | 64 | $fileNameBackup = Path::makeRelative( 65 | $fileNameBackup, 66 | $this->drupalFinder->getComposerRoot() 67 | ); 68 | 69 | $this->getIo()->success( 70 | 'File ' . $fileNameBackup . ' created.' 71 | ); 72 | 73 | } 74 | } 75 | 76 | protected function showFileCreatedMessage($fileName) { 77 | $fileName = Path::makeRelative( 78 | $fileName, 79 | $this->drupalFinder->getComposerRoot() 80 | ); 81 | 82 | $this->getIo()->success('File: ' . $fileName . ' created.'); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Command/HelpCommand.php: -------------------------------------------------------------------------------- 1 | 21 | */ 22 | class HelpCommand extends Command 23 | { 24 | private $command; 25 | 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | protected function configure() 30 | { 31 | $this->ignoreValidationErrors(); 32 | 33 | $this 34 | ->setName('help') 35 | ->setDefinition($this->createDefinition()) 36 | ->setDescription($this->trans('commands.help.description')) 37 | ->setHelp($this->trans('commands.help.help')); 38 | } 39 | 40 | /** 41 | * Sets the command. 42 | * 43 | * @param $command 44 | * The command to set 45 | */ 46 | public function setCommand($command) 47 | { 48 | $this->command = $command; 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | protected function execute(InputInterface $input, OutputInterface $output) 55 | { 56 | if (null === $this->command) { 57 | $this->command = $this->getApplication()->find($input->getArgument('command_name')); 58 | } 59 | 60 | if ($input->getOption('xml')) { 61 | $this->getIo()->info($this->trans('commands.help.messages.deprecated'), E_USER_DEPRECATED); 62 | $input->setOption('format', 'xml'); 63 | } 64 | 65 | $helper = new DescriptorHelper(); 66 | $helper->describe( 67 | $this->getIo(), 68 | $this->command, 69 | [ 70 | 'format' => $input->getOption('format'), 71 | 'raw_text' => $input->getOption('raw'), 72 | 'command_name' => $input->getArgument('command_name'), 73 | 'translator' => $this->getApplication()->getTranslator() 74 | ] 75 | ); 76 | 77 | $this->command = null; 78 | $this->getIo()->newLine(); 79 | } 80 | 81 | /** 82 | * {@inheritdoc} 83 | */ 84 | private function createDefinition() 85 | { 86 | return new InputDefinition( 87 | [ 88 | new InputArgument('command_name', InputArgument::OPTIONAL, $this->trans('commands.help.arguments.command-name'), 'help'), 89 | new InputOption('xml', null, InputOption::VALUE_NONE, $this->trans('commands.help.options.xml')), 90 | new InputOption('raw', null, InputOption::VALUE_NONE, $this->trans('commands.help.options.raw')), 91 | new InputOption('format', null, InputOption::VALUE_REQUIRED, $this->trans('commands.help.options.format'), 'txt'), 92 | ] 93 | ); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Command/ListCommand.php: -------------------------------------------------------------------------------- 1 | setName('list') 29 | ->setDefinition($this->createDefinition()) 30 | ->setDescription($this->trans('commands.list.description')) 31 | ->setHelp($this->trans('commands.list.help')); 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function getNativeDefinition() 38 | { 39 | return $this->createDefinition(); 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | protected function execute(InputInterface $input, OutputInterface $output) 46 | { 47 | if ($input->getOption('xml')) { 48 | $this->getIo()->info( 49 | 'The --xml option was deprecated in version 2.7 and will be removed in version 3.0. Use the --format option instead', 50 | E_USER_DEPRECATED 51 | ); 52 | $input->setOption('format', 'xml'); 53 | } 54 | $commandName = $input->getFirstArgument()?$input->getFirstArgument():'help'; 55 | $helper = new DescriptorHelper(); 56 | $helper->describe( 57 | $this->getIo(), 58 | $this->getApplication(), 59 | [ 60 | 'format' => $input->getOption('format'), 61 | 'raw_text' => $input->getOption('raw'), 62 | 'namespace' => $input->getArgument('namespace'), 63 | 'translator' => $this->getApplication()->getTranslator(), 64 | 'command' => $this->getApplication()->find($commandName) 65 | ] 66 | ); 67 | 68 | $this->getIo()->newLine(); 69 | } 70 | 71 | /** 72 | * {@inheritdoc} 73 | */ 74 | private function createDefinition() 75 | { 76 | return new InputDefinition( 77 | [ 78 | new InputArgument('namespace', InputArgument::OPTIONAL, $this->trans('commands.list.arguments.namespace')), 79 | new InputOption('xml', null, InputOption::VALUE_NONE, $this->trans('commands.list.options.xml')), 80 | new InputOption('raw', null, InputOption::VALUE_NONE, $this->trans('commands.list.options.raw')), 81 | new InputOption('format', null, InputOption::VALUE_REQUIRED, $this->trans('commands.list.options.format'), 'txt'), 82 | ] 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Command/Settings/SetCommand.php: -------------------------------------------------------------------------------- 1 | configurationManager = $configurationManager; 47 | $this->nestedArray = $nestedArray; 48 | 49 | parent::__construct(); 50 | } 51 | 52 | /** 53 | * {@inheritdoc} 54 | */ 55 | protected function configure() 56 | { 57 | $this 58 | ->setName('settings:set') 59 | ->addArgument( 60 | 'name', 61 | InputArgument::REQUIRED, 62 | $this->trans('commands.settings.set.arguments.name'), 63 | null 64 | ) 65 | ->addArgument( 66 | 'value', 67 | InputArgument::REQUIRED, 68 | $this->trans('commands.settings.set.arguments.value'), 69 | null 70 | ) 71 | ->setDescription($this->trans('commands.settings.set.description')); 72 | } 73 | 74 | /** 75 | * {@inheritdoc} 76 | */ 77 | protected function execute(InputInterface $input, OutputInterface $output) 78 | { 79 | $parser = new Parser(); 80 | $dumper = new Dumper(); 81 | 82 | $settingName = $input->getArgument('name'); 83 | $settingValue = $input->getArgument('value'); 84 | 85 | // Reset the default values ​​of the statistics. 86 | if ($settingName == 'statistics.enabled') { 87 | $this->configurationManager->updateConfigGlobalParameter( 88 | 'statistics.last-attempted', 89 | null 90 | ); 91 | $this->configurationManager->updateConfigGlobalParameter( 92 | 'statistics.times-attempted', 93 | 0 94 | ); 95 | } 96 | 97 | $userConfigFile = sprintf( 98 | '%s/.console/config.yml', 99 | $this->configurationManager->getHomeDirectory() 100 | ); 101 | 102 | if (!file_exists($userConfigFile)) { 103 | $this->getIo()->error( 104 | sprintf( 105 | $this->trans('commands.settings.set.messages.missing-file'), 106 | $userConfigFile 107 | ) 108 | ); 109 | return 1; 110 | } 111 | 112 | try { 113 | $userConfigFileParsed = $parser->parse( 114 | file_get_contents($userConfigFile) 115 | ); 116 | } catch (\Exception $e) { 117 | $this->getIo()->error( 118 | $this->trans( 119 | 'commands.settings.set.messages.error-parsing' 120 | ) . ': ' . $e->getMessage() 121 | ); 122 | return 1; 123 | } 124 | 125 | $parents = array_merge(['application'], explode(".", $settingName)); 126 | // Change the value type if it is boolean. 127 | $settingValue = json_decode($settingValue) === null ? $settingValue : json_decode($settingValue); 128 | 129 | $this->nestedArray->setValue( 130 | $userConfigFileParsed, 131 | $parents, 132 | $settingValue, 133 | true 134 | ); 135 | 136 | try { 137 | $userConfigFileDump = $dumper->dump($userConfigFileParsed, 10); 138 | } catch (\Exception $e) { 139 | $this->getIo()->error( 140 | [ 141 | $this->trans('commands.settings.set.messages.error-generating'), 142 | $e->getMessage() 143 | ] 144 | ); 145 | 146 | return 1; 147 | } 148 | 149 | if ($settingName == 'language') { 150 | $this->getApplication() 151 | ->getTranslator() 152 | ->changeCoreLanguage($settingValue); 153 | 154 | $translatorLanguage = $this->getApplication()->getTranslator()->getLanguage(); 155 | if ($translatorLanguage != $settingValue) { 156 | $this->getIo()->error( 157 | sprintf( 158 | $this->trans('commands.settings.set.messages.missing-language'), 159 | $settingValue 160 | ) 161 | ); 162 | 163 | return 1; 164 | } 165 | } 166 | 167 | try { 168 | file_put_contents($userConfigFile, $userConfigFileDump); 169 | } catch (\Exception $e) { 170 | $this->getIo()->error( 171 | [ 172 | $this->trans('commands.settings.set.messages.error-writing'), 173 | $e->getMessage() 174 | ] 175 | ); 176 | 177 | return 1; 178 | } 179 | 180 | $settingValue = is_bool($settingValue) ? $settingValue ? 'true' : 'false' : $settingValue; 181 | $this->getIo()->success( 182 | sprintf( 183 | $this->trans('commands.settings.set.messages.success'), 184 | $settingName, 185 | $settingValue 186 | ) 187 | ); 188 | 189 | return 0; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/Command/Shared/CommandTrait.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 30 | } 31 | 32 | /** 33 | * @param $key string 34 | * 35 | * @return string 36 | */ 37 | public function trans($key) 38 | { 39 | if (!$this->translator) { 40 | return $key; 41 | } 42 | 43 | return $this->translator->trans($key); 44 | } 45 | 46 | /** 47 | * @inheritdoc 48 | */ 49 | public function getDescription() 50 | { 51 | $description = sprintf( 52 | 'commands.%s.description', 53 | str_replace(':', '.', $this->getName()) 54 | ); 55 | 56 | if (parent::getDescription()==$description) { 57 | return $this->trans($description); 58 | } 59 | 60 | return parent::getDescription(); 61 | } 62 | 63 | /** 64 | * @inheritdoc 65 | */ 66 | public function getHelp() 67 | { 68 | $help = sprintf( 69 | 'commands.%s.help', 70 | str_replace(':', '.', $this->getName()) 71 | ); 72 | 73 | if (parent::getHelp()==$help) { 74 | return $this->trans($help); 75 | } 76 | 77 | return parent::getHelp(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Command/Shared/ContainerAwareCommandTrait.php: -------------------------------------------------------------------------------- 1 | container = $container; 27 | } 28 | 29 | /** 30 | * @param $key 31 | * @return null|object 32 | */ 33 | public function has($key) 34 | { 35 | if (!$key) { 36 | return null; 37 | } 38 | 39 | return $this->container->has($key); 40 | } 41 | 42 | /** 43 | * @param $key 44 | * @return null|object 45 | */ 46 | public function get($key) 47 | { 48 | if (!$key) { 49 | return null; 50 | } 51 | 52 | if ($this->has($key)) { 53 | return $this->container->get($key); 54 | } 55 | 56 | return null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Command/Shared/InputTrait.php: -------------------------------------------------------------------------------- 1 | $value) { 24 | if (!is_array($value)) { 25 | try { 26 | $inputAsArray[] = json_decode('[{'.$value.'}]', true)[0]; 27 | } catch (\Exception $e) { 28 | continue; 29 | } 30 | } 31 | } 32 | 33 | return $inputAsArray?$inputAsArray:$inputValue; 34 | } 35 | 36 | /** 37 | * @return array 38 | */ 39 | private function placeHolderInlineValueAsArray($inputValue) 40 | { 41 | $inputArrayValue = []; 42 | foreach ($inputValue as $key => $value) { 43 | if (!is_array($value)) { 44 | $separatorIndex = strpos($value, ':'); 45 | if (!$separatorIndex) { 46 | continue; 47 | } 48 | $inputKeyItem = substr($value, 0, $separatorIndex); 49 | $inputValueItem = substr($value, $separatorIndex+1); 50 | $inputArrayValue[$inputKeyItem] = $inputValueItem; 51 | } 52 | } 53 | 54 | return $inputArrayValue?$inputArrayValue:$inputValue; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/EventSubscriber/CallCommandListener.php: -------------------------------------------------------------------------------- 1 | chainQueue = $chainQueue; 38 | } 39 | 40 | /** 41 | * @param ConsoleTerminateEvent $event 42 | */ 43 | public function callCommands(ConsoleTerminateEvent $event) 44 | { 45 | $command = $event->getCommand(); 46 | 47 | /* @var DrupalStyle $io */ 48 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 49 | 50 | if (!$command instanceof Command) { 51 | return 0; 52 | } 53 | 54 | $application = $command->getApplication(); 55 | $commands = $this->chainQueue->getCommands(); 56 | 57 | if (!$commands) { 58 | return 0; 59 | } 60 | 61 | foreach ($commands as $chainedCommand) { 62 | $callCommand = $application->find($chainedCommand['name']); 63 | 64 | if (!$callCommand) { 65 | continue; 66 | } 67 | 68 | $input = new ArrayInput($chainedCommand['inputs']); 69 | if (!is_null($chainedCommand['interactive'])) { 70 | $input->setInteractive($chainedCommand['interactive']); 71 | } 72 | 73 | $io->text($chainedCommand['name']); 74 | $allowFailure = array_key_exists('allow_failure', $chainedCommand)?$chainedCommand['allow_failure']:false; 75 | try { 76 | $callCommand->run($input, $io); 77 | } catch (\Exception $e) { 78 | if (!$allowFailure) { 79 | $io->error($e->getMessage()); 80 | return 1; 81 | } 82 | } 83 | } 84 | } 85 | 86 | /** 87 | * @{@inheritdoc} 88 | */ 89 | public static function getSubscribedEvents() 90 | { 91 | return [ConsoleEvents::TERMINATE => 'callCommands']; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/EventSubscriber/DefaultValueEventListener.php: -------------------------------------------------------------------------------- 1 | configurationManager = $configurationManager; 48 | } 49 | 50 | /** 51 | * @param ConsoleCommandEvent $event 52 | */ 53 | public function setDefaultValues(ConsoleCommandEvent $event) 54 | { 55 | /* @var Command $command */ 56 | $command = $event->getCommand(); 57 | $configuration = $this->configurationManager 58 | ->getConfiguration(); 59 | 60 | if (in_array($command->getName(), $this->skipCommands)) { 61 | return; 62 | } 63 | 64 | $inputDefinition = $command->getDefinition(); 65 | $input = $event->getInput(); 66 | $commandConfigKey = sprintf( 67 | 'application.commands.defaults.%s', 68 | str_replace(':', '.', $command->getName()) 69 | ); 70 | $defaults = $configuration->get($commandConfigKey); 71 | 72 | $this->setOptions($defaults, $input, $inputDefinition); 73 | $this->setArguments($defaults, $input, $inputDefinition); 74 | } 75 | 76 | private function setOptions($defaults, $input, $inputDefinition) 77 | { 78 | $defaultOptions = $this->extractKey($defaults, 'options'); 79 | $defaultValues = []; 80 | if ($defaultOptions) { 81 | $reflection = new \ReflectionObject($input); 82 | $prop = $reflection->getProperty('tokens'); 83 | $prop->setAccessible(true); 84 | $tokens = $prop->getValue($input); 85 | foreach ($defaultOptions as $key => $defaultValue) { 86 | $option = $inputDefinition->getOption($key); 87 | if ($input->getOption($key)) { 88 | continue; 89 | } 90 | if ($option->acceptValue()) { 91 | $defaultValues[] = sprintf( 92 | '--%s=%s', 93 | $key, 94 | $defaultValue 95 | ); 96 | continue; 97 | } 98 | $defaultValues[] = sprintf( 99 | '--%s', 100 | $key 101 | ); 102 | } 103 | $prop->setValue( 104 | $input, 105 | array_unique(array_merge($tokens, $defaultValues)) 106 | ); 107 | } 108 | } 109 | 110 | private function setArguments($defaults, $input, $inputDefinition) 111 | { 112 | $defaultArguments = $this->extractKey($defaults, 'arguments'); 113 | 114 | foreach ($defaultArguments as $key => $defaultValue) { 115 | if ($input->getArgument($key)) { 116 | continue; 117 | } 118 | 119 | if ($argument = $inputDefinition->getArgument($key)) { 120 | $argument->setDefault($defaultValue); 121 | } 122 | } 123 | } 124 | 125 | private function extractKey($defaults, $key) 126 | { 127 | if (!$defaults || !is_array($defaults)) { 128 | return []; 129 | } 130 | 131 | $defaults = array_key_exists($key, $defaults)?$defaults[$key]:[]; 132 | if (!is_array($defaults)) { 133 | return []; 134 | } 135 | 136 | return $defaults; 137 | } 138 | 139 | /** 140 | * @{@inheritdoc} 141 | */ 142 | public static function getSubscribedEvents() 143 | { 144 | return [ConsoleEvents::COMMAND => 'setDefaultValues']; 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/EventSubscriber/MaintenanceModeListener.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 46 | $this->state = $state; 47 | } 48 | 49 | /** 50 | * Enable maintenance mode. 51 | * 52 | * @param ConsoleEvent $event 53 | */ 54 | public function enableMaintenanceMode(ConsoleEvent $event) 55 | { 56 | $this->switchMaintenanceMode($event, 'on'); 57 | } 58 | 59 | /** 60 | * Disable maintenance mode. 61 | * 62 | * @param ConsoleEvent $event 63 | */ 64 | public function disableMaintenanceMode(ConsoleEvent $event) 65 | { 66 | $this->switchMaintenanceMode($event, 'off'); 67 | } 68 | 69 | /** 70 | * Switch maintenance mode. 71 | * 72 | * @param ConsoleEvent $event 73 | * @param string $mode 74 | */ 75 | public function switchMaintenanceMode(ConsoleEvent $event, $mode) 76 | { 77 | /* @var Command $command */ 78 | $command = $event->getCommand(); 79 | 80 | if ($command->isMaintenance()) { 81 | 82 | /* @var DrupalStyle $io */ 83 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 84 | $stateName = 'system.maintenance_mode'; 85 | $modeMessage = null; 86 | 87 | if ($mode == 'on') { 88 | $this->state->set($stateName, true); 89 | $modeMessage = $this->translator->trans('commands.site.maintenance.messages.maintenance-on'); 90 | } 91 | 92 | if ($mode == 'off') { 93 | $this->state->set($stateName, false); 94 | $modeMessage = $this->translator->trans('commands.site.maintenance.messages.maintenance-off'); 95 | } 96 | 97 | if ($modeMessage) { 98 | $io->newLine(); 99 | $io->info($modeMessage, true); 100 | $io->newLine(); 101 | } 102 | } 103 | } 104 | 105 | 106 | /** 107 | * @{@inheritdoc} 108 | */ 109 | public static function getSubscribedEvents() 110 | { 111 | return [ 112 | ConsoleEvents::COMMAND => 'enableMaintenanceMode', 113 | ConsoleEvents::TERMINATE => 'disableMaintenanceMode', 114 | ]; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/EventSubscriber/RemoveMessagesListener.php: -------------------------------------------------------------------------------- 1 | messageManager = $messageManager; 38 | } 39 | 40 | /** 41 | * @param ConsoleTerminateEvent $event 42 | */ 43 | public function removeMessages(ConsoleTerminateEvent $event) 44 | { 45 | if ($event->getExitCode() != 0) { 46 | return; 47 | } 48 | 49 | /* @var Command $command */ 50 | $command = $event->getCommand(); 51 | 52 | $commandName = $command->getName(); 53 | 54 | $this->messageManager->remove($commandName); 55 | } 56 | 57 | /** 58 | * @{@inheritdoc} 59 | */ 60 | public static function getSubscribedEvents() 61 | { 62 | return [ConsoleEvents::TERMINATE => 'removeMessages']; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/EventSubscriber/SaveStatisticsListener.php: -------------------------------------------------------------------------------- 1 | countCodeLines = $countCodeLines; 60 | $this->configurationManager = $configurationManager; 61 | $this->translator = $translator; 62 | 63 | $this->fs = new Filesystem(); 64 | } 65 | 66 | /** 67 | * @param ConsoleTerminateEvent $event 68 | */ 69 | public function saveStatistics(ConsoleTerminateEvent $event) 70 | { 71 | if ($event->getExitCode() != 0) { 72 | return; 73 | } 74 | 75 | $configGlobalAsArray = $this->configurationManager->getConfigGlobalAsArray(); 76 | 77 | //Validate if the config is defined. 78 | if (is_null($configGlobalAsArray) || !isset($configGlobalAsArray['application']['statistics'])) { 79 | return; 80 | } 81 | 82 | //Validate if the statistics is enabled. 83 | if (!isset($configGlobalAsArray['application']['statistics']['enabled']) || !$configGlobalAsArray['application']['statistics']['enabled']) { 84 | return; 85 | } 86 | 87 | //Check that the namespace starts with 'Drupal\Console'. 88 | $class = new \ReflectionClass($event->getCommand()); 89 | if (strpos($class->getNamespaceName(), "Drupal\Console") !== 0) { 90 | return; 91 | } 92 | 93 | //Validate if the command is not a custom chain command. 94 | if ($event->getCommand() instanceof ChainCustomCommand) { 95 | return; 96 | } 97 | 98 | $path = $path = sprintf( 99 | '%s/.console/stats/', 100 | $this->configurationManager->getHomeDirectory() 101 | ); 102 | 103 | $information = $event->getCommand()->getName() . ',' . $this->translator->getLanguage(); 104 | 105 | $countCodeLines = $this->countCodeLines->getCountCodeLines(); 106 | if ($countCodeLines > 0) { 107 | $information = $information . ',' . $countCodeLines; 108 | } 109 | 110 | try{ 111 | $this->fs->appendToFile( 112 | $path . date('Y-m-d') . '.csv', 113 | $information . PHP_EOL 114 | ); 115 | }catch (\Exception $exception) { 116 | return; 117 | } 118 | } 119 | 120 | /** 121 | * @{@inheritdoc} 122 | */ 123 | public static function getSubscribedEvents() 124 | { 125 | return [ConsoleEvents::TERMINATE => 'saveStatistics']; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/EventSubscriber/SendStatisticsListener.php: -------------------------------------------------------------------------------- 1 | configurationManager = $configurationManager; 54 | $this->translator = $translator; 55 | $this->fs = new Filesystem(); 56 | } 57 | 58 | /** 59 | * @param ConsoleTerminateEvent $event 60 | */ 61 | public function calculateStatistics(ConsoleTerminateEvent $event) 62 | { 63 | if ($event->getExitCode() != 0) { 64 | return; 65 | } 66 | 67 | $date = date('Y-m-d'); 68 | $configGlobalAsArray = $this->configurationManager->getConfigGlobalAsArray(); 69 | 70 | //Validate if the config is defined. 71 | if (is_null($configGlobalAsArray) || !isset($configGlobalAsArray['application']['statistics'])) { 72 | return; 73 | } 74 | 75 | //Validate if the statistics is enabled. 76 | if (!isset($configGlobalAsArray['application']['statistics']['enabled']) || !$configGlobalAsArray['application']['statistics']['enabled']) { 77 | return; 78 | } 79 | 80 | /* @var DrupalStyle $io */ 81 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 82 | 83 | //Validate if the times attempted is 10 84 | if ($configGlobalAsArray['application']['statistics']['times-attempted'] >= 10) { 85 | $io->error($this->translator->trans('application.errors.statistics-failed')); 86 | 87 | $this->configurationManager->updateConfigGlobalParameter('statistics.enabled', false); 88 | return; 89 | } 90 | 91 | //Validate if the last attempted was today 92 | if ($configGlobalAsArray['application']['statistics']['last-attempted'] === $date) { 93 | return; 94 | } 95 | 96 | $path = sprintf( 97 | '%s/.console/stats', 98 | $this->configurationManager->getHomeDirectory() 99 | ); 100 | 101 | //Find all statistics with pending status from other days. 102 | $finder = new Finder(); 103 | $finder 104 | ->files() 105 | ->name('*.csv') 106 | ->notName($date.'.csv') 107 | ->in($path); 108 | 109 | //Validate if finder in not null 110 | if ($finder->count() == 0) { 111 | return; 112 | } 113 | 114 | $statisticsKeys = ['command', 'language', 'linesOfCode']; 115 | $commands = []; 116 | $languages = []; 117 | $filePathToDelete = []; 118 | 119 | foreach ($finder as $file) { 120 | if (($handle = fopen($file->getPathname(), "r")) !== false) { 121 | while (($content = fgetcsv($handle, 0, ',')) !== false) { 122 | 123 | /** 124 | * If the command doesn't have linesOfCode, 125 | * we add a null value at the end to combine with statistics keys. 126 | */ 127 | if (count($content) === 2) { 128 | array_push($content, 0); 129 | } 130 | 131 | $commands = $this->getCommandStatisticsAsArray($commands, array_combine($statisticsKeys, $content)); 132 | $languages = $this->getLanguageStatisticsAsArray($languages, array_combine($statisticsKeys, $content)); 133 | } 134 | 135 | fclose($handle); 136 | 137 | //Save file path to delete if the response is success. 138 | array_push($filePathToDelete, $file->getPathname()); 139 | } 140 | } 141 | 142 | try { 143 | if(!isset($configGlobalAsArray['application']['statistics']['url']) || empty($configGlobalAsArray['application']['statistics']['url'])){ 144 | $io->error($this->translator->trans('application.errors.statistics-url-failed')); 145 | return; 146 | } 147 | 148 | $client = new Client(); 149 | $response = $client->post( 150 | $configGlobalAsArray['application']['statistics']['url'], 151 | [ 152 | 'headers' => [ 153 | 'Accept' => 'application/json', 154 | ], 155 | 'json' => ['commands' => $commands, 'languages' => $languages] 156 | ] 157 | ); 158 | 159 | if ($response->getStatusCode() === 200) { 160 | $this->fs->remove($filePathToDelete); 161 | 162 | //Reset the count attempted to 0. 163 | $this->configurationManager->updateConfigGlobalParameter('statistics.times-attempted', 0); 164 | } 165 | } catch (\Exception $exception) { 166 | //Increase the count attempted in global config. 167 | $countAttempted = $configGlobalAsArray['application']['statistics']['times-attempted'] + 1; 168 | $this->configurationManager->updateConfigGlobalParameter('statistics.times-attempted', $countAttempted); 169 | } 170 | 171 | //Update last attempted in global config. 172 | $this->configurationManager->updateConfigGlobalParameter('statistics.last-attempted', $date); 173 | } 174 | 175 | /** 176 | * Build the statistics by command. 177 | * 178 | * @param $commands 179 | * @param $content 180 | * @return array 181 | */ 182 | private function getCommandStatisticsAsArray($commands, $content) 183 | { 184 | //Check if in $commands with the $content['command'] key with the value 'executed' have value to sum. 185 | $executed = $commands[$content['command']]['executed'] + 1; 186 | $linesOfCode = $commands[$content['command']]['linesOfCode'] + $content['linesOfCode']; 187 | 188 | $commands[$content['command']] = ["executed" => $executed, "linesOfCode" => $linesOfCode]; 189 | 190 | return $commands; 191 | } 192 | 193 | /** 194 | * Update the languages by command. 195 | * 196 | * @param $languages 197 | * @param $content 198 | * @return array 199 | */ 200 | private function getLanguageStatisticsAsArray($languages, $content) 201 | { 202 | //Check if in $commands with the $content['language'] key have value to sum. 203 | $languages[$content['language']] = $languages[$content['language']] + 1; 204 | 205 | return $languages; 206 | } 207 | 208 | /** 209 | * @{@inheritdoc} 210 | */ 211 | public static function getSubscribedEvents() 212 | { 213 | return [ConsoleEvents::TERMINATE => 'calculateStatistics']; 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/EventSubscriber/ShowGenerateChainListener.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 67 | } 68 | 69 | /** 70 | * @param ConsoleTerminateEvent $event 71 | */ 72 | public function showGenerateChain(ConsoleTerminateEvent $event) 73 | { 74 | if ($event->getExitCode() != 0) { 75 | return; 76 | } 77 | 78 | /* @var Command $command */ 79 | $command = $event->getCommand(); 80 | /* @var DrupalStyle $io */ 81 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 82 | 83 | $command_name = $command->getName(); 84 | 85 | $this->skipArguments[] = $command_name; 86 | 87 | if (in_array($command->getName(), $this->skipCommands)) { 88 | return; 89 | } 90 | 91 | $input = $event->getInput(); 92 | 93 | if ($input->getOption('generate-chain')) { 94 | $options = array_filter($input->getOptions()); 95 | foreach ($this->skipOptions as $remove_option) { 96 | unset($options[$remove_option]); 97 | } 98 | 99 | $arguments = array_filter($input->getArguments()); 100 | foreach ($this->skipArguments as $remove_argument) { 101 | unset($arguments[$remove_argument]); 102 | } 103 | 104 | $commandData['command'] = $command_name; 105 | 106 | if ($options) { 107 | $commandData['options'] = $options; 108 | } 109 | 110 | if ($arguments) { 111 | $commandData['arguments'] = $arguments; 112 | } 113 | 114 | $io->commentBlock( 115 | $this->translator->trans('application.messages.chain.generated') 116 | ); 117 | 118 | $dumper = new Dumper(); 119 | $tableRows = [ 120 | ' -', 121 | $dumper->dump($commandData, 4) 122 | ]; 123 | 124 | $io->writeln('commands:'); 125 | $io->table([], [$tableRows], 'compact'); 126 | } 127 | } 128 | 129 | /** 130 | * @{@inheritdoc} 131 | */ 132 | public static function getSubscribedEvents() 133 | { 134 | return [ConsoleEvents::TERMINATE => 'showGenerateChain']; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/EventSubscriber/ShowGenerateCountCodeLinesListener.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 48 | $this->countCodeLines = $countCodeLines; 49 | } 50 | 51 | /** 52 | * @param ConsoleTerminateEvent $event 53 | */ 54 | public function showGenerateCountCodeLines(ConsoleTerminateEvent $event) 55 | { 56 | if ($event->getExitCode() != 0) { 57 | return; 58 | } 59 | 60 | /* @var DrupalStyle $io */ 61 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 62 | 63 | $countCodeLines = $this->countCodeLines->getCountCodeLines(); 64 | if ($countCodeLines > 0) { 65 | $io->commentBlock( 66 | sprintf( 67 | $this->translator->trans('application.messages.lines-code'), 68 | $countCodeLines 69 | ) 70 | ); 71 | } 72 | } 73 | 74 | /** 75 | * @{@inheritdoc} 76 | */ 77 | public static function getSubscribedEvents() 78 | { 79 | return [ConsoleEvents::TERMINATE => 'showGenerateCountCodeLines']; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/EventSubscriber/ShowGenerateInlineListener.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 66 | } 67 | 68 | /** 69 | * @param ConsoleTerminateEvent $event 70 | */ 71 | public function showGenerateInline(ConsoleTerminateEvent $event) 72 | { 73 | if ($event->getExitCode() != 0) { 74 | return; 75 | } 76 | 77 | /* @var Command $command */ 78 | $command = $event->getCommand(); 79 | /* @var DrupalStyle $io */ 80 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 81 | 82 | $command_name = $command->getName(); 83 | 84 | $this->skipArguments[] = $command_name; 85 | 86 | if (in_array($command->getName(), $this->skipCommands)) { 87 | return; 88 | } 89 | 90 | $input = $event->getInput(); 91 | if ($input->getOption('generate-inline')) { 92 | $options = array_filter($input->getOptions()); 93 | foreach ($this->skipOptions as $remove_option) { 94 | unset($options[$remove_option]); 95 | } 96 | 97 | $arguments = array_filter($input->getArguments()); 98 | foreach ($this->skipArguments as $remove_argument) { 99 | unset($arguments[$remove_argument]); 100 | } 101 | 102 | $inline = ''; 103 | foreach ($arguments as $argument_id => $argument) { 104 | if (is_array($argument)) { 105 | $argument = implode(" ", $argument); 106 | } elseif (strstr($argument, ' ')) { 107 | $argument = '"' . $argument . '"'; 108 | } 109 | 110 | $inline .= " $argument"; 111 | } 112 | 113 | // Refactor and remove nested levels. Then apply to arguments. 114 | foreach ($options as $optionName => $optionValue) { 115 | if (is_array($optionValue)) { 116 | foreach ($optionValue as $optionItem) { 117 | if (is_array($optionItem)) { 118 | $inlineValue = implode( 119 | ', ', array_map( 120 | function ($v, $k) { 121 | return '"'.$k . '":"' . $v . '"'; 122 | }, 123 | $optionItem, 124 | array_keys($optionItem) 125 | ) 126 | ); 127 | } else { 128 | $inlineValue = $optionItem; 129 | } 130 | $inline .= ' --' . $optionName . '=\'' . $inlineValue . '\''; 131 | } 132 | } else { 133 | if (is_bool($optionValue)) { 134 | $inline.= ' --' . $optionName; 135 | } else { 136 | $inline.= ' --' . $optionName . '="' . $optionValue . '"'; 137 | } 138 | } 139 | } 140 | 141 | // Print YML output and message 142 | $io->commentBlock( 143 | $this->translator->trans('application.messages.inline.generated') 144 | ); 145 | 146 | $io->writeln( 147 | sprintf( 148 | '$ drupal %s %s --no-interaction', 149 | $command_name, 150 | $inline 151 | ) 152 | ); 153 | } 154 | } 155 | 156 | /** 157 | * @{@inheritdoc} 158 | */ 159 | public static function getSubscribedEvents() 160 | { 161 | return [ConsoleEvents::TERMINATE => 'showGenerateInline']; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/EventSubscriber/ShowGeneratedFilesListener.php: -------------------------------------------------------------------------------- 1 | fileQueue = $fileQueue; 44 | $this->showFile = $showFile; 45 | } 46 | 47 | /** 48 | * @param ConsoleTerminateEvent $event 49 | */ 50 | public function showGeneratedFiles(ConsoleTerminateEvent $event) 51 | { 52 | /* @var Command $command */ 53 | $command = $event->getCommand(); 54 | /* @var DrupalStyle $io */ 55 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 56 | 57 | if ($event->getExitCode() != 0) { 58 | return; 59 | } 60 | 61 | if ('self-update' == $command->getName()) { 62 | return; 63 | } 64 | 65 | $files = $this->fileQueue->getFiles(); 66 | if ($files) { 67 | $this->showFile->generatedFiles($io, $files, true); 68 | } 69 | } 70 | 71 | /** 72 | * @{@inheritdoc} 73 | */ 74 | public static function getSubscribedEvents() 75 | { 76 | return [ConsoleEvents::TERMINATE => 'showGeneratedFiles']; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/EventSubscriber/ShowTipsListener.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 38 | } 39 | 40 | /** 41 | * @param ConsoleCommandEvent $event 42 | */ 43 | public function showTips(ConsoleCommandEvent $event) 44 | { 45 | /* @var Command $command */ 46 | $command = $event->getCommand(); 47 | $input = $command->getDefinition(); 48 | /* @var DrupalStyle $io */ 49 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 50 | 51 | $learning = $input->getOption('learning'); 52 | 53 | // pick randomly one of the tips (5 tips as maximum). 54 | $tips = $this->getTip($command->getName()); 55 | 56 | if ($learning && $tips) { 57 | $io->commentBlock($tips); 58 | } 59 | } 60 | 61 | /** 62 | * @param $commandName 63 | * @return bool|string 64 | */ 65 | private function getTip($commandName) 66 | { 67 | $get_tip = $this->translator 68 | ->trans('commands.'.str_replace(':', '.', $commandName).'.tips.0.tip'); 69 | preg_match("/^commands./", $get_tip, $matches, null, 0); 70 | if (!empty($matches)) { 71 | return false; 72 | } 73 | 74 | $n = rand(0, 5); 75 | $get_tip = $this->translator 76 | ->trans('commands.'.str_replace(':', '.', $commandName).'.tips.' . $n . '.tip'); 77 | preg_match("/^commands./", $get_tip, $matches, null, 0); 78 | 79 | if (empty($matches)) { 80 | return $get_tip; 81 | } else { 82 | return $this->getTip($commandName); 83 | } 84 | } 85 | 86 | /** 87 | * @{@inheritdoc} 88 | */ 89 | public static function getSubscribedEvents() 90 | { 91 | return [ConsoleEvents::COMMAND => 'showTips']; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/EventSubscriber/ShowWelcomeMessageListener.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 38 | } 39 | 40 | /** 41 | * @param ConsoleCommandEvent $event 42 | */ 43 | public function showWelcomeMessage(ConsoleCommandEvent $event) 44 | { 45 | /* @var Command $command */ 46 | $command = $event->getCommand(); 47 | 48 | /* @var DrupalStyle $io */ 49 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 50 | 51 | $welcomeMessageKey = 'commands.'.str_replace(':', '.', $command->getName()).'.welcome'; 52 | $welcomeMessage = $this->translator->trans($welcomeMessageKey); 53 | 54 | if ($welcomeMessage != $welcomeMessageKey) { 55 | $io->text($welcomeMessage); 56 | } 57 | } 58 | 59 | /** 60 | * @{@inheritdoc} 61 | */ 62 | public static function getSubscribedEvents() 63 | { 64 | return [ConsoleEvents::COMMAND => 'showWelcomeMessage']; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/EventSubscriber/ValidateExecutionListener.php: -------------------------------------------------------------------------------- 1 | translator = $translator; 46 | $this->configurationManager = $configurationManager; 47 | } 48 | 49 | /** 50 | * @param ConsoleCommandEvent $event 51 | */ 52 | public function validateExecution(ConsoleCommandEvent $event) 53 | { 54 | /* @var Command $command */ 55 | $command = $event->getCommand(); 56 | /* @var DrupalStyle $io */ 57 | $io = new DrupalStyle($event->getInput(), $event->getOutput()); 58 | 59 | $configuration = $this->configurationManager->getConfiguration(); 60 | 61 | $mapping = $configuration->get('application.disable.commands')?:[]; 62 | if (array_key_exists($command->getName(), $mapping)) { 63 | $extra = $mapping[$command->getName()]; 64 | $message[] = sprintf( 65 | $this->translator->trans('application.messages.disable.command.error'), 66 | $command->getName() 67 | ); 68 | if ($extra) { 69 | $message[] = sprintf( 70 | $this->translator->trans('application.messages.disable.command.extra'), 71 | $extra 72 | ); 73 | } 74 | $io->commentBlock($message); 75 | } 76 | } 77 | 78 | /** 79 | * @{@inheritdoc} 80 | */ 81 | public static function getSubscribedEvents() 82 | { 83 | return [ConsoleEvents::COMMAND => 'validateExecution']; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Generator/Generator.php: -------------------------------------------------------------------------------- 1 | renderer = $renderer; 54 | } 55 | 56 | /** 57 | * @param $fileQueue 58 | */ 59 | public function setFileQueue(FileQueue $fileQueue) 60 | { 61 | $this->fileQueue = $fileQueue; 62 | } 63 | 64 | /** 65 | * @param $countCodeLines 66 | */ 67 | public function setCountCodeLines(CountCodeLines $countCodeLines) 68 | { 69 | $this->countCodeLines = $countCodeLines; 70 | } 71 | 72 | /** 73 | * @param DrupalFinder $drupalFinder 74 | */ 75 | public function setDrupalFinder($drupalFinder) 76 | { 77 | $this->drupalFinder = $drupalFinder; 78 | } 79 | 80 | /** 81 | * @return \Drupal\Console\Core\Style\DrupalStyle 82 | */ 83 | public function getIo() { 84 | return $this->io; 85 | } 86 | 87 | /** 88 | * @param \Drupal\Console\Core\Style\DrupalStyle $io 89 | */ 90 | public function setIo($io) { 91 | $this->io = $io; 92 | } 93 | 94 | /** 95 | * @param string $template 96 | * @param string $target 97 | * @param array $parameters 98 | * @param null $flag 99 | * 100 | * @return bool 101 | */ 102 | protected function renderFile( 103 | $template, 104 | $target, 105 | $parameters = [], 106 | $flag = null 107 | ) { 108 | if (!is_dir(dirname($target))) { 109 | if (!mkdir(dirname($target), 0777, true)) { 110 | throw new \InvalidArgumentException( 111 | sprintf( 112 | 'Path "%s" is invalid. You need to provide a valid path.', 113 | dirname($target) 114 | ) 115 | ); 116 | } 117 | } 118 | 119 | $currentLine = 0; 120 | if (!empty($flag) && file_exists($target)) { 121 | $currentLine = count(file($target)); 122 | } 123 | $content = $this->renderer->render($template, $parameters); 124 | 125 | if (file_put_contents($target, $content, $flag)) { 126 | $this->fileQueue->addFile($target); 127 | 128 | $newCodeLine = count(file($target)); 129 | 130 | if ($currentLine > 0) { 131 | $newCodeLine = ($newCodeLine-$currentLine); 132 | } 133 | 134 | $this->countCodeLines->addCountCodeLines($newCodeLine); 135 | 136 | return true; 137 | } 138 | 139 | return false; 140 | } 141 | 142 | public function addSkeletonDir($skeletonDir) 143 | { 144 | $this->renderer->addSkeletonDir($skeletonDir); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/Generator/GeneratorInterface.php: -------------------------------------------------------------------------------- 1 | configurationManager = $configurationManager; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function generate(array $parameters) 38 | { 39 | $userHome = $parameters['user_home']; 40 | $executableName = $parameters['executable_name']; 41 | $override = $parameters['override']; 42 | $destination = $parameters['destination']; 43 | $configParameters = $parameters['config_parameters']; 44 | 45 | $configFile = $userHome . 'config.yml'; 46 | if ($destination) { 47 | $configFile = $destination . 'config.yml'; 48 | } 49 | 50 | if (file_exists($configFile) && $override) { 51 | copy( 52 | $configFile, 53 | $configFile . '.old' 54 | ); 55 | } 56 | 57 | // If configFile is an override, we only change the value of statistics in the global config. 58 | $consoleDestination = $userHome . 'config.yml'; 59 | if ($configFile !== $consoleDestination) { 60 | if ($configParameters['statistics'] || file_exists($consoleDestination)) { 61 | $configParameters['statistics'] = $configParameters['statistics'] ? 'true' : 'false'; 62 | $this->renderFile( 63 | 'core/init/statistics.config.yml.twig', 64 | $consoleDestination, 65 | $configParameters 66 | ); 67 | } 68 | 69 | unset($configParameters['statistics']); 70 | } 71 | 72 | $configParameters = array_map( 73 | function ($item) { 74 | if (is_bool($item)) { 75 | return $item ? 'true' : 'false'; 76 | } 77 | return $item; 78 | }, 79 | $configParameters 80 | ); 81 | 82 | $this->renderFile( 83 | 'core/init/config.yml.twig', 84 | $configFile, 85 | $configParameters 86 | ); 87 | 88 | 89 | if ($executableName) { 90 | $parameters = [ 91 | 'executable' => $executableName, 92 | ]; 93 | 94 | $this->renderFile( 95 | 'core/autocomplete/console.rc.twig', 96 | $userHome . 'console.rc', 97 | $parameters 98 | ); 99 | 100 | $this->renderFile( 101 | 'core/autocomplete/console.fish.twig', 102 | $userHome . 'drupal.fish', 103 | $parameters 104 | ); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/Generator/SiteAliasGenerator.php: -------------------------------------------------------------------------------- 1 | renderFile( 18 | 'core/sites/alias.yml.twig', 19 | $parameters['directory'] . '/sites/' . $parameters['name'] . '.yml', 20 | $parameters, 21 | FILE_APPEND 22 | ); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Helper/DescriptorHelper.php: -------------------------------------------------------------------------------- 1 | 19 | */ 20 | class DescriptorHelper extends BaseHelper 21 | { 22 | /** 23 | * @var DescriptorInterface[] 24 | */ 25 | private $descriptors = []; 26 | /** 27 | * Constructor. 28 | */ 29 | public function __construct() 30 | { 31 | $this 32 | ->register('txt', new TextDescriptor()) 33 | ->register('xml', new XmlDescriptor()) 34 | ->register('json', new JsonDescriptor()) 35 | ->register('md', new MarkdownDescriptor()); 36 | } 37 | /** 38 | * Describes an object if supported. 39 | * 40 | * Available options are: 41 | * * format: string, the output format name 42 | * * raw_text: boolean, sets output type as raw 43 | * 44 | * @param OutputInterface $output 45 | * @param object $object 46 | * @param array $options 47 | * 48 | * @throws \InvalidArgumentException when the given format is not supported 49 | */ 50 | public function describe(OutputInterface $output, $object, array $options = []) 51 | { 52 | $options = array_merge( 53 | [ 54 | 'raw_text' => false, 55 | 'format' => 'txt', 56 | ], $options 57 | ); 58 | if (!isset($this->descriptors[$options['format']])) { 59 | throw new \InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format'])); 60 | } 61 | $descriptor = $this->descriptors[$options['format']]; 62 | $descriptor->describe($output, $object, $options); 63 | } 64 | /** 65 | * Registers a descriptor. 66 | * 67 | * @param string $format 68 | * @param DescriptorInterface $descriptor 69 | * 70 | * @return DescriptorHelper 71 | */ 72 | public function register($format, DescriptorInterface $descriptor) 73 | { 74 | $this->descriptors[$format] = $descriptor; 75 | return $this; 76 | } 77 | /** 78 | * {@inheritdoc} 79 | */ 80 | public function getName() 81 | { 82 | return 'descriptor'; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Helper/DrupalChoiceQuestionHelper.php: -------------------------------------------------------------------------------- 1 | getQuestion(); 26 | $default = $question->getDefault(); 27 | $choices = $question->getChoices(); 28 | 29 | $text = sprintf(' %s [%s]:', $text, $choices[$default]); 30 | 31 | $output->writeln($text); 32 | 33 | $output->write(' > '); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Style/DrupalStyle.php: -------------------------------------------------------------------------------- 1 | input = $input; 36 | parent::__construct($input, $output); 37 | } 38 | 39 | /** 40 | * @param string $question 41 | * @param array $choices 42 | * @param mixed $default 43 | * @param bool $skipValidation 44 | * 45 | * @return string 46 | */ 47 | public function choiceNoList( 48 | $question, 49 | array $choices, 50 | $default = null, 51 | $skipValidation = false 52 | ) { 53 | if (is_null($default)) { 54 | $default = current($choices); 55 | } 56 | 57 | if (!in_array($default, $choices)) { 58 | $choices[] = $default; 59 | } 60 | 61 | if (null !== $default) { 62 | $values = array_flip($choices); 63 | $default = $values[$default]; 64 | } 65 | 66 | $choiceQuestion = new ChoiceQuestion($question, $choices, $default); 67 | if ($skipValidation) { 68 | $choiceQuestion->setValidator( 69 | function ($answer) { 70 | return $answer; 71 | } 72 | ); 73 | } 74 | 75 | return trim($this->askChoiceQuestion($choiceQuestion)); 76 | } 77 | 78 | /** 79 | * @param string $question 80 | * @param array $choices 81 | * @param null $default 82 | * @param bool $multiple 83 | * 84 | * @return string 85 | */ 86 | public function choice($question, array $choices, $default = null, $multiple = false) 87 | { 88 | if (null !== $default) { 89 | $values = array_flip($choices); 90 | $default = $values[$default]; 91 | } 92 | 93 | $choiceQuestion = new ChoiceQuestion($question, $choices, $default); 94 | $choiceQuestion->setMultiselect($multiple); 95 | 96 | return $this->askQuestion($choiceQuestion); 97 | } 98 | 99 | /** 100 | * @param ChoiceQuestion $question 101 | * 102 | * @return string 103 | */ 104 | public function askChoiceQuestion(ChoiceQuestion $question) 105 | { 106 | $questionHelper = new DrupalChoiceQuestionHelper(); 107 | $answer = $questionHelper->ask($this->input, $this, $question); 108 | return $answer; 109 | } 110 | 111 | /** 112 | * @param $question 113 | * 114 | * @return string 115 | */ 116 | public function askHiddenEmpty($question) 117 | { 118 | $question = new Question($question, ''); 119 | $question->setHidden(true); 120 | $question->setValidator( 121 | function ($answer) { 122 | return $answer; 123 | } 124 | ); 125 | 126 | return trim($this->askQuestion($question)); 127 | } 128 | 129 | /** 130 | * @param string $question 131 | * @param string $default 132 | * @param null|callable $validator 133 | * 134 | * @return string 135 | */ 136 | public function askEmpty($question, $default = '', $validator = null) 137 | { 138 | $question = new Question($question, $default); 139 | if (!$validator) { 140 | $validator = function ($answer) { 141 | return $answer; 142 | }; 143 | } 144 | $question->setValidator($validator); 145 | 146 | return trim($this->askQuestion($question)); 147 | } 148 | 149 | /** 150 | * @param $message 151 | * @param bool $newLine 152 | */ 153 | public function info($message, $newLine = true) 154 | { 155 | $message = sprintf(' %s', $message); 156 | if ($newLine) { 157 | $this->writeln($message); 158 | } else { 159 | $this->write($message); 160 | } 161 | } 162 | 163 | /** 164 | * @param array|string $message 165 | * @param bool $newLine 166 | */ 167 | public function comment($message, $newLine = true) 168 | { 169 | $message = sprintf(' %s', $message); 170 | if ($newLine) { 171 | $this->writeln($message); 172 | } else { 173 | $this->write($message); 174 | } 175 | } 176 | 177 | /** 178 | * @param $message 179 | */ 180 | public function commentBlock($message) 181 | { 182 | $this->block( 183 | $message, null, 184 | 'bg=yellow;fg=black', 185 | ' ', 186 | true 187 | ); 188 | } 189 | 190 | /** 191 | * @param array $headers 192 | * @param array $rows 193 | * @param string $style 194 | */ 195 | public function table(array $headers, array $rows, $style = 'symfony-style-guide') 196 | { 197 | $headers = array_map( 198 | function ($value) { 199 | return sprintf('%s', $value); 200 | }, $headers 201 | ); 202 | 203 | if (!is_array(current($rows))) { 204 | $rows = array_map( 205 | function ($row) { 206 | return [$row]; 207 | }, 208 | $rows 209 | ); 210 | } 211 | 212 | $table = new Table($this); 213 | $table->setHeaders($headers); 214 | $table->setRows($rows); 215 | $table->setStyle($style); 216 | 217 | $table->render(); 218 | $this->newLine(); 219 | } 220 | 221 | /** 222 | * @param $message 223 | * @param bool $newLine 224 | */ 225 | public function simple($message, $newLine = true) 226 | { 227 | $message = sprintf(' %s', $message); 228 | if ($newLine) { 229 | $this->writeln($message); 230 | } else { 231 | $this->write($message); 232 | } 233 | } 234 | 235 | /** 236 | * {@inheritdoc} 237 | */ 238 | public function warning($message) 239 | { 240 | $this->block($message, 'WARNING', 'fg=white;bg=yellow', ' ', true); 241 | } 242 | 243 | /** 244 | * @param array|string $message 245 | */ 246 | public function text($message) 247 | { 248 | $message = sprintf('// %s', $message); 249 | parent::text($message); 250 | } 251 | 252 | public function successLite($message, $newLine = false) 253 | { 254 | $message = sprintf(' %s', $message); 255 | parent::text($message); 256 | if ($newLine) { 257 | parent::newLine(); 258 | } 259 | } 260 | 261 | public function errorLite($message, $newLine = false) 262 | { 263 | $message = sprintf('✘ %s', $message); 264 | parent::text($message); 265 | if ($newLine) { 266 | parent::newLine(); 267 | } 268 | } 269 | 270 | public function warningLite($message, $newLine = false) 271 | { 272 | $message = sprintf('! %s', $message); 273 | parent::text($message); 274 | if ($newLine) { 275 | parent::newLine(); 276 | } 277 | } 278 | 279 | public function customLite($message, $prefix = '*', $style = '', $newLine = false) 280 | { 281 | if ($style) { 282 | $message = sprintf( 283 | '<%s>%s %s', 284 | $style, 285 | $prefix, 286 | $style, 287 | $message 288 | ); 289 | } else { 290 | $message = sprintf( 291 | '%s %s', 292 | $prefix, 293 | $message 294 | ); 295 | } 296 | parent::text($message); 297 | if ($newLine) { 298 | parent::newLine(); 299 | } 300 | } 301 | 302 | /** 303 | * @return InputInterface 304 | */ 305 | public function getInput() 306 | { 307 | return $this->input; 308 | } 309 | } 310 | -------------------------------------------------------------------------------- /src/Utils/ArgvInputReader.php: -------------------------------------------------------------------------------- 1 | originalArgvValues = $_SERVER['argv']; 37 | $this->options = []; 38 | $this->setOptionsFromPlaceHolders(); 39 | $this->readArgvInputValues(); 40 | } 41 | 42 | /** 43 | * @param array $targetConfig 44 | */ 45 | public function setOptionsFromTargetConfiguration($targetConfig) 46 | { 47 | $options = []; 48 | if (array_key_exists('root', $targetConfig)) { 49 | $options['root'] = $targetConfig['root']; 50 | } 51 | if (array_key_exists('uri', $targetConfig)) { 52 | $options['uri'] = $targetConfig['uri']; 53 | } 54 | 55 | if (array_key_exists('remote', $targetConfig)) { 56 | $this->set('remote', true); 57 | } 58 | 59 | $this->setArgvOptions($options); 60 | } 61 | 62 | /** 63 | * @param array $options 64 | */ 65 | public function setOptionsFromConfiguration($options) 66 | { 67 | $this->setArgvOptions($options); 68 | } 69 | 70 | /** 71 | * @param $options 72 | */ 73 | private function setArgvOptions($options) 74 | { 75 | $argvInput = new ArgvInput(); 76 | foreach ($options as $key => $option) { 77 | if (!$option) { 78 | continue; 79 | } 80 | 81 | if (!$argvInput->hasParameterOption($key)) { 82 | if ($option == 1) { 83 | $_SERVER['argv'][] = sprintf('--%s', $key); 84 | } else { 85 | $_SERVER['argv'][] = sprintf('--%s=%s', $key, $option); 86 | } 87 | continue; 88 | } 89 | if ($key === 'root') { 90 | $option = sprintf( 91 | '%s%s', 92 | $argvInput->getParameterOption(['--root'], null), 93 | $option 94 | ); 95 | } 96 | foreach ($_SERVER['argv'] as $argvKey => $argv) { 97 | if (strpos($argv, '--'.$key) === 0) { 98 | if ($option == 1) { 99 | $_SERVER['argv'][$argvKey] = sprintf('--%s', $key); 100 | } else { 101 | $_SERVER['argv'][$argvKey] = sprintf( 102 | '--%s=%s', 103 | $key, 104 | $option 105 | ); 106 | } 107 | continue; 108 | } 109 | } 110 | } 111 | $this->readArgvInputValues(); 112 | } 113 | 114 | /** 115 | * setOptionsFromPlaceHolders. 116 | */ 117 | private function setOptionsFromPlaceHolders() 118 | { 119 | if (count($_SERVER['argv']) > 2 120 | && stripos($_SERVER['argv'][1], '@') === 0 121 | && stripos($_SERVER['argv'][2], '@') === 0 122 | ) { 123 | $_SERVER['argv'][1] = sprintf( 124 | '--source=%s', 125 | substr($_SERVER['argv'][1], 1) 126 | ); 127 | 128 | $_SERVER['argv'][2] = sprintf( 129 | '--target=%s', 130 | substr($_SERVER['argv'][2], 1) 131 | ); 132 | 133 | return; 134 | } 135 | 136 | if (count($_SERVER['argv']) > 1 && stripos($_SERVER['argv'][1], '@') === 0) { 137 | $_SERVER['argv'][1] = sprintf( 138 | '--target=%s', 139 | substr($_SERVER['argv'][1], 1) 140 | ); 141 | } 142 | } 143 | 144 | /** 145 | * ReadArgvInputValues. 146 | */ 147 | private function readArgvInputValues() 148 | { 149 | $input = new ArgvInput(); 150 | 151 | $source = $input->getParameterOption(['--source', '-s'], null); 152 | $target = $input->getParameterOption(['--target', '-t'], null); 153 | $root = $input->getParameterOption(['--root'], null); 154 | $debug = $input->hasParameterOption(['--debug']); 155 | $uri = $input->getParameterOption(['--uri', '-l']) ?: 'default'; 156 | if ($uri && !preg_match('/^(http|https):\/\//', $uri)) { 157 | $uri = sprintf('http://%s', $uri); 158 | } 159 | 160 | $this->set('command', $input->getFirstArgument()); 161 | $this->set('root', $root); 162 | $this->set('uri', $uri); 163 | $this->set('debug', $debug); 164 | $this->set('source', $source); 165 | $this->set('target', $target); 166 | } 167 | 168 | /** 169 | * @param $option 170 | * @param $value 171 | */ 172 | public function set($option, $value) 173 | { 174 | if ($value) { 175 | $this->options[$option] = $value; 176 | 177 | return; 178 | } 179 | 180 | if (!array_key_exists($option, $this->options)) { 181 | unset($this->options[$option]); 182 | } 183 | } 184 | 185 | /** 186 | * @param $option 187 | * @param null $value 188 | * 189 | * @return string 190 | */ 191 | public function get($option, $value = null) 192 | { 193 | if (!array_key_exists($option, $this->options)) { 194 | return $value; 195 | } 196 | 197 | return $this->options[$option]; 198 | } 199 | 200 | /** 201 | * @return array 202 | */ 203 | public function getAll() 204 | { 205 | return $this->options; 206 | } 207 | 208 | /** 209 | * setOptionsAsArgv 210 | */ 211 | public function setOptionsAsArgv() 212 | { 213 | foreach ($this->options as $optionName => $optionValue) { 214 | if ($optionName == 'command') { 215 | continue; 216 | } 217 | $optionFound = false; 218 | foreach ($_SERVER['argv'] as $key => $argv) { 219 | if (strpos($argv, '--'.$optionName) === 0) { 220 | $_SERVER['argv'][$key] = '--'.$optionName.'='.$optionValue; 221 | $optionFound = true; 222 | break; 223 | } 224 | } 225 | if (!$optionFound) { 226 | $_SERVER['argv'][] = '--'.$optionName.'='.$optionValue; 227 | } 228 | } 229 | } 230 | 231 | /** 232 | * @return array 233 | */ 234 | public function restoreOriginalArgvValues() 235 | { 236 | return $_SERVER['argv'] = $this->originalArgvValues; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/Utils/ChainQueue.php: -------------------------------------------------------------------------------- 1 | commands[] = 39 | [ 40 | 'name' => $name, 41 | 'inputs' => $inputs, 42 | 'interactive' => $interactive 43 | ]; 44 | } 45 | 46 | /** 47 | * @return array 48 | */ 49 | public function getCommands() 50 | { 51 | return $this->commands; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Utils/CountCodeLines.php: -------------------------------------------------------------------------------- 1 | countCodeLine = $this->countCodeLine + $countCodeLine; 28 | } 29 | 30 | /** 31 | * @return integer 32 | */ 33 | public function getCountCodeLines() 34 | { 35 | return $this->countCodeLine; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Utils/DrupalFinder.php: -------------------------------------------------------------------------------- 1 | getVendorDir(), 42 | $this->getComposerRoot() 43 | ); 44 | 45 | $this->definePaths($vendorDir); 46 | $this->defineConstants($vendorDir); 47 | 48 | return true; 49 | } 50 | 51 | $this->definePaths($vendorDir); 52 | $this->defineConstants($vendorDir); 53 | 54 | return false; 55 | } 56 | 57 | protected function definePaths($vendorDir) 58 | { 59 | $this->consoleCorePath = "/{$vendorDir}/drupal/console-core/"; 60 | $this->consolePath = "/{$vendorDir}/drupal/console/"; 61 | $this->consoleLanguagePath = "/{$vendorDir}/drupal/console-%s/translations/"; 62 | } 63 | 64 | protected function defineConstants($vendorDir) 65 | { 66 | if (!defined("DRUPAL_CONSOLE_CORE")) { 67 | define( 68 | "DRUPAL_CONSOLE_CORE", 69 | "/{$vendorDir}/drupal/console-core/" 70 | ); 71 | } 72 | if (!defined("DRUPAL_CONSOLE")) { 73 | define("DRUPAL_CONSOLE", "/{$vendorDir}/drupal/console/"); 74 | } 75 | if (!defined("DRUPAL_CONSOLE_LANGUAGE")) { 76 | define( 77 | "DRUPAL_CONSOLE_LANGUAGE", 78 | "/{$vendorDir}/drupal/console-%s/translations/" 79 | ); 80 | } 81 | if (!defined("DRUPAL_CONSOLE_LANGUAGE_INSTALLERS")) { 82 | define( 83 | "DRUPAL_CONSOLE_LANGUAGE_INSTALLERS", 84 | "/console/language/console-%s/translations/" 85 | ); 86 | } 87 | 88 | if (!defined("DRUPAL_CONSOLE_LIBRARY")) { 89 | define( 90 | "DRUPAL_CONSOLE_LIBRARY", 91 | "/{$vendorDir}/drupal/%s/console/translations/%s" 92 | ); 93 | } 94 | } 95 | 96 | /** 97 | * @return string 98 | */ 99 | public function getConsoleCorePath() 100 | { 101 | return $this->consoleCorePath; 102 | } 103 | 104 | /** 105 | * @return string 106 | */ 107 | public function getConsolePath() 108 | { 109 | return $this->consolePath; 110 | } 111 | 112 | /** 113 | * @return string 114 | */ 115 | public function getConsoleLanguagePath() 116 | { 117 | return $this->consoleLanguagePath; 118 | } 119 | 120 | public function isValidDrupal() { 121 | return ($this->getComposerRoot() && $this->getDrupalRoot()); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Utils/FileQueue.php: -------------------------------------------------------------------------------- 1 | appRoot = $appRoot; 35 | } 36 | 37 | /** 38 | * @param $file string 39 | */ 40 | public function addFile($file) 41 | { 42 | $file = str_replace($this->appRoot, '', $file); 43 | $this->files[] = $file; 44 | } 45 | 46 | /** 47 | * @return array 48 | */ 49 | public function getFiles() 50 | { 51 | return $this->files; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Utils/KeyValueStorage.php: -------------------------------------------------------------------------------- 1 | data); 26 | } 27 | 28 | /** 29 | * Gets the given key from the container, or returns the default if it does 30 | * not exist. 31 | * 32 | * @param string $key 33 | * The key to get. 34 | * @param mixed $default 35 | * Default value to return. 36 | * 37 | * @return mixed 38 | */ 39 | public function get($key, $default = null) 40 | { 41 | return $this->has($key) ? $this->data[$key] : $default; 42 | } 43 | 44 | /** 45 | * Sets the given key in the container. 46 | * 47 | * @param mixed $key 48 | * The key to set 49 | * @param mixed $value 50 | * The value. 51 | */ 52 | public function set($key, $value = null) 53 | { 54 | $this->data[$key] = $value; 55 | } 56 | 57 | /** 58 | * Removes the given key from the container. 59 | * 60 | * @param string $key The key to forget. 61 | * 62 | * @return void 63 | */ 64 | public function remove($key) 65 | { 66 | unset($this->data[$key]); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/Utils/MessageManager.php: -------------------------------------------------------------------------------- 1 | messages[] = [ 28 | 'type' =>$type, 29 | 'message' => $message, 30 | 'code' => $code, 31 | 'showBy' => $showBy, 32 | 'removeBy' => $removeBy, 33 | ]; 34 | } 35 | 36 | /** 37 | * @param $message 38 | * @param $code 39 | * @param $showBy 40 | * @param $removeBy 41 | */ 42 | public function error($message, $code = 0, $showBy = 'all', $removeBy = null) 43 | { 44 | $this->add('error', $message, $code, $showBy, $removeBy); 45 | } 46 | 47 | /** 48 | * @param $message 49 | * @param $code 50 | * @param $showBy 51 | * @param $removeBy 52 | */ 53 | public function warning($message, $code = 0, $showBy = 'all', $removeBy = null) 54 | { 55 | $this->add('warning', $message, $code, $showBy, $removeBy); 56 | } 57 | 58 | /** 59 | * @param $message 60 | * @param $code 61 | * @param $showBy 62 | * @param $removeBy 63 | */ 64 | public function info($message, $code = 0, $showBy = 'all', $removeBy = null) 65 | { 66 | $this->add('info', $message, $code, $showBy, $removeBy); 67 | } 68 | 69 | /** 70 | * @param $message 71 | * @param $code 72 | * @param $showBy 73 | * @param $removeBy 74 | */ 75 | public function listing(array $message, $code = 0, $showBy = 'all', $removeBy = null) 76 | { 77 | $this->add('listing', $message, $code, $showBy, $removeBy); 78 | } 79 | 80 | /** 81 | * @param $message 82 | * @param $code 83 | * @param $showBy 84 | * @param $removeBy 85 | */ 86 | public function comment($message, $code = 0, $showBy = 'all', $removeBy = null) 87 | { 88 | $this->add('comment', $message, $code, $showBy, $removeBy); 89 | } 90 | 91 | /** 92 | * @return array 93 | */ 94 | public function getMessages() 95 | { 96 | return $this->messages; 97 | } 98 | 99 | public function remove($removeBy = null) 100 | { 101 | $this->messages = array_filter( 102 | $this->messages, 103 | function ($message) use ($removeBy) { 104 | if (is_null($message['removeBy'])) { 105 | return true; 106 | } 107 | 108 | return !($message['removeBy'] == $removeBy); 109 | } 110 | ); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Utils/RequirementChecker.php: -------------------------------------------------------------------------------- 1 | parser = new Parser(); 45 | } 46 | 47 | /** 48 | * 49 | */ 50 | private function checkPHPVersion() 51 | { 52 | $requiredPHP = $this->requirements['requirements']['php']['required']; 53 | $currentPHP = phpversion(); 54 | $this->checkResult['php']['required'] = $requiredPHP; 55 | $this->checkResult['php']['current'] = $currentPHP; 56 | $this->valid = (version_compare($currentPHP, $requiredPHP) >= 0); 57 | $this->checkResult['php']['valid'] = $this->valid; 58 | } 59 | 60 | /** 61 | * checkRequiredExtensions 62 | */ 63 | private function checkRequiredExtensions() 64 | { 65 | $this->checkResult['extensions']['required']['missing'] = []; 66 | foreach ($this->requirements['requirements']['extensions']['required'] as $extension) { 67 | if (!extension_loaded($extension)) { 68 | $this->checkResult['extensions']['required']['missing'][] = $extension; 69 | $this->valid = false; 70 | } 71 | } 72 | } 73 | 74 | /** 75 | * checkRecommendedExtensions 76 | */ 77 | private function checkRecommendedExtensions() 78 | { 79 | $this->checkResult['extensions']['recommended']['missing'] = []; 80 | foreach ($this->requirements['requirements']['extensions']['recommended'] as $extension) { 81 | if (!extension_loaded($extension)) { 82 | $this->checkResult['extensions']['recommended']['missing'][] = $extension; 83 | } 84 | } 85 | } 86 | 87 | /** 88 | * checkRequiredConfigurations 89 | */ 90 | private function checkRequiredConfigurations() 91 | { 92 | $this->checkResult['configurations']['required']['overwritten'] = []; 93 | $this->checkResult['configurations']['required']['missing'] = []; 94 | foreach ($this->requirements['requirements']['configurations']['required'] as $configuration) { 95 | $defaultValue = null; 96 | if (is_array($configuration)) { 97 | $defaultValue = current($configuration); 98 | $configuration = key($configuration); 99 | } 100 | 101 | if (!ini_get($configuration)) { 102 | if ($defaultValue) { 103 | ini_set($configuration, $defaultValue); 104 | $this->checkResult['configurations']['required']['overwritten'] = [ 105 | $configuration => $defaultValue 106 | ]; 107 | $this->overwritten = true; 108 | continue; 109 | } 110 | $this->valid = false; 111 | $this->checkResult['configurations']['required']['missing'][] = $configuration; 112 | } 113 | } 114 | } 115 | 116 | /** 117 | * @param $files 118 | * @return array 119 | */ 120 | public function validate($files) 121 | { 122 | if (!is_array($files)) { 123 | $files = [$files]; 124 | } 125 | 126 | foreach ($files as $file) { 127 | if (file_exists($file)) { 128 | $this->requirements = array_merge( 129 | $this->requirements, 130 | $this->parser->parse( 131 | file_get_contents($file) 132 | ) 133 | ); 134 | } 135 | } 136 | 137 | if (!$this->checkResult) { 138 | $this->checkPHPVersion(); 139 | $this->checkRequiredExtensions(); 140 | $this->checkRecommendedExtensions(); 141 | $this->checkRequiredConfigurations(); 142 | } 143 | 144 | return $this->checkResult; 145 | } 146 | 147 | /** 148 | * @return array 149 | */ 150 | public function getCheckResult() 151 | { 152 | return $this->checkResult; 153 | } 154 | 155 | /** 156 | * @return boolean 157 | */ 158 | public function isOverwritten() 159 | { 160 | return $this->overwritten; 161 | } 162 | 163 | /** 164 | * @return bool 165 | */ 166 | public function isValid() 167 | { 168 | return $this->valid; 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /src/Utils/ShellProcess.php: -------------------------------------------------------------------------------- 1 | appRoot = $appRoot; 46 | $this->translator = $translator; 47 | 48 | $output = new ConsoleOutput(); 49 | $input = new ArrayInput([]); 50 | $this->io = new DrupalStyle($input, $output); 51 | } 52 | 53 | /** 54 | * @param string $command 55 | * @param string $workingDirectory 56 | * 57 | * @throws ProcessFailedException 58 | * 59 | * @return Process 60 | */ 61 | public function exec($command, $workingDirectory=null) 62 | { 63 | if (!$workingDirectory || $workingDirectory==='') { 64 | $workingDirectory = $this->appRoot; 65 | } 66 | 67 | if (realpath($workingDirectory)) { 68 | $this->io->comment( 69 | $this->translator->trans('commands.exec.messages.working-directory') .': ', 70 | false 71 | ); 72 | $this->io->writeln(realpath($workingDirectory)); 73 | } 74 | 75 | $this->io->comment( 76 | $this->translator->trans('commands.exec.messages.executing-command') .': ', 77 | false 78 | ); 79 | $this->io->writeln($command); 80 | 81 | $this->process = new Process($command); 82 | $this->process->setWorkingDirectory($workingDirectory); 83 | $this->process->enableOutput(); 84 | $this->process->setTimeout(null); 85 | $this->process->run( 86 | function ($type, $buffer) { 87 | $this->io->write($buffer); 88 | } 89 | ); 90 | 91 | if (!$this->process->isSuccessful()) { 92 | throw new ProcessFailedException($this->process); 93 | } 94 | 95 | return $this->process->isSuccessful(); 96 | } 97 | 98 | /** 99 | * @return string 100 | */ 101 | public function getOutput() 102 | { 103 | return $this->process->getOutput(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/Utils/ShowFile.php: -------------------------------------------------------------------------------- 1 | root = $root; 40 | $this->translator = $translator; 41 | } 42 | 43 | /** 44 | * @param DrupalStyle $io 45 | * @param string $files 46 | * @param boolean $showPath 47 | */ 48 | public function generatedFiles($io, $files, $showPath = true) 49 | { 50 | $pathKey = null; 51 | $path = null; 52 | if ($showPath) { 53 | $pathKey = 'application.messages.path'; 54 | $path = $this->root; 55 | } 56 | $this->showMMultiple( 57 | $io, 58 | $files, 59 | 'application.messages.files.generated', 60 | $pathKey, 61 | $path 62 | ); 63 | } 64 | 65 | /** 66 | * @param DrupalStyle $io 67 | * @param array $files 68 | * @param boolean $showPath 69 | */ 70 | public function copiedFiles($io, $files, $showPath = true) 71 | { 72 | $pathKey = null; 73 | $path = null; 74 | if ($showPath) { 75 | $pathKey = 'application.user.messages.path'; 76 | $path = rtrim(getenv('HOME') ?: getenv('USERPROFILE'), '/\\').'/.console/'; 77 | } 78 | $this->showMMultiple( 79 | $io, 80 | $files, 81 | 'application.messages.files.copied', 82 | $pathKey, 83 | $path 84 | ); 85 | } 86 | 87 | /** 88 | * @param DrupalStyle $io 89 | * @param array $files 90 | * @param string $headerKey 91 | * @param string $pathKey 92 | * @param string $path 93 | */ 94 | private function showMMultiple($io, $files, $headerKey, $pathKey, $path) 95 | { 96 | if (!$files) { 97 | return; 98 | } 99 | 100 | $io->writeln($this->translator->trans($headerKey)); 101 | 102 | if ($pathKey) { 103 | $io->info( 104 | sprintf('%s:', $this->translator->trans($pathKey)), 105 | false 106 | ); 107 | } 108 | if ($path) { 109 | $io->comment($path, false); 110 | } 111 | $io->newLine(); 112 | 113 | $index = 1; 114 | foreach ($files as $file) { 115 | $this->showSingle($io, $file, $index); 116 | ++$index; 117 | } 118 | } 119 | 120 | /** 121 | * @param DrupalStyle $io 122 | * @param string $file 123 | * @param int $index 124 | */ 125 | private function showSingle(DrupalStyle $io, $file, $index) 126 | { 127 | $io->info( 128 | sprintf('%s -', $index), 129 | false 130 | ); 131 | $io->comment($file, false); 132 | $io->newLine(); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/Utils/StringConverter.php: -------------------------------------------------------------------------------- 1 | trimMachineNameToMaxLength($machine_name); 41 | } 42 | 43 | /** 44 | * Converts camel-case strings to machine-name format. 45 | * 46 | * @param String $name User input 47 | * 48 | * @return String $machine_name User input in machine-name format 49 | */ 50 | public function camelCaseToMachineName($name) 51 | { 52 | $machine_name = preg_replace(self::REGEX_UPPER_CASE_LETTERS, '_$1', $name); 53 | $machine_name = preg_replace(self::REGEX_MACHINE_NAME_CHARS, '_', strtolower($machine_name)); 54 | $machine_name = trim($machine_name, '_'); 55 | 56 | return $this->trimMachineNameToMaxLength($machine_name); 57 | } 58 | 59 | /** 60 | * Trim machine name if it exceed max number of symbols for machine names. 61 | * 62 | * @param string $machine_name 63 | * Machine name. 64 | * 65 | * @return string 66 | * Machine name. 67 | */ 68 | public function trimMachineNameToMaxLength($machine_name) { 69 | if (strlen($machine_name) > self::MAX_MACHINE_NAME) { 70 | $machine_name = substr($machine_name, 0, self::MAX_MACHINE_NAME); 71 | } 72 | return $machine_name; 73 | } 74 | 75 | /** 76 | * Converts camel-case strings to under-score format. 77 | * 78 | * @param String $camel_case User input 79 | * 80 | * @return String 81 | */ 82 | public function camelCaseToUnderscore($camel_case) 83 | { 84 | return strtolower(preg_replace(self::REGEX_CAMEL_CASE_UNDER, '$1_$2', $camel_case)); 85 | } 86 | 87 | /** 88 | * Converts camel-case strings to human readable format. 89 | * 90 | * @param String $camel_case User input 91 | * 92 | * @return String 93 | */ 94 | public function camelCaseToHuman($camel_case) 95 | { 96 | return ucfirst(strtolower(preg_replace(self::REGEX_CAMEL_CASE_UNDER, '$1 $2', $camel_case))); 97 | } 98 | 99 | /** 100 | * @param $human 101 | * @return mixed 102 | */ 103 | public function humanToCamelCase($human) 104 | { 105 | return str_replace(' ', '', ucwords($human)); 106 | } 107 | 108 | /** 109 | * Converts My Name to my name. For permissions. 110 | * 111 | * @param String $permission User input 112 | * 113 | * @return String 114 | */ 115 | public function camelCaseToLowerCase($permission) 116 | { 117 | return strtolower(preg_replace(self::REGEX_SPACES, ' ', $permission)); 118 | } 119 | 120 | /** 121 | * Convert the first character of upper case. For permissions. 122 | * 123 | * @param String $permission_title User input 124 | * 125 | * @return String 126 | */ 127 | public function anyCaseToUcFirst($permission_title) 128 | { 129 | return ucfirst(preg_replace(self::REGEX_SPACES, ' ', $permission_title)); 130 | } 131 | 132 | /** 133 | * @param $className 134 | * @return string 135 | */ 136 | public function removeSuffix($className) 137 | { 138 | $suffixes = [ 139 | 'Form', 140 | 'Controller', 141 | 'Service', 142 | 'Command' 143 | ]; 144 | 145 | if (strlen($className) == 0) { 146 | return $className; 147 | } 148 | 149 | foreach ($suffixes as $suffix) { 150 | $length = strlen($suffix); 151 | if (strlen($className) <= $length) { 152 | continue; 153 | } 154 | 155 | if (substr($className, -$length) === $suffix) { 156 | return substr($className, 0, -$length); 157 | } 158 | } 159 | 160 | return $className; 161 | } 162 | 163 | /** 164 | * @param $input 165 | * @return string 166 | */ 167 | public function underscoreToCamelCase($input) 168 | { 169 | return lcfirst(str_replace('_', '', ucwords($input, '_'))); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /src/Utils/TranslatorManager.php: -------------------------------------------------------------------------------- 1 | parser = new Parser(); 64 | $this->filesystem = new Filesystem(); 65 | 66 | $output = new ConsoleOutput(); 67 | $input = new ArrayInput([]); 68 | $this->io = new DrupalStyle($input, $output); 69 | } 70 | 71 | /** 72 | * @param $resource 73 | * @param string $name 74 | */ 75 | private function addResource($resource, $name = 'yaml') 76 | { 77 | $this->translator->addResource( 78 | $name, 79 | $resource, 80 | $this->language 81 | ); 82 | } 83 | 84 | /** 85 | * @param $loader 86 | * @param string $name 87 | */ 88 | private function addLoader($loader, $name = 'yaml') 89 | { 90 | $this->translator->addLoader( 91 | $name, 92 | $loader 93 | ); 94 | } 95 | 96 | /** 97 | * @param $language 98 | * @param $directoryRoot 99 | * 100 | * @return array 101 | */ 102 | private function buildCoreLanguageDirectory( 103 | $language, 104 | $directoryRoot 105 | ) { 106 | $output = new ConsoleOutput(); 107 | $input = new ArrayInput([]); 108 | $io = new DrupalStyle($input, $output); 109 | 110 | $coreLanguageDirectory = 111 | $directoryRoot . 112 | sprintf( 113 | DRUPAL_CONSOLE_LANGUAGE, 114 | $language 115 | ); 116 | $installersLanguageDirectory = 117 | $directoryRoot . 118 | sprintf( 119 | DRUPAL_CONSOLE_LANGUAGE_INSTALLERS, 120 | $language 121 | ); 122 | 123 | $languageDirectory = null; 124 | foreach ([$coreLanguageDirectory, $installersLanguageDirectory] as $candidate) { 125 | if (is_dir($candidate)) { 126 | $languageDirectory = $candidate; 127 | } 128 | } 129 | 130 | if (!isset($languageDirectory)) { 131 | if ($language == 'en') { 132 | throw new \Exception('No languages found. Make sure you have installed a console language package in a supported directory'); 133 | }else{ 134 | $io->warning( 135 | sprintf( 136 | 'Language not available please execute this command in order to get the language locally using composer, run composer require drupal/console-'.$language.'' 137 | ) 138 | ); 139 | } 140 | return $this->buildCoreLanguageDirectory('en', $directoryRoot); 141 | } 142 | 143 | if (!$this->coreLanguageRoot) { 144 | $this->coreLanguageRoot = $directoryRoot; 145 | } 146 | 147 | return [$language, $languageDirectory]; 148 | } 149 | 150 | /** 151 | * {@inheritdoc} 152 | */ 153 | public function loadCoreLanguage($language, $directoryRoot) 154 | { 155 | $coreLanguageDirectory = $this->buildCoreLanguageDirectory( 156 | $language, 157 | $directoryRoot 158 | ); 159 | 160 | $this->loadResource( 161 | $coreLanguageDirectory[0], 162 | $coreLanguageDirectory[1] 163 | ); 164 | 165 | return $this; 166 | } 167 | 168 | /** 169 | * {@inheritdoc} 170 | */ 171 | public function changeCoreLanguage($language) 172 | { 173 | return $this->loadCoreLanguage($language, $this->coreLanguageRoot); 174 | } 175 | 176 | /** 177 | * {@inheritdoc} 178 | */ 179 | public function loadResource($language, $directoryRoot) 180 | { 181 | if (!is_dir($directoryRoot)) { 182 | return; 183 | } 184 | 185 | $this->language = $language; 186 | $this->translator = new Translator($this->language); 187 | $this->addLoader(new ArrayLoader(), 'array'); 188 | $this->addLoader(new YamlFileLoader(), 'yaml'); 189 | 190 | /* @TODO fallback to en */ 191 | $finder = new Finder(); 192 | $finder->files() 193 | ->name('*.yml') 194 | ->in($directoryRoot); 195 | 196 | foreach ($finder as $file) { 197 | $resource = $directoryRoot.'/'.$file->getBasename(); 198 | $filename = $file->getBasename('.yml'); 199 | 200 | // Handle application file different than commands 201 | if ($filename == 'application') { 202 | try { 203 | $this->loadTranslationByFile($resource, 'application'); 204 | } catch (ParseException $e) { 205 | $this->io->error('application.yml'.' '.$e->getMessage()); 206 | } 207 | 208 | continue; 209 | } 210 | $key = 'commands.'.$filename; 211 | try { 212 | $this->loadTranslationByFile($resource, $key); 213 | } catch (ParseException $e) { 214 | $this->io->error($key.'.yml '.$e->getMessage()); 215 | } 216 | } 217 | 218 | return; 219 | } 220 | 221 | /** 222 | * Load yml translation where filename is part of translation key. 223 | * 224 | * @param $resource 225 | * @param $resourceKey 226 | */ 227 | protected function loadTranslationByFile($resource, $resourceKey = null) 228 | { 229 | $resourceParsed = $this->parser->parse(file_get_contents($resource)); 230 | 231 | if ($resourceKey) { 232 | $parents = explode('.', $resourceKey); 233 | $resourceArray = []; 234 | $this->setResourceArray($parents, $resourceArray, $resourceParsed); 235 | $resourceParsed = $resourceArray; 236 | } 237 | 238 | $this->addResource($resourceParsed, 'array'); 239 | } 240 | 241 | /** 242 | * @param $parents 243 | * @param $parentsArray 244 | * @param $resource 245 | * 246 | * @return mixed 247 | */ 248 | private function setResourceArray($parents, &$parentsArray, $resource) 249 | { 250 | $ref = &$parentsArray; 251 | foreach ($parents as $parent) { 252 | $ref[$parent] = []; 253 | $previous = &$ref; 254 | $ref = &$ref[$parent]; 255 | } 256 | 257 | $previous[$parent] = $resource; 258 | 259 | return $parentsArray; 260 | } 261 | 262 | /** 263 | * {@inheritdoc} 264 | */ 265 | public function getTranslator() 266 | { 267 | return $this->translator; 268 | } 269 | 270 | /** 271 | * {@inheritdoc} 272 | */ 273 | public function getLanguage() 274 | { 275 | return $this->language; 276 | } 277 | 278 | /** 279 | * {@inheritdoc} 280 | */ 281 | public function trans($key) 282 | { 283 | return $this->translator->trans($key); 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /src/Utils/TranslatorManagerInterface.php: -------------------------------------------------------------------------------- 1 | /dev/null 10 | fi 11 | -------------------------------------------------------------------------------- /templates/core/druplicon/1.twig: -------------------------------------------------------------------------------- 1 | /` 2 | +o/` 3 | -oooo/. 4 | .+oooooo/- 5 | ./oooooo+//::` 6 | `.:+ooooo/-` 7 | .:+ooooooo+. `...` 8 | ./+ooooooooo/ ./oooooo+- 9 | -+ooooooooooo+` -oooooooooo/ ` 10 | `/ooooooooooooo/ +ooooooooooo. .+. 11 | `+oooooooooooooo+ /ooooooooooo. -oo/` 12 | +oooooooooooooooo- `/oooooooo+. +ooo+` 13 | :oooooooooooooooo+/` `-////:. `+ooooo+` 14 | +oooooooooooo+:.` `:+ooooooo: 15 | ooooooooooo/` .:+oooooooooo+ 16 | ooooooooo+` `.-::--` :oooooooooooo 17 | /ooooooo/ -+oooooooo+:` -oooooooooo+ 18 | .oooooo+` `+oooooooooooo+. /ooooooooo- 19 | :ooooo: /oooooooooooooo+` .oooooooo/ 20 | /oooo- +ooooooooooooooo. `ooooooo/ 21 | :ooo: :oooooooooooooo+ .oooooo: 22 | `/oo` :oooooooooooo+` /oooo/. 23 | ./+` .:+ooooooo/- :ooo/. 24 | `-` `..... `/o/-` 25 | `-:.` 26 | -------------------------------------------------------------------------------- /templates/core/druplicon/2.twig: -------------------------------------------------------------------------------- 1 | .,. 2 | .cd:.. 3 | .xXd,,'.. 4 | .lXWx;;;,,.. 5 | .,dXWXo;;;;;,,.. 6 | .;dKWWKx:;;;;;;;,,'.. 7 | .;oOXNXKOo;;;;;;;;;;;;,,,'.. 8 | .:dOXWMMN0Okl;;;;;;;;;;;;;;;;,,,'.. 9 | .,lk0NMMMMMMNKOxc;;;;;;;;;;;;;;;;;;;;,,,'.. 10 | .'cx0XWMMMMMMMWX0kd:;;;;;;;;;;;;;;;;;;;;;;;;;,,,.. 11 | .'cx0NMMMMMMMMMWX0Oxl;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,'.. 12 | .;d0NMMMMMMMMMMWX0Oxl:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,... 13 | .:kXWMMMMMMMMMWNK0kdl:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,'.. 14 | .cONMMMMMMMMMWNX0Okoc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,'. 15 | .;kNMMMMMMMMWNX0Okdl:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,'.. 16 | .oXMMMMMMWWXK0Oxdl:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,'.. 17 | ,oKWWWWNXKK0kxoc:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,'.. 18 | 'lOO0000OOxdlc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,'''. 19 | .,lxkxxdolc:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,''''.. 20 | .,;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,'''''.. 21 | .,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,'''''''. 22 | .';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,'''''''.. 23 | .',;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,'''''''''.. 24 | .,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,''''''''''.. 25 | ',;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,''''''''''''. 26 | ,,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,''''''''''''''. 27 | ,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,'''''''''''''''. 28 | ,;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;,,'''''''''''''''''' 29 | ,;;;;;;;;;;;;;;;;;;;;;;;;;;;cldxkkOkkxxdlc;;;;;;;;;;;;;;;;;;;;;;;;,,''''''''''','''''''' 30 | ,;;;;;;;;;;;;;;;;;;;;;;;:ox0XWMMMMMMMMMWNX0kxdc;;;;;;;;;;;;;;;;,,,'''''''';cdk00Okl,'''' 31 | ,;;;;;;;;;;;;;;;;;;;;;cxKWMMMMMMMMMMMMMMMMMMMWN0xl;;;;;;;;;;,,,'''''''';lkKWMMMMMMW0c''' 32 | ',;;;;;;;;;;;;;;;;;;:dKWMMMMMMMMMMMMMMMMMMMMMMMMMN0xl;;;;;,,'''''''';okXWMMMMMMMMMMM0:'. 33 | .,;;;;;;;;;;;;;;;;;:kNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN0xl;''''''',:oOXWMMMMMMMMMMMMMMNd'. 34 | .',;;;;;;;;;;;;;;;;xWMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN0xolccoxONMMMMMMMMMMMMMMMMMMWd'. 35 | .,;;;;;;;;;;;;;;;oXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWNWMMMMMMMMMMMMMMMMMMMMMMXl.. 36 | .',;;;;;;;;;;;;;;xNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWX0OOOKNMMMMMMMMMMMMMMMMMMMM0;. 37 | .',;;;;;;;;;;;;;dNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWN0xl:,''',cxXWMMMMMMMMMMMMMMMMWd. 38 | .',;;;;;;;;;;;;lKMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKko:,'''''''''':dKWMMMMMMMMMMMMMWk, 39 | .',;;;;;;;;;;;;dXMMMMMMMMMMMMMMMMMMMMMMMMWX0xl;'''',;:::;,''''';oKWMMMMMMMMMMWO, 40 | ..',,;;;;;;;;;;o0NMMMMMMMMMMMMMMMMMMN0xdo:,''',cdO0XXXXK0kl,'''';o0WMMMMMMMNd, 41 | .''',,,,,,,,,,;lk0XWMMMMMMMMWNX0ko:,'''''';oONN0xdoodx0NNx,''''';lOXWWWXkc. 42 | ..'''''''''''''',:lloodddoolc;'''''''''',xN0dc,'''''',oK0:''''''',:clc;.. 43 | ...''''''''''''''''''''''''''''''''''''':c,''''''''''';;''''''''''''.. 44 | ..''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''... 45 | ...'''''''''''''''''''''',lxdc,'''''''''''''''''',:oxkl''''''.. 46 | ...''''''''''''''''''':kNMNK0OxdollcccclllodxO0XX0d;'''.. 47 | ..'''''''''''''''''',cxOKXXNWMMWWWWWWWWNXKOxo:'''.. 48 | ...'.'''''''''''''''',;:clooodddoollc:,'''... 49 | ....'''''''''''''''''''''''''''..... 50 | ....'..''''''''''''........ 51 | 52 | Originally from: https://gist.github.com/ericjsilva/aef0808c61c213a2e578 53 | -------------------------------------------------------------------------------- /templates/core/elephpant/1.twig: -------------------------------------------------------------------------------- 1 | Art by Morfina 2 | __ 3 | '. \ 4 | '- \ 5 | / /_ .---. 6 | / | \\,.\/--.// ) 7 | | \// )/ / 8 | \ ' ^ ^ / )____.----.. 6 9 | '.____. .___/ \._) 10 | .\/. ) 11 | '\ / 12 | _/ \/ ). ) ( 13 | /# .! | /\ / 14 | \ C// # /'-----''/ # / 15 | . 'C/ | | | | |mrf , 16 | \), .. .'OOO-'. ..'OOO'OOO-'. ..\(, 17 | -------------------------------------------------------------------------------- /templates/core/elephpant/2.twig: -------------------------------------------------------------------------------- 1 | Baby Elephant by Shanaka Dias 2 | 3 | _.-- ,.--. 4 | .' .' / 5 | | @ |'..--------._ 6 | / \._/ '. 7 | / .-.- \ 8 | ( / \ \ 9 | \\ '. | # 10 | \\ \ -. / 11 | :\ | )._____.' \ 12 | " | / \ | \ ) 13 | snd | |./' :__ \.-' 14 | '--' 15 | -------------------------------------------------------------------------------- /templates/core/elephpant/3.twig: -------------------------------------------------------------------------------- 1 | .-~ ~--"~-. ._ "-. 2 | / ./_ Y "-. \ 3 | Y :~ ! Y 4 | lq p | / .| 5 | _ \. .-, l / |j 6 | ()\___) |/ \_/"; ! 7 | \._____.-~\ . ~\. ./ 8 | Y_ Y_. "vr"~ T 9 | ( ( |L j -Row 10 | [nn[nn..][nn..] 11 | ~~~~~~~~~~~~~~~~~~~~~~~ 12 | "Bob The Elephant" 13 | -------------------------------------------------------------------------------- /templates/core/elephpant/4.twig: -------------------------------------------------------------------------------- 1 | ___.-~"~-._ __....__ 2 | .' ` \ ~"~ ``-. 3 | /` _ ) `\ `\ 4 | /` a) / | P H P `\ 5 | :` / | \ 6 | |` ( / . `;\\ 7 | { _.'-.;\___/' . . | \\ 8 | { }` | / / .' \\ 9 | { } | ' ' / :`; 10 | { } .\ /`~`=-.: / `` 11 | [ ] /`\ | `\ /( 12 | `.´ / /\ | `\ / \ 13 | J / Y | | /`\ \ 14 | / | | | | | | | 15 | "---" /___| /___| /__| 16 | -------------------------------------------------------------------------------- /templates/core/init/config.yml.twig: -------------------------------------------------------------------------------- 1 | application: 2 | environment: 'prod' 3 | {% if statistics is defined %} 4 | statistics: 5 | enabled: {{statistics}} 6 | url: 'https://drupalconsole.com/statistics?_format=json' 7 | last-attempted: ~ 8 | times-attempted: 0 9 | {% endif %} 10 | language: '{{language}}' 11 | # editor: 'vim' 12 | temp: '{{temp}}' 13 | develop: 'false' 14 | command: 'list' 15 | checked: 'false' 16 | clear: 'false' 17 | extras: 18 | alias: 'true' 19 | extend: 'true' 20 | config: 'true' 21 | chains: 'true' 22 | mappings: 'true' 23 | overrides: 24 | config: 25 | skip-validate-site-uuid: true 26 | remote: 27 | port: '22' 28 | user: 'drupal' 29 | type: 'ssh' 30 | options: 31 | learning: {{learning}} 32 | # target: 'site-alias.dev' 33 | # uri: 'multi-site.dev' 34 | generate-inline: {{generate_inline}} 35 | generate-chain: {{generate_chain}} 36 | -------------------------------------------------------------------------------- /templates/core/init/statistics.config.yml.twig: -------------------------------------------------------------------------------- 1 | application: 2 | statistics: 3 | enabled: {{statistics}} 4 | url: 'https://drupalconsole.com/statistics?_format=json' 5 | last-attempted: ~ 6 | times-attempted: 0 7 | -------------------------------------------------------------------------------- /templates/core/sites/alias.yml.twig: -------------------------------------------------------------------------------- 1 | {{ environment }}: 2 | type: {{ type }} 3 | root: {{ root }} 4 | {% if host %} 5 | host: {{ host }} 6 | {% endif %} 7 | {% if port %} 8 | port: {{ port }} 9 | {% endif %} 10 | {% if user %} 11 | user: {{ user }} 12 | {% endif %} 13 | {% if uri or drupal_console_binary %} 14 | options: 15 | {% if uri %} 16 | uri: {{ uri }} 17 | {% endif %} 18 | {% if drupal_console_binary %} 19 | drupal-console-binary: {{ drupal_console_binary }} 20 | {% endif %} 21 | {% else %} 22 | # options: 23 | {% endif %} 24 | # arguments: 25 | {% if extra_options %} 26 | extra-options: '{{ extra_options }}' 27 | {% endif %} 28 | --------------------------------------------------------------------------------