Bearsampp 2026.3.26
API documentation
Loading...
Searching...
No Matches
class.action.editVhost.php
Go to the documentation of this file.
1<?php
2/*
3 *
4 * * Copyright (c) 2022-2025 Bearsampp
5 * * License: GNU General Public License version 3 or later; see LICENSE.txt
6 * * Website: https://bearsampp.com
7 * * Github: https://github.com/Bearsampp
8 *
9 */
10
16{
22 private $wbLabelExp;
23
24 const GAUGE_SAVE = 3; // Override: needs extra step for SSL cert regeneration
25
26 protected function getGaugeSave()
27 {
28 return self::GAUGE_SAVE;
29 }
30
31 protected function getWindowTitle()
32 {
33 global $bearsamppLang;
34 return sprintf($bearsamppLang->getValue(Lang::EDIT_VHOST_TITLE), $this->initValue);
35 }
36
37 protected function getDialogTitle()
38 {
39 global $bearsamppLang;
40 return sprintf($bearsamppLang->getValue(Lang::EDIT_VHOST_TITLE), $this->initValue);
41 }
42
43 protected function getDeleteDialogTitle()
44 {
45 global $bearsamppLang;
47 }
48
49 protected function initializeDialog($args)
50 {
51 global $bearsamppRoot;
52
53 if (!isset($args[0]) || empty($args[0])) {
54 return false;
55 }
56
57 $filePath = $bearsamppRoot->getVhostsPath() . '/' . $args[0] . '.conf';
58 if (!file_exists($filePath)) {
59 return false;
60 }
61
62 $fileContent = file_get_contents($filePath);
63 if (!preg_match('/ServerName\s+(.*)/', $fileContent, $matchServerName) ||
64 !preg_match('/DocumentRoot\s+"(.*)"/', $fileContent, $matchDocumentRoot)) {
65 return false;
66 }
67
68 $this->initValue = trim($matchServerName[1]);
69 return true;
70 }
71
72 protected function createFormFields($bearsamppWinbinder)
73 {
75
76 // Load existing vhost data
77 $filePath = $bearsamppRoot->getVhostsPath() . '/' . $this->initValue . '.conf';
78 $fileContent = file_get_contents($filePath);
79 preg_match('/DocumentRoot\s+"(.*)"/', $fileContent, $matchDocumentRoot);
80 $initDocumentRoot = Util::formatWindowsPath(trim($matchDocumentRoot[1]));
81
82 $this->wbLabelServerName = $bearsamppWinbinder->createLabel(
83 $this->wbWindow,
85 15, 15, 85, null, WBC_RIGHT
86 );
87 $this->wbInputServerName = $bearsamppWinbinder->createInputText(
88 $this->wbWindow,
89 $this->initValue,
90 105, 13, 150, null
91 );
92
93 $this->wbLabelDocRoot = $bearsamppWinbinder->createLabel(
94 $this->wbWindow,
96 15, 45, 85, null, WBC_RIGHT
97 );
98 $this->wbInputDocRoot = $bearsamppWinbinder->createInputText(
99 $this->wbWindow,
100 $initDocumentRoot,
101 105, 43, 190, null, null, WBC_READONLY
102 );
103 $this->wbBtnDocRoot = $bearsamppWinbinder->createButton(
104 $this->wbWindow,
106 300, 43, 110
107 );
108
109 $this->wbLabelExp = $bearsamppWinbinder->createLabel(
110 $this->wbWindow,
111 sprintf($bearsamppLang->getValue(Lang::VHOST_EXP_LABEL), $this->initValue, $initDocumentRoot),
112 15, 80, 470, 50
113 );
114 }
115
116 protected function getFormValues($bearsamppWinbinder)
117 {
118 return [
119 'serverName' => $bearsamppWinbinder->getText($this->wbInputServerName[WinBinder::CTRL_OBJ]),
120 'documentRoot' => $bearsamppWinbinder->getText($this->wbInputDocRoot[WinBinder::CTRL_OBJ])
121 ];
122 }
123
124 protected function validateInput($values)
125 {
126 global $bearsamppLang;
127
128 if (!Util::isValidDomainName($values['serverName'])) {
129 return [
130 'valid' => false,
131 'error' => sprintf($bearsamppLang->getValue(Lang::VHOST_NOT_VALID_DOMAIN), $values['serverName'])
132 ];
133 }
134
135 return ['valid' => true];
136 }
137
138 protected function itemExists($values)
139 {
140 global $bearsamppRoot, $bearsamppLang, $bearsamppWinbinder;
141
142 // Only check if name changed
143 if ($values['serverName'] != $this->initValue && is_file($bearsamppRoot->getVhostsPath() . '/' . $values['serverName'] . '.conf')) {
144 $bearsamppWinbinder->messageBoxError(
145 sprintf($bearsamppLang->getValue(Lang::VHOST_ALREADY_EXISTS), $values['serverName']),
146 $this->getDialogTitle()
147 );
148 return true;
149 }
150
151 return false;
152 }
153
154 protected function saveItem($values)
155 {
156 global $bearsamppRoot, $bearsamppBins, $bearsamppOpenSsl;
157
158 // Remove old vhost and certificate
159 $bearsamppOpenSsl->removeCrt($this->initValue);
160 @unlink($bearsamppRoot->getVhostsPath() . '/' . $this->initValue . '.conf');
161
162 // Create new SSL certificate
163 if (!$bearsamppOpenSsl->createCrt($values['serverName'])) {
164 return false;
165 }
166
167 // Create new vhost configuration file
168 return file_put_contents(
169 $bearsamppRoot->getVhostsPath() . '/' . $values['serverName'] . '.conf',
170 $bearsamppBins->getApache()->getVhostContent($values['serverName'], $values['documentRoot'])
171 ) !== false;
172 }
173
174 protected function deleteItem()
175 {
176 global $bearsamppRoot, $bearsamppOpenSsl;
177
178 return $bearsamppOpenSsl->removeCrt($this->initValue) &&
179 @unlink($bearsamppRoot->getVhostsPath() . '/' . $this->initValue . '.conf');
180 }
181
182 protected function getSaveSuccessMessage($values)
183 {
184 global $bearsamppLang;
185 return sprintf(
187 $values['serverName'],
188 $values['serverName'],
189 $values['documentRoot']
190 );
191 }
192
193 protected function getSaveErrorMessage()
194 {
195 global $bearsamppLang;
197 }
198
199 protected function getDeleteConfirmMessage()
200 {
201 global $bearsamppLang;
202 return sprintf($bearsamppLang->getValue(Lang::DELETE_VHOST), $this->initValue);
203 }
204
205 protected function getDeleteSuccessMessage()
206 {
207 global $bearsamppLang;
208 return sprintf($bearsamppLang->getValue(Lang::VHOST_REMOVED), $this->initValue);
209 }
210
211 protected function getDeleteErrorMessage()
212 {
214 return sprintf(
216 $bearsamppRoot->getVhostsPath() . '/' . $this->initValue . '.conf'
217 );
218 }
219
220 protected function restartService()
221 {
222 global $bearsamppBins;
223 $bearsamppBins->getApache()->getService()->restart();
224 }
225
226 protected function handleCustomEvent($window, $id, $ctrl, $param1, $param2)
227 {
228 global $bearsamppLang, $bearsamppWinbinder;
229
230 $serverName = $bearsamppWinbinder->getText($this->wbInputServerName[WinBinder::CTRL_OBJ]);
231 $documentRoot = $bearsamppWinbinder->getText($this->wbInputDocRoot[WinBinder::CTRL_OBJ]);
232
233 // Handle server name input change
234 if ($id == $this->wbInputServerName[WinBinder::CTRL_ID]) {
235 $bearsamppWinbinder->setText(
236 $this->wbLabelExp[WinBinder::CTRL_OBJ],
237 sprintf($bearsamppLang->getValue(Lang::VHOST_EXP_LABEL), $serverName, $documentRoot)
238 );
239 $bearsamppWinbinder->setEnabled(
240 $this->wbBtnSave[WinBinder::CTRL_OBJ],
241 !empty($serverName)
242 );
243 }
244
245 // Handle browse button
246 if ($id == $this->wbBtnDocRoot[WinBinder::CTRL_ID]) {
247 $documentRoot = $bearsamppWinbinder->sysDlgPath(
248 $window,
250 $documentRoot
251 );
252 if ($documentRoot && is_dir($documentRoot)) {
253 $bearsamppWinbinder->setText($this->wbInputDocRoot[WinBinder::CTRL_OBJ], $documentRoot . '\\');
254 $bearsamppWinbinder->setText(
255 $this->wbLabelExp[WinBinder::CTRL_OBJ],
256 sprintf($bearsamppLang->getValue(Lang::VHOST_EXP_LABEL), $serverName, $documentRoot . '\\')
257 );
258 }
259 }
260 }
261}
global $bearsamppBins
global $bearsamppLang
global $bearsamppRoot
createFormFields($bearsamppWinbinder)
handleCustomEvent($window, $id, $ctrl, $param1, $param2)
getFormValues($bearsamppWinbinder)
const VHOST_EXP_LABEL
const VHOST_REMOVE_ERROR
const VHOST_SERVER_NAME_LABEL
const VHOST_CREATED_ERROR
const BUTTON_BROWSE
const VHOST_CREATED
const VHOST_NOT_VALID_DOMAIN
const DELETE_VHOST_TITLE
const VHOST_DOCUMENT_ROOT_LABEL
const DELETE_VHOST
const VHOST_ALREADY_EXISTS
const VHOST_DOC_ROOT_PATH
const VHOST_REMOVED
const EDIT_VHOST_TITLE
static isValidDomainName($domainName)
static formatWindowsPath($path)