<?php
							 | 
						|
								
							 | 
						|
								namespace App\Factories;
							 | 
						|
								
							 | 
						|
								use PhpSchool\CliMenu\Builder\CliMenuBuilder;
							 | 
						|
								use PhpSchool\CliMenu\CliMenu;
							 | 
						|
								use PhpSchool\CliMenu\MenuItem\CheckboxItem;
							 | 
						|
								use PhpSchool\CliMenu\MenuItem\MenuMenuItem;
							 | 
						|
								use PhpSchool\CliMenu\Style\SelectableStyle;
							 | 
						|
								use PhpSchool\CliMenu\Style\ItemStyle;
							 | 
						|
								
							 | 
						|
								use PhpSchool\CliMenu\Action\ExitAction;
							 | 
						|
								
							 | 
						|
								use App\Menus\Nginx\NginxVhostGoBackAction;
							 | 
						|
								
							 | 
						|
								class NginxVhostFactory
							 | 
						|
								{
							 | 
						|
								    /**
							 | 
						|
								     *  adding Vhosts behind index
							 | 
						|
								     *
							 | 
						|
								     *  @param [type] $mainmenu
							 | 
						|
								     *  @param [type] $vhosts
							 | 
						|
								     *  @param [type] $vhostIndex
							 | 
						|
								     */
							 | 
						|
								    public function addVhosts($mainmenu, $vhosts, $insertAfterIndex)
							 | 
						|
								    {
							 | 
						|
								        // get items
							 | 
						|
								        $items = $mainmenu->getItems();
							 | 
						|
								
							 | 
						|
								        // new items
							 | 
						|
								        $newItems = [];
							 | 
						|
								
							 | 
						|
								        // lastIndex
							 | 
						|
								        $insertUntilIndex = 0;
							 | 
						|
								
							 | 
						|
								        // get all items before
							 | 
						|
								        foreach($items as $index => $item) {
							 | 
						|
								            if ($index < $insertAfterIndex) {
							 | 
						|
								                $newItems[] = $item;
							 | 
						|
								            } else {
							 | 
						|
								                break;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // check for linebreak-object
							 | 
						|
								        foreach($items as $index => $item) {
							 | 
						|
								            if ($index >= $insertAfterIndex && get_class($item) === 'PhpSchool\CliMenu\MenuItem\LineBreakItem') {
							 | 
						|
								                $insertUntilIndex = $index;
							 | 
						|
								                break;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // add submenu for each vhost
							 | 
						|
								        foreach($vhosts as $vhost) {
							 | 
						|
								            $newItems[] = self::createVhostSubmenu($vhost, $mainmenu);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        // fillup last items from mainmenu
							 | 
						|
								        foreach($items as $index => $item) {
							 | 
						|
								            if ($index >= $insertUntilIndex) {
							 | 
						|
								                $newItems[] = $item;
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        $mainmenu->setItems($newItems);
							 | 
						|
								
							 | 
						|
								        return $mainmenu;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *
							 | 
						|
								     *
							 | 
						|
								     *  @param  [type] $vhost
							 | 
						|
								     *  @param  [type] $mainmenu
							 | 
						|
								     *  @return [type]
							 | 
						|
								     */
							 | 
						|
								    private function createVhostSubmenu($vhost, $mainmenu)
							 | 
						|
								    {
							 | 
						|
								        $builder = CliMenuBuilder::newSubMenu($mainmenu->getTerminal());
							 | 
						|
								
							 | 
						|
								        // create checkbox for disable / enabled
							 | 
						|
								        $checkbox = self::createVhostCheckbox($vhost);
							 | 
						|
								
							 | 
						|
								        // if vhost is enabled
							 | 
						|
								        if ($vhost['enabled']) {
							 | 
						|
								            $checkbox->setChecked();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        $builder
							 | 
						|
								            ->setTitle('Nginx > '.$vhost['domain'])
							 | 
						|
								            ->disableDefaultItems()
							 | 
						|
								
							 | 
						|
								            // edit configuration
							 | 
						|
								            ->addItem('edit', function(CliMenu $menu) use (&$vhost) {
							 | 
						|
								                system('nano /etc/nginx/sites-available/'.$vhost['file'].' > `tty`');
							 | 
						|
								            })
							 | 
						|
								
							 | 
						|
								            // delete configuration
							 | 
						|
								            ->addItem('delete', function(CliMenu $menu) use (&$vhost) {
							 | 
						|
								
							 | 
						|
								                if ($vhost['enabled'] === true) {
							 | 
						|
								                    $menu->flash('Please disable first!')->display();
							 | 
						|
								                } else {
							 | 
						|
								
							 | 
						|
								                    // input domain for confirmation
							 | 
						|
								                    $result = $menu->askText()
							 | 
						|
								                        ->setPromptText('Enter the domain name as confirmation: '.$vhost['domain'].' / [ESC] for Cancel')
							 | 
						|
								                        ->ask();
							 | 
						|
								
							 | 
						|
								                    // if result matching delete vhost an close menu
							 | 
						|
								                    if ($result->fetch() === $vhost['domain']) {
							 | 
						|
								                        unlink('/etc/nginx/sites-available/'.$vhost['file']);
							 | 
						|
								                        $menu->confirm($vhost['domain'].' is deleted!')->display('OK!');
							 | 
						|
								
							 | 
						|
								                        // get
							 | 
						|
								                        $parent = $menu->getParent();
							 | 
						|
								                        $menu->closeThis();
							 | 
						|
								
							 | 
						|
								                        // remove current vhost from mainmenu
							 | 
						|
								                        $parent->removeItem($parent->getSelectedItem());
							 | 
						|
								                        $parent->open();
							 | 
						|
								
							 | 
						|
								                    // cancel input
							 | 
						|
								                    } else if (empty($result->fetch())) {
							 | 
						|
								                        $menu->flash('Cancel')->display();
							 | 
						|
								
							 | 
						|
								                    // if domain not matching
							 | 
						|
								                    } else {
							 | 
						|
								                        $menu->flash('Not matching! Domain not deleted!')->display();
							 | 
						|
								                    }
							 | 
						|
								
							 | 
						|
								                }
							 | 
						|
								
							 | 
						|
								            })
							 | 
						|
								            ->addLineBreak('-')
							 | 
						|
								            ->addMenuItem($checkbox)
							 | 
						|
								            ->addLineBreak('-');
							 | 
						|
								
							 | 
						|
								        if ($vhost['ssl'] === true) {
							 | 
						|
								            if ($vhost['ssl_certificate_exists']) {
							 | 
						|
								                $builder->addStaticItem('expired_at: '.$vhost['ssl_certificate_expired_at']);
							 | 
						|
								            } else {
							 | 
						|
								
							 | 
						|
								                // add certificate
							 | 
						|
								                $builder->addItem('add certificate', function(CliMenu $menu) {
							 | 
						|
								                    $result = $menu->askText()
							 | 
						|
								                        ->setPromptText('Enter E-Mail')
							 | 
						|
								                        ->ask();
							 | 
						|
								
							 | 
						|
								                    $email = $result->fetch();
							 | 
						|
								                    system(base_path().' php mcp lets-encrypt:add '.$email.' '.$vhost['domain']);
							 | 
						|
								
							 | 
						|
								                    if ($vhost['redirect_www'] === true) {
							 | 
						|
								                        system(base_path().' php mcp lets-encrypt:add '.$email.' www.'.$vhost['domain']);
							 | 
						|
								                    }
							 | 
						|
								
							 | 
						|
								                });
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            $builder->addLineBreak('-');
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        $builder
							 | 
						|
								            ->addItem('Back', new NginxVhostGoBackAction())
							 | 
						|
								            ->addItem('Exit', new ExitAction());
							 | 
						|
								
							 | 
						|
								        $submenu = $builder->build();
							 | 
						|
								
							 | 
						|
								        $submenu->setParent($mainmenu);
							 | 
						|
								        $submenu->setStyle($mainmenu->getStyle());
							 | 
						|
								
							 | 
						|
								        // create MenuMenuItem
							 | 
						|
								        $item = new MenuMenuItem(
							 | 
						|
								            $vhost['domain'],
							 | 
						|
								            $submenu,
							 | 
						|
								            $builder->isMenuDisabled()
							 | 
						|
								        );
							 | 
						|
								
							 | 
						|
								        $item->getStyle()->setSelectedMarker("\xF0\x9D\x8C\xA1 ")->setUnselectedMarker('  ');
							 | 
						|
								
							 | 
						|
								        // show item extra if domain is enabled
							 | 
						|
								        $item->getStyle()->setItemExtra('[ enabled ]');
							 | 
						|
								        if ($vhost['enabled']) {
							 | 
						|
								            $item->showItemExtra();
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        return $item;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *
							 | 
						|
								     *  @param  [type] $vhost
							 | 
						|
								     *  @return [type]
							 | 
						|
								     */
							 | 
						|
								    private function createVhostCheckbox(&$vhost)
							 | 
						|
								    {
							 | 
						|
								        // create checkbox for enabled / disabled
							 | 
						|
								        $checkbox = new CheckboxItem('enabled', function(CliMenu $menu) use (&$vhost) {
							 | 
						|
								
							 | 
						|
								            // check status
							 | 
						|
								            if ($menu->getSelectedItem()->getChecked()) {
							 | 
						|
								                symlink('/etc/nginx/sites-available/'.$vhost['file'], '/etc/nginx/sites-enabled/'.$vhost['file']);
							 | 
						|
								
							 | 
						|
								                exec('nginx -c /etc/nginx/nginx.conf -t 2>&1', $output);
							 | 
						|
								                $result = preg_match_all("/syntax is ok/", implode(' ', $output), $output);
							 | 
						|
								
							 | 
						|
								                // restart if success message was found
							 | 
						|
								                if ($result > 0) {
							 | 
						|
								                    exec('service nginx restart');
							 | 
						|
								                    $menu->confirm('Success! ')->display('OK!');
							 | 
						|
								
							 | 
						|
								                    $vhost['enabled'] = true;
							 | 
						|
								                    $status = 'enabled';
							 | 
						|
								                } else {
							 | 
						|
								                    unlink('/etc/nginx/sites-enabled/'.$vhost['file']);
							 | 
						|
								                    $menu->confirm('Error! Configuration not Working!')->display('OK!');
							 | 
						|
								
							 | 
						|
								                    // @TODO: find a way to show logs, https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp/issues/15
							 | 
						|
								                    // implode(PHP_EOL, $output);
							 | 
						|
								
							 | 
						|
								                    $vhost['enabled'] = false;
							 | 
						|
								                    $status = 'disabled';
							 | 
						|
								                }
							 | 
						|
								            } else {
							 | 
						|
								                unlink('/etc/nginx/sites-enabled/'.$vhost['file']);
							 | 
						|
								
							 | 
						|
								                $vhost['enabled'] = false;
							 | 
						|
								                $status = 'disabled';
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            if ($vhost['enabled']) {
							 | 
						|
								                $menu->getSelectedItem()->setChecked();
							 | 
						|
								            } else {
							 | 
						|
								                $menu->getSelectedItem()->setUnchecked();
							 | 
						|
								            }
							 | 
						|
								
							 | 
						|
								            $menu->redraw();
							 | 
						|
								
							 | 
						|
								        });
							 | 
						|
								
							 | 
						|
								        return $checkbox;
							 | 
						|
								    }
							 | 
						|
								}
							 |