diff --git a/app/Commands/NginxVhostsCommand.php b/app/Commands/NginxVhostsCommand.php index 87808b0..6c7e3ce 100644 --- a/app/Commands/NginxVhostsCommand.php +++ b/app/Commands/NginxVhostsCommand.php @@ -10,6 +10,7 @@ use Jenssegers\Blade\Blade; use App\Facades\Install; use App\Facades\NginxVhost; use App\Facades\NginxVhostFactory; +use App\Facades\TerminalHelper; use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; @@ -17,6 +18,9 @@ use PhpSchool\CliMenu\MenuItem\CheckboxItem; use PhpSchool\CliMenu\Style\SelectableStyle; use PhpSchool\CliMenu\MenuItem\MenuMenuItem; +use Respect\Validation\Validator as v; +use Respect\Validation\Exceptions\NestedValidationException; + use Log; use Closure; @@ -34,7 +38,7 @@ class NginxVhostsCommand extends Command const TEMPLATES_DIR = '/resources/nginx/templates'; // index for vhosts - const VHOST_INDEX = 1; + const VHOST_INDEX = 0; /** * The signature of the command. @@ -155,10 +159,11 @@ class NginxVhostsCommand extends Command $checkboxRedirect->setChecked($configuration['redirect_www']); $builder - ->setTitle('Nginx Vhosts > Add > '.$template['name']) + ->setTitle('Nginx > Add > '.$template['name']) + ->setGoBackButtonText('Cancel') // input domain - ->addItem('domain', function(CliMenu $menu) use (&$configuration) { + ->addItem('domain: -', function(CliMenu $menu) use (&$configuration) { $result = $menu->askText()->ask(); $configuration['domain'] = $result->fetch(); @@ -167,7 +172,7 @@ class NginxVhostsCommand extends Command }) // input root - ->addItem('root', function(CliMenu $menu) use (&$configuration) { + ->addItem('root: -', function(CliMenu $menu) use (&$configuration) { $result = $menu->askText()->ask(); $configuration['root'] = $result->fetch(); @@ -176,11 +181,11 @@ class NginxVhostsCommand extends Command }) // input index - ->addItem($configuration['index'], function(CliMenu $menu) use (&$configuration) { + ->addItem('index: '.$configuration['index'], function(CliMenu $menu) use (&$configuration) { $result = $menu->askText()->ask(); $configuration['index'] = $result->fetch(); - $menu->getSelectedItem()->setText($result->fetch()); + $menu->getSelectedItem()->setText('index: '.$result->fetch()); $menu->redraw(); }) ->addLineBreak('-') @@ -193,23 +198,45 @@ class NginxVhostsCommand extends Command // create ->addItem('Create', function(CliMenu $menu) use (&$configuration, $template, $blade, $self) { - // render configuration - $content = $blade->render($template['name'], $configuration); + $data = $configuration; + + // add directory for validator to check if file exits + $data['index'] = $data['root'].'/'.$data['index']; + + $validator = v::key('domain', v::domain()) + ->key('root', v::directory()) + ->key('index', v::file()); + + try { + $validator->assert($data); + } catch(NestedValidationException $exception) { + $errors = $exception->getMessages(); + } + + if (isset($errors)) { + TerminalHelper::confirmArray($menu, $errors); + } else { - // create filename - $filename = $configuration['domain'].'.conf'; + // render configuration + $content = $blade->render($template['name'], $configuration); - // write configuration to file - file_put_contents('/etc/nginx/sites-available/'.$filename, $content); + // create filename + $filename = $configuration['domain'].'.conf'; - // prepare for close current submenu and open mainmenu - $parent = $menu->getParent(); - $menu->closeThis(); + // write configuration to file + file_put_contents('/etc/nginx/sites-available/'.$filename, $content); - $mainmenu = $parent->getParent(); + $menu->confirm('Success!')->display('Ok!'); - $mainmenu = NginxVhostFactory::addVhosts($mainmenu, NginxVhost::find(), self::VHOST_INDEX); - $mainmenu->open(); + // prepare for close current submenu and open mainmenu + $parent = $menu->getParent(); + $menu->closeThis(); + + $mainmenu = $parent->getParent(); + + $mainmenu = NginxVhostFactory::addVhosts($mainmenu, NginxVhost::find(), self::VHOST_INDEX); + $mainmenu->open(); + } }) ->addLineBreak('-'); }; @@ -229,12 +256,6 @@ class NginxVhostsCommand extends Command // create menu $mainmenu = $this->menu('Nginx') - // change style of menu - ->modifySelectableStyle(function(SelectableStyle $style) { - $style->setSelectedMarker("\xE2\x96\xB6 ") - ->setUnselectedMarker(' '); - }) - // add Submenu for select templates ->addLineBreak('-') ->addSubMenu('Add', $submenuSelectTemplate); @@ -249,6 +270,11 @@ class NginxVhostsCommand extends Command $mainmenu = $mainmenu->build(); + // remove first item + $items = $mainmenu->getItems(); + unset($items[0]); + $mainmenu->setItems($items); + // adding current vhosts $mainmenu = NginxVhostFactory::addVhosts($mainmenu, NginxVhost::find(), self::VHOST_INDEX); diff --git a/app/Facades/TerminalHelper.php b/app/Facades/TerminalHelper.php new file mode 100644 index 0000000..292c059 --- /dev/null +++ b/app/Facades/TerminalHelper.php @@ -0,0 +1,20 @@ +getItems(); @@ -25,22 +26,25 @@ class NginxVhostFactory // new items $newItems = []; - // check for linebreak-object + // lastIndex + $insertUntilIndex = 0; + + // get all items before foreach($items as $index => $item) { - if (get_class($item) === 'PhpSchool\CliMenu\MenuItem\LineBreakItem') { - $startIndex = $index + 1; + if ($index < $insertAfterIndex) { + $newItems[] = $item; + } else { break; } } - /*** + // check for linebreak-object foreach($items as $index => $item) { - if ($index <= $vhostIndex) { - $newItems[] = $item; - } else { + if ($index >= $insertAfterIndex && get_class($item) === 'PhpSchool\CliMenu\MenuItem\LineBreakItem') { + $insertUntilIndex = $index; break; } - }*/ + } // add submenu for each vhost foreach($vhosts as $vhost) { @@ -49,7 +53,7 @@ class NginxVhostFactory // fillup last items from mainmenu foreach($items as $index => $item) { - if ($index >= $startIndex) { + if ($index >= $insertUntilIndex) { $newItems[] = $item; } } @@ -70,16 +74,8 @@ class NginxVhostFactory { $builder = CliMenuBuilder::newSubMenu($mainmenu->getTerminal()); - // style selected and unselected - $builder->modifySelectableStyle(function(SelectableStyle $style) { - $style->setSelectedMarker('> ') - ->setUnselectedMarker(' '); - }); - - $log = ''; - // create checkbox for disable / enabled - $checkbox = self::createVhostCheckbox($vhost, $log); + $checkbox = self::createVhostCheckbox($vhost); // if vhost is enabled if ($vhost['enabled']) { @@ -167,7 +163,7 @@ class NginxVhostFactory private function createVhostCheckbox($vhost) { // create checkbox for enabled / disabled - $checkbox = new CheckboxItem('enabled', function(CliMenu $menu) use (&$vhost, &$log) { + $checkbox = new CheckboxItem('enabled', function(CliMenu $menu) use ($vhost) { // check status if ($menu->getSelectedItem()->getChecked()) { diff --git a/app/Helpers/TerminalHelper.php b/app/Helpers/TerminalHelper.php new file mode 100644 index 0000000..fd7bb21 --- /dev/null +++ b/app/Helpers/TerminalHelper.php @@ -0,0 +1,39 @@ + $message) { + if (is_array($message)) { + $this->confirmArray($menu, $message, $text, $key); + } else { + + // reset prefix + $prefix = ''; + + // if field is not null, add prefix + if ($field) { + $prefix = $field.' '; + } + + // adding confirm message + $menu->confirm($prefix.$message)->display($text); + } + } + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index ea94353..0a2525b 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,8 @@ "jenssegers/blade": "^1.3", "laminas/laminas-text": "^2.7", "laravel-zero/framework": "^7.0", - "nunomaduro/laravel-console-menu": "^3.0" + "nunomaduro/laravel-console-menu": "^3.0", + "respect/validation": "^2.0" }, "require-dev": { "mockery/mockery": "^1.3.1", diff --git a/composer.lock b/composer.lock index 153ee0e..7f4a52d 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "24f2c4d139d1824b34245b0ceab0eea1", + "content-hash": "0e8b08aebfaf581a3ebfba5152ff8a4c", "packages": [ { "name": "beberlei/assert", @@ -929,16 +929,6 @@ "template", "view" ], - "funding": [ - { - "url": "https://github.com/jenssegers", - "type": "github" - }, - { - "url": "https://opencollective.com/jenssegers-blade", - "type": "open_collective" - } - ], "time": "2020-03-17T15:00:55+00:00" }, { @@ -1068,12 +1058,6 @@ "service-manager", "servicemanager" ], - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], "time": "2020-05-11T14:43:22+00:00" }, { @@ -1228,12 +1212,6 @@ "laminas", "zf" ], - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], "time": "2020-05-20T16:45:56+00:00" }, { @@ -1527,16 +1505,6 @@ "logging", "psr-3" ], - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", - "type": "tidelift" - } - ], "time": "2020-05-22T08:12:19+00:00" }, { @@ -1742,20 +1710,6 @@ "php", "symfony" ], - "funding": [ - { - "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], "time": "2020-03-06T10:04:44+00:00" }, { @@ -2380,6 +2334,121 @@ ], "time": "2020-02-21T04:36:14+00:00" }, + { + "name": "respect/stringifier", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/Respect/Stringifier.git", + "reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Respect/Stringifier/zipball/e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59", + "reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.8", + "malukenho/docheader": "^0.1.7", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Respect\\Stringifier\\": "src/" + }, + "files": [ + "src/stringify.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Respect/Stringifier Contributors", + "homepage": "https://github.com/Respect/Stringifier/graphs/contributors" + } + ], + "description": "Converts any value to a string", + "homepage": "http://respect.github.io/Stringifier/", + "keywords": [ + "respect", + "stringifier", + "stringify" + ], + "time": "2017-12-29T19:39:25+00:00" + }, + { + "name": "respect/validation", + "version": "2.0.16", + "source": { + "type": "git", + "url": "https://github.com/Respect/Validation.git", + "reference": "fc14c6c6695c3f870ad8810a2acddccec015841d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Respect/Validation/zipball/fc14c6c6695c3f870ad8810a2acddccec015841d", + "reference": "fc14c6c6695c3f870ad8810a2acddccec015841d", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "respect/stringifier": "^0.2.0", + "symfony/polyfill-mbstring": "^1.2" + }, + "require-dev": { + "egulias/email-validator": "^2.1", + "malukenho/docheader": "^0.1", + "mikey179/vfsstream": "^1.6", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-deprecation-rules": "^0.11.0", + "phpstan/phpstan-phpunit": "^0.11.0", + "phpunit/phpunit": "^7.5", + "respect/coding-standard": "^2.1", + "squizlabs/php_codesniffer": "^3.5", + "symfony/validator": "^3.0||^4.0", + "zendframework/zend-validator": "^2.1" + }, + "suggest": { + "egulias/email-validator": "Strict (RFC compliant) email validation", + "ext-bcmath": "Arbitrary Precision Mathematics", + "ext-fileinfo": "File Information", + "ext-mbstring": "Multibyte String Functions", + "symfony/validator": "Use Symfony validator through Respect\\Validation", + "zendframework/zend-validator": "Use Zend Framework validator through Respect\\Validation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Respect\\Validation\\": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Respect/Validation Contributors", + "homepage": "https://github.com/Respect/Validation/graphs/contributors" + } + ], + "description": "The most awesome validation engine ever created for PHP", + "homepage": "http://respect.github.io/Validation/", + "keywords": [ + "respect", + "validation", + "validator" + ], + "time": "2020-07-25T18:34:16+00:00" + }, { "name": "symfony/console", "version": "v5.1.2", @@ -5030,6 +5099,5 @@ "platform": { "php": "^7.2.5" }, - "platform-dev": [], - "plugin-api-version": "1.1.0" + "platform-dev": [] } diff --git a/resources/nginx/templates/flight.blade.php b/resources/nginx/templates/flight.blade.php index 6a7cf1d..d747672 100644 --- a/resources/nginx/templates/flight.blade.php +++ b/resources/nginx/templates/flight.blade.php @@ -1,10 +1,11 @@ @extends($ssl ? 'layouts.ssl' : 'layouts.no-ssl') @section('server') -root {{ $root }}; -index {{ $index }}; -location / { - try_files $uri $uri/ /index.php; -} + root {{ $root }}; + index {{ $index }}; + + location / { + try_files $uri $uri/ /index.php; + } @endsection \ No newline at end of file diff --git a/resources/nginx/templates/layouts/no-ssl.blade.php b/resources/nginx/templates/layouts/no-ssl.blade.php index 9b75a66..314959f 100644 --- a/resources/nginx/templates/layouts/no-ssl.blade.php +++ b/resources/nginx/templates/layouts/no-ssl.blade.php @@ -1,7 +1,7 @@ server { listen 80; listen [::]:80; - server_name {{ $domain }} @if ($redirect_www) www.{{ $domain }} @endif; + server_name {{ $domain }}@if ($redirect_www) www.{{ $domain }}@endif; return 301 http://{{ $domain }}$request_uri; } diff --git a/resources/nginx/templates/partials/default.blade.php b/resources/nginx/templates/partials/default.blade.php index 4deda7b..cd1edad 100644 --- a/resources/nginx/templates/partials/default.blade.php +++ b/resources/nginx/templates/partials/default.blade.php @@ -1,9 +1,9 @@ -server_name {{ $domain }}; + server_name {{ $domain }}; -# include snippets -include /etc/nginx/snippets/deny.conf; -include /etc/nginx/snippets/expires.conf; + # include snippets + include /etc/nginx/snippets/deny.conf; + include /etc/nginx/snippets/expires.conf; -# logs -access_log /var/log/nginx/{{ $domain }}.access.log; -error_log /var/log/nginx/{{ $domain }}.error.log; \ No newline at end of file + # logs + access_log /var/log/nginx/{{ $domain }}.access.log; + error_log /var/log/nginx/{{ $domain }}.error.log; \ No newline at end of file