Merge pull request #3 from PhyreApps/main

pull from main
This commit is contained in:
Bozhidar Slaveykov 2024-05-16 11:07:20 +03:00 committed by GitHub
commit adf98d6259
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
52 changed files with 1098 additions and 103 deletions

View file

@ -8,7 +8,7 @@ steps:
- sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
- sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
- yum update -y
- dnf -y install sudo wget
- dnf -yq install sudo wget
- sudo wget -q -O - http://www.atomicorp.com/installers/atomic | sh
- mkdir /phyre-panel
@ -38,7 +38,7 @@ steps:
DEBIAN_FRONTEND: noninteractive
commands:
- apt-get update
- apt-get install -y libicu-dev sudo cron apt-utils -yqq daemonize dbus-user-session fontconfig rsync
- apt-get install -yq libicu-dev sudo cron apt-utils -yqq daemonize dbus-user-session fontconfig rsync
- daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
- mkdir /phyre-panel

View file

@ -7,10 +7,11 @@ steps:
environment:
DEBIAN_FRONTEND: noninteractive
commands:
- apt-get install -yq libicu-dev sudo cron apt-utils daemonize dbus-user-session fontconfig rsync
- service mysql start
- service phyre start
- MAIN_REPO_DIR=$(pwd)
- apt-get install -y rsync
- apt-get install -yq rsync
- cp /usr/local/phyre/web/phyre-config.ini /usr/local/phyre/phyre-config.ini.bak
- rm -rf /usr/local/phyre/web
- cp -r $MAIN_REPO_DIR/web /usr/local/phyre/web
@ -21,13 +22,14 @@ steps:
- COMPOSER_ALLOW_SUPERUSER=1 phyre-php composer.phar install
- phyre-php artisan phyre:set-ini-settings APP_ENV "local"
- phyre-php artisan migrate
- phyre-php artisan test --filter AutoInstallPanelTest
- phyre-php artisan test
---
kind: pipeline
name: Ubuntu 22.04 - Unit Test & Code Coverage
steps:
- name: run
image: ubuntu:22.04
platform: linux/amd64
environment:
DEBIAN_FRONTEND: noninteractive
CODECOV_TOKEN:
@ -36,7 +38,7 @@ steps:
- export DEBIAN_FRONTEND=noninteractive
- MAIN_REPO_DIR=$(pwd)
- apt-get update
- apt-get install -y libicu-dev sudo cron apt-utils -yqq daemonize dbus-user-session fontconfig rsync
- apt-get install -yq libicu-dev sudo cron apt-utils daemonize dbus-user-session fontconfig rsync
- daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
- ls -la
@ -81,10 +83,11 @@ steps:
- cd /usr/local/phyre/web/
- chmod -R 777 vendor
- apt install composer -y
- phyre-php artisan phyre:set-ini-settings APP_ENV "local"
- composer test:coverage
- mv clover.xml $MAIN_REPO_DIR/clover.xml
- mv coverage.xml $MAIN_REPO_DIR/coverage.xml
- cd $MAIN_REPO_DIR
- apt install -y pip
- apt install -yq pip
- pip install codecov-cli
- codecovcli --verbose upload-process -t $CODECOV_TOKEN

View file

@ -11,7 +11,7 @@ steps:
commands:
- MAIN_REPO_DIR=$(pwd)
- apt-get update
- apt-get install -y libicu-dev sudo cron apt-utils -yqq daemonize dbus-user-session fontconfig rsync
- apt-get install -yq libicu-dev sudo cron apt-utils -yqq daemonize dbus-user-session fontconfig rsync
- daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
- ls -la
@ -60,6 +60,6 @@ steps:
- mv clover.xml $MAIN_REPO_DIR/clover.xml
- mv coverage.xml $MAIN_REPO_DIR/coverage.xml
- cd $MAIN_REPO_DIR
- apt install -y pip
- apt install -yq pip
- pip install codecov-cli
- codecovcli --verbose upload-process -t $CODECOV_TOKEN

View file

@ -23,27 +23,27 @@ jobs:
run: |
ls -la
sudo mkdir /phyre-panel
sudo cp installers/${{ matrix.os }}/install-partial/install_base.sh /phyre-panel/install_base.sh
sudo chmod +x /phyre-panel/install_base.sh
sudo /phyre-panel/install_base.sh
sudo cp installers/${{ matrix.os }}/install-partial/install_web.sh /phyre-panel/install_web.sh
sudo chmod +x /phyre-panel/install_web.sh
- name: Run Code Coverage
run: |
sudo cp -r web /usr/local/phyre/web/
cd /usr/local/phyre/web/
ls -la
sudo wget https://getcomposer.org/download/latest-stable/composer.phar
sudo COMPOSER_ALLOW_SUPERUSER=1 phyre-php composer.phar install
sudo /phyre-panel/install_web.sh
sudo apt-get install autoconf build-essential -y
sudo apt-get install autoconf build-essential -yq
sudo mkdir -p /usr/local/phyre/php-xdebug
cd /usr/local/phyre/php-xdebug
sudo wget http://xdebug.org/files/xdebug-3.3.2.tgz
@ -52,17 +52,17 @@ jobs:
sudo /usr/local/phyre/php/bin/phpize
sudo ./configure --enable-xdebug --with-php-config=/usr/local/phyre/php/bin/php-config
sudo make
sudo mkdir -p /usr/local/phyre/php/zend-xdebug
sudo cp modules/xdebug.so /usr/local/phyre/php/zend-xdebug/xdebug.so
sudo chmod 777 /usr/local/phyre/php/zend-xdebug/xdebug.so
sudo cp /usr/local/phyre/web/tests/xdebug-php-ini.txt /usr/local/phyre/php/bin/php.ini
sudo chmod 777 /usr/local/phyre/php/bin/php.ini
phyre-php -v
cd /usr/local/phyre/web/
sudo chmod -R 777 vendor
apt install composer -y

View file

@ -2,7 +2,7 @@
FROM ubuntu:22.04 AS production
RUN apt-get update && apt-get install -y wget
RUN apt-get update && apt-get install -yq wget
RUN ls -la
RUN wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/main/installers/install.sh -O phyre-install.sh
RUN chmod +x phyre-install.sh

View file

@ -35,7 +35,7 @@ DEPENDENCIES_LIST=(
)
# Check if the dependencies are installed
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
yum install -y $DEPENDENCY
yum install -yq $DEPENDENCY
done
# Start MySQL

View file

@ -35,7 +35,7 @@ DEPENDENCIES_LIST=(
)
# Check if the dependencies are installed
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
apt install -y $DEPENDENCY
apt install -yq $DEPENDENCY
done
# Start MySQL

View file

@ -35,7 +35,7 @@ DEPENDENCIES_LIST=(
)
# Check if the dependencies are installed
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
apt install -y $DEPENDENCY
apt install -yq $DEPENDENCY
done
# Start MySQL

View file

@ -35,7 +35,7 @@ DEPENDENCIES_LIST=(
)
# Check if the dependencies are installed
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
apt install -y $DEPENDENCY
apt install -yq $DEPENDENCY
done
# Start MySQL

View file

@ -35,7 +35,7 @@ DEPENDENCIES_LIST=(
)
# Check if the dependencies are installed
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
apt install -y $DEPENDENCY
apt install -yq $DEPENDENCY
done
# Start MySQL

View file

@ -4,6 +4,7 @@
"description": "",
"keywords": [],
"priority": 0,
"hidden": true,
"logoIcon": "email-logo",
"category": "DevOps",
"adminUrl": "/admin/email",

View file

@ -4,6 +4,7 @@
"description": "",
"keywords": [],
"priority": 0,
"hidden": true,
"logoIcon": "minecraft-logo",
"category": "Game Servers",
"adminUrl": "/admin/minecraft/servers",

View file

@ -21,7 +21,7 @@ DEPENDENCIES_LIST=(
)
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
sudo apt install -y $DEPENDENCY
sudo apt install -yq $DEPENDENCY
done
echo "Done!"

127
web/app/ApacheParser.php Normal file
View file

@ -0,0 +1,127 @@
<?php
namespace App;
class ApacheParser
{
private static $commentRegex = '/#.*/i';
private static $directiveRegex = '/([^\\s]+)\\s*(.+)/i';
private static $sectionOpenRegex = '/<([^\\/\\s>]+)\\s*([^>]+)?>/i';
private static $sectionCloseRegex = '/<\\/([^\\s>]+)\\s*>/i';
public function parse($confPath)
{
if (empty($confPath)) {
throw new \Exception("Configuration path cannot be null or empty.");
}
if (!file_exists($confPath)) {
throw new \Exception("Configuration file not found: " . $confPath);
}
$currentNode = ConfigNode::createRootNode();
try {
$lines = file($confPath); // Don't add flags to file() function, this will broke line numbers (Line numbers are important for debugging)
$i = 0;
foreach ($lines as $line) {
$i++;
if (preg_match(self::$commentRegex, $line)) {
continue;
}
if (preg_match(self::$sectionOpenRegex, $line, $sectionOpenMatch)) {
$name = $sectionOpenMatch[1];
$content = isset($sectionOpenMatch[2]) ? $sectionOpenMatch[2] : '';
$sectionNode = ConfigNode::createChildNode($name, $content, $currentNode, $i);
$currentNode = $sectionNode;
} elseif (preg_match(self::$sectionCloseRegex, $line, $sectionCloseMatch)) {
$currentNode->endLine = $i;
$currentNode = $currentNode->getParent();
} elseif (preg_match(self::$directiveRegex, $line, $directiveMatch)) {
$name = $directiveMatch[1];
$content = $directiveMatch[2];
ConfigNode::createChildNode($name, $content, $currentNode, $i);
}
}
} catch (\Exception $e) {
throw new \Exception("An error occurred while reading the configuration file.", 0, $e);
}
return $currentNode;
}
}
class ConfigNode
{
private $name;
private $content;
private $parent;
private $children;
public $startLine;
public $endLine;
private function __construct($name, $content, $parent, $line = null)
{
$this->name = $name;
$this->content = $content;
$this->parent = $parent;
$this->children = [];
$this->startLine = $line;
}
public function getName()
{
return $this->name;
}
public function getContent()
{
return $this->content;
}
public function getStartLine()
{
return $this->startLine;
}
public function getEndLine()
{
return $this->endLine;
}
public static function createRootNode()
{
return new ConfigNode('root', null, null, null);
}
public static function createChildNode($name, $content, $parent, $line = null)
{
$node = new ConfigNode($name, $content, $parent, $line);
if ($parent !== null) {
$parent->children[] = $node;
}
return $node;
}
public function getParent()
{
return $this->parent;
}
public function getChildren()
{
return $this->children;
}
public function __toString()
{
return trim($this->name . ' ' . $this->content);
}
}

