View file app/Controllers/Admin/ModuleController.php

File size: 6.16Kb
<?php

namespace App\Controllers\Admin;

use App\Models\Module;
use App\Models\User;
use Illuminate\Http\Request;
use Phinx\Config\Config;
use Phinx\Console\Command\Migrate;
use Phinx\Console\PhinxApplication;
use Phinx\Wrapper\TextWrapper;

class ModuleController extends AdminController
{
    /**
     * ModuleController constructor.
     */
    public function __construct()
    {
        parent::__construct();

        if (! isAdmin(User::BOSS)) {
            abort('403', 'Доступ запрещен!');
        }
    }

    /**
     * Главная страница
     *
     * @return string
     */
    public function index(): string
    {
        $modules      = glob(APP . '/Modules/*', GLOB_ONLYDIR);
        $moduleActive = Module::query()->pluck('version', 'name')->all();

        $moduleNames = [];
        foreach ($modules as $module) {
            if (file_exists($module . '/module.php')) {
                $moduleNames[basename($module)] = include $module . '/module.php';
            }
        }

        return view('admin/modules/index', compact('moduleNames', 'moduleActive'));
    }

    /**
     * Просмотр модуля
     *
     * @param Request $request
     * @return string
     */
    public function module(Request $request): string
    {
        $moduleName = check($request->input('module'));
        $modulePath = APP . '/Modules/' . $moduleName;

        if (! preg_match('|^[A-Z][\w\-]+$|', $moduleName) || ! file_exists($modulePath)) {
            abort('default', 'Данный модуль не найден!');
        }

        $moduleActive = Module::query()->where('name', $moduleName)->first();

        $module = include $modulePath . '/module.php';

        if (file_exists($modulePath . '/screenshots')) {
            $module['screenshots'] = glob($modulePath . '/screenshots/*.{gif,png,jpg,jpeg}', GLOB_BRACE);
        }

        if (file_exists($modulePath . '/migrations')) {
            $module['migrations'] = array_map('basename', glob($modulePath . '/migrations/*.php'));
        }

        if ($module['symlinks']) {
            $module['symlinks'] = array_map(function ($symlink) {
                return str_replace(HOME, '', $symlink);
            }, $module['symlinks']);
        }

        return view('admin/modules/module', compact('module', 'moduleName', 'moduleActive'));
    }

    /**
     * Включение модуля
     *
     * @param Request          $request
     * @param PhinxApplication $app
     * @return void
     */
    public function install(Request $request, PhinxApplication $app): void
    {
        $moduleName = check($request->input('module'));
        $modulePath = APP . '/Modules/' . $moduleName;

        if (! preg_match('|^[A-Z][\w\-]+$|', $moduleName) || ! file_exists($modulePath)) {
            abort('default', 'Данный модуль не найден!');
        }

        $module = include $modulePath . '/module.php';

        // Создание ссылок
        if (isset($module['symlinks'])) {
            foreach ($module['symlinks'] as $key => $symlink) {
                if (file_exists($symlink)) {
                    unlink($symlink);
                }

                symlink($modulePath . '/' . $key, $symlink);
            }
        }

        // Выполнение миграций
        if (file_exists($modulePath . '/migrations')) {
            $app->add(new Migrate());

            /** @var Migrate $command */
            $command = $app->find('migrate');

            $config = require APP . '/migration.php';
            $config['paths']['migrations'] = $modulePath . '/migrations';

            $command->setConfig(new Config($config));

            $wrap = new TextWrapper($app);
            $wrap->getMigrate();
        }

        if (file_exists(STORAGE . '/temp/routes.dat')) {
            unlink (STORAGE . '/temp/routes.dat');
        }

        $mod = Module::query()->firstOrNew(['name' => $moduleName]);

        if ($mod->exists) {
            $mod->update([
                'version'    => $module['version'],
                'updated_at' => SITETIME,
            ]);

            $result = 'Модуль успешно обновлен!';
        } else {
            $mod->fill([
                'version'    => $module['version'],
                'updated_at' => SITETIME,
                'created_at' => SITETIME,
            ])->save();

            $result = 'Модуль успешно включен!';
        }

        setFlash('success', $result);
        redirect('/admin/modules/module?module=' . $moduleName);
    }

    /**
     * Отключение модуля
     *
     * @param Request          $request
     * @param PhinxApplication $app
     * @return void
     */
    public function uninstall(Request $request, PhinxApplication $app): void
    {
        $moduleName = check($request->input('module'));
        $modulePath = APP . '/Modules/' . $moduleName;

        if (! preg_match('|^[A-Z][\w\-]+$|', $moduleName) || ! file_exists($modulePath)) {
            abort('default', 'Данный модуль не найден!');
        }

        $module = include $modulePath . '/module.php';

        // Удаление ссылок
        if (isset($module['symlinks'])) {
            foreach ($module['symlinks'] as $key => $symlink) {
                if (file_exists($symlink)) {
                    unlink($symlink);
                }
            }
        }

        // Откат миграций
        if (file_exists($modulePath . '/migrations')) {

            $app->add(new Migrate());

            /** @var Migrate $command */
            $command = $app->find('rollback');

            $config = require APP . '/migration.php';
            $config['paths']['migrations'] = $modulePath . '/migrations';

            $command->setConfig(new Config($config));

            $wrap = new TextWrapper($app);
            $wrap->getRollback(null, 0);
        }

        if (file_exists(STORAGE . '/temp/routes.dat')) {
            unlink (STORAGE . '/temp/routes.dat');
        }

        Module::query()->where('name', $moduleName)->delete();

        setFlash('success', 'Модуль успешно отключен!');
        redirect('/admin/modules/module?module=' . $moduleName);
    }
}