admin theme pack

This commit is contained in:
2024-12-23 14:14:59 +03:00
parent 093b04c2c9
commit de690dfd39
111 changed files with 187 additions and 55 deletions
View File
+1
View File
@@ -3,6 +3,7 @@
"version": "0.1", "version": "0.1",
"author": "Kavalar", "author": "Kavalar",
"slug": "custom", "slug": "custom",
"type": "admin_theme",
"description": "Custom admin theme", "description": "Custom admin theme",
"preview": "nrnv2024_640x360.jpg", "preview": "nrnv2024_640x360.jpg",
"resource": "/resources/custom", "resource": "/resources/custom",
@@ -18,31 +18,15 @@ class AdminThemeController extends ConsoleController
throw new \Exception('Missing admin theme path "--path" specified'); throw new \Exception('Missing admin theme path "--path" specified');
} }
$zip = new ZipArchive; if (file_exists(ROOT_DIR . $this->argv['path'])) {
$tmpThemeDir = md5(time()); $adminThemeService = new AdminThemeService();
$res = $zip->open(ROOT_DIR . $this->argv['path']); if ($adminThemeService->install($this->argv['path'])) {
if ($res === TRUE) { $this->out->r("Тема админ-панели установлена", 'green');
$tmpThemeDirFull = RESOURCES_DIR . '/tmp/ad/' . $tmpThemeDir . "/"; } else {
$zip->extractTo($tmpThemeDirFull); $this->out->r("Ошибка установки темы админ-панели", 'red');
$zip->close(); }
$this->out->r('Архив распакован', 'green');
} else { } else {
$this->out->r('Message: Ошибка чтения архива', 'red'); $this->out->r("Тема админ-панели не найдена", 'red');
}
if (file_exists($tmpThemeDirFull . "meta/manifest.json")){
$manifestJson = getConst(file_get_contents($tmpThemeDirFull . "meta/manifest.json"));
$manifest = Manifest::getWithVars($manifestJson);
$this->out->r('manifest.json инициализирован', 'green');
$fileHelper = new Files();
$fileHelper->copy_folder($tmpThemeDirFull . "meta", $manifest['theme_path']);
$fileHelper->copy_folder($tmpThemeDirFull . "resources", $manifest['resource_path']);
$this->out->r("Удаляем временные файлы", 'green');
$fileHelper->recursiveRemoveDir($tmpThemeDirFull);
$this->out->r("Тема " . $manifest['name'] . " установлена", 'green');
} }
} }
@@ -53,17 +37,11 @@ class AdminThemeController extends ConsoleController
} }
if (file_exists(ROOT_DIR . $this->argv['path'])) { if (file_exists(ROOT_DIR . $this->argv['path'])) {
$themeName = basename($this->argv['path']); $adminThemeService = new AdminThemeService();
$active_admin_theme = Option::where("key", "active_admin_theme")->first(); $adminThemeService->uninstall($this->argv['path']);
if ($active_admin_theme->value === ROOT_DIR . $this->argv['path']) {
$this->out->r("Меняем тему на базовую", 'green');
$adminThemeService = new AdminThemeService();
$adminThemeService->setActiveAdminTheme(KERNEL_ADMIN_THEMES_DIR . '/default');
$this->out->r("Тема изменена", 'green');
}
$fileHelper = new Files();
$fileHelper->recursiveRemoveDir(ROOT_DIR . $this->argv['path']);
$fileHelper->recursiveRemoveDir(RESOURCES_DIR . '/' . $themeName);
$this->out->r("Тема удалена", 'green'); $this->out->r("Тема удалена", 'green');
} else { } else {
@@ -71,4 +49,22 @@ class AdminThemeController extends ConsoleController
} }
} }
/**
* @throws \Exception
*/
public function actionPackTheme(): void
{
if (!isset($this->argv['path'])) {
throw new \Exception('Missing admin theme path "--path" specified');
}
if (file_exists(ROOT_DIR . $this->argv['path'])) {
$adminThemeService = new AdminThemeService();
$adminThemeService->pack($this->argv['path']);
$this->out->r("Тема админ-панели заархивирована", 'green');
} else {
$this->out->r("Тема админ-панели не найдена", 'red');
}
}
} }
+4
View File
@@ -35,6 +35,10 @@ App::$collector->group(["prefix" => "admin-theme"], callback: function (RouteCol
[\kernel\console\controllers\AdminThemeController::class, 'actionUninstallTheme'], [\kernel\console\controllers\AdminThemeController::class, 'actionUninstallTheme'],
additionalInfo: ['description' => 'Удалить тему админ-панели', 'params' => ['--path' => 'Путь к удаляемой теме']] additionalInfo: ['description' => 'Удалить тему админ-панели', 'params' => ['--path' => 'Путь к удаляемой теме']]
); );
App::$collector->console('pack',
[\kernel\console\controllers\AdminThemeController::class, 'actionPackTheme'],
additionalInfo: ['description' => 'Заархивировать тему админ-панели', 'params' => ['--path' => 'Путь к теме, которую нужно заархивировать']]
);
}); });
App::$collector->group(["prefix" => "secure"], callback: function (RouteCollector $router){ App::$collector->group(["prefix" => "secure"], callback: function (RouteCollector $router){
+23
View File
@@ -0,0 +1,23 @@
<?php
namespace kernel\filters;
use Itguild\Tables\Filter\Filter;
class CustomSelectFilter extends Filter
{
public function fetch()
{
$this->html = "<td><select class='form-control' name='$this->name'>";
foreach ($this->param as $value) {
if ($value === $this->value) {
$this->html .= "<option value='$value' selected>$value</option>";
} else {
$this->html .= "<option value='$value'>$value</option>";
}
}
$this->html .= "value='$this->value'</select></td>";
return $this->html;
}
}
@@ -42,15 +42,15 @@ $table->addAction(function ($row, $url) use ($moduleService) {
$table->columns([ $table->columns([
'type' => [ 'type' => [
'filter' => [ 'filter' => [
'class' => \Itguild\Tables\Filter\SelectFilter::class, 'class' => \kernel\filters\CustomSelectFilter::class,
'param' => ['kernel', 'entity'], 'param' => ['kernel', 'entity'],
'value' => "kernel" 'value' => "kernel"
], ],
] ]
]); ]);
$table->addAction(function ($row, $url) use ($moduleService){ $table->addAction(function ($row, $url) use ($moduleService) {
if ($row['slug'] !== 'kernel') { if ($row['type'] === 'entity' || $row['type'] === 'additional_property') {
if ($moduleService->isInstall($row['slug'])) { if ($moduleService->isInstall($row['slug'])) {
$url = "$url/delete/?slug=" . $row['slug']; $url = "$url/delete/?slug=" . $row['slug'];
@@ -61,16 +61,19 @@ $table->addAction(function ($row, $url) use ($moduleService){
return \kernel\widgets\IconBtn\IconBtnInstallWidget::create(['url' => $url])->run(); return \kernel\widgets\IconBtn\IconBtnInstallWidget::create(['url' => $url])->run();
} }
} }
return null;
return false;
}); });
$table->addAction(function ($row, $url) use ($moduleService) { $table->addAction(function ($row, $url) use ($moduleService) {
$slug = $row['slug']; if ($row['type'] === 'entity' || $row['type'] === 'additional_property') {
if ($moduleService->isInstall($slug)) { $slug = $row['slug'];
if (!$moduleService->isLastVersion($slug)) { if ($moduleService->isInstall($slug)) {
$url = "$url/update/?slug=" . $slug; if (!$moduleService->isLastVersion($slug)) {
$url = "$url/update/?slug=" . $slug;
return \kernel\widgets\IconBtn\IconBtnUpdateWidget::create(['url' => $url])->run(); return \kernel\widgets\IconBtn\IconBtnUpdateWidget::create(['url' => $url])->run();
}
} }
} }
@@ -78,8 +81,7 @@ $table->addAction(function ($row, $url) use ($moduleService) {
}); });
$table->addAction(function ($row, $url) use ($kernelService) { $table->addAction(function ($row, $url) use ($kernelService) {
$slug = $row['slug']; if ($row['type'] === 'kernel') {
if ($slug === 'kernel') {
if (!$kernelService->isLastVersion()) { if (!$kernelService->isLastVersion()) {
$url = "$url/kernel/update_form/"; $url = "$url/kernel/update_form/";
@@ -91,9 +93,8 @@ $table->addAction(function ($row, $url) use ($kernelService) {
}); });
$table->addAction(function ($row, $url) use ($adminThemeService) { $table->addAction(function ($row, $url) use ($adminThemeService) {
$type = $row['type']; if ($row['type'] === 'admin_theme') {
$slug = $row['slug']; $slug = $row['slug'];
if ($type === 'admin_theme') {
if ($adminThemeService->isInstall($slug)) { if ($adminThemeService->isInstall($slug)) {
if (!$adminThemeService->isLastVersion($slug)) { if (!$adminThemeService->isLastVersion($slug)) {
$url = "$url/admin_theme/update/"; $url = "$url/admin_theme/update/";
+107 -4
View File
@@ -4,12 +4,16 @@ namespace kernel\services;
use DirectoryIterator; use DirectoryIterator;
use kernel\helpers\Debug; use kernel\helpers\Debug;
use kernel\helpers\Files;
use kernel\helpers\Manifest; use kernel\helpers\Manifest;
use kernel\helpers\RESTClient; use kernel\helpers\RESTClient;
use kernel\models\Option; use kernel\models\Option;
use ZipArchive;
class AdminThemeService class AdminThemeService
{ {
protected array $errors = [];
protected Option $option; protected Option $option;
protected string $active_theme; protected string $active_theme;
protected ModuleService $moduleService; protected ModuleService $moduleService;
@@ -22,6 +26,24 @@ class AdminThemeService
$this->moduleService = new ModuleService(); $this->moduleService = new ModuleService();
} }
/**
* @return array
*/
public function getErrors(): array
{
return $this->errors;
}
/**
* @param $msg
* @return void
*/
public function addError($msg): void
{
$this->errors[] = $msg;
}
public function findActiveAdminTheme(): void public function findActiveAdminTheme(): void
{ {
$model = Option::where("key", "active_admin_theme")->first(); $model = Option::where("key", "active_admin_theme")->first();
@@ -50,7 +72,7 @@ class AdminThemeService
$info = []; $info = [];
$theme = getConst($theme); $theme = getConst($theme);
$info['path'] = $theme; $info['path'] = $theme;
if (file_exists($theme . "/manifest.json")){ if (file_exists($theme . "/manifest.json")) {
$manifest = file_get_contents($theme . "/manifest.json"); $manifest = file_get_contents($theme . "/manifest.json");
$manifest = Manifest::getWithVars($manifest); $manifest = Manifest::getWithVars($manifest);
$manifest['preview'] = $manifest['resource'] . "/" . $manifest['preview']; $manifest['preview'] = $manifest['resource'] . "/" . $manifest['preview'];
@@ -60,6 +82,11 @@ class AdminThemeService
return $info; return $info;
} }
public function getAdminThemeInfoBySlug(string $slug)
{
// TODO
}
public function isInstall(string $slug): bool public function isInstall(string $slug): bool
{ {
$adminThemePaths = Option::where("key", "admin_theme_paths")->first(); $adminThemePaths = Option::where("key", "admin_theme_paths")->first();
@@ -85,12 +112,13 @@ class AdminThemeService
public function isLastVersion(string $slug): bool public function isLastVersion(string $slug): bool
{ {
if ($this->moduleService->isServerAvailable()) { if ($this->moduleService->isServerAvailable()) {
$modules_info = RESTClient::request($_ENV['MODULE_SHOP_URL'] . '/api/module_shop/gb_slug'); $modulesInfo = RESTClient::request($_ENV['MODULE_SHOP_URL'] . '/api/module_shop/gb_slug');
$modules_info = json_decode($modules_info->getBody()->getContents(), true); $modulesInfo = json_decode($modulesInfo->getBody()->getContents(), true);
$themeInfo = $this->getAdminThemeInfo($slug); $themeInfo = $this->getAdminThemeInfo($slug);
foreach ($modules_info as $mod) { Debug::dd($themeInfo);
foreach ($modulesInfo as $mod) {
if ($mod['slug'] === $themeInfo['slug'] && $mod['version'] === $themeInfo['version']) { if ($mod['slug'] === $themeInfo['slug'] && $mod['version'] === $themeInfo['version']) {
return true; return true;
} }
@@ -99,4 +127,79 @@ class AdminThemeService
return false; return false;
} }
public function pack(string $path): void
{
$themeName = basename($path);
$tmpThemeDirFull = RESOURCES_DIR . '/tmp/ad/' . $themeName . "/";
$fileHelper = new Files();
$fileHelper->copy_folder(ROOT_DIR . $path, $tmpThemeDirFull . 'meta/');
$fileHelper->copy_folder(RESOURCES_DIR . '/' . $themeName, $tmpThemeDirFull . 'resources/');
if (!is_dir(RESOURCES_DIR . '/tmp/admin_themes')) {
$old_mask = umask(0);
mkdir(RESOURCES_DIR . '/tmp/admin_themes', 0775, true);
umask($old_mask);
}
$fileHelper->pack($tmpThemeDirFull, RESOURCES_DIR . '/tmp/admin_themes/' . $themeName . '.igt');
}
public function install(string $path): bool
{
$zip = new ZipArchive;
$tmpThemeDir = md5(time());
$res = $zip->open(ROOT_DIR . $path);
if ($res === TRUE) {
$tmpThemeDirFull = RESOURCES_DIR . '/tmp/ad/' . $tmpThemeDir . "/";
$zip->extractTo($tmpThemeDirFull);
$zip->close();
} else {
$this->addError('unable to open zip archive');
return false;
}
if (!file_exists($tmpThemeDirFull . "meta/manifest.json")){
$this->addError('manifest.json not found');
return false;
}
$manifestJson = getConst(file_get_contents($tmpThemeDirFull . "meta/manifest.json"));
$manifest = Manifest::getWithVars($manifestJson);
$fileHelper = new Files();
if (isset($manifest['theme_path'])) {
$fileHelper->copy_folder($tmpThemeDirFull . "meta", $manifest['theme_path']);
} else {
$fileHelper->copy_folder($tmpThemeDirFull . "meta", APP_DIR . '/admin_themes/' . $manifest['slug']);
}
if (isset($manifest['resource_path'])) {
$fileHelper->copy_folder($tmpThemeDirFull . "resources", $manifest['resource_path']);
} else {
$fileHelper->copy_folder($tmpThemeDirFull . "resources", RESOURCES_DIR . '/' . $manifest['slug']);
}
$fileHelper->recursiveRemoveDir($tmpThemeDirFull);
unlink(ROOT_DIR . $path);
return true;
}
public function uninstall(string $path): void
{
$themeInfo = $this->getAdminThemeInfo(APP_DIR . '/admin_themes/' . basename($path));
$active_admin_theme = Option::where("key", "active_admin_theme")->first();
if ($active_admin_theme->value === ROOT_DIR . $path) {
$this->setActiveAdminTheme(KERNEL_ADMIN_THEMES_DIR . '/default');
}
$fileHelper = new Files();
if (file_exists(ROOT_DIR . $path)) {
$fileHelper->recursiveRemoveDir(ROOT_DIR . $path);
}
if (file_exists(RESOURCES_DIR . '/' . $themeInfo['slug'])) {
$fileHelper->recursiveRemoveDir(RESOURCES_DIR . '/' . $themeInfo['slug']);
}
}
} }
+6 -2
View File
@@ -362,11 +362,15 @@ class ModuleService
if (file_exists(KERNEL_APP_MODULES_DIR . '/' . $moduleName)) { if (file_exists(KERNEL_APP_MODULES_DIR . '/' . $moduleName)) {
$fileHelper->copy_folder(KERNEL_APP_MODULES_DIR . '/' . $moduleName, $tmpModuleDirFull . 'kernel/'); $fileHelper->copy_folder(KERNEL_APP_MODULES_DIR . '/' . $moduleName, $tmpModuleDirFull . 'kernel/');
} else { } else {
mkdir($tmpModuleDirFull . 'kernel/'); $old_mask = umask(0);
mkdir($tmpModuleDirFull . 'kernel/', 0775, true);
umask($old_mask);
} }
if (!is_dir(RESOURCES_DIR . '/tmp/modules')) { if (!is_dir(RESOURCES_DIR . '/tmp/modules')) {
mkdir(RESOURCES_DIR . '/tmp/modules', 0777, true); $old_mask = umask(0);
mkdir(RESOURCES_DIR . '/tmp/modules', 0775, true);
umask($old_mask);
} }
$fileHelper->pack($tmpModuleDirFull, RESOURCES_DIR . '/tmp/modules/' . $moduleName . '.igm'); $fileHelper->pack($tmpModuleDirFull, RESOURCES_DIR . '/tmp/modules/' . $moduleName . '.igm');
} }
Vendored Regular → Executable
View File
View File
View File
View File
View File
View File
Regular → Executable
View File
Regular → Executable
View File

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Regular → Executable
View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Vendored Regular → Executable
View File
Vendored Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
Vendored Regular → Executable
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File

Some files were not shown because too many files have changed in this diff Show More