View file

@ -2,8 +2,8 @@
namespace App\Console\Commands;
use App\Jobs\ApacheBuild;
use App\Models\Domain;
use App\VirtualHosts\ApacheBuild;
use Illuminate\Console\Command;
class RunDomainRepair extends Command
@ -27,8 +27,6 @@ class RunDomainRepair extends Command
*/
public function handle()
{
$apache = new ApacheBuild();
$apache->fixPermissions();
$apache->build();
ApacheBuild::dispatch(true);
}
}

View file

@ -2,12 +2,16 @@
namespace app\Console\Commands;
use App\ApacheParser;
use App\Jobs\ApacheBuild;
use App\Models\Backup;
use App\Models\Domain;
use App\Models\HostingSubscription;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
class RunRepair extends Command
{
@ -48,11 +52,81 @@ class RunRepair extends Command
if (strpos($checkSupervisorStatus, 'active (running)') !== false) {
$this->info('Supervisor is running');
} else {
$this->info('Supervisor is not running');
$this->info('Restarting supervisor');
shell_exec('service supervisor restart');
$this->info('Supervisor is not running. Please check supervisor status');
}
$this->fixApacheErrors();
}
public function fixApacheErrors()
{
// Rebuild apache config
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
$checkApacheStatus = shell_exec('service apache2 status');
if (strpos($checkApacheStatus, 'Syntax error on line') !== false) {
$apacheErrorLine = null;
preg_match('/Syntax error on line (\d+)/', $checkApacheStatus, $matchApacheErrorLine);
if (isset($matchApacheErrorLine[1]) && is_numeric($matchApacheErrorLine[1])) {
$apacheErrorLine = $matchApacheErrorLine[1];
}
$apacheBrokenVirtualHosts = [];
$parser = new ApacheParser();
$configNode = $parser->parse('/etc/apache2/apache2.conf');
$configChildren = $configNode->getChildren();
foreach ($configChildren as $child) {
if ($child->getName() == 'VirtualHost') {
$virtualHost = [
'startLine' => $child->getStartLine(),
'endLine' => $child->getEndLine(),
'content' => $child->getContent()
];
$childChildren = $child->getChildren();
if (isset($childChildren[0])) {
foreach ($childChildren as $childChild) {
$virtualHost[$childChild->getName()] = $childChild->getContent();
}
}
if ($child->getStartLine() <= $apacheErrorLine && $child->getEndLine() >= $apacheErrorLine) {
$apacheBrokenVirtualHosts[] = $virtualHost;
}
}
}
if (count($apacheBrokenVirtualHosts) > 0) {
$this->error('Broken virtual hosts found');
foreach ($apacheBrokenVirtualHosts as $brokenVirtualHost) {
$this->error('Virtual host found: ' . $brokenVirtualHost['ServerName']);
$this->error('Turn on maintenance mode: ' . $brokenVirtualHost['ServerName']);
$findDomain = Domain::where('domain', $brokenVirtualHost['ServerName'])->first();
if ($findDomain) {
$findDomain->status = Domain::STATUS_BROKEN;
$findDomain->save();
}
}
$this->info('Run apache build...');
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
}
}
shell_exec('service apache2 restart');
$newCheckApacheStatus = shell_exec('service apache2 status');
if (Str::contains($newCheckApacheStatus, 'active (running)')) {
$this->info('Apache is running');
} else {
$this->info('Apache is not running. Please check apache status');
}
}
}

View file

@ -9,7 +9,7 @@ use Illuminate\Support\Str;
class Modules extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-puzzle-piece';
protected static ?string $navigationIcon = 'heroicon-o-cube';
protected static string $view = 'filament.pages.modules';

View file

@ -0,0 +1,74 @@
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
class PHPInfo extends Page
{
protected static string $view = 'filament.pages.php-info';
protected static ?string $navigationLabel = 'PHP Info';
protected static ?string $slug = 'php-info';
protected static bool $shouldRegisterNavigation = false;
public function getTitle(): string
{
return 'PHP Info';
}
public function getInstalledPHPModules($phpVersion)
{
$modules = [];
$getModules = shell_exec('php' . $phpVersion . ' -m');
if (!empty($getModules)) {
$getModules = explode("\n", $getModules);
if (is_array($getModules)) {
$getModules = array_filter($getModules);
foreach ($getModules as $module) {
if ($module == '[PHP Modules]') {
continue;
}
if ($module == '[Zend Modules]') {
continue;
}
$modules[] = $module;
}
$modules = array_unique($modules);
}
}
return $modules;
}
protected function getViewData(): array
{
$installedPHPVersions = [];
$getPHPVersions = shell_exec('sudo update-alternatives --list php');
if (!empty($getPHPVersions)) {
$getPHPVersions = explode("\n", $getPHPVersions);
if (is_array($getPHPVersions)) {
$getPHPVersions = array_filter($getPHPVersions);
foreach ($getPHPVersions as $phpVersion) {
$phpVersion = str_replace('/usr/bin/php', '', $phpVersion);
$phpVersion = str_replace('php', '', $phpVersion);
$phpVersion = str_replace('.', '', $phpVersion);
$phpVersion = substr($phpVersion, 0, 1) . '.' . substr($phpVersion, 1);
$installedPHPVersions[] = [
'version' => $phpVersion,
'modules' => $this->getInstalledPHPModules($phpVersion) ?? 'No modules found.',
];
}
}
}
return [
'installedPHPVersions' => $installedPHPVersions,
];
}
}

View file

@ -0,0 +1,111 @@
<?php
namespace App\Filament\Pages;
use App\Installers\Server\Applications\NodeJsInstaller;
use App\Installers\Server\Applications\PythonInstaller;
use App\Installers\Server\Applications\RubyInstaller;
use App\Livewire\Installer;
use App\SupportedApplicationTypes;
use Filament\Forms\Components\CheckboxList;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Wizard;
use Filament\Forms\Form;
use Filament\Forms\Get;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\HtmlString;
class PHPInstaller extends Installer
{
protected static string $layout = 'filament-panels::components.layout.index';
protected static string $view = 'filament.pages.php-installer';
protected static ?string $navigationLabel = 'PHP Installer';
protected static ?string $slug = 'php-installer';
protected static bool $shouldRegisterNavigation = false;
public function getTitle(): string
{
return 'PHP Installer';
}
public function form(Form $form): Form
{
return $form
->schema([
Wizard::make([
Wizard\Step::make('Step 1')
->description('Install PHP, Addons, and Extensions')
->schema([
// PHP Configuration
CheckboxList::make('server_php_versions')
->default([
'8.2'
])
->label('PHP Version')
->options(SupportedApplicationTypes::getPHPVersions())
->columns(5)
->required(),
CheckboxList::make('server_php_modules')
->label('PHP Modules')
->columns(5)
->options(SupportedApplicationTypes::getPHPModules()),
])->afterValidation(function () {
$this->install_log = 'Prepare installation...';
if (is_file(storage_path('server-app-configuration.json'))) {
unlink(storage_path('server-app-configuration.json'));
}
$phpInstaller = new \App\Installers\Server\Applications\PHPInstaller();
$phpInstaller->setPHPVersions($this->server_php_versions);
$phpInstaller->setPHPModules($this->server_php_modules);
$phpInstaller->setLogFilePath(storage_path($this->install_log_file_path));
$phpInstaller->install();
}),
Wizard\Step::make('Step 2')
->description('Finish installation')
->schema([
TextInput::make('install_log')
->view('livewire.installer-install-log')
->label('Installation Log'),
])
])->persistStepInQueryString()
//->startOnStep($startOnStep)
->submitAction(new HtmlString(Blade::render(<<<BLADE
<x-filament::button
type="submit"
size="sm"
color="primary"
wire:click="install"
>
Submit
</x-filament::button>
BLADE)))
]);
}
public function getRedirectLinkAfterInstall()
{
return '/admin/php-info';
}
}

View file

@ -4,7 +4,7 @@ namespace App\Filament\Pages;
use Filament\Pages\Page;
class Updates extends Page
class PhyreUpdates extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-arrow-path';
@ -16,6 +16,8 @@ class Updates extends Page
protected static ?int $navigationSort = 1;
protected static bool $shouldRegisterNavigation = false;
public $logFilePath = '/usr/local/phyre/update/update.log';
public function startUpdate()

View file

