OpenSource CLI-App to install and handle stuff related to Web-Server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
7.4 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <?php
  2. namespace App\Factories;
  3. use PhpSchool\CliMenu\Builder\CliMenuBuilder;
  4. use PhpSchool\CliMenu\CliMenu;
  5. use PhpSchool\CliMenu\MenuItem\CheckboxItem;
  6. use PhpSchool\CliMenu\MenuItem\MenuMenuItem;
  7. use PhpSchool\CliMenu\Style\SelectableStyle;
  8. use PhpSchool\CliMenu\Style\ItemStyle;
  9. use PhpSchool\CliMenu\Action\ExitAction;
  10. use App\Menus\Nginx\NginxVhostGoBackAction;
  11. class NginxVhostFactory
  12. {
  13. /**
  14. * adding Vhosts behind index
  15. *
  16. * @param [type] $mainmenu
  17. * @param [type] $vhosts
  18. * @param [type] $vhostIndex
  19. */
  20. public function addVhosts($mainmenu, $vhosts, $insertAfterIndex)
  21. {
  22. // get items
  23. $items = $mainmenu->getItems();
  24. // new items
  25. $newItems = [];
  26. // lastIndex
  27. $insertUntilIndex = 0;
  28. // get all items before
  29. foreach($items as $index => $item) {
  30. if ($index < $insertAfterIndex) {
  31. $newItems[] = $item;
  32. } else {
  33. break;
  34. }
  35. }
  36. // check for linebreak-object
  37. foreach($items as $index => $item) {
  38. if ($index >= $insertAfterIndex && get_class($item) === 'PhpSchool\CliMenu\MenuItem\LineBreakItem') {
  39. $insertUntilIndex = $index;
  40. break;
  41. }
  42. }
  43. // add submenu for each vhost
  44. foreach($vhosts as $vhost) {
  45. $newItems[] = self::createVhostSubmenu($vhost, $mainmenu);
  46. }
  47. // fillup last items from mainmenu
  48. foreach($items as $index => $item) {
  49. if ($index >= $insertUntilIndex) {
  50. $newItems[] = $item;
  51. }
  52. }
  53. $mainmenu->setItems($newItems);
  54. return $mainmenu;
  55. }
  56. /**
  57. *
  58. *
  59. * @param [type] $vhost
  60. * @param [type] $mainmenu
  61. * @return [type]
  62. */
  63. private function createVhostSubmenu($vhost, $mainmenu)
  64. {
  65. $builder = CliMenuBuilder::newSubMenu($mainmenu->getTerminal());
  66. // create checkbox for disable / enabled
  67. $checkbox = self::createVhostCheckbox($vhost);
  68. // if vhost is enabled
  69. if ($vhost['enabled']) {
  70. $checkbox->setChecked();
  71. }
  72. $builder
  73. ->setTitle('Nginx > '.$vhost['domain'])
  74. ->disableDefaultItems()
  75. // edit configuration
  76. ->addItem('edit', function(CliMenu $menu) use (&$vhost) {
  77. system('nano /etc/nginx/sites-available/'.$vhost['file'].' > `tty`');
  78. })
  79. // delete configuration
  80. ->addItem('delete', function(CliMenu $menu) use (&$vhost) {
  81. if ($vhost['enabled'] === true) {
  82. $menu->flash('Please disable first!')->display();
  83. } else {
  84. // input domain for confirmation
  85. $result = $menu->askText()
  86. ->setPromptText('Enter the domain name as confirmation: '.$vhost['domain'].' / [ESC] for Cancel')
  87. ->ask();
  88. // if result matching delete vhost an close menu
  89. if ($result->fetch() === $vhost['domain']) {
  90. unlink('/etc/nginx/sites-available/'.$vhost['file']);
  91. $menu->confirm($vhost['domain'].' is deleted!')->display('OK!');
  92. // get
  93. $parent = $menu->getParent();
  94. $menu->closeThis();
  95. // remove current vhost from mainmenu
  96. $parent->removeItem($parent->getSelectedItem());
  97. $parent->open();
  98. // cancel input
  99. } else if (empty($result->fetch())) {
  100. $menu->flash('Cancel')->display();
  101. // if domain not matching
  102. } else {
  103. $menu->flash('Not matching! Domain not deleted!')->display();
  104. }
  105. }
  106. })
  107. ->addLineBreak('-')
  108. ->addMenuItem($checkbox)
  109. ->addLineBreak('-');
  110. if ($vhost['ssl'] === true) {
  111. if ($vhost['ssl_certificate_exists']) {
  112. $builder->addStaticItem('expired_at: '.$vhost['ssl_certificate_expired_at']);
  113. } else {
  114. $builder->addItem('add certificate', function(CliMenu $menu) {
  115. $result = $menu->askText()
  116. ->setPromptText('Enter E-Mail')
  117. ->ask();
  118. $email = $result->fetch();
  119. $this->call('lets-encrypt:add', [ 'email' => $email, 'domain' => $vhost['domain'] ]);
  120. if ($vhost['redirect_www'] === true) {
  121. $this->call('lets-encrypt:add', [ 'email' => $email, 'domain' => 'www.'.$vhost['domain'] ]);
  122. }
  123. });
  124. }
  125. $builder->addLineBreak('-');
  126. }
  127. $builder
  128. ->addItem('Back', new NginxVhostGoBackAction())
  129. ->addItem('Exit', new ExitAction());
  130. $submenu = $builder->build();
  131. $submenu->setParent($mainmenu);
  132. $submenu->setStyle($mainmenu->getStyle());
  133. // create MenuMenuItem
  134. $item = new MenuMenuItem(
  135. $vhost['domain'],
  136. $submenu,
  137. $builder->isMenuDisabled()
  138. );
  139. $item->getStyle()->setSelectedMarker("\xF0\x9D\x8C\xA1 ")->setUnselectedMarker(' ');
  140. // show item extra if domain is enabled
  141. $item->getStyle()->setItemExtra('[ enabled ]');
  142. if ($vhost['enabled']) {
  143. $item->showItemExtra();
  144. }
  145. return $item;
  146. }
  147. /**
  148. *
  149. * @param [type] $vhost
  150. * @return [type]
  151. */
  152. private function createVhostCheckbox(&$vhost)
  153. {
  154. // create checkbox for enabled / disabled
  155. $checkbox = new CheckboxItem('enabled', function(CliMenu $menu) use (&$vhost) {
  156. // check status
  157. if ($menu->getSelectedItem()->getChecked()) {
  158. symlink('/etc/nginx/sites-available/'.$vhost['file'], '/etc/nginx/sites-enabled/'.$vhost['file']);
  159. exec('nginx -c /etc/nginx/nginx.conf -t 2>&1', $output);
  160. $result = preg_match_all("/syntax is ok/", implode(' ', $output), $output);
  161. // restart if success message was found
  162. if ($result > 0) {
  163. exec('service nginx restart');
  164. $menu->confirm('Success! ')->display('OK!');
  165. $vhost['enabled'] = true;
  166. $status = 'enabled';
  167. } else {
  168. unlink('/etc/nginx/sites-enabled/'.$vhost['file']);
  169. $menu->confirm('Error! Configuration not Working!')->display('OK!');
  170. // @TODO: find a way to show logs, https://gitea.tentakelfabrik.de/Tentakelfabrik/mcp/issues/15
  171. // implode(PHP_EOL, $output);
  172. $vhost['enabled'] = false;
  173. $status = 'disabled';
  174. }
  175. } else {
  176. unlink('/etc/nginx/sites-enabled/'.$vhost['file']);
  177. $vhost['enabled'] = false;
  178. $status = 'disabled';
  179. }
  180. if ($vhost['enabled']) {
  181. $menu->getSelectedItem()->setChecked();
  182. } else {
  183. $menu->getSelectedItem()->setUnchecked();
  184. }
  185. $menu->redraw();
  186. });
  187. return $checkbox;
  188. }
  189. }