kokjan/backend/modules/administrator/controllers/ThemeEditorController.php

97 lines
2.7 KiB
PHP
Raw Normal View History

<?php
namespace backend\modules\administrator\controllers;
use Yii;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\helpers\FileHelper;
use yii\filters\AccessControl;
/**
* ThemeEditorController implements online file editing for frontend themes.
*/
class ThemeEditorController extends Controller
{
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'rules' => [
[
'allow' => true,
'roles' => ['@'], // Only logged in users
],
],
],
];
}
/**
* Get the base path for theme files.
*/
protected function getThemePath()
{
return Yii::getAlias('@frontend/themes/mali/views/layouts');
}
/**
* Lists all editable theme files.
*/
public function actionIndex()
{
$path = $this->getThemePath();
$files = FileHelper::findFiles($path, [
'only' => ['*.php', '*.css', '*.js'],
'recursive' => false,
]);
$fileList = [];
foreach ($files as $file) {
$fileList[] = basename($file);
}
return $this->render('index', [
'files' => $fileList,
]);
}
/**
* Edit a specific file.
*/
public function actionEdit($file)
{
$path = $this->getThemePath() . DIRECTORY_SEPARATOR . $file;
// Security check: ensure file is within theme directory
if (!file_exists($path) || strpos(realpath($path), realpath($this->getThemePath())) !== 0) {
throw new NotFoundHttpException('The requested file does not exist or access is denied.');
}
$content = file_get_contents($path);
if (Yii::$app->request->isPost) {
$newContent = Yii::$app->request->post('content');
// Backup before save
copy($path, $path . '.bak');
if (file_put_contents($path, $newContent) !== false) {
Yii::$app->session->setFlash('success', "บันทึกไฟล์ $file เรียบร้อยแล้ว (สำรองไฟล์เดิมไว้ที่ $file.bak)");
} else {
Yii::$app->session->setFlash('error', "ไม่สามารถบันทึกไฟล์ $file ได้ กรุณาตรวจสอบ Permission");
}
return $this->refresh();
}
return $this->render('edit', [
'filename' => $file,
'content' => $content,
]);
}
}