diff --git a/app/BladeFile.php b/app/BladeFile.php index 9f27e84..3fa7ee5 100644 --- a/app/BladeFile.php +++ b/app/BladeFile.php @@ -5,9 +5,12 @@ namespace App; use Jenssegers\Blade\Blade; /** + * wrapper for blade * * - * + * @author Björn Hase, Tentakelfabrik + * @license http://opensource.org/licenses/MIT The MIT License + * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp * */ class BladeFile @@ -19,7 +22,7 @@ class BladeFile private $blade; /** - * + * create blade * * * @param {string} $templateDir diff --git a/app/Commands/Fail2banDisableCommand.php b/app/Commands/Fail2banDisableCommand.php index 587eb65..5d79259 100644 --- a/app/Commands/Fail2banDisableCommand.php +++ b/app/Commands/Fail2banDisableCommand.php @@ -16,7 +16,7 @@ class Fail2banDisableCommand extends Command // destination to jail const DESTINATION_FAIL2BAN_JAIL_DIRECTORY = '/etc/fail2ban/jail.d'; - // source to jail + // source to jail const SOURCE_FAIL2BAN_JAIL_DIRECTORY = '/resources/fail2ban/jail.d'; /** @@ -54,6 +54,6 @@ class Fail2banDisableCommand extends Command unlink(self::DESTINATION_FAIL2BAN_JAIL_DIRECTORY.'/'.$configuration.'.conf'); exec('service fail2ban restart'); - $this->info('fail2ban...'.$configuration.' disabled'); + $this->info('Fail2ban...'.$configuration.' disabled'); } } diff --git a/app/Commands/Fail2banEnableCommand.php b/app/Commands/Fail2banEnableCommand.php index 0955247..074a5e3 100644 --- a/app/Commands/Fail2banEnableCommand.php +++ b/app/Commands/Fail2banEnableCommand.php @@ -60,8 +60,8 @@ class Fail2banEnableCommand extends Command } copy($source, $destination); - $this->info('fail2ban...'.$configuration.' enabled'); - exec('service fail2ban restart'); + + $this->info('Fail2ban...'.$configuration.' enabled'); } } diff --git a/app/Commands/LetsEncryptInstallCommand.php b/app/Commands/LetsEncryptInstallCommand.php index 812d2ab..998de0e 100644 --- a/app/Commands/LetsEncryptInstallCommand.php +++ b/app/Commands/LetsEncryptInstallCommand.php @@ -43,7 +43,7 @@ class LetsEncryptInstallCommand extends Command exec('apt-get install certbot python3-certbot-nginx 2>&1'); if (Install::isReady('certbot')) { - $this->info("Success!"); + $this->info('LetsEncrypt installing...Success! \o/'); } else { $this->error("Failed! Please check log-file!"); } diff --git a/app/Commands/MariadbInstallCommand.php b/app/Commands/MariadbInstallCommand.php index 9261564..213e9f6 100644 --- a/app/Commands/MariadbInstallCommand.php +++ b/app/Commands/MariadbInstallCommand.php @@ -91,8 +91,8 @@ class MariadbInstallCommand extends Command // update privileges exec('sudo mysql -u root -e "FLUSH PRIVILEGES;"'); - $this->info('Mariadb installing...Success! \o/ Check '.self::MCP_LOG_FILE); file_put_contents(self::MCP_LOG_FILE, "Mariadb installed\nuser: root\npassword: $password\n--\n", FILE_APPEND); + $this->info('Mariadb installing...Success! \o/ Check '.self::MCP_LOG_FILE); } else { $this->error('Failed! Please check log-file!'); diff --git a/app/Commands/NginxVhostsCommand.php b/app/Commands/NginxVhostsCommand.php index 549b38c..76c9eb2 100644 --- a/app/Commands/NginxVhostsCommand.php +++ b/app/Commands/NginxVhostsCommand.php @@ -13,9 +13,9 @@ use App\Facades\TerminalHelper; use App\Facades\Menus\StylesFactory; use App\Helpers\NginxTemplateHelper; -use App\Menus\Nginx\NginxVhostGoBackAction; -use App\BladeFile; +use App\Menus\Nginx\NginxVhostGoBackAction; +use App\Menus\Nginx\TemplateMenuFactory; use PhpSchool\CliMenu\Builder\CliMenuBuilder; use PhpSchool\CliMenu\CliMenu; @@ -23,26 +23,20 @@ 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; - /** * Add and Edit Configurations of Vhosts from Nginx * * Using php-school/cli-menu * - * + * @author Björn Hase, Tentakelfabrik + * @license http://opensource.org/licenses/MIT The MIT License + * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp * */ class NginxVhostsCommand extends Command { - // path templates - const TEMPLATES_DIR = '/resources/nginx/templates'; - // index for vhosts + // @TODO move this in a global class const VHOST_INDEX = 0; /** @@ -59,183 +53,6 @@ class NginxVhostsCommand extends Command */ protected $description = 'Create and Manage Nginx Vhosts'; - /** - * - * - * - */ - private function selectTemplate() - { - $menu = function(CliMenuBuilder $builder) - { - // create blade - $bladeFile = new BladeFile(self::TEMPLATES_DIR); - - $builder - ->setTitle('Nginx > Add') - ->setGoBackButtonText('Back'); - - $nginxTemplateHelper = new NginxTemplateHelper(); - - foreach($nginxTemplateHelper->find() as $template) { - $submenuCallable = $this->createConfiguration($template, $bladeFile); - $builder - ->addSubMenu($template['name'], $submenuCallable); - } - - $builder->addLineBreak('-'); - }; - - return $menu; - } - - /** - * create Configuration, add for each template a submenu - * - * - * @param array $template - * @param Blade $blade - * @return CliMenuBuilder - */ - private function createConfiguration($template, $bladeFile) - { - $menu = function(CliMenuBuilder $builder) use ($template, $bladeFile) - { - $configuration = [ - 'domain' => '', - 'root' => '', - 'index' => 'index.php', - 'ssl' => true, - 'redirect_www' => true - ]; - - exec('find /lib/systemd/system/ -name "php[0-9\.]*-fpm.service"', $files); - - // create checkbox for ssl - $checkboxSSL = new CheckboxItem('ssl', function(CliMenu $menu) use (&$configuration) { - $configuration['ssl'] = $menu->getSelectedItem()->getChecked(); - }); - - $checkboxSSL->setChecked($configuration['ssl']); - - // create checkbox for redirect from www - $checkboxRedirect = new CheckboxItem('redirect www', function(CliMenu $menu) use (&$configuration) { - $configuration['redirect_www'] = $menu->getSelectedItem()->getChecked(); - }); - - $checkboxRedirect->setChecked($configuration['redirect_www']); - - $builder - ->setTitle('Nginx > Add > '.$template['name']) - ->setGoBackButtonText('Cancel') - - // input domain - ->addItem('domain: -', function(CliMenu $menu) use (&$configuration) { - - $input = $menu->askText(); - - if ($configuration['domain']) { - $input->setPlaceholderText($configuration['domain']); - } - - $result = $input->ask(); - $configuration['domain'] = $result->fetch(); - - $menu->getSelectedItem()->setText('domain: '.$result->fetch()); - $menu->redraw(); - }) - - // input root - ->addItem('root: -', function(CliMenu $menu) use (&$configuration) { - - $input = $menu->askText(); - - if ($configuration['root']) { - $input->setPlaceholderText($configuration['root']); - } - - $result = $input->ask(); - $configuration['root'] = $result->fetch(); - - $menu->getSelectedItem()->setText('root: '.$result->fetch()); - $menu->redraw(); - }) - - // input index - ->addItem('index: '.$configuration['index'], function(CliMenu $menu) use (&$configuration) { - - $input = $menu->askText(); - - if ($configuration['index']) { - $input->setPlaceholderText($configuration['index']); - } - - $result = $input->ask(); - $configuration['index'] = $result->fetch(); - - $menu->getSelectedItem()->setText('index: '.$result->fetch()); - $menu->redraw(); - }) - ->addLineBreak('-'); - - foreach($files as $index => $file) { - $file = str_replace('/lib/systemd/system/', '', $file); - $file = str_replace('.service', '', $file); - - $builder->addRadioItem($file, function(CliMenu $menu) use (&$configuration) { - $configuration['phpFpm'] = $menu->getSelectedItem()->getText(); - }); - } - - $builder - ->addLineBreak('-') - - // options - ->addMenuItem($checkboxSSL) - ->addMenuItem($checkboxRedirect) - ->addLineBreak('-') - - // create - ->addItem('Create', function(CliMenu $menu) use (&$configuration, $template, $bladeFile) { - - $data = $configuration; - - // add directory for validator to check if file exits - $data['index'] = $data['root'].'/'.$data['index']; - - $validator = v::key('domain', v::domain(false)) - ->key('root', v::directory()) - ->key('index', v::file()) - ->key('phpFpm', v::notEmpty()); - - try { - $validator->assert($data); - } catch(NestedValidationException $exception) { - $errors = $exception->getMessages(); - } - - if (isset($errors)) { - TerminalHelper::confirmArray($menu, $errors); - } else { - - // create filename - $filename = $configuration['domain'].'.conf'; - - // write configuration to file - $bladeFile->put($template['name'], '/etc/nginx/sites-available/'.$filename, $configuration); - $menu->confirm('Success!')->display('Ok!'); - - // invoke action - $action = new NginxVhostGoBackAction(); - is_callable($action($menu)); - } - }) - ->addLineBreak('-'); - }; - - return $menu; - } - /** * let it rain * @@ -243,14 +60,14 @@ class NginxVhostsCommand extends Command */ public function handle() { - $submenuSelectTemplate = $this->selectTemplate(); + $nginxTemplateHelper = new TemplateMenuFactory(); // create menu $builder = $this->menu('Nginx') // add Submenu for select templates ->addLineBreak('-') - ->addSubMenu('Add', $submenuSelectTemplate); + ->addSubMenu('Add', $nginxTemplateHelper->addSelectTemplateItem()); $builder->addLineBreak('-'); diff --git a/app/Helpers/NginxTemplateHelper.php b/app/Helpers/NginxTemplateHelper.php index acfd783..1c55f49 100644 --- a/app/Helpers/NginxTemplateHelper.php +++ b/app/Helpers/NginxTemplateHelper.php @@ -5,7 +5,9 @@ namespace App\Helpers; /** * * - * + * @author Björn Hase, Tentakelfabrik + * @license http://opensource.org/licenses/MIT The MIT License + * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp * */ class NginxTemplateHelper @@ -22,10 +24,11 @@ class NginxTemplateHelper ]; /** + * search for templates + * * - * @param [type] $files [description] - * @param [type] $templatePath [description] - * @return [type] [description] + * @param string $templatePath + * @return array */ private function getTemplates($templatePath) { @@ -59,7 +62,9 @@ class NginxTemplateHelper } /** - * getting templates + * find templates + * + * @return array * */ public function find() diff --git a/app/Menus/Nginx/NginxVhostGoBackAction.php b/app/Menus/Nginx/NginxVhostGoBackAction.php index 85632c6..741d7f2 100644 --- a/app/Menus/Nginx/NginxVhostGoBackAction.php +++ b/app/Menus/Nginx/NginxVhostGoBackAction.php @@ -7,7 +7,13 @@ use App\Facades\NginxVhost; use App\Facades\NginxVhostFactory; /** - * @author Aydin Hassan + * Action that override default-action for go back + * reload vhosts + * + * @author Björn Hase, Tentakelfabrik + * @license http://opensource.org/licenses/MIT The MIT License + * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp + * */ class NginxVhostGoBackAction { @@ -24,6 +30,7 @@ class NginxVhostGoBackAction $parent = $menu->getParent(); $menu->closeThis(); + // check for parent if exists, get parent if ($parent->getParent()) { $menu = $parent->getParent(); } else { diff --git a/app/Menus/Nginx/TemplateMenuFactory.php b/app/Menus/Nginx/TemplateMenuFactory.php new file mode 100644 index 0000000..2bd1fed --- /dev/null +++ b/app/Menus/Nginx/TemplateMenuFactory.php @@ -0,0 +1,246 @@ +setTitle('Nginx > Add') + ->setGoBackButtonText('Back'); + + $nginxTemplateHelper = new NginxTemplateHelper(); + + // get templates + foreach($nginxTemplateHelper->find() as $template) { + $submenuCallable = $this->addCreateItem($template, $bladeFile); + $builder + ->addSubMenu($template['name'], $submenuCallable); + } + + $builder->addLineBreak('-'); + }; + + return $menu; + } + + /** + * default configuration + * + * @TODO will be removed after + * + * @return array + */ + private function getConfiguration() + { + return [ + 'domain' => '', + 'root' => '', + 'index' => 'index.php', + 'ssl' => true, + 'redirect_www' => true + ]; + } + + /** + * add input item + * + * @param string $key + * @param string $label + * @param array $configuration + */ + private function addInputItem($key, $label, &$configuration) + { + $callable = function(CliMenu $menu) use ($key, $label, &$configuration) + { + $input = $menu->askText(); + + if ($configuration[$key]) { + $input->setPlaceholderText($configuration[$key]); + } + + $result = $input->ask(); + $configuration[$key] = $result->fetch(); + + $menu->getSelectedItem()->setText($label.': '.$result->fetch()); + $menu->redraw(); + }; + + return $callable; + } + + /** + * add item to publish configuration + * + * @param string $template + * @param object $bladeFile + * @param array $configuration + */ + private function addPublishItem($template, $bladeFile, &$configuration) + { + $callable = function(CliMenu $menu) use ($template, $bladeFile, &$configuration) + { + // getting configuration + $data = $configuration; + + // add directory for validator to check if file exits + $data['index'] = $data['root'].'/'.$data['index']; + + $validator = v::key('domain', v::domain(false)) + ->key('root', v::directory()) + ->key('index', v::file()) + ->key('phpFpm', v::notEmpty()); + + try { + $validator->assert($data); + } catch(NestedValidationException $exception) { + $errors = $exception->getMessages(); + } + + if (isset($errors)) { + TerminalHelper::confirmArray($menu, $errors); + } else { + + // create filename + $filename = $configuration['domain'].'.conf'; + + // write configuration to file + $bladeFile->put($template['name'], '/etc/nginx/sites-available/'.$filename, $configuration); + $menu->confirm('Success!')->display('Ok!'); + + // invoke action + $action = new NginxVhostGoBackAction(); + is_callable($action($menu)); + } + }; + + return $callable; + } + + /** + * adding radio buttons to select php-fpm version + * + * + * @param CliMenuBuilder $builder + * @param array $configuration + */ + private function addPhpFpmItems($builder, &$configuration) + { + // get php-fpm services + exec('find /lib/systemd/system/ -name "php[0-9\.]*-fpm.service"', $files); + + foreach($files as $index => $file) { + + // remove path + $file = str_replace('/lib/systemd/system/', '', $file); + + // remove extension + $file = str_replace('.service', '', $file); + + $builder->addRadioItem($file, function(CliMenu $menu) use (&$configuration) { + $configuration['phpFpm'] = $menu->getSelectedItem()->getText(); + }); + } + + return $builder; + } + + /** + * add create item + * + * + * @param array $template + * @param Blade $blade + * @return CliMenuBuilder + */ + private function addCreateItem($template, $bladeFile) + { + $menu = function(CliMenuBuilder $builder) use ($template, $bladeFile) + { + $configuration = $this->getConfiguration(); + + // create checkbox for ssl + $checkboxSSL = new CheckboxItem('ssl', function(CliMenu $menu) use (&$configuration) { + $configuration['ssl'] = $menu->getSelectedItem()->getChecked(); + }); + + $checkboxSSL->setChecked($configuration['ssl']); + + // create checkbox for redirect from www + $checkboxRedirect = new CheckboxItem('redirect www', function(CliMenu $menu) use (&$configuration) { + $configuration['redirect_www'] = $menu->getSelectedItem()->getChecked(); + }); + + $checkboxRedirect->setChecked($configuration['redirect_www']); + + $builder + ->setTitle('Nginx > Add > '.$template['name']) + ->setGoBackButtonText('Cancel') + + // input domain + ->addItem('domain: -', $this->addInputItem('domain', 'domain', $configuration)) + + // input root + ->addItem('root: -', $this->addInputItem('root', 'root', $configuration)) + + // input index + ->addItem('index: '.$configuration['index'], $this->addInputItem('index', 'index', $configuration)) + ->addLineBreak('-'); + + // add php-fpm items + $builder = $this->addPhpFpmItems($builder, $configuration); + + $builder + ->addLineBreak('-') + + // options + ->addMenuItem($checkboxSSL) + ->addMenuItem($checkboxRedirect) + ->addLineBreak('-') + + // create + ->addItem('publish', $this->addPublishItem($template, $bladeFile, $configuration)) + ->addLineBreak('-'); + }; + + return $menu; + } +} \ No newline at end of file diff --git a/app/Menus/StylesFactory.php b/app/Menus/StylesFactory.php index 17668b8..d5ad87f 100644 --- a/app/Menus/StylesFactory.php +++ b/app/Menus/StylesFactory.php @@ -5,8 +5,11 @@ namespace App\Menus; use PhpSchool\CliMenu\Builder\CliMenuBuilder; /** + * Default Styles * - * + * @author Björn Hase, Tentakelfabrik + * @license http://opensource.org/licenses/MIT The MIT License + * @link https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp * */ class StylesFactory