Bearsampp 2026.9.23
Loading...
Searching...
No Matches
class.bin.apache.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
17class BinApache extends Module
18{
22 const SERVICE_NAME = 'bearsamppapache';
26 const SERVICE_PARAMS = '-k runservice';
27
31 const ROOT_CFG_ENABLE = 'apacheEnable';
35 const ROOT_CFG_VERSION = 'apacheVersion';
36
40 const LOCAL_CFG_EXE = 'apacheExe';
44 const LOCAL_CFG_CONF = 'apacheConf';
48 const LOCAL_CFG_PORT = 'apachePort';
52 const LOCAL_CFG_SSL_PORT = 'apacheSslPort';
56 const LOCAL_CFG_OPENSSL_EXE = 'apacheOpensslExe';
57
61 const CMD_VERSION_NUMBER = '-v';
77 const CMD_VHOSTS_SETTINGS = '-S';
81 const CMD_LOADED_MODULES = '-M';
85 const CMD_SYNTAX_CHECK = '-t';
86
90 const TAG_START_SWITCHONLINE = '# START switchOnline tag - Do not replace!';
94 const TAG_END_SWITCHONLINE = '# END switchOnline tag - Do not replace!';
95
99 private $service;
107 private $sslConf;
111 private $accessLog;
115 private $rewriteLog;
119 private $errorLog;
120
124 private $exe;
128 private $conf;
132 private $port;
136 private $sslPort;
140 private $opensslExe;
141
148 public function __construct($id, $type)
149 {
150 Log::initClass($this);
151 $this->reload($id, $type);
152 }
153
160 public function reload($id = null, $type = null)
161 {
163 Log::reloadClass($this);
164
165 $this->name = $bearsamppLang->getValue(Lang::APACHE);
166 $this->version = $bearsamppConfig->getRaw(self::ROOT_CFG_VERSION);
167 parent::reload($id, $type);
168
169 $this->enable = $this->enable && $bearsamppConfig->getRaw(self::ROOT_CFG_ENABLE);
170 $this->service = new Win32Service(self::SERVICE_NAME);
171 $this->modulesPath = $this->symlinkPath . '/modules';
172 $this->sslConf = $this->symlinkPath . '/conf/extra/httpd-ssl.conf';
173 $this->accessLog = Path::getLogsPath() . '/apache_access.log';
174 $this->rewriteLog = Path::getLogsPath() . '/apache_rewrite.log';
175 $this->errorLog = Path::getLogsPath() . '/apache_error.log';
176
177 if ($this->bearsamppConfRaw !== false) {
178 $this->exe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_EXE];
179 $this->conf = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_CONF];
180 $this->port = $this->bearsamppConfRaw[self::LOCAL_CFG_PORT];
181 $this->sslPort = $this->bearsamppConfRaw[self::LOCAL_CFG_SSL_PORT];
182 $this->opensslExe = $this->symlinkPath . '/' . $this->bearsamppConfRaw[self::LOCAL_CFG_OPENSSL_EXE];
183 }
184
185 if (!$this->enable) {
186 Log::info($this->name . ' is not enabled!');
187
188 return;
189 }
190 if (!is_dir($this->currentPath)) {
191 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->currentPath));
192
193 return;
194 }
195 if (!is_dir($this->symlinkPath)) {
196 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_FILE_NOT_FOUND), $this->name . ' ' . $this->version, $this->symlinkPath));
197
198 return;
199 }
200 if (!is_file($this->bearsamppConf)) {
201 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->bearsamppConf));
202
203 return;
204 }
205 if (!is_file($this->sslConf)) {
206 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->sslConf));
207
208 return;
209 }
210 if (!is_file($this->exe)) {
211 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->exe));
212
213 return;
214 }
215 if (!is_file($this->conf)) {
216 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_CONF_NOT_FOUND), $this->name . ' ' . $this->version, $this->conf));
217
218 return;
219 }
220 if (!is_numeric($this->port) || $this->port <= 0) {
221 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_INVALID_PARAMETER), self::LOCAL_CFG_PORT, $this->port));
222
223 return;
224 }
225 if (!is_numeric($this->sslPort) || $this->sslPort <= 0) {
226 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_INVALID_PARAMETER), self::LOCAL_CFG_SSL_PORT, $this->sslPort));
227
228 return;
229 }
230 if (!is_file($this->opensslExe)) {
231 Log::error(sprintf($bearsamppLang->getValue(Lang::ERROR_EXE_NOT_FOUND), $this->name . ' ' . $this->version, $this->opensslExe));
232
233 return;
234 }
235
236 $nssm = new Nssm(self::SERVICE_NAME);
237 $nssm->setDisplayName(APP_TITLE . ' ' . $this->getName());
238 $nssm->setBinPath($this->exe);
239 $nssm->setParams('');
240 $nssm->setStart(Nssm::SERVICE_DEMAND_START);
241
242 $this->service->setNssm($nssm);
243 }
244
250 protected function replaceAll($params)
251 {
252 $content = file_get_contents($this->bearsamppConf);
253
254 foreach ($params as $key => $value) {
255 $content = preg_replace('|' . $key . ' = .*|', $key . ' = ' . '"' . $value . '"', $content);
256 $this->bearsamppConfRaw[$key] = $value;
257 switch ($key) {
258 case self::LOCAL_CFG_PORT:
259 $this->port = $value;
260 break;
261 case self::LOCAL_CFG_SSL_PORT:
262 $this->sslPort = $value;
263 break;
264 }
265 }
266
267 file_put_contents($this->bearsamppConf, $content);
268
269 self::invalidateConfigCacheForPath($this->bearsamppConf);
270 }
271
281 public function changePort($port, $checkUsed = false, $wbProgressBar = null)
282 {
283 global $bearsamppWinbinder;
284
285 if (!Util::isValidPort($port)) {
286 Log::error($this->getName() . ' port not valid: ' . $port);
287
288 return false;
289 }
290
291 $port = intval($port);
292 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
293
294 $isPortInUse = ServiceHelper::isPortInUse($port);
295 if (!$checkUsed || $isPortInUse === false) {
296 // bearsampp.conf
297 $this->setPort($port);
298 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
299
300 // conf
301 $this->update();
302 $bearsamppWinbinder->incrProgressBar($wbProgressBar);
303
304 return true;
305 }
306
307 Log::debug($this->getName() . ' port in used: ' . $port . ' - ' . $isPortInUse);
308
309 return $isPortInUse;
310 }
311
321 public function checkPort($port, $ssl = false, $showWindow = false)
322 {
323 global $bearsamppLang, $bearsamppWinbinder;
324 $boxTitle = sprintf($bearsamppLang->getValue(Lang::CHECK_PORT_TITLE), $this->getName(), $port);
325
326 if (!Util::isValidPort($port)) {
327 Log::error($this->getName() . ' port not valid: ' . $port);
328
329 return false;
330 }
331
332 // $verify = false: this pings the app's own Apache on localhost, which uses a local
333 // self-signed certificate. Certificate verification stays on for all remote fetches.
334 $headers = HttpClient::getHttpHeaders('http' . ($ssl ? 's' : '') . '://localhost:' . $port . '/' . Path::getWebResourcesPath() . '/ping.php', false);
335 if (!empty($headers)) {
336 foreach ($headers as $row) {
337 if (UtilString::startWith($row, 'Server: ') || UtilString::startWith($row, 'server: ')) {
339 $this->getName() . ' port ' . $port . ' is used by: ' . $this->getName() . ' ' . str_replace('Server: ', '', str_replace('server: ', '', trim($row)))
340 );
341 if ($showWindow) {
342 $bearsamppWinbinder->messageBoxInfo(
343 sprintf($bearsamppLang->getValue(Lang::PORT_USED_BY), $port, str_replace('Server: ', '', str_replace('server: ', '', trim($row)))),
344 $boxTitle
345 );
346 }
347
348 return true;
349 }
350 }
351 Log::debug($this->getName() . ' port ' . $port . ' is used by another application');
352 if ($showWindow) {
353 $bearsamppWinbinder->messageBoxWarning(
354 sprintf($bearsamppLang->getValue(Lang::PORT_NOT_USED_BY), $port),
355 $boxTitle
356 );
357 }
358 } else {
359 Log::debug($this->getName() . ' port ' . $port . ' is not used');
360 if ($showWindow) {
361 $bearsamppWinbinder->messageBoxError(
362 sprintf($bearsamppLang->getValue(Lang::PORT_NOT_USED), $port),
363 $boxTitle
364 );
365 }
366 }
367
368 return false;
369 }
370
379 public function switchVersion($version, $showWindow = false)
380 {
381 Log::debug('Switch ' . $this->name . ' version to ' . $version);
382
383 return $this->updateConfig($version, 0, $showWindow);
384 }
385
395 protected function updateConfig($version = null, $sub = 0, $showWindow = false)
396 {
397 global $bearsamppRoot, $bearsamppLang, $bearsamppBins, $bearsamppWinbinder;
398
399 if (!$this->enable) {
400 return true;
401 }
402
403 $version = $version == null ? $this->version : $version;
404 Log::debug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'Update ' . $this->name . ' ' . $version . ' config');
405
406 $boxTitle = sprintf($bearsamppLang->getValue(Lang::SWITCH_VERSION_TITLE), $this->getName(), $version);
407
408 $conf = str_replace('apache' . $this->getVersion(), 'apache' . $version, $this->getConf());
409 $bearsamppConf = str_replace('apache' . $this->getVersion(), 'apache' . $version, $this->bearsamppConf);
410
411 $tsDll = $bearsamppBins->getPhp()->getTsDll();
412
413 $apachePhpModuleName = null;
414 if ($tsDll !== false) {
415 $apachemoduleNamePrefix = substr($tsDll, 0, 4);
416 $apachePhpModuleName = ($apachemoduleNamePrefix == 'php8' ? 'php' : $apachemoduleNamePrefix) . '_module';
417 }
418 $apachePhpModulePath = $bearsamppBins->getPhp()->getApacheModule($version);
419 $apachePhpModuleDll = basename($apachePhpModulePath);
420
421 Log::debug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'PHP TsDll found: ' . $tsDll);
422 Log::debug(($sub > 0 ? str_repeat(' ', 2 * $sub) : '') . 'PHP Apache module found: ' . $apachePhpModulePath);
423
424 if (!file_exists($conf) || !file_exists($bearsamppConf)) {
425 Log::error('bearsampp config files not found for ' . $this->getName() . ' ' . $version);
426 if ($showWindow) {
427 $bearsamppWinbinder->messageBoxError(
428 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_NOT_FOUND_ERROR), $this->getName() . ' ' . $version),
429 $boxTitle
430 );
431 }
432
433 return false;
434 }
435
436 $bearsamppConfRaw = parse_ini_file($bearsamppConf);
437 if ($bearsamppConfRaw === false || !isset($bearsamppConfRaw[self::ROOT_CFG_VERSION]) || $bearsamppConfRaw[self::ROOT_CFG_VERSION] != $version) {
438 Log::error('bearsampp config file malformed for ' . $this->getName() . ' ' . $version);
439 if ($showWindow) {
440 $bearsamppWinbinder->messageBoxError(
441 sprintf($bearsamppLang->getValue(Lang::BEARSAMPP_CONF_MALFORMED_ERROR), $this->getName() . ' ' . $version),
442 $boxTitle
443 );
444 }
445
446 return false;
447 }
448
449 if ($tsDll === false || $apachePhpModulePath === false) {
450 Log::debug($this->getName() . ' ' . $version . ' does not seem to be compatible with PHP ' . $bearsamppBins->getPhp()->getVersion());
451 if ($showWindow) {
452 $bearsamppWinbinder->messageBoxError(
453 sprintf($bearsamppLang->getValue(Lang::APACHE_INCPT), $version, $bearsamppBins->getPhp()->getVersion()),
454 $boxTitle
455 );
456 }
457
458 return false;
459 }
460
461 // httpd.conf
462 $this->setVersion($version);
463
464 // conf
465 Log::debug('httpd.conf = ' . $conf);
467 // PHP module
468 '/^#?PHPIniDir\s.*/' => ($bearsamppBins->getPhp()->isEnable() ? '' : '#') . 'PHPIniDir "' . Path::getModuleSymlinkPath(
469 $bearsamppBins->getPhp()
470 ) . '"',
471 '/^#?LoadFile\s.*php.ts\.dll.*/' => ($bearsamppBins->getPhp()->isEnable() ? '' : '#') . (!file_exists(
472 Path::getModuleSymlinkPath($bearsamppBins->getPhp()) . '/' . $tsDll
473 ) ? '#' : '') . 'LoadFile "' . Path::getModuleSymlinkPath($bearsamppBins->getPhp()) . '/' . $tsDll . '"',
474 '/^#?LoadModule\sphp.*/' => ($bearsamppBins->getPhp()
475 ->isEnable() ? '' : '#') . 'LoadModule ' . $apachePhpModuleName . ' "' . Path::getModuleSymlinkPath(
476 $bearsamppBins->getPhp()
477 ) . '/' . $apachePhpModuleDll . '"',
478 '/^#?LoadModule\sphp_*/' => ($bearsamppBins->getPhp()
479 ->isEnable() ? '' : '#') . 'LoadModule ' . $apachePhpModuleName . ' "' . Path::getModuleSymlinkPath(
480 $bearsamppBins->getPhp()
481 ) . '/' . $apachePhpModuleDll . '"',
482
483
484 // Port
485 '/^Listen\s(\d+)/' => 'Listen ' . $this->port,
486 '/^ServerName\s+([a-zA-Z0-9.]+):(\d+)/' => 'ServerName {{1}}:' . $this->port,
487 '/^NameVirtualHost\s+([a-zA-Z0-9.*]+):(\d+)/' => 'NameVirtualHost {{1}}:' . $this->port,
488 '/^<VirtualHost\s+([a-zA-Z0-9.*]+):(\d+)>/' => '<VirtualHost {{1}}:' . $this->port . '>'
489 ));
490
491 // vhosts
492 foreach ($this->getVhosts() as $vhost) {
493 Util::replaceInFile(Path::getVhostsPath() . '/' . $vhost . '.conf', array(
494 '/^<VirtualHost\s+([a-zA-Z0-9.*]+):(\d+)>$/' => '<VirtualHost {{1}}:' . $this->port . '>$'
495 ));
496 }
497
498 // www .htaccess
499 Util::replaceInFile(Path::getWwwPath() . '/.htaccess', array(
500 '/(.*)http:\/\/localhost(.*)/' => '{{1}}http://localhost' . ($this->port != 80 ? ':' . $this->port : '') . '/$1 [QSA,R=301,L]',
501 ));
502
503 return true;
504 }
505
511 public function getModules()
512 {
513 $fromFolder = $this->getModulesFromFolder();
514 $fromConf = $this->getModulesFromConf();
515 $result = array_merge($fromFolder, $fromConf);
516 ksort($result);
517
518 return $result;
519 }
520
526 public function getModulesFromConf()
527 {
528 $result = array();
529
530 if (!$this->enable) {
531 return $result;
532 }
533
534 $confContent = file($this->getConf());
535 foreach ($confContent as $row) {
536 $modMatch = array();
537 if (preg_match('/^(#)?LoadModule\s*([a-z0-9_-]+)\s*"?(.*)"?/i', $row, $modMatch)) {
538 $name = $modMatch[2];
539 //$path = $modMatch[3];
540 if (!UtilString::startWith($name, 'php')) {
541 if ($modMatch[1] == '#') {
543 } else {
545 }
546 }
547 }
548 }
549
550 ksort($result);
551
552 return $result;
553 }
554
560 public function getModulesLoaded()
561 {
562 $result = array();
563 foreach ($this->getModulesFromConf() as $name => $status) {
565 $result[] = $name;
566 }
567 }
568
569 return $result;
570 }
571
577 private function getModulesFromFolder()
578 {
579 $result = array();
580
581 if (!$this->enable) {
582 return $result;
583 }
584
585 $handle = @opendir($this->getModulesPath());
586 if (!$handle) {
587 return $result;
588 }
589
590 while (false !== ($file = readdir($handle))) {
591 if ($file != '.' && $file != '..' && UtilString::startWith($file, 'mod_') && (UtilString::endWith($file, '.so') || UtilString::endWith($file, '.dll'))) {
592 $name = str_replace(array('mod_', '.so', '.dll'), '', $file) . '_module';
594 }
595 }
596
597 closedir($handle);
598 ksort($result);
599
600 return $result;
601 }
602
608 public function getAlias()
609 {
610 global $bearsamppRoot;
611 $result = array();
612
613 $handle = @opendir(Path::getAliasPath());
614 if (!$handle) {
615 return $result;
616 }
617
618 while (false !== ($file = readdir($handle))) {
619 if ($file != '.' && $file != '..' && UtilString::endWith($file, '.conf')) {
620 $result[] = str_replace('.conf', '', $file);
621 }
622 }
623
624 closedir($handle);
625 ksort($result);
626
627 return $result;
628 }
629
635 public function getVhosts()
636 {
637 global $bearsamppRoot;
638 $result = array();
639
640 $handle = @opendir(Path::getVhostsPath());
641 if (!$handle) {
642 return $result;
643 }
644
645 while (false !== ($file = readdir($handle))) {
646 if ($file != '.' && $file != '..' && UtilString::endWith($file, '.conf')) {
647 $result[] = str_replace('.conf', '', $file);
648 }
649 }
650
651 closedir($handle);
652 ksort($result);
653
654 return $result;
655 }
656
662 public function getVhostsUrl()
663 {
664 global $bearsamppRoot;
665 $result = array();
666
667 foreach ($this->getVhosts() as $vhost) {
668 $vhostContent = file(Path::getVhostsPath() . '/' . $vhost . '.conf');
669 foreach ($vhostContent as $vhostLine) {
670 $vhostLine = trim($vhostLine);
671 $enabled = !UtilString::startWith($vhostLine, '#');
672 if (preg_match_all('/ServerName\s+(.*)/', $vhostLine, $matches)) {
673 foreach ($matches as $match) {
674 $found = isset($match[1]) ? trim($match[1]) : trim($match[0]);
675 if (filter_var('http://' . $found, FILTER_VALIDATE_URL) !== false) {
676 $result[$found] = $enabled;
677 break 2;
678 }
679 }
680 }
681 }
682 }
683
684 return $result;
685 }
686
692 public function getWwwDirectories()
693 {
694 global $bearsamppRoot;
695 $result = array();
696
697 $handle = @opendir(Path::getWwwPath());
698 if (!$handle) {
699 return $result;
700 }
701
702 while (false !== ($file = readdir($handle))) {
703 if ($file != '.' && $file != '..' && is_dir(Path::getWwwPath() . '/' . $file)) {
704 $result[] = $file;
705 }
706 }
707
708 closedir($handle);
709 ksort($result);
710
711 return $result;
712 }
713
721 public function getCmdLineOutput($cmd)
722 {
723 $result = array(
724 'syntaxOk' => false,
725 'content' => null,
726 );
727
728 if (file_exists($this->getExe())) {
729 $tmpResult = Batch::exec('apacheGetCmdLineOutput', '"' . $this->getExe() . '" ' . $cmd);
730 if ($tmpResult !== false && is_array($tmpResult)) {
731 $result['syntaxOk'] = trim($tmpResult[count($tmpResult) - 1]) == 'Syntax OK';
732 if ($result['syntaxOk']) {
733 unset($tmpResult[count($tmpResult) - 1]);
734 }
735 $result['content'] = implode(PHP_EOL, $tmpResult);
736 }
737 }
738
739 return $result;
740 }
741
749 private function getOnlineContent($version = null)
750 {
751 $version = $version != null ? $version : $this->getVersion();
752 $result = self::TAG_START_SWITCHONLINE . PHP_EOL;
753
754 if (UtilString::startWith($version, '2.4')) {
755 $result .= 'Require all granted' . PHP_EOL;
756 } else {
757 $result .= 'Order Allow,Deny' . PHP_EOL .
758 'Allow from all' . PHP_EOL;
759 }
760
761 return $result . self::TAG_END_SWITCHONLINE;
762 }
763
771 private function getOfflineContent($version = null)
772 {
773 $version = $version != null ? $version : $this->getVersion();
774 $result = self::TAG_START_SWITCHONLINE . PHP_EOL;
775
776 if (UtilString::startWith($version, '2.4')) {
777 $result .= 'Require local' . PHP_EOL;
778 } else {
779 $result .= 'Order Deny,Allow' . PHP_EOL .
780 'Deny from all' . PHP_EOL .
781 'Allow from ' . APP_LOCALHOST . ' ::1' . PHP_EOL;
782 }
783
784 return $result . self::TAG_END_SWITCHONLINE;
785 }
786
794 private function getRequiredContent($version = null)
795 {
796 global $bearsamppConfig;
797
798 return $bearsamppConfig->isOnline() ? $this->getOnlineContent($version) : $this->getOfflineContent($version);
799 }
800
809 public function getAliasContent($name, $dest)
810 {
811 $dest = Path::formatUnixPath($dest);
812
813 return 'Alias /' . $name . ' "' . $dest . '"' . PHP_EOL . PHP_EOL .
814 '<Directory "' . $dest . '">' . PHP_EOL .
815 ' Options Indexes FollowSymLinks MultiViews' . PHP_EOL .
816 ' AllowOverride all' . PHP_EOL .
817 $this->getRequiredContent() . PHP_EOL .
818 '</Directory>' . PHP_EOL;
819 }
820
829 public function getVhostContent($serverName, $documentRoot)
830 {
831 global $bearsamppRoot;
832
833 $documentRoot = Path::formatUnixPath($documentRoot);
834
835 return '<VirtualHost *:' . $this->getPort() . '>' . PHP_EOL .
836 ' ServerAdmin webmaster@' . $serverName . PHP_EOL .
837 ' DocumentRoot "' . $documentRoot . '"' . PHP_EOL .
838 ' ServerName ' . $serverName . PHP_EOL .
839 ' ErrorLog "' . Path::getLogsPath() . '/' . $serverName . '_error.log"' . PHP_EOL .
840 ' CustomLog "' . Path::getLogsPath() . '/' . $serverName . '_access.log" combined' . PHP_EOL . PHP_EOL .
841 ' <Directory "' . $documentRoot . '">' . PHP_EOL .
842 ' Options Indexes FollowSymLinks MultiViews' . PHP_EOL .
843 ' AllowOverride all' . PHP_EOL .
844 $this->getRequiredContent() . PHP_EOL .
845 ' </Directory>' . PHP_EOL .
846 '</VirtualHost>' . PHP_EOL . PHP_EOL .
847 '<IfModule ssl_module>' . PHP_EOL .
848 '<VirtualHost *:' . $this->getSslPort() . '> #SSL' . PHP_EOL .
849 ' DocumentRoot "' . $documentRoot . '"' . PHP_EOL .
850 ' ServerName ' . $serverName . PHP_EOL .
851 ' ServerAdmin webmaster@' . $serverName . PHP_EOL .
852 ' ErrorLog "' . Path::getLogsPath() . '/' . $serverName . '_error.log"' . PHP_EOL .
853 ' TransferLog "' . Path::getLogsPath() . '/' . $serverName . '_access.log"' . PHP_EOL . PHP_EOL .
854 ' SSLEngine on' . PHP_EOL .
855 ' SSLProtocol all -SSLv2' . PHP_EOL .
856 ' SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5' . PHP_EOL .
857 ' SSLCertificateFile "' . Path::getSslPath() . '/' . $serverName . '.crt"' . PHP_EOL .
858 ' SSLCertificateKeyFile "' . Path::getSslPath() . '/' . $serverName . '.ppk"' . PHP_EOL .
859 ' BrowserMatch "MSIE [2-5]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0' . PHP_EOL .
860 ' CustomLog "' . Path::getLogsPath() . '/' . $serverName . '_sslreq.log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"' . PHP_EOL . PHP_EOL .
861 ' <Directory "' . $documentRoot . '">' . PHP_EOL .
862 ' SSLOptions +StdEnvVars' . PHP_EOL .
863 ' Options Indexes FollowSymLinks MultiViews' . PHP_EOL .
864 ' AllowOverride all' . PHP_EOL .
865 $this->getRequiredContent() . PHP_EOL .
866 ' </Directory>' . PHP_EOL .
867 '</VirtualHost>' . PHP_EOL .
868 '</IfModule>' . PHP_EOL;
869 }
870
876 public function refreshConf($putOnline)
877 {
878 if (!$this->enable) {
879 return;
880 }
881
882 $onlineContent = $this->getOnlineContent();
883 $offlineContent = $this->getOfflineContent();
884
885 $conf = file_get_contents($this->getConf());
886 Log::trace('refreshConf ' . $this->getConf());
887 preg_match('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $conf, $matches);
888 Log::trace(isset($matches[1]) ? print_r($matches[1], true) : 'N/A');
889
890 if ($putOnline) {
891 $conf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $onlineContent, $conf, -1, $count);
892 } else {
893 $conf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $offlineContent, $conf, -1, $count);
894 }
895 file_put_contents($this->getConf(), $conf);
896 Log::debug('Refresh ' . $this->getConf() . ': ' . $count . ' occurrence(s) replaced');
897
898 $sslConf = file_get_contents($this->getSslConf());
899 Log::trace('refreshConf ' . $this->getSslConf());
900 preg_match('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $sslConf, $matches);
901 Log::trace(isset($matches[1]) ? print_r($matches[1], true) : 'N/A');
902
903 if ($putOnline) {
904 $sslConf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $onlineContent, $sslConf, -1, $count);
905 } else {
906 $sslConf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $offlineContent, $sslConf, -1, $count);
907 }
908 file_put_contents($this->getSslConf(), $sslConf);
909 Log::debug('Refresh ' . $this->getSslConf() . ': ' . $count . ' occurrence(s) replaced');
910 }
911
917 public function refreshAlias($putOnline)
918 {
920
921 if (!$this->enable) {
922 return;
923 }
924
925 $onlineContent = $this->getOnlineContent();
926 $offlineContent = $this->getOfflineContent();
927
928 foreach ($this->getAlias() as $alias) {
929 $aliasConf = file_get_contents(Path::getAliasPath() . '/' . $alias . '.conf');
930 Log::trace('refreshAlias ' . Path::getAliasPath() . '/' . $alias . '.conf');
931 preg_match('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $aliasConf, $matches);
932 Log::trace(isset($matches[1]) ? print_r($matches[1], true) : 'N/A');
933
934 if ($putOnline) {
935 $aliasConf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $onlineContent, $aliasConf, -1, $count);
936 } else {
937 $aliasConf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $offlineContent, $aliasConf, -1, $count);
938 }
939 file_put_contents(Path::getAliasPath() . '/' . $alias . '.conf', $aliasConf);
940 Log::debug('Refresh ' . Path::getAliasPath() . '/' . $alias . '.conf: ' . $count . ' occurrence(s) replaced');
941 }
942
943 // Homepage
944 $bearsamppHomepage->refreshAliasContent();
945 }
946
952 public function refreshVhosts($putOnline)
953 {
954 global $bearsamppRoot;
955
956 if (!$this->enable) {
957 return;
958 }
959
960 $onlineContent = $this->getOnlineContent();
961 $offlineContent = $this->getOfflineContent();
962
963 foreach ($this->getVhosts() as $vhost) {
964 $vhostConf = file_get_contents(Path::getVhostsPath() . '/' . $vhost . '.conf');
965 Log::trace('refreshVhost ' . Path::getVhostsPath() . '/' . $vhost . '.conf');
966 preg_match('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $vhostConf, $matches);
967 Log::trace(isset($matches[1]) ? print_r($matches[1], true) : 'N/A');
968
969 if ($putOnline) {
970 $vhostConf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $onlineContent, $vhostConf, -1, $count);
971 } else {
972 $vhostConf = preg_replace('/' . self::TAG_START_SWITCHONLINE . '(.*?)' . self::TAG_END_SWITCHONLINE . '/s', $offlineContent, $vhostConf, -1, $count);
973 }
974 file_put_contents(Path::getVhostsPath() . '/' . $vhost . '.conf', $vhostConf);
975 Log::debug('Refresh ' . Path::getVhostsPath() . '/' . $vhost . '.conf: ' . $count . ' occurrence(s) replaced');
976 }
977 }
978
989 public function setEnable($enabled, $showWindow = false)
990 {
991 global $bearsamppConfig, $bearsamppLang, $bearsamppWinbinder;
992
993 if ($enabled == Config::ENABLED && !is_dir($this->currentPath)) {
994 Log::debug($this->getName() . ' cannot be enabled because bundle ' . $this->getVersion() . ' does not exist in ' . $this->currentPath);
995 if ($showWindow) {
996 $bearsamppWinbinder->messageBoxError(
997 sprintf($bearsamppLang->getValue(Lang::ENABLE_BUNDLE_NOT_EXIST), $this->getName(), $this->getVersion(), $this->currentPath),
998 sprintf($bearsamppLang->getValue(Lang::ENABLE_TITLE), $this->getName())
999 );
1000 }
1001 $enabled = Config::DISABLED;
1002 }
1003
1004 Log::info($this->getName() . ' switched to ' . ($enabled == Config::ENABLED ? 'enabled' : 'disabled'));
1005 $this->enable = $enabled == Config::ENABLED;
1006 $bearsamppConfig->replace(self::ROOT_CFG_ENABLE, $enabled);
1007
1008 $this->reload();
1009 if ($this->enable) {
1010 ServiceHelper::installService($this, $this->port, self::CMD_SYNTAX_CHECK, $showWindow);
1011 } else {
1012 ServiceHelper::removeService($this->service, $this->name);
1013 }
1014 }
1015
1023 public function setVersion($version)
1024 {
1025 global $bearsamppConfig;
1026 $this->version = $version;
1027 $bearsamppConfig->replace(self::ROOT_CFG_VERSION, $version);
1028 $this->reload();
1029 }
1030
1036 public function getService()
1037 {
1038 return $this->service;
1039 }
1040
1046 public function getModulesPath()
1047 {
1048 return $this->modulesPath;
1049 }
1050
1056 public function getSslConf()
1057 {
1058 return $this->sslConf;
1059 }
1060
1066 public function getAccessLog()
1067 {
1068 return $this->accessLog;
1069 }
1070
1076 public function getRewriteLog()
1077 {
1078 return $this->rewriteLog;
1079 }
1080
1086 public function getErrorLog()
1087 {
1088 return $this->errorLog;
1089 }
1090
1096 public function getExe()
1097 {
1098 return $this->exe;
1099 }
1100
1106 public function getConf()
1107 {
1108 return $this->conf;
1109 }
1110
1116 public function getPort()
1117 {
1118 return $this->port;
1119 }
1120
1128 public function setPort($port)
1129 {
1130 $this->replace(self::LOCAL_CFG_PORT, $port);
1131 }
1132
1138 public function getSslPort()
1139 {
1140 return $this->sslPort;
1141 }
1142
1150 public function setSslPort($sslPort)
1151 {
1152 $this->replace(self::LOCAL_CFG_SSL_PORT, $sslPort);
1153 }
1154
1160 public function getOpensslExe()
1161 {
1162 return $this->opensslExe;
1163 }
1164}
$result
global $bearsamppBins
global $bearsamppLang
global $bearsamppRoot
static exec($basename, $content, $timeout=true, $catchOutput=true, $standalone=false, $silent=true, $rebuild=true)
const TAG_START_SWITCHONLINE
const CMD_SYNTAX_CHECK
const CMD_CONFIG_DIRECTIVES
replaceAll($params)
getRequiredContent($version=null)
getOnlineContent($version=null)
updateConfig($version=null, $sub=0, $showWindow=false)
const LOCAL_CFG_SSL_PORT
getAliasContent($name, $dest)
const CMD_COMPILE_SETTINGS
switchVersion($version, $showWindow=false)
setSslPort($sslPort)
const ROOT_CFG_ENABLE
const CMD_COMPILED_MODULES
setVersion($version)
changePort($port, $checkUsed=false, $wbProgressBar=null)
setEnable($enabled, $showWindow=false)
refreshConf($putOnline)
const CMD_LOADED_MODULES
checkPort($port, $ssl=false, $showWindow=false)
const TAG_END_SWITCHONLINE
getVhostContent($serverName, $documentRoot)
const CMD_VERSION_NUMBER
const LOCAL_CFG_OPENSSL_EXE
reload($id=null, $type=null)
getOfflineContent($version=null)
const CMD_VHOSTS_SETTINGS
refreshAlias($putOnline)
const ROOT_CFG_VERSION
__construct($id, $type)
refreshVhosts($putOnline)
const DISABLED
const ENABLED
static getHttpHeaders($pingUrl, $verify=true)
const ENABLE_BUNDLE_NOT_EXIST
const BEARSAMPP_CONF_MALFORMED_ERROR
const APACHE_INCPT
const ERROR_EXE_NOT_FOUND
const ERROR_CONF_NOT_FOUND
const APACHE
const BEARSAMPP_CONF_NOT_FOUND_ERROR
const PORT_NOT_USED
const ERROR_INVALID_PARAMETER
const ENABLE_TITLE
const PORT_NOT_USED_BY
const SWITCH_VERSION_TITLE
const CHECK_PORT_TITLE
const PORT_USED_BY
const ERROR_FILE_NOT_FOUND
static info($data, $file=null)
static debug($data, $file=null)
static reloadClass($classInstance)
static trace($data, $file=null)
static error($data, $file=null)
static initClass($classInstance)
update($sub=0, $showWindow=false)
static invalidateConfigCacheForPath($sourcePath)
replace($key, $value)
const SERVICE_DEMAND_START
static getWebResourcesPath()
static getAliasPath($aetrayPath=false)
static getSslPath($aetrayPath=false)
static getLogsPath($aetrayPath=false)
static getWwwPath($aetrayPath=false)
static getVhostsPath($aetrayPath=false)
static formatUnixPath($path)
static getModuleSymlinkPath($module)
static installService($bin, $port, $syntaxCheckCmd, $showWindow=false)
static removeService($service, $name)
static isPortInUse($port)
static isValidPort($port)
static replaceInFile($path, $replaceList)
static startWith($string, $search)
static endWith($string, $search)
global $bearsamppConfig
Definition homepage.php:46
global $bearsamppHomepage
Definition homepage.php:46
const APP_LOCALHOST
Definition root.php:21
const APP_TITLE
Definition root.php:19