@ -0,0 +1,213 @@
<?php
namespace App\Filament\Pages;
use Filament\Pages\Page;
class Settings extends Page
{
protected static ?string $navigationIcon = 'heroicon-o-cog';
protected static string $view = 'filament.pages.settings';
protected static ?string $navigationGroup = 'Server Management';
protected static ?int $navigationSort = 4;
protected function getViewData(): array
{
$links = [
'Security'=>[
'title'=>'Security',
'icon'=>'heroicon-o-lock-closed',
'links' =>[
[
'title'=>'Users',
'icon'=>'heroicon-o-user',
'url'=> route('filament.admin.resources.users.index')
],
[
'title'=>'API Keys',
'icon'=>'heroicon-o-key',
'url'=> route('filament.admin.resources.api-keys.index')
],
]
],
// 'Assistance and Troubleshooting'=>[
// 'title'=>'Assistance and Troubleshooting',
// 'icon'=>'heroicon-o-lifebuoy',
// 'links' =>[
// [
// 'title'=>'Logs',
// 'icon'=>'heroicon-o-clipboard-list',
// 'url'=> ''
// ],
// [
// 'title'=>'Support',
// 'icon'=>'heroicon-o-chat-alt',
// 'url'=>''
// ],
// ]
// ],
'Tools & Resources'=>[
'title'=>'Tools & Resources',
'icon'=>'heroicon-o-cog',
'links' =>[
[
'title'=>'Backups',
'icon'=>'heroicon-o-cloud-upload',
'url'=> route('filament.admin.resources.backups.index')
],
[
'title'=>'Cron Jobs',
'icon'=>'heroicon-o-clock',
'url'=> route('filament.admin.resources.cron-jobs.index')
],
]
],
'General Settings'=>[
'title'=>'General Settings',
'icon'=>'heroicon-o-cog',
'links' =>[
[
'title'=>'Server Settings',
'icon'=>'heroicon-o-cog',
'url'=> route('filament.admin.pages.general-settings')
],
]
],
'Server Management'=>[
'title'=>'Server Management',
'icon'=>'heroicon-o-server',
'links'=> [
[
'title'=>'PHP Info',
'icon'=>'heroicon-o-information-circle',
'url'=> route('filament.admin.pages.php-info')
],
[
'title'=>'PHP Installer',
'icon'=>'heroicon-o-cog',
'url'=> route('filament.admin.pages.php-installer')
]
// [
// 'title'=>'Server Information',
// 'icon'=>'heroicon-o-information-circle',
// 'url'=> ''
// ],
// [
// 'title'=>'Server Status',
// 'icon'=>'heroicon-o-check-circle',
// 'url'=>''
// ],
// [
// 'title'=>'Server Resources',
// 'icon'=>'heroicon-o-chart-pie',
// 'url'=>''
// ],
// [
// 'title'=>'Server Logs',
// 'icon'=>'heroicon-o-clipboard-list',
// 'url'=>''
// ],
// [
// 'title'=>'Server Updates',
// 'icon'=>'heroicon-o-cloud-upload',
// 'url'=>''
// ],
]
],
'Statistics'=> [
'title'=>'Statistics',
'icon'=>'heroicon-o-chart-bar',
'links'=> [
[
'title'=>'Server Statistics',
'icon'=>'heroicon-o-chart-bar',
'url'=> route('filament.admin.pages.dashboard')
],
[
'title'=>'Customers Statistics',
'icon'=>'heroicon-o-chart-bar',
'url'=> route('filament.admin.resources.customers.index')
],
]
],
// 'Mail'=> [
// 'title'=>'Mail',
// 'icon'=>'heroicon-o-envelope',
// 'links'=> [
// [
// 'title'=>'Mail Settings',
// 'icon'=>'heroicon-o-cog',
// 'url'=> ''
// ],
// [
// 'title'=>'Mail Logs',
// 'icon'=>'heroicon-o-clipboard-list',
// 'url'=>''
// ],
// ]
// ],
// 'Applications & Databases'=>[
// 'title'=>'Applications & Databases',
// 'icon'=>'heroicon-o-cube',
// 'links'=> [
// [
// 'title'=>'Applications',
// 'icon'=>'heroicon-o-cube',
// 'url'=> ''
// ],
// [
// 'title'=>'Databases',
// 'icon'=>'heroicon-o-database',
// 'url'=>''
// ],
// ]
// ],
'Phyre'=> [
'title'=>'Phyre',
'icon'=>'heroicon-o-fire',
'links'=> [
// [
// 'title'=>'Phyre Settings',
// 'icon'=>'heroicon-o-cog',
// 'url'=> ''
// ],
// [
// 'title'=>'Phyre Logs',
// 'icon'=>'heroicon-o-clipboard-list',
// 'url'=>''
// ],
[
'title'=>'Phyre Updates',
'icon'=>'heroicon-o-cloud-upload',
'url'=> route('filament.admin.pages.phyre-updates')
]
]
],
'Phyre Apperance'=> [
'title'=>'Phyre Apperance',
'icon'=>'heroicon-o-paint-brush',
'links'=> [
[
'title'=>'Phyre Logo',
'icon'=>'heroicon-o-photograph',
'url'=> route('filament.admin.pages.phyre-apperance')
],
[
'title'=>'Phyre Theme',
'icon'=>'heroicon-o-color-swatch',
'url'=> route('filament.admin.pages.phyre-apperance')
],
]
]
];
return [
'linkGroups' => $links
];
}
}

View file

