Skip to content

Commit

Permalink
Reusable trait to save and regenerate reusable list when a new reusab…
Browse files Browse the repository at this point in the history
…le section/block is added

Revisions trait for template revisions
Global trait to save global sections in templates like common footer/header.
Changed template revisions/backup file format to fix save issue on windows that doesn't allow | and : in file names #93
  • Loading branch information
givanz committed Mar 1, 2024
1 parent 28be959 commit 56ef0bf
Show file tree
Hide file tree
Showing 4 changed files with 336 additions and 63 deletions.
98 changes: 47 additions & 51 deletions admin/controller/editor/editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
use Vvveb\System\Sites;

class Editor extends Base {
use GlobalTrait;

protected $revisionDateFormat = 'Y-m-d_H:i:s';

private $themeConfig = [];
Expand All @@ -62,13 +64,15 @@ function oEmbedProxy() {
$this->response->output($result);
}

function getThemeFolder() {
$theme = $this->request->get['theme'] ?? Sites::getTheme() ?? 'default';
private function getTheme() {
return $theme = sanitizeFileName($this->request->get['theme'] ?? Sites::getTheme() ?? 'default');
}

return DIR_THEMES . DS . $theme;
private function getThemeFolder() {
return DIR_THEMES . $this->getTheme();
}

function loadThemeConfig() {
private function loadThemeConfig() {
$config = $this->getThemeFolder() . DS . 'theme.php';

if (file_exists($config)) {
Expand All @@ -78,16 +82,16 @@ function loadThemeConfig() {
}
}

function loadTemplateList() {
private function loadTemplateList($theme = null) {
$list = $this->themeConfig['pages'] ?? [];

$pages = $list + \Vvveb\getTemplateList();
$pages = $list + \Vvveb\getTemplateList($theme);
list($pages) = Event::trigger(__CLASS__, __FUNCTION__, $pages);

return $pages;
}

function loadEditorData() {
private function loadEditorData() {
$data = [];

//menu list
Expand All @@ -104,7 +108,7 @@ function loadEditorData() {
/*
Load theme sections, components and inputs
*/
function loadThemeAssets() {
private function loadThemeAssets() {
$themeFolder = $this->getThemeFolder();
$view = &$this->view;
$themeJs = [];
Expand Down Expand Up @@ -136,9 +140,11 @@ function loadThemeAssets() {
}

function index() {
$theme = sanitizeFileName($this->request->get['theme'] ?? false);
$themeParam = ($theme ? '&theme=' . $theme : '');
$view = View::getInstance();
$view->themeBaseUrl = PUBLIC_PATH . 'themes/' . (Sites::getTheme() ?? 'default') . '/';
$view->pages = $this->loadTemplateList();
$view->themeBaseUrl = PUBLIC_PATH . 'themes/' . ($this->getTheme() ?? 'default') . '/';
$view->pages = $this->loadTemplateList($theme);

$this->loadThemeAssets();

Expand All @@ -155,45 +161,51 @@ function index() {
$name = 'homepage-live';
}

$current_page = ['name' => $name, 'file' => $file, 'url' => $url, 'title' => $title, 'folder' => '', 'className' => 'page'];
$current_page = ['name' => $name,
'file' => $file,
'url' => $url . ($theme ? '?theme=' . $theme : ''),
'title' => $title,
'folder' => '',
'className' => 'page', ];

$view->pages = [$name => $current_page] + $view->pages;
}

$admin_path = \Vvveb\adminPath();
$mediaControllerPath = $admin_path . 'index.php?module=media/media';
$controllerPath = $admin_path . 'index.php?module=editor/editor';
$revisionsPath = $admin_path . 'index.php?module=editor/revisions';
$controllerPath = $admin_path . 'index.php?module=editor/editor' . $themeParam;
$revisionsPath = $admin_path . 'index.php?module=editor/revisions' . $themeParam;
$reusablePath = $admin_path . 'index.php?module=editor/reusable' . $themeParam;

$this->view->scanUrl = "$mediaControllerPath&action=scan";
$this->view->uploadUrl = "$mediaControllerPath&action=upload";
$this->view->saveUrl = "$controllerPath&action=save";
$this->view->deleteUrl = "$controllerPath&action=delete";
$this->view->renameUrl = "$controllerPath&action=rename";
$this->view->saveReusableUrl = "$controllerPath&action=saveReusable";
$this->view->saveReusableUrl = "$reusablePath&action=save";
$this->view->oEmbedProxyUrl = "$controllerPath&action=oEmbedProxy";

$this->view->revisionsUrl = "$revisionsPath&action=revisions";
$this->view->revisionLoadUrl = "$revisionsPath&action=revisionLoad";
$this->view->revisionDeleteUrl = "$revisionsPath&action=revisionDelete";
$this->view->revisionLoadUrl = "$revisionsPath&action=load";
$this->view->revisionDeleteUrl = "$revisionsPath&action=delete";

$view->templates = \Vvveb\getTemplateList();
$view->folders = \Vvveb\getThemeFolderList();
$view->templates = \Vvveb\getTemplateList($theme);
$view->folders = \Vvveb\getThemeFolderList($theme);
$view->data = $this->loadEditorData();
}

function getComponent($html, $options) {
}

function backup($page) {
private function backup($page) {
$themeFolder = $this->getThemeFolder() . DS;
$backupFolder = $themeFolder . 'backup' . DS;
$page = str_replace('.html', '', sanitizeFileName($page));
$backupName = str_replace(DS, '-', $page) . '|' . date($this->revisionDateFormat) . '.html';
$backupName = str_replace(DS, '-', $page) . '@' . str_replace(':',';', date($this->revisionDateFormat)) . '.html';
$file = $themeFolder . $page . '.html';

if (is_dir($backupFolder)) {
if (file_exists($file)) {
$content = file_get_contents($themeFolder . $page . '.html');
$base = str_replace('/admin', '', PUBLIC_THEME_PATH) . 'themes/' . $this->getTheme() . '/';
$content = preg_replace('/<base(.*)href=["\'](.*?)["\'](.*?)>/', '<base$1href="' . $base . '"$3>', $content);

return file_put_contents($backupFolder . $backupName, $content);
}
Expand All @@ -202,7 +214,7 @@ function backup($page) {
return false;
}

function saveElements($elements) {
private function saveElements($elements) {
$products = new ProductSQL();
$posts = new PostSQL();
$components = [];
Expand Down Expand Up @@ -313,36 +325,16 @@ function rename() {
$this->response->output($message);
}

function saveReusable() {
$name = slugify(sanitizeFileName($this->request->post['name']));
$type = $this->request->post['type'];
$html = $this->request->post['html'];

$themeFolder = $this->getThemeFolder();
$folder = $themeFolder . DS . $type . 's' . DS . 'reusable' . DS;
$file = "$name.html";

@mkdir($folder);

if (file_put_contents($folder . $file, $html)) {
$message = ['success' => true, 'message' => __('Element saved!')];
} else {
$message = ['success' => false, 'message' => __('Error saving!')];
}

$this->response->setType('json');
$this->response->output($message);
}

function save() {
$file = $this->request->post['file'] ?? '';
$folder = $this->request->post['folder'] ?? '';
$startTemplateUrl = $this->request->post['startTemplateUrl'] ?? '';
$name = $this->request->post['name'] ?? '';
$content = $this->request->post['content'] ?? 'Lorem ipsum';
$type = $this->request->post['type'] ?? false;
$addMenu = $this->request->post['add-menu'] ?? false;
$menu_id = $this->request->post['menu_id'] ?? false;
$type = $this->request->post['type'] ?? false;
$addMenu = $this->request->post['add-menu'] ?? false;
$menu_id = $this->request->post['menu_id'] ?? false;
$theme = sanitizeFileName($this->request->get['theme'] ?? false);
$url = '';

$file = sanitizeFileName(str_replace('.html', '', $file)) . '.html';
Expand All @@ -369,7 +361,8 @@ function save() {
'content' => $content,
'language_id' => $this->global['language_id'],
]],
] + $this->global, ] + $this->global);
] + $this->global,
'site_id' => [$this->global['site_id']], ] + $this->global);

if ($result['post']) {
$success = true;
Expand Down Expand Up @@ -398,7 +391,8 @@ function save() {
'content' => $content,
'language_id' => $this->global['language_id'],
]],
] + $this->global, ] + $this->global);
] + $this->global,
'site_id' => [$this->global['site_id']], ] + $this->global);

if ($result['product']) {
$success = true;
Expand All @@ -419,8 +413,8 @@ function save() {
$success = false;
$text = '';

$baseUrl = '/themes/' . $this->getTheme() . '/' . ($folder ? $folder . '/' : '');
$themeFolder = $this->getThemeFolder();
$baseUrl = '/themes/' . (Sites::getTheme() ?? 'default') . '/' . ($folder ? $folder . '/' : '');

if ($startTemplateUrl) {
$content = file_get_contents($themeFolder . DS . $startTemplateUrl);
Expand Down Expand Up @@ -478,6 +472,8 @@ function save() {
$fileName = $themeFolder . DS . ($folder ? $folder . DS : '') . $file;
}

$this->saveGlobalElements($content);

if (file_put_contents($fileName, $content)) {
$success = true;
$text .= __('File saved!');
Expand Down
102 changes: 102 additions & 0 deletions admin/controller/editor/global-trait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

/**
* Vvveb
*
* Copyright (C) 2022 Ziadin Givan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

namespace Vvveb\Controller\Editor;

use Vvveb\System\Core\View;

trait GlobalTrait {
private function saveGlobalElements($content) {
$document = new \DomDocument();
$document->preserveWhiteSpace = false;
$document->recover = true;
$document->strictErrorChecking = false;
$document->formatOutput = false;
$document->resolveExternals = false;
$document->validateOnParse = false;
$document->xmlStandalone = true;

$view = View::getInstance();
libxml_use_internal_errors(true);

@$document->loadHTML($content);

$xpath = new \DOMXpath($document);

$elements = $xpath->query('//*[ @data-v-save-global ]');

if ($elements && $elements->length) {
$toDocument = new \DomDocument();
$toDocument->preserveWhiteSpace = false;
$toDocument->recover = true;
$toDocument->strictErrorChecking = false;
$toDocument->formatOutput = false;
$toDocument->resolveExternals = false;
$toDocument->validateOnParse = false;
$toDocument->xmlStandalone = true;

$themeFolder = $this->getThemeFolder();

foreach ($elements as $element) {
$attribute = $element->getAttribute('data-v-save-global');

if (strpos($attribute, ',') !== false) {
list($file, $selector) = explode(',',$attribute);

$file = html_entity_decode($file);
$selector = html_entity_decode($selector);
$file = $themeFolder . DS . $file;

$toDocument->loadHTMLFile($file);

$toXpath = new \DOMXpath($toDocument);

$toElements = $toXpath->query(\Vvveb\cssToXpath($selector));

$count = 0;

if ($elements && $elements->length) {
foreach ($toElements as $externalNode) {
$parent = $externalNode->parentNode;

$importedNode = $toDocument->importNode($element, true);

if ($parent) {
if ($count) {
$parent->appendChild($importedNode);
} else {
$parent->replaceChild($importedNode, $externalNode);
}
$externalNode = $importedNode;
$parent = $externalNode->parentNode;
$count++;
}
}

$html= $toDocument->saveHTML();
file_put_contents($file, $html);
}
}
}
}
}
}
Loading

0 comments on commit 56ef0bf

Please sign in to comment.