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

0
app/admin_themes/custom/layout/main.php Normal file → Executable file
View File

1
app/admin_themes/custom/manifest.json Normal file → Executable file
View File

@ -3,6 +3,7 @@
"version": "0.1",
"author": "Kavalar",
"slug": "custom",
"type": "admin_theme",
"description": "Custom admin theme",
"preview": "nrnv2024_640x360.jpg",
"resource": "/resources/custom",

View File

@ -18,31 +18,15 @@ class AdminThemeController extends ConsoleController
throw new \Exception('Missing admin theme path "--path" specified');
}
$zip = new ZipArchive;
$tmpThemeDir = md5(time());
$res = $zip->open(ROOT_DIR . $this->argv['path']);
if ($res === TRUE) {
$tmpThemeDirFull = RESOURCES_DIR . '/tmp/ad/' . $tmpThemeDir . "/";
$zip->extractTo($tmpThemeDirFull);
$zip->close();
$this->out->r('Архив распакован', 'green');
if (file_exists(ROOT_DIR . $this->argv['path'])) {
$adminThemeService = new AdminThemeService();
if ($adminThemeService->install($this->argv['path'])) {
$this->out->r("Тема админ-панели установлена", 'green');
} else {
$this->out->r("Ошибка установки темы админ-панели", 'red');
}
} else {
$this->out->r('Message: Ошибка чтения архива', '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');
$this->out->r("Тема админ-панели не найдена", 'red');
}
}
@ -53,17 +37,11 @@ class AdminThemeController extends ConsoleController
}
if (file_exists(ROOT_DIR . $this->argv['path'])) {
$themeName = basename($this->argv['path']);
$active_admin_theme = Option::where("key", "active_admin_theme")->first();
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);
$adminThemeService = new AdminThemeService();
$adminThemeService->uninstall($this->argv['path']);
$this->out->r("Тема удалена", 'green');
} 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');
}
}
}

View File

@ -35,6 +35,10 @@ App::$collector->group(["prefix" => "admin-theme"], callback: function (RouteCol
[\kernel\console\controllers\AdminThemeController::class, 'actionUninstallTheme'],
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){

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;
}
}

View File