@ -17,11 +17,10 @@ use Monarobase\CountryList\CountryList;
use Outerweb\FilamentSettings\Filament\Pages\Settings as BaseSettings;
use Symfony\Component\Console\Input\Input;
class Settings extends BaseSettings
class GeneralSettings extends BaseSettings
{
protected static ?string $navigationGroup = 'Server Management';
protected static ?int $navigationSort = 4;
protected static bool $shouldRegisterNavigation = false;
public function save() : void
{

View file

@ -0,0 +1,32 @@
<?php
namespace App\Filament\Pages\Settings;
use App\Helpers;
use App\MasterDomain;
use Closure;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\ColorPicker;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\Tabs;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Get;
use Illuminate\Support\Facades\Storage;
use Monarobase\CountryList\CountryList;
use Outerweb\FilamentSettings\Filament\Pages\Settings as BaseSettings;
use Symfony\Component\Console\Input\Input;
class PhyreApperance extends BaseSettings
{
protected static bool $shouldRegisterNavigation = false;
public function schema(): array|Closure
{
return [
TextInput::make('general.brand_name'),
TextInput::make('general.brand_logo_url'),
ColorPicker::make('general.brand_primary_color'),
];
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace app\Filament\Pages;
namespace App\Filament\Pages;
use Filament\Pages\Page;

View file

@ -23,6 +23,8 @@ class ApiKeyResource extends Resource
protected static ?int $navigationSort = 5;
protected static bool $shouldRegisterNavigation = false;
public static function form(Form $form): Form
{
return $form

View file

@ -36,6 +36,8 @@ class BackupResource extends Resource
protected static ?int $navigationSort = 97;
protected static bool $shouldRegisterNavigation = false;
public static function form(Form $form): Form
{
return $form

View file

@ -20,6 +20,8 @@ class CronJobResource extends Resource
protected static ?int $navigationSort = 98;
protected static bool $shouldRegisterNavigation = false;
public static function form(Form $form): Form
{
return $form

View file

@ -25,7 +25,7 @@ class HostingSubscriptionResource extends Resource
{
protected static ?string $model = HostingSubscription::class;
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
protected static ?string $navigationIcon = 'heroicon-o-star';
protected static ?string $navigationGroup = 'Hosting Services';

View file

@ -20,6 +20,8 @@ class UserResource extends Resource
protected static ?int $navigationSort = 3;
protected static bool $shouldRegisterNavigation = false;
public static function form(Form $form): Form
{
return $form

View file

@ -19,13 +19,13 @@ class DovecotInstaller
$commands[] = 'echo "Installing dovecot..."';
// postfix - internet site
$commands[] = 'apt-get install -y telnet exim4 dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd';
$commands[] = 'apt-get install -yq telnet exim4 dovecot-core dovecot-imapd dovecot-pop3d dovecot-lmtpd';
// /var/lib/roundcube
// wget https://github.com/roundcube/roundcubemail/releases/download/1.6.0/roundcubemail-1.6.0-complete.tar.gz
// $commands[] = 'apt-get install -y roundcube roundcube-core roundcube-mysql roundcube-plugins';
// $commands[] = 'apt-get install -yq roundcube roundcube-core roundcube-mysql roundcube-plugins';
$shellFileContent = '';
foreach ($commands as $command) {

View file

@ -21,7 +21,8 @@ class NodeJsInstaller
public function install()
{
$commands = [];
$commands[] = 'apt-get install -y npm';
$commands[] = 'export DEBIAN_FRONTEND=noninteractive';
$commands[] = 'apt-get install -yq npm';
$commands[] = 'curl -sL https://deb.nodesource.com/setup_20.x -o /tmp/nodesource_setup.sh';
$commands[] = 'bash /tmp/nodesource_setup.sh';
$commands[] = 'apt-get install nodejs -y';
@ -30,7 +31,7 @@ class NodeJsInstaller
$commands[] = 'curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null';
$commands[] = "sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger jammy main > /etc/apt/sources.list.d/passenger.list'";
$commands[] = 'apt-get update';
$commands[] = 'sudo apt-get install -y libapache2-mod-passenger';
$commands[] = 'sudo apt-get install -yq libapache2-mod-passenger';
$commands[] = 'sudo a2enmod passenger';
$commands[] = 'sudo service apache2 restart';

View file

@ -27,7 +27,8 @@ class PHPInstaller
{
$commands = [];
$commands[] = 'echo "Starting PHP Installation..."';
$commands[] = 'apt-get install -y sudo';
$commands[] = 'export DEBIAN_FRONTEND=noninteractive';
$commands[] = 'apt-get install -yq sudo';
$commands[] = 'add-apt-repository -y ppa:ondrej/php';
$commands[] = 'add-apt-repository -y ppa:ondrej/apache2';
@ -51,7 +52,7 @@ class PHPInstaller
$dependencies = implode(' ', $dependenciesList);
$commands[] = 'apt-get install -y ' . $dependencies;
$commands[] = 'apt-get install -yq ' . $dependencies;
$lastItem = end($this->phpVersions);
foreach ($this->phpVersions as $phpVersion) {

View file

@ -21,19 +21,20 @@ class PythonInstaller
public function install()
{
$commands = [];
$commands[] = 'export DEBIAN_FRONTEND=noninteractive';
foreach ($this->pythonVersions as $pythonVersion) {
$commands[] = 'apt-get install -y python' . $pythonVersion;
$commands[] = 'apt-get install -y python' . $pythonVersion . '-dev';
$commands[] = 'apt-get install -y python' . $pythonVersion . '-venv';
$commands[] = 'apt-get install -y python' . $pythonVersion . '-setuptools';
$commands[] = 'apt-get install -y python' . $pythonVersion . '-wheel';
$commands[] = 'apt-get install -yq python' . $pythonVersion;
$commands[] = 'apt-get install -yq python' . $pythonVersion . '-dev';
$commands[] = 'apt-get install -yq python' . $pythonVersion . '-venv';
$commands[] = 'apt-get install -yq python' . $pythonVersion . '-setuptools';
$commands[] = 'apt-get install -yq python' . $pythonVersion . '-wheel';
}
// Install Apache Passenger
$commands[] = 'curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null';
$commands[] = "sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger jammy main > /etc/apt/sources.list.d/passenger.list'";
$commands[] = 'apt-get update';
$commands[] = 'sudo apt-get install -y libapache2-mod-passenger';
$commands[] = 'sudo apt-get install -yq libapache2-mod-passenger';
$commands[] = 'sudo a2enmod passenger';
$commands[] = 'sudo service apache2 restart';

View file

@ -21,17 +21,18 @@ class RubyInstaller
public function install()
{
$commands = [];
$commands[] = 'export DEBIAN_FRONTEND=noninteractive';
foreach ($this->rubyVersions as $rubyVersion) {
$commands[] = 'apt-get install -y ruby' . $rubyVersion;
$commands[] = 'apt-get install -y ruby' . $rubyVersion . '-dev';
$commands[] = 'apt-get install -y ruby' . $rubyVersion . '-bundler';
$commands[] = 'apt-get install -yq ruby' . $rubyVersion;
$commands[] = 'apt-get install -yq ruby' . $rubyVersion . '-dev';
$commands[] = 'apt-get install -yq ruby' . $rubyVersion . '-bundler';
}
// Install Apache Passenger
$commands[] = 'curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null';
$commands[] = "sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger jammy main > /etc/apt/sources.list.d/passenger.list'";
$commands[] = 'apt-get update';
$commands[] = 'sudo apt-get install -y libapache2-mod-passenger';
$commands[] = 'sudo apt-get install -yq libapache2-mod-passenger';
$commands[] = 'sudo a2enmod passenger';
$commands[] = 'sudo service apache2 restart';

View file

@ -1,23 +1,35 @@
<?php
namespace App\VirtualHosts;
namespace App\Jobs;
use App\MasterDomain;
use App\Models\Domain;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ApacheBuild
class ApacheBuild implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $fixPermissions = false;
public function fixPermissions()
/**
* Create a new job instance.
*/
public function __construct($fixPermissions = false)
{
$this->fixPermissions = true;
$this->fixPermissions = $fixPermissions;
}
public function build()
/**
* Execute the job.
*/
public function handle(): void
{
$getAllDomains = Domain::all();
$getAllDomains = Domain::whereNot('status','<=>', 'broken')->get();
$virtualHosts = [];
foreach ($getAllDomains as $domain) {
$virtualHostSettings = $domain->configureVirtualHost();
@ -29,7 +41,6 @@ class ApacheBuild
}
}
// Make master domain virtual host
if (!empty(setting('general.master_domain'))) {
// Make master domain virtual host
@ -62,10 +73,11 @@ class ApacheBuild
'virtualHosts' => $virtualHosts
])->render();
$apache2 = preg_replace('~(*ANY)\A\s*\R|\s*(?!\r\n)\s$~mu', '', $apache2);
file_put_contents('/etc/apache2/apache2.conf', $apache2);
shell_exec('systemctl reload apache2');
}
}

View file

@ -305,7 +305,7 @@ class Installer extends Page
file_put_contents(storage_path('installed'), 'installed-'.date('Y-m-d H:i:s'));
return redirect('/admin/login');
return redirect($this->getRedirectLinkAfterInstall());
}
} else {
@ -313,4 +313,9 @@ class Installer extends Page
}
}
public function getRedirectLinkAfterInstall()
{
return '/admin/login';
}
}

View file

@ -5,8 +5,8 @@ namespace App\Models;
use App\Actions\ApacheWebsiteDelete;
use App\Events\DomainIsCreated;
use App\Events\ModelDomainDeleting;
use App\Jobs\ApacheBuild;
use App\ShellApi;
use App\VirtualHosts\ApacheBuild;
use App\VirtualHosts\DTO\ApacheVirtualHostSettings;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
@ -20,6 +20,8 @@ class Domain extends Model
public const STATUS_DELETED = 'deleted';
public const STATUS_DEACTIVATED = 'deactivated';
public const STATUS_BROKEN = 'broken';
protected $fillable = [
'domain',
'domain_root',
@ -87,8 +89,7 @@ class Domain extends Model
$model->configureVirtualHost(true);
$apacheBuild = new ApacheBuild();
$apacheBuild->build();
ApacheBuild::dispatch();
});
@ -273,6 +274,17 @@ class Domain extends Model
}
$apacheVirtualHostBuilder->setDomainRoot($deactivatedPath);
$apacheVirtualHostBuilder->setDomainPublic($deactivatedPath);
} else if ($this->status == self::STATUS_BROKEN) {
$brokenPath = '/var/www/html/broken';
if (!is_dir($brokenPath)) {
mkdir($brokenPath, 0755, true);
}
if (!is_file($brokenPath . '/index.html')) {
$brokenPageHtmlPath = base_path('resources/views/actions/samples/apache/html/app-broken-page.html');
file_put_contents($brokenPath . '/index.html', file_get_contents($brokenPageHtmlPath));
}
$apacheVirtualHostBuilder->setDomainRoot($brokenPath);
$apacheVirtualHostBuilder->setDomainPublic($brokenPath);
} else {
// $apacheVirtualHostBuilder->setEnableLogs(true);

View file

@ -2,7 +2,7 @@
namespace App\Providers\Filament;
use App\Filament\Pages\Settings\Settings;
use App\Filament\Pages\Settings\GeneralSettings;
use App\Filament\Widgets\CustomersCount;
use App\Filament\Widgets\ServerDiskUsageStatistic;
use App\Filament\Widgets\ServerMemoryStatistic;
@ -72,7 +72,7 @@ class AdminPanelProvider extends PanelProvider
// FilamentAuthenticationLogPlugin::make(),
FilamentApexChartsPlugin::make(),
FilamentSettingsPlugin::make()->pages([
Settings::class,
GeneralSettings::class,
]),
])
// ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')

View file

@ -0,0 +1,186 @@
<!DOCTYPE html>
<html>
<head>
<title>Phyre Panel - Website is broken </title>
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=albert-sans:400,500,600,700&display=swap" rel="stylesheet" />
<style>
:root {
--font-family: 'Albert Sans';
--sidebar-width: 15rem;
--collapsed-sidebar-width: 4.5rem;
--default-theme-mode: system;
}
body {
font-family: var(--font-family) !important;;
}
</style>
<script src="//cdn.tailwindcss.com"></script>
</head>
<body>
<main>
<div class="flex flex-col justify-center items-center h-[calc(100vh-140px)]">
<div class="w-full text-center mt-12">
<h3 class="text-5xl text-gray-600">
Website is broken
</h3>
<p class="text-2xl text-gray-600/90 mt-4">
Please contact your administrator.
</p>
</div>
</div>
<div class="flex justify-end p-12">
<svg class="" style="width:180px;" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 808.52 192.65">
<defs>
<style>
.cls-1 {
fill: url(#linear-gradient-12);
}
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7, .cls-8, .cls-9, .cls-10, .cls-11, .cls-12, .cls-13 {
stroke-width: 0px;
}
.cls-2 {
fill: url(#linear-gradient);
}
.cls-3 {
fill: url(#linear-gradient-6);
}
.cls-4 {
fill: url(#linear-gradient-11);
}
.cls-5 {
fill: url(#linear-gradient-5);
}
.cls-6 {
fill: #f9be22;
}
.cls-7 {
fill: url(#linear-gradient-2);
}
.cls-8 {
fill: url(#linear-gradient-7);
}
.cls-9 {
fill: url(#linear-gradient-3);
}
.cls-10 {
fill: url(#linear-gradient-9);
}
.cls-11 {
fill: url(#linear-gradient-8);
}
.cls-12 {
fill: url(#linear-gradient-10);
}
.cls-13 {
fill: url(#linear-gradient-4);
}
</style>
<linearGradient id="linear-gradient" x1="5.89" y1="67.83" x2="786.82" y2="71" gradientUnits="userSpaceOnUse">
<stop offset=".25" stop-color="#f8bd20"/>
<stop offset=".41" stop-color="#f9c628"/>
<stop offset=".69" stop-color="#fbd131"/>
<stop offset="1" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="694.68" y1="13.95" x2="808.52" y2="13.95" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8bd20"/>
<stop offset=".63" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="642.49" y1="69.62" x2="785.47" y2="69.62" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8bd20" stop-opacity=".9"/>
<stop offset=".15" stop-color="rgba(249, 197, 39, .94)" stop-opacity=".94"/>
<stop offset=".37" stop-color="rgba(250, 206, 47, .97)" stop-opacity=".97"/>
<stop offset=".63" stop-color="rgba(251, 211, 51, .99)" stop-opacity=".99"/>
<stop offset="1" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-4" x1="647.99" y1="69.56" x2="785.96" y2="69.56" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8bd20"/>
<stop offset=".63" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-5" x1="161.7" y1="69.56" x2="212.2" y2="69.56" gradientUnits="userSpaceOnUse">
<stop offset=".45" stop-color="#f8bd20"/>
<stop offset=".54" stop-color="#f9c326"/>
<stop offset=".78" stop-color="#fbd031"/>
<stop offset="1" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-6" x1="-14.8" y1="68.54" x2="812.93" y2="71.9" gradientUnits="userSpaceOnUse">
<stop offset=".23" stop-color="#f8bd20"/>
<stop offset=".23" stop-color="#f8bd20"/>
<stop offset=".4" stop-color="#faca2c"/>
<stop offset=".6" stop-color="#fbd232"/>
<stop offset="1" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-7" x1="19.43" y1="68.42" x2="756.99" y2="71.42" xlink:href="#linear-gradient-6"/>
<linearGradient id="linear-gradient-8" x1="-12.06" y1="69.99" x2="808.02" y2="73.32" xlink:href="#linear-gradient-6"/>
<linearGradient id="linear-gradient-9" x1="0" y1="69.56" x2="54.12" y2="69.56" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8bd20"/>
<stop offset=".21" stop-color="#f9c628"/>
<stop offset=".58" stop-color="#fbd131"/>
<stop offset="1" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-10" x1="-24.07" y1="41.56" x2="837.97" y2="45.06" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8bd20"/>
<stop offset=".07" stop-color="#f9c628"/>
<stop offset=".2" stop-color="#fbd131"/>
<stop offset=".34" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-11" x1="485.03" y1="69.56" x2="538.44" y2="69.56" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f8bd20"/>
<stop offset=".21" stop-color="#f9c628"/>
<stop offset=".58" stop-color="#fbd131"/>
<stop offset="1" stop-color="#fcd535"/>
</linearGradient>
<linearGradient id="linear-gradient-12" x1="521.21" y1="69.56" x2="642.79" y2="69.56" xlink:href="#linear-gradient-11"/>
</defs>
<g>
<path class="cls-6" d="M383.66,189.79l.87-4.15c.31-1.47-.81-2.86-2.32-2.86h-10.04c-1.12,0-2.08.78-2.32,1.87l-1.31,6.12c-.23,1.09-1.2,1.87-2.32,1.87h0c-1.51,0-2.63-1.39-2.32-2.86l4.22-19.87c.23-1.09,1.2-1.88,2.32-1.88h0c1.51,0,2.63,1.39,2.32,2.86l-.88,4.17c-.31,1.47.81,2.86,2.32,2.86h10.04c1.12,0,2.08-.78,2.32-1.87l1.32-6.14c.23-1.09,1.2-1.87,2.32-1.87h0c1.51,0,2.63,1.39,2.32,2.86l-4.22,19.87c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86Z"/>
<path class="cls-6" d="M416.74,192.65h-11c-1.72,0-3.35-.79-4.41-2.14h0c-1.03-1.31-1.42-3-1.08-4.62l2.37-11.23c.33-1.56,1.18-2.96,2.41-3.97l.86-.7c1.53-1.25,3.45-1.94,5.43-1.94h10.39c1.72,0,3.35.79,4.41,2.14h0c1.03,1.31,1.42,3,1.08,4.62l-2.37,11.19c-.34,1.59-1.2,3.01-2.45,4.04l-1.27,1.04c-1.23,1.01-2.78,1.57-4.38,1.57ZM419.35,172.9h-8.48c-1.77,0-3.3,1.24-3.66,2.97l-1.7,7.97c-.43,2.03,1.12,3.95,3.2,3.95h7.89c1.76,0,3.28-1.23,3.64-2.95l1.83-8.58c.37-1.73-.95-3.35-2.72-3.35Z"/>
<path class="cls-6" d="M450.21,192.65h-13.09c-1.44,0-2.52-1.33-2.22-2.74l.07-.32c.22-1.05,1.15-1.8,2.22-1.8h14.24c1.27,0,2.51-.44,3.49-1.25h0c.35-.29.59-.68.69-1.12h0c.14-.6,0-1.22-.38-1.71l-.04-.05c-.43-.55-1.09-.88-1.79-.88h-10.13c-1.67,0-2.95-.63-3.99-1.94h0c-1.07-1.36-1.12-3.12-1.09-4.97l.07-1.88c0-.68.15-1.66.56-2.43.48-.92.95-1.56,2.87-2.8h0c1.32-.83,3.78-.72,6.91-.72h12.75c1.44,0,2.52,1.33,2.22,2.74l-.07.32c-.22,1.05-1.15,1.8-2.22,1.8h-14.3c-1.25,0-2.46.43-3.43,1.22h0c-.36.3-.61.7-.7,1.16h0c-.12.59.02,1.2.39,1.67h0c.48.61,1.21.97,1.99.97h10.37c1.41,0,2.74.64,3.61,1.75h0c1.23,1.56,1.71,3.59,1.29,5.53l-.25,1.19c-.28,1.33-1.01,2.52-2.05,3.38h0c-2.26,1.86-5.09,2.87-8.01,2.87Z"/>
<path class="cls-6" d="M488.37,174.78l-3.4,16c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86l2.98-14.03c.31-1.47-.81-2.86-2.32-2.86h-4.04c-1.51,0-2.63-1.39-2.32-2.86l.03-.12c.23-1.1,1.2-1.88,2.32-1.88h19.77c1.51,0,2.63,1.39,2.32,2.86l-.03.12c-.23,1.1-1.2,1.88-2.32,1.88h-6.04c-1.12,0-2.08.78-2.32,1.88Z"/>
<path class="cls-6" d="M505.5,189.68l4.2-19.69c.24-1.14,1.25-1.95,2.41-1.95h0c1.57,0,2.73,1.44,2.41,2.97l-4.2,19.69c-.24,1.14-1.25,1.95-2.41,1.95h0c-1.57,0-2.73-1.44-2.41-2.97Z"/>
<path class="cls-6" d="M539.69,191.61l-9.6-14.15c-.48-.7-1.56-.49-1.74.34l-2.76,12.97c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86l4.13-19.43c.29-1.35,1.48-2.31,2.86-2.31h.53c1.06,0,2.06.53,2.65,1.41l9.51,14.05c.41.6,1.34.42,1.49-.29l2.83-13.29c.23-1.09,1.2-1.88,2.32-1.88h0c1.51,0,2.63,1.39,2.32,2.86l-4.22,19.87c-.23,1.09-1.2,1.88-2.32,1.88h-1.4c-.79,0-1.52-.39-1.96-1.04Z"/>
<path class="cls-6" d="M573.43,192.64l-10.43.02c-1.83,0-3.56-.83-4.7-2.27l-.04-.05c-.95-1.2-1.31-2.74-.99-4.22l2.41-11.39c.34-1.6,1.21-3.04,2.48-4.08l1.22-1c1.26-1.04,2.85-1.6,4.48-1.6h10.94c1.72,0,3.34.79,4.4,2.14h0c1.02,1.3,1.42,2.99,1.08,4.62-.05.26-.11.51-.16.74-.16.75-.82,1.29-1.6,1.29h-1.49c-1.03,0-1.8-.96-1.59-1.97h0c.21-1.01-.55-1.96-1.59-1.96-3.11,0-9,0-11.62,0-.77,0-1.43.54-1.59,1.29l-2.46,11.65c-.21,1.01.56,1.97,1.6,1.97h11.59c.77,0,1.44-.54,1.6-1.29l.37-1.76c.21-1.01-.56-1.97-1.6-1.97h-5.86c-1.04,0-1.81-.96-1.59-1.97l.34-1.6c.16-.75.83-1.29,1.59-1.29h6.15c1.9,0,3.7.87,4.88,2.36l.15.19c.84,1.05,1.16,2.43.88,3.74l-.55,2.61c-.22,1.05-.8,1.99-1.63,2.67l-1.62,1.33c-1.42,1.17-3.21,1.81-5.05,1.81Z"/>
<path class="cls-6" d="M629.48,182.79h-10.75c-1.12,0-2.08.78-2.32,1.87l-1.31,6.12c-.23,1.09-1.2,1.87-2.32,1.87h0c-1.51,0-2.63-1.39-2.32-2.86l4.22-19.87c.23-1.09,1.2-1.88,2.32-1.88h15.74c1.73,0,3.37.8,4.44,2.16h0c1.02,1.3,1.41,2.98,1.07,4.59l-.43,2.02c-.24,1.13-.85,2.15-1.75,2.89l-1.51,1.25c-1.43,1.19-3.23,1.83-5.09,1.83ZM631.75,172.9h-11.58c-.73,0-1.35.51-1.51,1.22l-.4,1.88c-.21.99.55,1.92,1.56,1.92h11.52c.82,0,1.54-.58,1.71-1.38l.34-1.6c.23-1.05-.57-2.04-1.65-2.04Z"/>
<path class="cls-6" d="M665.75,189.79l.89-4.18c.31-1.47-.81-2.86-2.32-2.86h-10.07c-1.12,0-2.08.78-2.32,1.87l-1.32,6.15c-.23,1.1-1.21,1.88-2.33,1.87h-.02c-1.5,0-2.62-1.39-2.31-2.86l3.11-14.63c.4-1.88,1.43-3.57,2.92-4.79l.53-.43c1.5-1.22,3.37-1.89,5.3-1.89h10.74c1.55,0,3.01.71,3.97,1.93h0c1.13,1.45,1.57,3.32,1.19,5.11l-3.33,15.69c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86ZM667.11,172.9h-11.14c-.9,0-1.67.63-1.86,1.5l-.32,1.52c-.22,1.03.57,2,1.62,2h11.64c.71,0,1.33-.5,1.48-1.19l.35-1.64c.24-1.13-.61-2.19-1.77-2.19Z"/>
<path class="cls-6" d="M700.08,191.39l-9.28-13.69c-.54-.79-1.76-.55-1.96.38l-2.7,12.69c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86l4.16-19.56c.27-1.28,1.4-2.19,2.71-2.19h.51c1.15,0,2.23.57,2.88,1.53l9.3,13.74c.45.67,1.49.47,1.66-.32l2.78-13.07c.23-1.09,1.2-1.88,2.32-1.88h0c1.51,0,2.63,1.39,2.32,2.86l-4.12,19.37c-.29,1.39-1.52,2.38-2.94,2.38h-.62c-.95,0-1.84-.47-2.37-1.26Z"/>
<path class="cls-6" d="M717.03,189.71l4.2-19.75c.24-1.12,1.23-1.92,2.38-1.92h19.64c1.54,0,2.7,1.42,2.38,2.93h0c-.24,1.12-1.23,1.93-2.38,1.93h-15.81c-1.15,0-2.14.8-2.38,1.92l-.03.16c-.32,1.51.83,2.94,2.38,2.94h9.8c1.54,0,2.7,1.42,2.38,2.93h0c-.24,1.12-1.23,1.93-2.38,1.93h-11.87c-1.14,0-2.13.8-2.37,1.92l-.03.14c-.33,1.51.83,2.95,2.37,2.95h13.75c1.54,0,2.7,1.42,2.38,2.93h0c-.24,1.12-1.23,1.93-2.38,1.93h-19.64c-1.55,0-2.7-1.42-2.38-2.94Z"/>
<path class="cls-6" d="M752.53,189.67l4.22-19.85c.23-1.1,1.2-1.88,2.33-1.88h0c1.51,0,2.64,1.39,2.33,2.87l-2.99,14c-.32,1.48.81,2.87,2.33,2.87h13.78c1.57,0,2.74,1.44,2.41,2.97h0c-.09.41-.14.86-.42,1.18-.76.87-1.78.71-3.38.71h-12.75c-2.1,0-2.93.07-5.76.01-1.58-.03-2.19-.74-2.09-2.89Z"/>
</g>
<path class="cls-2" d="M428.17,83.3h-2.67c-6.07,0-11.32,4.24-12.59,10.18l-7.54,35.19c-1.27,5.94-6.52,10.18-12.59,10.18h-.87c-8.18,0-14.28-7.52-12.6-15.52l4.96-23.63c1.77-8.45-4.67-16.4-13.31-16.4h0c-9.55,0-18.57-4.38-24.47-11.89l-.06-.08c-5.89-7.49-8.16-17.22-6.17-26.54l7.29-34.33c1.26-5.95,6.52-10.2,12.6-10.2h.87c8.18,0,14.28,7.52,12.6,15.52l-5.17,24.62c-.77,3.69.11,7.53,2.41,10.51h0c2.44,3.16,6.21,5.01,10.2,5.01h50.24c5.4,0,10.62-1.9,14.76-5.38h0c3.4-2.85,5.74-6.76,6.66-11.1l6.16-28.99c1.26-5.95,6.52-10.2,12.6-10.2h.95c8.19,0,14.3,7.54,12.6,15.55l-5.43,25.56c-2.5,11.74-8.89,22.3-18.14,29.95h0c-9.36,7.74-21.12,11.98-33.26,11.98Z"/>
<path class="cls-7" d="M808.22,16.77h0c1.79-8.51-4.7-16.51-13.39-16.51h-94.61s-5.53,27.37-5.53,27.37h100.15c6.47,0,12.06-4.53,13.39-10.86Z"/>
<path class="cls-9" d="M774.88,72.44h0c1.79-8.51-4.7-16.51-13.39-16.51h-72.87l-5.77,27.37h78.64c6.47,0,12.06-4.53,13.39-10.86Z"/>
<path class="cls-13" d="M677.87,111.48l6.11-28.18h0l6.01-28.49h.05s5.78-27.18,5.78-27.18l5.79-27.03c.04-.18-.1-.34-.27-.34h-5.32c-12.69,0-23.65,8.88-26.29,21.29l-21.42,100.78c-1.81,8.51,4.68,16.53,13.39,16.53h110.59c6.47,0,12.06-4.53,13.39-10.86h0c1.79-8.51-4.7-16.51-13.39-16.51h-94.4Z"/>
<path class="cls-5" d="M203.58,55.93l8.32-39.57c1.75-8.3-4.59-16.1-13.06-16.1h0c-6.3,0-11.75,4.41-13.06,10.58l-23.78,111.89c-1.77,8.31,4.57,16.13,13.06,16.13h0c6.29,0,11.73-4.4,13.05-10.55l9.66-45.01h0l5.82-27.37h0Z"/>
<polygon class="cls-3" points="203.58 55.87 197.77 83.24 282.37 83.3 288.17 55.93 203.58 55.87"/>
<path class="cls-8" d="M311.44.26c-6.29,0-11.73,4.4-13.05,10.55l-9.59,44.73h0l-6.55,30.92h-.03s-7.64,36.29-7.64,36.29c-1.75,8.3,4.58,16.1,13.06,16.1h.01c6.3,0,11.75-4.41,13.06-10.57l23.78-111.9c1.77-8.3-4.57-16.12-13.06-16.12h0Z"/>
<polygon class="cls-11" points="288.73 55.94 288.7 55.93 288.7 55.93 288.17 55.93 282.37 83.3 282.88 83.3 282.22 86.46 282.25 86.47 288.73 55.94"/>
<path class="cls-10" d="M21.82,21.46L.3,122.73c-1.77,8.31,4.57,16.13,13.06,16.13h0c6.29,0,11.73-4.4,13.05-10.55l9.66-45.01-.02.12,5.84-27.49,6.01-28.3h0L54.12.26h-6.12c-12.64,0-23.55,8.84-26.18,21.2Z"/>
<path class="cls-12" d="M111.53,0l-57.79.26-5.95,27.37h66.44c9.04,0,15.77,8.34,13.87,17.18h0c-1.4,6.5-7.12,11.16-13.77,11.2l-72.69.53-5.73,27.37,69.83-.49c11.47-.08,24.22-2.55,33.06-9.86h0c6.97-5.77,14.29-13.29,16.46-31.62h0c-.56-20.89-7.73-28.5-7.73-28.5h0S140.06,1,111.53,0Z"/>
<path class="cls-4" d="M506.81,21.58l-21.48,101.08c-1.77,8.34,4.59,16.2,13.12,16.2h0c6.32,0,11.78-4.41,13.11-10.59l9.65-44.96h.02l5.71-27.37h0l5.96-28.17,5.55-27.42s-.02-.08-.07-.08h-5.23c-12.71,0-23.69,8.89-26.33,21.32Z"/>
<path class="cls-1" d="M636.82,13.71l-2.27-2.89c-5.24-6.67-13.25-10.57-21.73-10.57h-74.36l-5.55,27.37h78.11c3.05,0,5.35,2.78,4.77,5.78h0c-.21,1.11-.81,2.11-1.68,2.82l-16.44,13.56c-4.81,3.96-10.84,6.13-17.07,6.13h-53.68l-5.72,27.37h51.65c7.31,0,14.23,3.35,18.76,9.09l1.28,1.62c4.97,6.29,6.86,14.46,5.18,22.29l-1.48,6.87c-1.74,8.07,4.41,15.68,12.66,15.68h0c6.55,0,12.2-4.58,13.56-10.99l5.11-24.08c1.74-8.21-.24-16.77-5.42-23.38l-5.33-6.81c-1.76-2.25-1.41-5.48.79-7.3l14.59-12.04c4.67-3.85,7.88-9.18,9.12-15.1l.52-2.49c1.68-8.07-.28-16.47-5.38-22.95Z"/>
</svg>
</div>
</main>
</body>
</html>

View file

@ -0,0 +1,63 @@
<x-filament-panels::page>
<div class="grid grid-cols-2 gap-x-8">
<div>
@if (!empty($installedPHPVersions))
<div>
Installed PHP Versions on server are:
</div>
<div class="flex flex-col gap-y-4 mt-4">
@foreach($installedPHPVersions as $phpVersion)
<x-filament::section>
<div x-data="{showModules:false}">
<div class="flex gap-4">
<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" class="w-12 text-primary-500" viewBox="0 0 24 24">
<path fill="currentColor" d="M12 5.601h-.116c-1.61 0-3.18.175-4.69.507l.144-.027a16.125 16.125 0 0 0-3.91 1.343l.094-.042a8.123 8.123 0 0 0-2.57 1.93l-.007.008A3.6 3.6 0 0 0 0 11.684v.004c.019.914.374 1.741.946 2.367l-.002-.003a8.105 8.105 0 0 0 2.529 1.917l.048.021a15.7 15.7 0 0 0 3.71 1.282l.106.019c1.366.305 2.936.48 4.546.48h.123H12h.116c1.61 0 3.18-.175 4.69-.507l-.144.027a16.125 16.125 0 0 0 3.91-1.343l-.094.042a8.123 8.123 0 0 0 2.57-1.93l.007-.008A3.6 3.6 0 0 0 24 11.688v-.004a3.608 3.608 0 0 0-.947-2.371l.002.003a8.105 8.105 0 0 0-2.529-1.917l-.048-.021a15.7 15.7 0 0 0-3.71-1.282l-.106-.019a21.212 21.212 0 0 0-4.546-.48h-.123h.006zm-3.12 7.264c-.131.119-.28.221-.442.301l-.011.005a2.916 2.916 0 0 1-.482.179l-.021.005a1.723 1.723 0 0 1-.579.099h-.024h.001H5.35l-.32 1.963H3.583l1.28-6.675h2.773l.062-.001c.36 0 .706.063 1.026.179l-.021-.007c.295.108.546.276.748.489l.001.001c.175.223.3.493.354.789l.002.011a2.932 2.932 0 0 1-.015 1.059l.003-.019a2.82 2.82 0 0 1-.142.485l.007-.019q-.086.221-.184.417q-.122.196-.27.393a2.164 2.164 0 0 1-.317.343l-.003.002zm4.172.589l.565-2.822c.024-.107.038-.229.038-.355l-.002-.078v.004a.426.426 0 0 0-.111-.283a.671.671 0 0 0-.241-.134l-.005-.001a1.388 1.388 0 0 0-.418-.062l-.051.001h.002h-1.126l-.736 3.73H9.544l1.28-6.48h1.423l-.343 1.767h1.28l.073-.001c.331 0 .653.041.961.117l-.027-.006c.249.055.466.172.641.332l-.001-.001a.84.84 0 0 1 .306.498l.001.005a1.945 1.945 0 0 1-.04.787l.003-.014l-.589 2.994zm7.902-2.184c-.04.181-.082.328-.132.473l.009-.031c-.054.159-.12.297-.201.425l.005-.008a1.812 1.812 0 0 1-.248.408l.003-.004c-.098.122-.203.23-.317.329l-.003.003c-.131.119-.28.221-.442.301l-.011.005a2.916 2.916 0 0 1-.482.179l-.021.005a1.723 1.723 0 0 1-.579.099h-.024h.001h-1.972l-.343 1.959h-1.423l1.28-6.675h2.749l.073-.001c.365 0 .716.063 1.041.18l-.022-.007c.287.104.529.272.718.488l.002.002c.19.222.325.497.378.799l.002.01a2.763 2.763 0 0 1-.04 1.076l.004-.019zm-2.7-1.547h-.978l-.513 2.749h.908c.25 0 .496-.023.734-.066l-.025.004c.204-.036.386-.109.546-.212l-.006.003c.136-.122.25-.263.339-.421l.004-.008c.103-.188.18-.407.219-.638l.002-.012a1.877 1.877 0 0 0 .036-.649l.001.009a.812.812 0 0 0-.161-.419l.001.002a1.116 1.116 0 0 0-.409-.243l-.008-.002a1.982 1.982 0 0 0-.689-.096h.003zm-11.19 0h-.978l-.515 2.749h.91c.25 0 .496-.023.734-.066l-.025.004c.204-.036.386-.109.546-.212l-.006.003c.136-.122.25-.263.339-.421l.004-.008c.103-.188.18-.407.219-.638l.002-.012a1.877 1.877 0 0 0 .036-.649l.001.009a.812.812 0 0 0-.161-.419l.001.002a1.116 1.116 0 0 0-.409-.243l-.008-.002a1.982 1.982 0 0 0-.689-.096h.003z" />
</svg>
</div>
<div>
<div class="flex items-center gap-2">
PHP {{ $phpVersion['version'] }}
</div>
<div class="text-sm">
<a href="#" x-on:click="showModules = ! showModules">
<span x-show="showModules">Hide modules</span>
<span x-show="!showModules">Show modules</span>
</a>
</div>
</div>
</div>
<div x-show="showModules" class="text-sm">
@foreach($phpVersion['modules'] as $phpModule)
{{ $phpModule }}{{ !$loop->last ? ', ' : '' }}
@endforeach
</div>
</div>
</x-filament::section>
@endforeach
</div>
@else
No PHP versions found.
@endif
</div>
<div class="">
<x-filament::section>
<div class="text-center">
<div>
<svg xmlns="http://www.w3.org/2000/svg" class="text-primary-500 w-[4rem] m-auto" viewBox="0 0 512 512">
<path fill="currentColor" d="M170.322 349.808c-2.4-15.66-9-28.38-25.02-34.531c-6.27-2.4-11.7-6.78-17.88-9.54c-7.02-3.15-14.16-6.15-21.57-8.1c-5.61-1.5-10.83 1.02-14.16 5.94c-3.15 4.62-.87 8.97 1.77 12.84c2.97 4.35 6.27 8.49 9.6 12.57c5.52 6.78 11.37 13.29 16.74 20.161c5.13 6.57 9.51 13.86 8.76 22.56c-1.65 19.08-10.29 34.891-24.21 47.76c-1.53 1.38-4.23 2.37-6.21 2.19c-8.88-.96-16.95-4.32-23.46-10.53c-7.47-7.11-6.33-15.48 2.61-20.67c2.13-1.23 4.35-2.37 6.3-3.87c5.46-4.11 7.29-11.13 4.32-17.22c-1.41-2.94-3-6.12-5.34-8.25c-11.43-10.41-22.651-21.151-34.891-30.63C18.01 307.447 2.771 276.968.43 240.067c-2.64-40.981 6.87-79.231 28.5-114.242c8.19-13.29 17.73-25.951 32.37-32.52c9.96-4.47 20.88-6.99 31.531-9.78c29.311-7.71 58.89-13.5 89.401-8.34c26.28 4.41 45.511 17.94 54.331 43.77c5.79 16.89 7.17 34.35 5.37 52.231c-3.54 35.131-29.49 66.541-63.331 75.841c-14.67 4.02-22.68 1.77-31.5-10.44c-6.33-8.79-11.58-18.36-17.25-27.631c-.84-1.38-1.44-2.97-2.16-4.44c-.69-1.47-1.44-2.88-2.16-4.35c2.13 15.24 5.67 29.911 13.98 42.99c4.5 7.11 10.5 12.36 19.29 13.14c32.34 2.91 59.641-7.71 79.021-33.721c21.69-29.101 26.461-62.581 20.19-97.831c-1.23-6.96-3.3-13.77-4.77-20.7c-.99-4.47.78-7.77 5.19-9.33c2.04-.69 4.14-1.26 6.18-1.68c26.461-5.7 53.221-7.59 80.191-4.86c30.601 3.06 59.551 11.46 85.441 28.471c40.531 26.67 65.641 64.621 79.291 110.522c1.98 6.66 2.28 13.95 2.46 20.971c.12 4.68-2.88 5.91-6.45 2.97c-3.93-3.21-7.53-6.87-10.92-10.65c-3.15-3.57-5.67-7.65-8.73-11.4c-2.37-2.94-4.44-2.49-5.58 1.17c-.72 2.22-1.35 4.41-1.98 6.63c-7.08 25.26-18.24 48.3-36.33 67.711c-2.52 2.73-4.77 6.78-5.07 10.38c-.78 9.96-1.35 20.13-.39 30.06c1.98 21.331 5.07 42.57 7.47 63.871c1.35 12.03-2.52 19.11-13.83 23.281c-7.95 2.91-16.47 5.04-24.87 5.64c-13.38.93-26.88.27-40.32.27c-.36-15 .93-29.731-13.17-37.771c2.73-11.13 5.88-21.69 7.77-32.49c1.56-8.97.24-17.79-6.06-25.14c-5.91-6.93-13.32-8.82-20.101-4.86c-20.43 11.91-41.671 11.97-63.301 4.17c-9.93-3.6-16.86-1.56-22.351 7.5c-5.91 9.75-8.4 20.7-7.74 31.771c.84 13.95 3.27 27.75 5.13 41.64c1.02 7.77.15 9.78-7.56 11.76c-17.13 4.35-34.56 4.83-52.081 3.42c-.93-.09-1.86-.48-2.46-.63c-.87-14.55.66-29.671-16.68-37.411c7.68-16.29 6.63-33.18 3.99-50.07l-.06-.15zm-103.561-57.09c2.55-2.4 4.59-6.15 5.31-9.6c1.8-8.64-4.68-20.22-12.18-23.43c-3.99-1.74-7.47-1.11-10.29 2.07c-6.87 7.77-13.65 15.63-20.401 23.521c-1.14 1.35-2.16 2.94-2.97 4.53c-2.7 5.19-1.11 8.97 4.65 10.38c3.48.87 7.08 1.05 10.65 1.56c9.3-.9 18.3-2.46 25.23-9zm.78-86.371c-.03-6.18-5.19-11.34-11.28-11.37c-6.27-.03-11.67 5.58-11.46 11.76c.27 6.21 5.43 11.19 11.61 11.07c6.24-.09 11.22-5.19 11.16-11.43z" />
</svg>
</div>
Do you want to install another php version ?
<x-filament::link :href="route('filament.admin.pages.php-installer')">
Click here to install
</x-filament::link>
</div>
</x-filament::section>
</div>
</div>
</x-filament-panels::page>

View file

@ -0,0 +1,7 @@
<x-filament-panels::page>
<div>
{{$this->form}}
</div>
</x-filament-panels::page>

View file

@ -0,0 +1,29 @@
<x-filament-panels::page>
<div class="grid grid-cols-3 gap-4 gap-y-8 p-8 rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:divide-white/10 dark:bg-gray-900 dark:ring-white/10">
@foreach($linkGroups as $group)
<div>
<div class="flex gap-2 items-center">
<x-filament::icon-button size="xl" icon="{{$group['icon']}}" />
<div class="text-primary-500 text-lg">
{{ $group['title'] }}
</div>
</div>
<div class="pl-[2.1rem] mt-2">
<ul class="flex flex-col gap-y-1">
@foreach($group['links'] as $link)
<li>
<a class="cursor-pointer text-sm font-medium hover:text-primary-500 transition" href="{{$link['url']}}">
{{$link['title']}}
</a>
</li>
@endforeach
</ul>
</div>
</div>
@endforeach
</div>
</x-filament-panels::page>

View file

@ -1,13 +1,13 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Installers\Server\Applications\PHPInstaller;
use App\SupportedApplicationTypes;
use Illuminate\Support\Str;
use Tests\TestCase;
class AutoInstallPanelTest extends TestCase
class AutoInstallTest extends TestCase
{
public function testInstall()
{

View file

@ -1,6 +1,6 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Filament\Pages\Modules;
use App\Models\Module;

View file

@ -1,6 +1,6 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Filament\Enums\BackupStatus;
use App\Helpers;
@ -21,14 +21,15 @@ use Illuminate\Support\Str;
use Tests\Feature\Api\ActionTestCase;
use Illuminate\Support\Facades\Queue;
class HostingSubscriptionBackupTest extends ActionTestCase
class HSBackupTest extends ActionTestCase
{
public function testFullBackup()
{
ini_set('memory_limit', '-1');
ini_set('max_execution_time', 0);
Queue::fake();
// Queue::fake();
$chs = $this->_createHostingSubscription();
@ -37,6 +38,7 @@ class HostingSubscriptionBackupTest extends ActionTestCase
$newBackup->hosting_subscription_id = $chs['hostingSubscriptionId'];
$newBackup->save();
$phsb = new ProcessHostingSubscriptionBackup($newBackup->id);
$phsb->handle();

View file

@ -1,9 +1,10 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Http\Middleware\ApiKeyMiddleware;
use App\Installers\Server\Applications\PHPInstaller;
use App\Jobs\ApacheBuild;
use App\Models\Database;
use App\Models\DatabaseUser;
use App\Models\Domain;
@ -13,9 +14,9 @@ use Illuminate\Support\Str;
use PHPUnit\Framework\TestCase;
use Tests\Feature\Api\ActionTestCase;
class HostingSubscriptionCreateTest extends ActionTestCase
class HSCreateTest extends ActionTestCase
{
function test_route_contains_middleware()
function testRouteContainsMiddleware()
{
$this->assertRouteContainsMiddleware(
'api.hosting-subscriptions.index',
@ -32,10 +33,10 @@ class HostingSubscriptionCreateTest extends ActionTestCase
ApiKeyMiddleware::class
);
$this->assertRouteContainsMiddleware(
'api.hosting-subscriptions.destroy',
ApiKeyMiddleware::class
);
// $this->assertRouteContainsMiddleware(
// 'api.hosting-subscriptions.destroy',
// ApiKeyMiddleware::class
// );
}
@ -96,6 +97,9 @@ class HostingSubscriptionCreateTest extends ActionTestCase
]
)->json();
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
$this->assertArrayHasKey('status', $callHostingSubscriptionStoreResponse);
$this->assertTrue($callHostingSubscriptionStoreResponse['status'] == 'ok');

View file

@ -1,11 +1,12 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Http\Middleware\ApiKeyMiddleware;
use App\Installers\Server\Applications\NodeJsInstaller;
use App\Installers\Server\Applications\PHPInstaller;
use App\Installers\Server\Applications\PythonInstaller;
use App\Jobs\ApacheBuild;
use App\Models\Database;
use App\Models\DatabaseUser;
use App\Models\Domain;
@ -16,9 +17,9 @@ use Illuminate\Support\Str;
use PHPUnit\Framework\TestCase;
use Tests\Feature\Api\ActionTestCase;
class HostingSubscriptionWithNodeJSCreateTest extends ActionTestCase
class HSNodeJSTest extends ActionTestCase
{
function test_route_contains_middleware()
function testRouteContainsMiddleware()
{
$this->assertRouteContainsMiddleware(
'api.hosting-subscriptions.index',
@ -42,10 +43,10 @@ class HostingSubscriptionWithNodeJSCreateTest extends ActionTestCase
}
function test_create()
function testCreate()
{
$this->assertTrue(Str::contains(php_uname(),'Ubuntu'));
//
$isNodeJsInstalled = false;
@ -140,6 +141,9 @@ class HostingSubscriptionWithNodeJSCreateTest extends ActionTestCase
]
)->json();
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
$this->assertArrayHasKey('status', $callHostingSubscriptionStoreResponse);
$this->assertTrue($callHostingSubscriptionStoreResponse['status'] == 'ok');

View file

@ -1,6 +1,6 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Http\Middleware\ApiKeyMiddleware;
use App\Installers\Server\Applications\PHPInstaller;
@ -17,7 +17,7 @@ use Tests\Feature\Api\ActionTestCase;
class HostingSubscriptionWithPythonCreateTest extends ActionTestCase
{
function test_route_contains_middleware()
function testRouteContainsMiddleware()
{
$this->assertRouteContainsMiddleware(
'api.hosting-subscriptions.index',
@ -130,6 +130,9 @@ class HostingSubscriptionWithPythonCreateTest extends ActionTestCase
]
)->json();
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
$this->assertArrayHasKey('status', $callHostingSubscriptionStoreResponse);
$this->assertTrue($callHostingSubscriptionStoreResponse['status'] == 'ok');

View file

@ -1,15 +1,15 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Http\Middleware\ApiKeyMiddleware;
use PHPUnit\Framework\TestCase;
use Tests\Feature\Api\ActionTestCase;
class HostingSubscriptionsTest extends ActionTestCase
class HSTest extends ActionTestCase
{
function test_route_contains_middleware()
function testRouteContainsMiddleware()
{
$this->assertRouteContainsMiddleware(
'api.hosting-subscriptions.index',
@ -23,13 +23,13 @@ class HostingSubscriptionsTest extends ActionTestCase
'api.hosting-subscriptions.update',
ApiKeyMiddleware::class
);
$this->assertRouteContainsMiddleware(
'api.hosting-subscriptions.destroy',
ApiKeyMiddleware::class
);
// $this->assertRouteContainsMiddleware(
// 'api.hosting-subscriptions.destroy',
// ApiKeyMiddleware::class
// );
}
function test_index()
function testIndex()
{
// Make unauthorized call
$callUnauthorizedResponse = $this->callRouteAction('api.hosting-subscriptions.index')->json();

View file

@ -1,7 +1,8 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Jobs\ApacheBuild;
use App\Models\HostingPlan;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Str;
@ -9,7 +10,7 @@ use Modules\Microweber\Filament\Clusters\Microweber\Pages\Version;
use Modules\Microweber\Jobs\DownloadMicroweber;
use Tests\Feature\Api\ActionTestCase;
class MicroweberHostingSubscriptionCreateTest extends ActionTestCase
class MWHSCreateTest extends ActionTestCase
{
function testCreateInstallation()
{
@ -29,9 +30,15 @@ class MicroweberHostingSubscriptionCreateTest extends ActionTestCase
'disk_space' => 1000,
'bandwidth' => 1000,
'default_server_application_type' => 'apache_php',
'default_database_server_type' => 'mysql',
'default_server_application_settings' => [
'php_version' => '8.2',
],
'additional_services' => ['microweber'],
'default_database_server_type' => 'internal',
])->json();
$this->assertArrayHasKey('status', $callHostingPlanStoreResponse);
$this->assertTrue($callHostingPlanStoreResponse['status'] == 'ok');
$hostingPlanId = $callHostingPlanStoreResponse['data']['hostingPlan']['id'];
@ -66,6 +73,8 @@ class MicroweberHostingSubscriptionCreateTest extends ActionTestCase
$this->assertIsInt($callCustomerStoreResponse['data']['customer']['id']);
$customerId = $callCustomerStoreResponse['data']['customer']['id'];
// TODO
return;
$hostingSubscriptionDomain = 'phyre-unit-test-microweber-'.rand(1000, 9999).'.com';
$callHostingSubscriptionStoreResponse = $this->callApiAuthorizedRouteAction('api.hosting-subscriptions.store',[
@ -74,6 +83,13 @@ class MicroweberHostingSubscriptionCreateTest extends ActionTestCase
'domain' => $hostingSubscriptionDomain,
])->json();
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
if (!isset($callHostingSubscriptionStoreResponse['status'])) {
$this->fail(json_encode($callHostingSubscriptionStoreResponse));
}
$this->assertArrayHasKey('status', $callHostingSubscriptionStoreResponse);
$this->assertTrue($callHostingSubscriptionStoreResponse['status'] == 'ok');
$this->assertArrayHasKey('data', $callHostingSubscriptionStoreResponse);

View file

@ -1,7 +1,8 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Jobs\ApacheBuild;
use Faker\Factory;
use Tests\Feature\Api\ActionTestCase;
@ -110,6 +111,10 @@ class SecurityTest extends ActionTestCase
'domain' => 'phyre-unit-test-'.$randId.'.com',
]
)->json();
$apacheBuild = new ApacheBuild();
$apacheBuild->handle();
$this->assertArrayHasKey('status', $callHostingSubscriptionStoreResponse);
$this->assertTrue($callHostingSubscriptionStoreResponse['status'] == 'ok');
$secondHostingSubscription = $callHostingSubscriptionStoreResponse['data']['hostingSubscription'];

View file

@ -1,6 +1,6 @@
<?php
namespace tests\Unit;
namespace Tests\Unit;
use App\Filament\Enums\BackupStatus;
use App\Helpers;