Files
ave-cms/adminx/modules/Console/Controller.php
T
2026-07-27 12:58:44 +03:00

151 lines
5.2 KiB
PHP

<?php
/*
|--------------------------------------------------------------------------------------
| AVE.cms
|--------------------------------------------------------------------------------------
| @package AVE.cms
| @file adminx/modules/Console/Controller.php
| @author AVE.cms <support@ave-cms.ru>
| @copyright 2007-2026 (c) AVE.cms
| @link https://ave-cms.ru
| @version 3.3
*/
namespace App\Adminx\Console;
defined('BASEPATH') || die('Direct access to this location is not allowed.');
use App\Adminx\Support\CodeEditor;
use App\Adminx\Support\PhpCode;
use App\Common\AdminAssets;
use App\Common\AuditLog;
use App\Common\Auth;
use App\Common\Controller as BaseController;
use App\Common\Permission;
use App\Helpers\Request;
use App\Helpers\Response;
class Controller extends BaseController
{
public function index(array $params = array())
{
if (!Permission::check('view_console')) {
Response::forbidden();
return '';
}
AdminAssets::addStyle($this->base() . '/modules/Console/assets/console.css', 50);
AdminAssets::addScript($this->base() . '/modules/Console/assets/console.js', 50);
CodeEditor::useCodeMirror('application/x-httpd-php');
return $this->render('@console/index.twig', array(
'snippets' => Model::all(),
'can_manage' => Permission::check('manage_console'),
'can_execute' => Permission::check('execute_console'),
'runner_enabled' => Runner::enabled(),
));
}
public function show(array $params = array())
{
if (!Permission::check('view_console')) {
return $this->error('Недостаточно прав', array(), 403);
}
$item = Model::one(isset($params['id']) ? (int) $params['id'] : 0);
return $item ? $this->success('', array('data' => $item)) : $this->error('Сниппет не найден', array(), 404);
}
public function save(array $params = array())
{
if (($error = $this->guard('manage_console')) !== null) { return $error; }
$id = Request::postInt('id', 0);
$name = trim(Request::postStr('name', ''));
$code = Request::postStr('code', '');
if ($name === '' || trim($code) === '') {
return $this->error('Укажите название и код', array('name' => $name === '' ? 'Обязательное поле' : '', 'code' => trim($code) === '' ? 'Обязательное поле' : ''));
}
if ($id > 0 && !Model::one($id)) {
return $this->error('Сниппет не найден', array(), 404);
}
$id = Model::save($id, $name, $code, Auth::id());
$this->audit('console.snippet_saved', $id, array('name' => $name));
return $this->success('Сниппет сохранён', array('data' => array('id' => $id, 'snippets' => Model::all())));
}
public function delete(array $params = array())
{
if (($error = $this->guard('manage_console')) !== null) { return $error; }
$id = isset($params['id']) ? (int) $params['id'] : 0;
if (!Model::one($id) || !Model::delete($id)) {
return $this->error('Сниппет не найден', array(), 404);
}
$this->audit('console.snippet_deleted', $id);
return $this->success('Сниппет удалён', array('data' => array('snippets' => Model::all())));
}
public function lint(array $params = array())
{
if (($error = $this->guard('manage_console')) !== null) { return $error; }
$result = PhpCode::lint(Request::postStr('code', ''));
return $result['ok']
? $this->success($result['message'], array('data' => $result))
: $this->error($result['message'], array('code' => $result['output']), 422);
}
public function execute(array $params = array())
{
if (($error = $this->guard('execute_console')) !== null) { return $error; }
$code = Request::postStr('code', '');
if (trim($code) === '') {
return $this->error('Введите PHP-код', array('code' => 'Обязательное поле'));
}
try {
$result = Runner::execute($code);
} catch (\Throwable $e) {
$this->audit('console.execution_failed', null, array('error' => $e->getMessage(), 'code_hash' => sha1($code)));
return $this->error($e->getMessage(), array(), 422);
}
$this->audit('console.executed', null, array(
'code_hash' => sha1($code),
'duration_ms' => $result['duration_ms'],
'exit_code' => $result['exit_code'],
'timed_out' => $result['timed_out'],
));
if ($result['ok']) {
return $this->success('Код выполнен', array('data' => $result));
}
return $this->json(array(
'success' => false,
'message' => $result['timed_out'] ? 'Превышен лимит времени' : 'Процесс завершился с ошибкой',
'data' => $result,
'html' => new \stdClass(),
'redirect' => null,
'errors' => new \stdClass(),
), 422);
}
protected function guard($permission)
{
return $this->guardPermission($permission);
}
protected function audit($action, $targetId = null, array $meta = array())
{
$user = Auth::user();
AuditLog::record($action, array(
'actor_id' => Auth::id(),
'actor_name' => $user && isset($user['name']) ? (string) $user['name'] : '',
'target_type' => 'system_console',
'target_id' => $targetId,
'meta' => $meta,
));
}
}