<?php
							 | 
						|
								
							 | 
						|
								namespace App\Commands;
							 | 
						|
								
							 | 
						|
								use Illuminate\Console\Scheduling\Schedule;
							 | 
						|
								use LaravelZero\Framework\Commands\Command;
							 | 
						|
								use Illuminate\Support\Facades\File;
							 | 
						|
								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;
							 | 
						|
								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
							 | 
						|
								 *
							 | 
						|
								 *
							 | 
						|
								 *
							 | 
						|
								 */
							 | 
						|
								class NginxVhostsCommand extends Command
							 | 
						|
								{
							 | 
						|
								    // path templates
							 | 
						|
								    const TEMPLATES_DIR = '/resources/nginx/templates';
							 | 
						|
								
							 | 
						|
								    // index for vhosts
							 | 
						|
								    const VHOST_INDEX = 0;
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * The signature of the command.
							 | 
						|
								     *
							 | 
						|
								     * @var string
							 | 
						|
								     */
							 | 
						|
								    protected $signature = 'nginx:vhosts';
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * The description of the command.
							 | 
						|
								     *
							 | 
						|
								     * @var string
							 | 
						|
								     */
							 | 
						|
								    protected $description = 'Create and Manage Nginx Vhosts';
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *
							 | 
						|
								     *  @param  string $prefix [description]
							 | 
						|
								     *  @return [type]         [description]
							 | 
						|
								     */
							 | 
						|
								    private function getTemplates($prefix = '')
							 | 
						|
								    {
							 | 
						|
								        // templates
							 | 
						|
								        $templates = [];
							 | 
						|
								
							 | 
						|
								        // getting templates
							 | 
						|
								        $files = scandir(base_path().self::TEMPLATES_DIR);
							 | 
						|
								
							 | 
						|
								        foreach($files as $file) {
							 | 
						|
								
							 | 
						|
								            // create filepath
							 | 
						|
								            $filepath = base_path().self::TEMPLATES_DIR.'/'.$file;
							 | 
						|
								
							 | 
						|
								            // getting info
							 | 
						|
								            $pathinfo = pathinfo($filepath);
							 | 
						|
								
							 | 
						|
								            // if extension isset and php
							 | 
						|
								            if (isset($pathinfo['extension']) && $pathinfo['extension'] === 'php') {
							 | 
						|
								
							 | 
						|
								                $name = str_replace('.blade.php', '', $file);
							 | 
						|
								
							 | 
						|
								                $templates[] = [
							 | 
						|
								                    'name' => $name,
							 | 
						|
								                    'file' => $file,
							 | 
						|
								                    'filepath' => $filepath
							 | 
						|
								                ];
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return $templates;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *
							 | 
						|
								     *
							 | 
						|
								     *
							 | 
						|
								     */
							 | 
						|
								    private function selectTemplate()
							 | 
						|
								    {
							 | 
						|
								        // getting templates
							 | 
						|
								        $templates = $this->getTemplates();
							 | 
						|
								
							 | 
						|
								        $menu = function(CliMenuBuilder $builder) use ($templates)
							 | 
						|
								        {
							 | 
						|
								            // writing configuration
							 | 
						|
								            $blade = new Blade(base_path().self::TEMPLATES_DIR, base_path().'/storage/cache');
							 | 
						|
								
							 | 
						|
								            $builder
							 | 
						|
								                ->setTitle('Nginx > Add')
							 | 
						|
								                ->setGoBackButtonText('Back');
							 | 
						|
								
							 | 
						|
								            foreach($templates as $template) {
							 | 
						|
								                $submenuCallable = $this->createConfiguration($template, $blade);
							 | 
						|
								                $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, $blade)
							 | 
						|
								    {
							 | 
						|
								        $self = $this;
							 | 
						|
								
							 | 
						|
								        $menu = function(CliMenuBuilder $builder) use ($template, $blade, $self)
							 | 
						|
								        {
							 | 
						|
								            $configuration = [
							 | 
						|
								                'domain' => '',
							 | 
						|
								                'root' => '',
							 | 
						|
								                'index' => 'index.php',
							 | 
						|
								                'ssl' => true,
							 | 
						|
								                'redirect_www' => true
							 | 
						|
								            ];
							 | 
						|
								
							 | 
						|
								            // 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) {
							 | 
						|
								                    $result = $menu->askText()->ask();
							 | 
						|
								                    $configuration['domain'] = $result->fetch();
							 | 
						|
								
							 | 
						|
								                    $menu->getSelectedItem()->setText('domain: '.$result->fetch());
							 | 
						|
								                    $menu->redraw();
							 | 
						|
								                })
							 | 
						|
								
							 | 
						|
								                // input root
							 | 
						|
								                ->addItem('root: -', function(CliMenu $menu) use (&$configuration) {
							 | 
						|
								                    $result = $menu->askText()->ask();
							 | 
						|
								                    $configuration['root'] = $result->fetch();
							 | 
						|
								
							 | 
						|
								                    $menu->getSelectedItem()->setText('root: '.$result->fetch());
							 | 
						|
								                    $menu->redraw();
							 | 
						|
								                })
							 | 
						|
								
							 | 
						|
								                // input index
							 | 
						|
								                ->addItem('index: '.$configuration['index'], function(CliMenu $menu) use (&$configuration) {
							 | 
						|
								                    $result = $menu->askText()->ask();
							 | 
						|
								                    $configuration['index'] = $result->fetch();
							 | 
						|
								
							 | 
						|
								                    $menu->getSelectedItem()->setText('index: '.$result->fetch());
							 | 
						|
								                    $menu->redraw();
							 | 
						|
								                })
							 | 
						|
								                ->addLineBreak('-')
							 | 
						|
								
							 | 
						|
								                // options
							 | 
						|
								                ->addMenuItem($checkboxSSL)
							 | 
						|
								                ->addMenuItem($checkboxRedirect)
							 | 
						|
								                ->addLineBreak('-')
							 | 
						|
								
							 | 
						|
								                // create
							 | 
						|
								                ->addItem('Create', function(CliMenu $menu) use (&$configuration, $template, $blade, $self) {
							 | 
						|
								
							 | 
						|
								                    $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 {
							 | 
						|
								
							 | 
						|
								                        // render configuration
							 | 
						|
								                        $content = $blade->render($template['name'], $configuration);
							 | 
						|
								
							 | 
						|
								                        // create filename
							 | 
						|
								                        $filename = $configuration['domain'].'.conf';
							 | 
						|
								
							 | 
						|
								                        // write configuration to file
							 | 
						|
								                        file_put_contents('/etc/nginx/sites-available/'.$filename, $content);
							 | 
						|
								
							 | 
						|
								                        $menu->confirm('Success!')->display('Ok!');
							 | 
						|
								
							 | 
						|
								                        // 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('-');
							 | 
						|
								        };
							 | 
						|
								
							 | 
						|
								        return $menu;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  let it rain
							 | 
						|
								     *
							 | 
						|
								     *
							 | 
						|
								     */
							 | 
						|
								    public function handle()
							 | 
						|
								    {
							 | 
						|
								        $submenuSelectTemplate = $this->selectTemplate();
							 | 
						|
								
							 | 
						|
								        // create menu
							 | 
						|
								        $mainmenu = $this->menu('Nginx')
							 | 
						|
								
							 | 
						|
								            // add Submenu for select templates
							 | 
						|
								            ->addLineBreak('-')
							 | 
						|
								            ->addSubMenu('Add', $submenuSelectTemplate);
							 | 
						|
								
							 | 
						|
								        $mainmenu->addLineBreak('-');
							 | 
						|
								
							 | 
						|
								        // apperance
							 | 
						|
								        $mainmenu->setWidth($mainmenu->getTerminal()->getWidth());
							 | 
						|
								        $mainmenu->setBorderLeftWidth(4);
							 | 
						|
								        $mainmenu->setBorderColour('magenta');
							 | 
						|
								        $mainmenu->setMargin(2);
							 | 
						|
								
							 | 
						|
								        $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);
							 | 
						|
								
							 | 
						|
								        $mainmenu->open();
							 | 
						|
								    }
							 | 
						|
								}
							 |