Bearsampp
2026.7.11
Toggle main menu visibility
Loading...
Searching...
No Matches
class.action.quit.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
class
ActionQuit
17
{
21
private
$splash
;
22
26
const
GAUGE_PROCESSES
= 1;
27
const
GAUGE_OTHERS
= 1;
28
35
public
function
__construct
($args)
36
{
37
global
$bearsamppCore
,
$bearsamppLang
,
$bearsamppBins
, $bearsamppWinbinder, $arrayOfCurrents;
38
39
Log::info
(
'ActionQuit constructor called - starting exit process'
);
40
Log::debug
(
'Number of services to stop: '
. count(
$bearsamppBins
->getServices()));
41
42
// Start splash screen
43
$this->splash =
new
Splash
();
44
$this->splash->init(
45
$bearsamppLang
->getValue(
Lang::QUIT
),
46
self::GAUGE_PROCESSES * count(
$bearsamppBins
->getServices() ) + self::GAUGE_OTHERS,
47
sprintf(
$bearsamppLang
->getValue(
Lang::EXIT_LEAVING_TEXT
),
APP_TITLE
.
' '
.
$bearsamppCore
->getAppVersion() )
48
);
49
50
Log::debug
(
'Splash screen initialized'
);
51
52
// Set handler for the splash screen window
53
$bearsamppWinbinder->setHandler( $this->splash->getWbWindow(), $this,
'processWindow'
, 2000 );
54
Log::debug
(
'Window handler set, starting main loop'
);
55
56
$bearsamppWinbinder->mainLoop();
57
Log::debug
(
'Main loop exited'
);
58
59
$bearsamppWinbinder->reset();
60
Log::info
(
'ActionQuit constructor completed'
);
61
}
62
63
70
private
function
getServiceShutdownOrder
()
71
{
72
// Define shutdown order: dependent services first, then core services
73
// This prevents connection errors and ensures clean shutdown
74
return
[
75
// Tier 1: Application services (no dependencies on other services)
76
BinMailpit::SERVICE_NAME
,
// Mail testing tool
77
BinMemcached::SERVICE_NAME
,
// Caching service
78
BinXlight::SERVICE_NAME
,
// FTP server
79
80
// Tier 2: Database services (web server depends on these)
81
BinPostgresql::SERVICE_NAME
,
// PostgreSQL database
82
BinMariadb::SERVICE_NAME
,
// MariaDB database
83
BinMysql::SERVICE_NAME
,
// MySQL database
84
85
// Tier 3: Web server (depends on databases and other services)
86
BinApache::SERVICE_NAME
,
// Apache web server (stopped last)
87
];
88
}
89
97
private
function
getServiceDisplayName
($sName, $service)
98
{
99
global
$bearsamppBins
;
100
101
$name =
''
;
102
103
if
($sName ==
BinApache::SERVICE_NAME
) {
104
$name =
$bearsamppBins
->getApache()->getName() .
' '
.
$bearsamppBins
->getApache()->getVersion();
105
}
106
elseif ($sName ==
BinMysql::SERVICE_NAME
) {
107
$name =
$bearsamppBins
->getMysql()->getName() .
' '
.
$bearsamppBins
->getMysql()->getVersion();
108
}
109
elseif ($sName ==
BinMailpit::SERVICE_NAME
) {
110
$name =
$bearsamppBins
->getMailpit()->getName() .
' '
.
$bearsamppBins
->getMailpit()->getVersion();
111
}
112
elseif ($sName ==
BinMariadb::SERVICE_NAME
) {
113
$name =
$bearsamppBins
->getMariadb()->getName() .
' '
.
$bearsamppBins
->getMariadb()->getVersion();
114
}
115
elseif ($sName ==
BinPostgresql::SERVICE_NAME
) {
116
$name =
$bearsamppBins
->getPostgresql()->getName() .
' '
.
$bearsamppBins
->getPostgresql()->getVersion();
117
}
118
elseif ($sName ==
BinMemcached::SERVICE_NAME
) {
119
$name =
$bearsamppBins
->getMemcached()->getName() .
' '
.
$bearsamppBins
->getMemcached()->getVersion();
120
}
121
elseif ($sName ==
BinXlight::SERVICE_NAME
) {
122
$name =
$bearsamppBins
->getXlight()->getName() .
' '
.
$bearsamppBins
->getXlight()->getVersion();
123
}
124
125
$name .=
' ('
. $service->getName() .
')'
;
126
return
$name;
127
}
128
139
public
function
processWindow
($window, $id, $ctrl, $param1, $param2)
140
{
141
global
$bearsamppBins
,
$bearsamppLang
, $bearsamppWinbinder;
142
143
Log::info
(
'Starting graceful shutdown process with optimized service order'
);
144
145
// Get all available services
146
$allServices =
$bearsamppBins
->getServices();
147
148
// Get optimal shutdown order
149
$shutdownOrder = $this->
getServiceShutdownOrder
();
150
151
Log::debug
(
'Service shutdown order: '
. implode(
' -> '
, $shutdownOrder));
152
153
// Stop services in optimal order
154
foreach
($shutdownOrder as $sName) {
155
// Check if this service exists and is installed
156
if
(!isset($allServices[$sName])) {
157
Log::debug
(
'Service not found in available services: '
. $sName);
158
continue
;
159
}
160
161
$service = $allServices[$sName];
162
$displayName = $this->
getServiceDisplayName
($sName, $service);
163
164
Log::info
(
'Stopping service: '
. $displayName);
165
166
$this->splash->incrProgressBar();
167
$this->splash->setTextLoading(sprintf(
$bearsamppLang
->getValue(
Lang::EXIT_REMOVE_SERVICE_TEXT
), $displayName));
168
169
// Delete (stop and remove) the service
170
$result
= $service->delete();
171
172
if
(
$result
) {
173
Log::info
(
'Successfully stopped and removed service: '
. $displayName);
174
}
else
{
175
Log::warning
(
'Failed to stop/remove service: '
. $displayName .
' (may not be installed)'
);
176
}
177
}
178
179
// Handle any services not in the shutdown order (for extensibility)
180
foreach
($allServices as $sName => $service) {
181
if
(!in_array($sName, $shutdownOrder)) {
182
$displayName = $this->
getServiceDisplayName
($sName, $service);
183
Log::warning
(
'Stopping unlisted service: '
. $displayName);
184
185
$this->splash->incrProgressBar();
186
$this->splash->setTextLoading(sprintf(
$bearsamppLang
->getValue(
Lang::EXIT_REMOVE_SERVICE_TEXT
), $displayName));
187
$service->delete();
188
}
189
}
190
191
Log::info
(
'All services stopped successfully'
);
192
193
// Purge "current" symlinks
194
$this->splash->setTextLoading(
'Removing symlinks...'
);
195
Symlinks::deleteCurrentSymlinks
();
196
197
// Stop other processes
198
$this->splash->incrProgressBar();
199
$this->splash->setTextLoading(
$bearsamppLang
->getValue(
Lang::EXIT_STOP_OTHER_PROCESS_TEXT
));
200
Win32Ps::killBins
(
true
);
201
202
// Explicitly kill NodeJS if still running (it's not a Windows service)
203
Log::trace
(
'Explicitly terminating NodeJS processes'
);
204
Win32Ps::killBins
([
'node.exe'
]);
205
206
// Perform cleanup verification in background (non-blocking)
207
$this->splash->setTextLoading(
'Performing cleanup verification...'
);
208
$this->
performQuickCleanupVerification
($allServices);
209
210
// Terminate any remaining processes
211
// Final termination sequence
212
$this->splash->setTextLoading(
'Completing shutdown...'
);
213
if
(strtoupper(substr(PHP_OS, 0, 3)) ===
'WIN'
) {
214
$currentPid =
Win32Ps::getCurrentPid
();
215
216
// Terminate PHP processes with a timeout of 15 seconds
217
self::terminatePhpProcesses
($currentPid, $window, $this->splash, 15);
218
219
// Force exit if still running
220
exit
(0);
221
}
222
223
// Non-Windows fallback
224
$bearsamppWinbinder->destroyWindow($window);
225
exit
(0);
226
}
227
237
public
static
function
terminatePhpProcesses
($excludePid, $window =
null
,
$splash
=
null
, $timeout = 10)
238
{
239
global $bearsamppWinbinder,
$bearsamppCore
;
240
241
$currentPid =
Win32Ps::getCurrentPid
();
242
$startTime = microtime(
true
);
243
244
Log::trace
(
'Starting PHP process termination (excluding PID: '
. $excludePid .
')'
);
245
246
// Get list of loading PIDs to exclude from termination
247
$loadingPids = array();
248
if
(file_exists(
$bearsamppCore
->getLoadingPid())) {
249
$pids = file(
$bearsamppCore
->getLoadingPid());
250
foreach
($pids as $pid) {
251
$loadingPids[] = intval(trim($pid));
252
}
253
Log::trace
(
'Loading PIDs to preserve: '
. implode(
', '
, $loadingPids));
254
}
255
256
$targets = [
'php-win.exe'
,
'php.exe'
];
257
foreach
(
Win32Ps::getListProcs
() as
$proc
) {
258
// Check if we've exceeded our timeout
259
if
(microtime(
true
) - $startTime > $timeout) {
260
Log::trace
(
'Process termination timeout exceeded, continuing with remaining operations'
);
261
break
;
262
}
263
264
$exe = strtolower(basename(
$proc
[
Win32Ps::EXECUTABLE_PATH
]));
265
$pid =
$proc
[
Win32Ps::PROCESS_ID
];
266
267
// Skip if this is the excluded PID or a loading window PID
268
if
(in_array($exe, $targets) && $pid != $excludePid && !in_array($pid, $loadingPids)) {
269
Log::trace
(
'Terminating PHP process: '
. $pid);
270
Win32Ps::kill
($pid);
271
usleep(100000);
// 100ms delay between terminations
272
} elseif (in_array($pid, $loadingPids)) {
273
Log::trace
(
'Preserving loading window process: '
. $pid);
274
}
275
}
276
277
// Initiate self-termination with timeout
278
if
(
$splash
!==
null
) {
279
$splash
->setTextLoading(
'Final cleanup...'
);
280
}
281
282
try
{
283
Log::trace
(
'Initiating self-termination for PID: '
. $currentPid);
284
// Add a timeout wrapper around the killProc call
285
$killSuccess =
Win32Native::killProcess
($currentPid);
286
if
(!$killSuccess) {
287
Log::trace
(
'Self-termination via Win32Native::killProcess failed, using alternative method'
);
288
}
289
}
catch
(\Exception $e) {
290
Log::trace
(
'Exception during self-termination: '
. $e->getMessage());
291
}
292
293
// Destroy window after process termination
294
// Fix for PHP 8.2: Check if window is not null before destroying
295
if
($window && $bearsamppWinbinder) {
296
try
{
297
Log::trace
(
'Destroying window'
);
298
$bearsamppWinbinder->destroyWindow($window);
299
}
catch
(\Exception $e) {
300
Log::trace
(
'Exception during window destruction: '
. $e->getMessage());
301
}
302
}
303
304
// Force exit if still running after timeout
305
if
(microtime(
true
) - $startTime > $timeout * 1.5) {
306
Log::trace
(
'Forcing exit due to timeout'
);
307
exit
(0);
308
}
309
}
310
317
private
function
verifyServicesStoppedAndCleanup
($services)
318
{
319
Log::info
(
'Verifying all services are stopped...'
);
320
321
$results = [
322
'all_stopped'
=>
true
,
323
'services'
=> [],
324
'still_running'
=> [],
325
'verification_failed'
=> []
326
];
327
328
foreach
($services as $sName => $service) {
329
$displayName = $this->
getServiceDisplayName
($sName, $service);
330
331
try
{
332
// Check if service is still installed/running
333
$isInstalled = $service->isInstalled();
334
$isRunning = $isInstalled ? $service->isRunning() :
false
;
335
336
$results[
'services'
][$sName] = [
337
'name'
=> $displayName,
338
'installed'
=> $isInstalled,
339
'running'
=> $isRunning
340
];
341
342
if
($isRunning) {
343
Log::warning
(
'Service still running after shutdown: '
. $displayName);
344
$results[
'still_running'
][] = $displayName;
345
$results[
'all_stopped'
] =
false
;
346
347
// Attempt to force stop
348
Log::info
(
'Attempting to force stop: '
. $displayName);
349
$service->stop();
350
usleep(500000);
// Wait 500ms
351
352
// Verify again
353
if
($service->isRunning()) {
354
Log::error
(
'Failed to force stop service: '
. $displayName);
355
}
else
{
356
Log::info
(
'Successfully force stopped service: '
. $displayName);
357
}
358
} elseif ($isInstalled) {
359
Log::debug
(
'Service stopped but still installed: '
. $displayName);
360
}
else
{
361
Log::debug
(
'Service verified stopped and removed: '
. $displayName);
362
}
363
364
}
catch
(\Exception $e) {
365
Log::error
(
'Failed to verify service status for '
. $displayName .
': '
. $e->getMessage());
366
$results[
'verification_failed'
][] = $displayName;
367
$results[
'all_stopped'
] =
false
;
368
}
369
}
370
371
if
($results[
'all_stopped'
]) {
372
Log::info
(
'All services verified stopped successfully'
);
373
}
else
{
374
Log::warning
(
'Some services could not be verified as stopped'
);
375
}
376
377
return
$results;
378
}
379
385
private
function
verifySymlinksRemoved
()
386
{
387
global
$bearsamppRoot
;
388
389
Log::info
(
'Verifying symlinks are removed...'
);
390
391
$results = [
392
'success'
=>
true
,
393
'remaining'
=> []
394
];
395
396
// Check common symlink locations
397
$symlinkPaths = [
398
Path::getRootPath
() .
'/apache'
,
399
Path::getRootPath
() .
'/php'
,
400
Path::getRootPath
() .
'/mysql'
,
401
Path::getRootPath
() .
'/mariadb'
,
402
Path::getRootPath
() .
'/postgresql'
,
403
Path::getRootPath
() .
'/nodejs'
,
404
Path::getRootPath
() .
'/memcached'
,
405
Path::getRootPath
() .
'/mailpit'
,
406
Path::getRootPath
() .
'/xlight'
407
];
408
409
foreach
($symlinkPaths as $path) {
410
if
(file_exists($path) || is_link($path)) {
411
Log::warning
(
'Symlink still exists: '
. $path);
412
$results[
'remaining'
][] = basename($path);
413
$results[
'success'
] =
false
;
414
415
// Attempt to remove it using robust method
416
try
{
417
$removed =
\Symlinks::safeRemoveSymlink
($path);
418
419
// Verify removal
420
if
($removed && !file_exists($path) && !is_link($path)) {
421
Log::info
(
'Successfully removed remaining symlink: '
. $path);
422
$results[
'remaining'
] = array_diff($results[
'remaining'
], [basename($path)]);
423
if
(empty($results[
'remaining'
])) {
424
$results[
'success'
] =
true
;
425
}
426
}
427
}
catch
(\Exception $e) {
428
Log::error
(
'Failed to remove symlink '
. $path .
': '
. $e->getMessage());
429
}
430
}
431
}
432
433
if
($results[
'success'
]) {
434
Log::info
(
'All symlinks verified removed'
);
435
}
else
{
436
Log::warning
(
'Some symlinks could not be removed: '
. implode(
', '
, $results[
'remaining'
]));
437
}
438
439
return
$results;
440
}
441
447
private
function
cleanupTemporaryFiles
()
448
{
449
global
$bearsamppCore
;
450
451
Log::info
(
'Cleaning up temporary files...'
);
452
453
$results = [
454
'success'
=>
true
,
455
'cleaned'
=> 0,
456
'failed'
=> [],
457
'size_freed'
=> 0
458
];
459
460
$tmpPath =
Path::getTmpPath
();
461
462
if
(!is_dir($tmpPath)) {
463
Log::debug
(
'Temp directory does not exist: '
. $tmpPath);
464
return
$results;
465
}
466
467
try
{
468
$files = glob($tmpPath .
'/*'
);
469
470
if
($files ===
false
) {
471
Log::warning
(
'Failed to list temporary files'
);
472
return
$results;
473
}
474
475
foreach
($files as $file) {
476
// Skip certain files that should be preserved
477
$basename = basename($file);
478
if
(in_array($basename, [
'.'
,
'..'
,
'.gitkeep'
,
'README.md'
])) {
479
continue
;
480
}
481
482
try
{
483
$size = is_file($file) ? filesize($file) : 0;
484
485
if
(is_link($file)) {
486
if
(@unlink($file) || @rmdir($file)) {
487
$results[
'cleaned'
]++;
488
$results[
'size_freed'
] += $size;
489
Log::debug
(
'Removed temp symlink: '
. $basename);
490
}
else
{
491
$results[
'failed'
][] = $basename;
492
$results[
'success'
] =
false
;
493
Log::warning
(
'Failed to remove temp symlink: '
. $basename);
494
}
495
} elseif (is_file($file)) {
496
if
(@unlink($file)) {
497
$results[
'cleaned'
]++;
498
$results[
'size_freed'
] += $size;
499
Log::debug
(
'Removed temp file: '
. $basename);
500
}
else
{
501
$results[
'failed'
][] = $basename;
502
$results[
'success'
] =
false
;
503
Log::warning
(
'Failed to remove temp file: '
. $basename);
504
}
505
} elseif (is_dir($file)) {
506
Util::deleteFolder
($file);
507
if
(!file_exists($file)) {
508
$results[
'cleaned'
]++;
509
Log::debug
(
'Removed temp directory: '
. $basename);
510
}
else
{
511
$results[
'failed'
][] = $basename;
512
$results[
'success'
] =
false
;
513
Log::warning
(
'Failed to remove temp directory: '
. $basename);
514
}
515
}
516
}
catch
(\Exception $e) {
517
$results[
'failed'
][] = $basename;
518
$results[
'success'
] =
false
;
519
Log::error
(
'Error removing temp file '
. $basename .
': '
. $e->getMessage());
520
}
521
}
522
523
$sizeMB = round($results[
'size_freed'
] / 1024 / 1024, 2);
524
Log::info
(
'Cleaned up '
. $results[
'cleaned'
] .
' temporary files ('
. $sizeMB .
' MB freed)'
);
525
526
if
(!empty($results[
'failed'
])) {
527
Log::warning
(
'Failed to clean up '
. count($results[
'failed'
]) .
' files'
);
528
}
529
530
}
catch
(\Exception $e) {
531
Log::error
(
'Error during temp file cleanup: '
. $e->getMessage());
532
$results[
'success'
] =
false
;
533
}
534
535
return
$results;
536
}
537
543
private
function
checkForOrphanedProcesses
()
544
{
545
global
$bearsamppRoot
;
546
547
Log::info
(
'Checking for orphaned processes...'
);
548
549
$orphaned = [
550
'found'
=>
false
,
551
'processes'
=> []
552
];
553
554
try
{
555
$procs =
Win32Ps::getListProcs
();
556
$bearsamppPath = strtolower(
Path::formatUnixPath
(
Path::getRootPath
()));
557
$currentPid =
Win32Ps::getCurrentPid
();
558
559
foreach
($procs as
$proc
) {
560
$exePath = strtolower(
Path::formatUnixPath
(
$proc
[
Win32Ps::EXECUTABLE_PATH
]));
561
$pid =
$proc
[
Win32Ps::PROCESS_ID
];
562
563
// Skip current process
564
if
($pid == $currentPid) {
565
continue
;
566
}
567
568
// Check if process is from Bearsampp directory
569
if
(strpos($exePath, $bearsamppPath) === 0) {
570
$processName = basename($exePath);
571
572
// Skip www directory processes (user applications)
573
if
(strpos($exePath, $bearsamppPath .
'/www/'
) === 0) {
574
continue
;
575
}
576
577
// Skip the main Bearsampp executable
578
if
(strtolower($processName) ===
'bearsampp.exe'
) {
579
Log::debug
(
'Skipping main Bearsampp process: '
. $processName .
' (PID: '
. $pid .
')'
);
580
continue
;
581
}
582
583
// These are orphaned Bearsampp processes
584
$orphaned[
'found'
] =
true
;
585
$orphaned[
'processes'
][] = [
586
'pid'
=> $pid,
587
'name'
=> $processName,
588
'path'
=> $exePath
589
];
590
591
Log::warning
(
'Found orphaned process: '
. $processName .
' (PID: '
. $pid .
')'
);
592
593
// Attempt to kill orphaned process
594
try
{
595
Win32Ps::kill
($pid);
596
Log::info
(
'Terminated orphaned process: '
. $processName .
' (PID: '
. $pid .
')'
);
597
}
catch
(\Exception $e) {
598
Log::error
(
'Failed to terminate orphaned process '
. $processName .
': '
. $e->getMessage());
599
}
600
}
601
}
602
603
if
(!$orphaned[
'found'
]) {
604
Log::info
(
'No orphaned processes found'
);
605
}
else
{
606
Log::warning
(
'Found '
. count($orphaned[
'processes'
]) .
' orphaned process(es)'
);
607
}
608
609
}
catch
(\Exception $e) {
610
Log::error
(
'Error checking for orphaned processes: '
. $e->getMessage());
611
}
612
613
return
$orphaned;
614
}
615
625
private
function
generateCleanupReport
($serviceVerification, $symlinkVerification, $tempCleanup, $orphanedProcesses)
626
{
627
$report = [
628
'success'
=>
true
,
629
'warnings'
=> [],
630
'errors'
=> [],
631
'summary'
=> []
632
];
633
634
// Service verification
635
if
(!$serviceVerification[
'all_stopped'
]) {
636
$report[
'success'
] =
false
;
637
638
if
(!empty($serviceVerification[
'still_running'
])) {
639
$report[
'errors'
][] =
'Services still running: '
. implode(
', '
, $serviceVerification[
'still_running'
]);
640
}
641
642
if
(!empty($serviceVerification[
'verification_failed'
])) {
643
$report[
'warnings'
][] =
'Could not verify status of: '
. implode(
', '
, $serviceVerification[
'verification_failed'
]);
644
}
645
}
646
647
$report[
'summary'
][] =
'Services checked: '
. count($serviceVerification[
'services'
]);
648
649
// Symlink verification
650
if
(!$symlinkVerification[
'success'
]) {
651
$report[
'warnings'
][] =
'Symlinks not fully removed: '
. implode(
', '
, $symlinkVerification[
'remaining'
]);
652
}
653
654
// Temp file cleanup
655
if
($tempCleanup[
'cleaned'
] > 0) {
656
$sizeMB = round($tempCleanup[
'size_freed'
] / 1024 / 1024, 2);
657
$report[
'summary'
][] =
'Temp files cleaned: '
. $tempCleanup[
'cleaned'
] .
' ('
. $sizeMB .
' MB)'
;
658
}
659
660
if
(!empty($tempCleanup[
'failed'
])) {
661
$report[
'warnings'
][] =
'Failed to clean '
. count($tempCleanup[
'failed'
]) .
' temp file(s)'
;
662
}
663
664
// Orphaned processes
665
if
($orphanedProcesses[
'found'
]) {
666
$report[
'warnings'
][] =
'Found '
. count($orphanedProcesses[
'processes'
]) .
' orphaned process(es)'
;
667
foreach
($orphanedProcesses[
'processes'
] as
$proc
) {
668
$report[
'summary'
][] =
'Orphaned: '
.
$proc
[
'name'
] .
' (PID: '
.
$proc
[
'pid'
] .
')'
;
669
}
670
}
671
672
return
$report;
673
}
674
682
private
function
performQuickCleanupVerification
($services)
683
{
684
Log::info
(
'Performing quick cleanup verification...'
);
685
686
$startTime = microtime(
true
);
687
$maxTime = 2;
// Maximum 2 seconds for verification
688
689
try
{
690
// Quick temp file cleanup (non-blocking)
691
$tempCleanup = $this->
cleanupTemporaryFiles
();
692
693
// Check if we're running out of time
694
if
(microtime(
true
) - $startTime > $maxTime) {
695
Log::debug
(
'Cleanup verification timeout reached, skipping remaining checks'
);
696
return
;
697
}
698
699
// Quick orphaned process check (non-blocking)
700
$orphanedProcesses = $this->
checkForOrphanedProcesses
();
701
702
// Log summary
703
if
($tempCleanup[
'cleaned'
] > 0) {
704
$sizeMB = round($tempCleanup[
'size_freed'
] / 1024 / 1024, 2);
705
Log::info
(
'Quick cleanup: '
. $tempCleanup[
'cleaned'
] .
' temp files removed ('
. $sizeMB .
' MB freed)'
);
706
}
707
708
if
($orphanedProcesses[
'found'
]) {
709
Log::info
(
'Quick cleanup: '
. count($orphanedProcesses[
'processes'
]) .
' orphaned process(es) terminated'
);
710
}
711
712
$duration = round(microtime(
true
) - $startTime, 2);
713
Log::info
(
'Quick cleanup verification completed in '
. $duration .
' seconds'
);
714
715
}
catch
(\Exception $e) {
716
Log::warning
(
'Quick cleanup verification failed: '
. $e->getMessage());
717
}
718
}
719
}
$result
$result
Definition
ajax.apache.php:19
$bearsamppBins
global $bearsamppBins
Definition
ajax.apache.php:16
$bearsamppLang
global $bearsamppLang
Definition
ajax.apache.php:16
$bearsamppRoot
global $bearsamppRoot
Definition
ajax.apache.php:16
exit
exit
Definition
ajax.apply.moduleconfig.php:63
$bearsamppCore
global $bearsamppCore
Definition
ajax.latestversion.php:24
$proc
$proc
Definition
ajax.php:45
ActionQuit
Definition
class.action.quit.php:17
ActionQuit\verifyServicesStoppedAndCleanup
verifyServicesStoppedAndCleanup($services)
Definition
class.action.quit.php:317
ActionQuit\getServiceShutdownOrder
getServiceShutdownOrder()
Definition
class.action.quit.php:70
ActionQuit\__construct
__construct($args)
Definition
class.action.quit.php:35
ActionQuit\$splash
$splash
Definition
class.action.quit.php:21
ActionQuit\GAUGE_PROCESSES
const GAUGE_PROCESSES
Definition
class.action.quit.php:26
ActionQuit\performQuickCleanupVerification
performQuickCleanupVerification($services)
Definition
class.action.quit.php:682
ActionQuit\generateCleanupReport
generateCleanupReport($serviceVerification, $symlinkVerification, $tempCleanup, $orphanedProcesses)
Definition
class.action.quit.php:625
ActionQuit\checkForOrphanedProcesses
checkForOrphanedProcesses()
Definition
class.action.quit.php:543
ActionQuit\terminatePhpProcesses
static terminatePhpProcesses($excludePid, $window=null, $splash=null, $timeout=10)
Definition
class.action.quit.php:237
ActionQuit\cleanupTemporaryFiles
cleanupTemporaryFiles()
Definition
class.action.quit.php:447
ActionQuit\getServiceDisplayName
getServiceDisplayName($sName, $service)
Definition
class.action.quit.php:97
ActionQuit\processWindow
processWindow($window, $id, $ctrl, $param1, $param2)
Definition
class.action.quit.php:139
ActionQuit\verifySymlinksRemoved
verifySymlinksRemoved()
Definition
class.action.quit.php:385
ActionQuit\GAUGE_OTHERS
const GAUGE_OTHERS
Definition
class.action.quit.php:27
BinApache\SERVICE_NAME
const SERVICE_NAME
Definition
class.bin.apache.php:19
BinMailpit\SERVICE_NAME
const SERVICE_NAME
Definition
class.bin.mailpit.php:19
BinMariadb\SERVICE_NAME
const SERVICE_NAME
Definition
class.bin.mariadb.php:18
BinMemcached\SERVICE_NAME
const SERVICE_NAME
Definition
class.bin.memcached.php:18
BinMysql\SERVICE_NAME
const SERVICE_NAME
Definition
class.bin.mysql.php:18
BinPostgresql\SERVICE_NAME
const SERVICE_NAME
Definition
class.bin.postgresql.php:18
BinXlight\SERVICE_NAME
const SERVICE_NAME
Definition
class.bin.xlight.php:19
Lang\QUIT
const QUIT
Definition
class.lang.php:62
Lang\EXIT_LEAVING_TEXT
const EXIT_LEAVING_TEXT
Definition
class.lang.php:301
Lang\EXIT_REMOVE_SERVICE_TEXT
const EXIT_REMOVE_SERVICE_TEXT
Definition
class.lang.php:302
Lang\EXIT_STOP_OTHER_PROCESS_TEXT
const EXIT_STOP_OTHER_PROCESS_TEXT
Definition
class.lang.php:303
Log\info
static info($data, $file=null)
Definition
class.log.php:627
Log\debug
static debug($data, $file=null)
Definition
class.log.php:616
Log\warning
static warning($data, $file=null)
Definition
class.log.php:638
Log\trace
static trace($data, $file=null)
Definition
class.log.php:605
Log\error
static error($data, $file=null)
Definition
class.log.php:650
Path\getRootPath
static getRootPath($aetrayPath=false)
Definition
class.path.php:309
Path\formatUnixPath
static formatUnixPath($path)
Definition
class.path.php:156
Path\getTmpPath
static getTmpPath($aetrayPath=false)
Definition
class.path.php:940
Splash
Definition
class.splash.php:17
Symlinks\safeRemoveSymlink
static safeRemoveSymlink($path)
Definition
class.symlinks.php:180
Symlinks\deleteCurrentSymlinks
static deleteCurrentSymlinks()
Definition
class.symlinks.php:248
Util\deleteFolder
static deleteFolder($path)
Definition
class.util.php:108
Win32Native\killProcess
static killProcess($pid)
Definition
class.win32native.php:141
Win32Ps\getCurrentPid
static getCurrentPid()
Definition
class.win32ps.php:68
Win32Ps\getListProcs
static getListProcs()
Definition
class.win32ps.php:79
Win32Ps\killBins
static killBins($refreshProcs=false)
Definition
class.win32ps.php:192
Win32Ps\kill
static kill($pid)
Definition
class.win32ps.php:178
Win32Ps\EXECUTABLE_PATH
const EXECUTABLE_PATH
Definition
class.win32ps.php:22
Win32Ps\PROCESS_ID
const PROCESS_ID
Definition
class.win32ps.php:21
APP_TITLE
const APP_TITLE
Definition
root.php:13
sandbox
core
classes
actions
class.action.quit.php
Generated by
1.17.0