@ -42,15 +42,15 @@ $table->addAction(function ($row, $url) use ($moduleService) {
$table->columns([
'type' => [
'filter' => [
'class' => \Itguild\Tables\Filter\SelectFilter::class,
'class' => \kernel\filters\CustomSelectFilter::class,
'param' => ['kernel', 'entity'],
'value' => "kernel"
],
]
]);
$table->addAction(function ($row, $url) use ($moduleService){
if ($row['slug'] !== 'kernel') {
$table->addAction(function ($row, $url) use ($moduleService) {
if ($row['type'] === 'entity' || $row['type'] === 'additional_property') {
if ($moduleService->isInstall($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 null;
return false;
});
$table->addAction(function ($row, $url) use ($moduleService) {
$slug = $row['slug'];
if ($moduleService->isInstall($slug)) {
if (!$moduleService->isLastVersion($slug)) {
$url = "$url/update/?slug=" . $slug;
if ($row['type'] === 'entity' || $row['type'] === 'additional_property') {
$slug = $row['slug'];
if ($moduleService->isInstall($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) {
$slug = $row['slug'];
if ($slug === 'kernel') {
if ($row['type'] === 'kernel') {
if (!$kernelService->isLastVersion()) {
$url = "$url/kernel/update_form/";
@ -91,9 +93,8 @@ $table->addAction(function ($row, $url) use ($kernelService) {
});
$table->addAction(function ($row, $url) use ($adminThemeService) {
$type = $row['type'];
$slug = $row['slug'];
if ($type === 'admin_theme') {
if ($row['type'] === 'admin_theme') {
$slug = $row['slug'];
if ($adminThemeService->isInstall($slug)) {
if (!$adminThemeService->isLastVersion($slug)) {
$url = "$url/admin_theme/update/";

View File

@ -4,12 +4,16 @@ namespace kernel\services;
use DirectoryIterator;
use kernel\helpers\Debug;
use kernel\helpers\Files;
use kernel\helpers\Manifest;
use kernel\helpers\RESTClient;
use kernel\models\Option;
use ZipArchive;
class AdminThemeService
{
protected array $errors = [];
protected Option $option;
protected string $active_theme;
protected ModuleService $moduleService;
@ -22,6 +26,24 @@ class AdminThemeService
$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
{
$model = Option::where("key", "active_admin_theme")->first();
@ -50,7 +72,7 @@ class AdminThemeService
$info = [];
$theme = getConst($theme);
$info['path'] = $theme;
if (file_exists($theme . "/manifest.json")){
if (file_exists($theme . "/manifest.json")) {
$manifest = file_get_contents($theme . "/manifest.json");
$manifest = Manifest::getWithVars($manifest);
$manifest['preview'] = $manifest['resource'] . "/" . $manifest['preview'];
@ -60,6 +82,11 @@ class AdminThemeService
return $info;
}
public function getAdminThemeInfoBySlug(string $slug)
{
// TODO
}
public function isInstall(string $slug): bool
{
$adminThemePaths = Option::where("key", "admin_theme_paths")->first();
@ -85,12 +112,13 @@ class AdminThemeService
public function isLastVersion(string $slug): bool
{
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);
foreach ($modules_info as $mod) {
Debug::dd($themeInfo);
foreach ($modulesInfo as $mod) {
if ($mod['slug'] === $themeInfo['slug'] && $mod['version'] === $themeInfo['version']) {
return true;
}
@ -99,4 +127,79 @@ class AdminThemeService
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']);
}
}
}

View File

@ -362,11 +362,15 @@ class ModuleService
if (file_exists(KERNEL_APP_MODULES_DIR . '/' . $moduleName)) {
$fileHelper->copy_folder(KERNEL_APP_MODULES_DIR . '/' . $moduleName, $tmpModuleDirFull . 'kernel/');
} else {
mkdir($tmpModuleDirFull . 'kernel/');
$old_mask = umask(0);
mkdir($tmpModuleDirFull . 'kernel/', 0775, true);
umask($old_mask);
}
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');
}

0
resources/custom/css/bootstrap.min.css vendored Normal file → Executable file
View File

0
resources/custom/css/bootstrap/_media.css Normal file → Executable file
View File

View File

View File

0
resources/custom/css/bootstrap/mixins/_visibility.css Normal file → Executable file
View File

View File

0
resources/custom/css/style.css Normal file → Executable file
View File

0
resources/custom/images/bg_1.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

0
resources/custom/images/logo.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

0
resources/custom/js/bootstrap.min.js vendored Normal file → Executable file
View File

0
resources/custom/js/jquery.min.js vendored Normal file → Executable file
View File

0
resources/custom/js/main.js Normal file → Executable file
View File

0
resources/custom/js/popper.js Normal file → Executable file
View File

0
resources/custom/nrnv2024_640x360.jpg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

0
resources/custom/scss/bootstrap/_alert.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_badge.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_breadcrumb.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_button-group.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_buttons.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_card.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_carousel.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_close.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_code.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_custom-forms.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_dropdown.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_forms.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_functions.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_grid.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_images.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_input-group.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_jumbotron.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_list-group.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_media.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_mixins.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_modal.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_nav.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_navbar.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_pagination.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_popover.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_print.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_progress.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_reboot.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_root.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_spinners.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_tables.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_toasts.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_tooltip.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_transitions.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_type.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_utilities.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/_variables.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/bootstrap-grid.scss vendored Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/bootstrap-reboot.scss vendored Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/bootstrap.scss vendored Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_alert.scss Normal file → Executable file
View File

View File

0
resources/custom/scss/bootstrap/mixins/_badge.scss Normal file → Executable file
View File

View File

View File

View File

0
resources/custom/scss/bootstrap/mixins/_buttons.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_caret.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_clearfix.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_deprecate.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_float.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_forms.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_gradients.scss Normal file → Executable file
View File

View File

0
resources/custom/scss/bootstrap/mixins/_grid.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_hover.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_image.scss Normal file → Executable file
View File

View File

0
resources/custom/scss/bootstrap/mixins/_lists.scss Normal file → Executable file
View File

View File

View File

View File

0
resources/custom/scss/bootstrap/mixins/_resize.scss Normal file → Executable file
View File

View File

0
resources/custom/scss/bootstrap/mixins/_size.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/mixins/_table-row.scss Normal file → Executable file
View File

View File

0
resources/custom/scss/bootstrap/mixins/_text-hide.scss Normal file → Executable file
View File

View File

View File

View File

0
resources/custom/scss/bootstrap/utilities/_align.scss Normal file → Executable file
View File

View File

View File

View File

View File

0
resources/custom/scss/bootstrap/utilities/_embed.scss Normal file → Executable file
View File

0
resources/custom/scss/bootstrap/utilities/_flex.scss Normal file → Executable file
View File

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