222 lines
5.8 KiB
PHP
222 lines
5.8 KiB
PHP
<?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\System\Extensions;
|
|
|
|
use \Vvveb\System\Cache;
|
|
use \Vvveb\System\Event;
|
|
use \Vvveb\System\Sites;
|
|
use function Vvveb\__;
|
|
use function Vvveb\getDefaultTemplateList;
|
|
use Vvveb\System\Functions\Str;
|
|
|
|
class Themes extends Extensions {
|
|
static protected $extension = 'theme';
|
|
|
|
static protected $baseDir = DIR_THEMES;
|
|
|
|
static protected $url = 'https://themes.vvveb.com';
|
|
|
|
static protected $feedUrl = 'https://themes.vvveb.com/feed/themes';
|
|
|
|
static protected $categoriesFeedUrl = 'https://themes.vvveb.com/feed/categories';
|
|
|
|
static protected $themes = [];
|
|
|
|
static protected $categories = [];
|
|
|
|
static function getInfo($content, $name = false) {
|
|
$params = parent::getInfo($content, $name);
|
|
$params['screenshot'] = PUBLIC_PATH . 'themes/' . $name . '/screenshot.png';
|
|
|
|
return $params;
|
|
}
|
|
|
|
static function clearThemesCache($site_id = SITE_ID) {
|
|
$cacheDriver = Cache :: getInstance();
|
|
$cacheKey = "themes_list_$site_id";
|
|
$cacheDriver->delete('vvveb', $cacheKey);
|
|
}
|
|
|
|
static function getList($site_id = false, $cache = true) {
|
|
$cacheDriver = Cache :: getInstance();
|
|
$cacheKey = "themes_list_$site_id";
|
|
$activeTheme = Sites::getTheme($site_id) ?? 'default';
|
|
|
|
if ($cache && $themes = $cacheDriver->get('vvveb', $cacheKey)) {
|
|
foreach ($themes as &$theme) {
|
|
$theme['active'] = ($activeTheme == $theme['folder']);
|
|
}
|
|
|
|
if (isset($themes[$activeTheme])) {
|
|
$theme = $themes[$activeTheme];
|
|
unset($themes[$activeTheme]);
|
|
$themes = [$activeTheme => $theme] + $themes;
|
|
}
|
|
|
|
return $themes;
|
|
} else {
|
|
$list = glob(DIR_ROOT . '/public/themes/*/index.html');
|
|
|
|
$themes = [];
|
|
|
|
foreach ($list as $file) {
|
|
$folder = Str::match('@/([^/]+)/[a-z]+.\w+$@', $file);
|
|
$dir = Str::match('@(.+)/[a-z]+.\w+$@', $file);
|
|
$themeConfig = $dir . DS . 'theme.php';
|
|
|
|
if ($folder == 'default') {
|
|
continue;
|
|
}
|
|
$theme = [];
|
|
$theme['file'] = $file;
|
|
$theme['folder'] = $folder;
|
|
$theme['slug'] = $folder;
|
|
$theme['import'] = false;
|
|
$theme['author'] = 'n/a';
|
|
|
|
if (file_exists($themeConfig)) {
|
|
$content = file_get_contents($themeConfig);
|
|
$theme = static::getInfo($content, $folder) + $theme;
|
|
$theme['import'] = file_exists($dir . DS . 'import');
|
|
}
|
|
|
|
$theme['name'] = $theme['name'] ?? ucfirst($theme['folder']);
|
|
$theme['screenshot'] = $theme['screenshot'] ?? (file_exists($dir . DS . 'screenshot.png') ? PUBLIC_PATH . 'themes/' . $folder . '/screenshot.png' : '/../media/extension.svg');
|
|
|
|
$themes[$folder] = $theme;
|
|
|
|
if ($theme['active'] = ($activeTheme == $theme['folder'])) {
|
|
unset($themes[$activeTheme]);
|
|
$themes = [$activeTheme => $theme] + $themes;
|
|
}
|
|
}
|
|
|
|
static :: $extensions[static :: $extension] = $themes;
|
|
|
|
if ($cache) {
|
|
$cacheDriver->set('vvveb', $cacheKey, $themes);
|
|
}
|
|
}
|
|
|
|
return $themes;
|
|
}
|
|
|
|
/*
|
|
* Add missing templates by copying from available template
|
|
*/
|
|
static function fixIfMissingTemplates($slug) {
|
|
//check templates in order
|
|
$defaultTemplate = '';
|
|
|
|
foreach (['content' . DS . 'page.html', 'blank.html', 'index.html'] as $page) {
|
|
if (file_exists(DIR_THEMES . $slug . DS . $page)) {
|
|
$defaultTemplate = $page;
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ($defaultTemplate) {
|
|
$templates = getDefaultTemplateList();
|
|
|
|
foreach ($templates as $template) {
|
|
$file = DIR_THEMES . $slug . DS . $template;
|
|
|
|
if (! file_exists($file)) {
|
|
$dir = dirname($template);
|
|
|
|
if ($dir && ! file_exists($dir)) {
|
|
@mkdir(DIR_THEMES . $slug . DS . $dir);
|
|
}
|
|
|
|
@copy(DIR_THEMES . $slug . DS . $defaultTemplate, $file);
|
|
}
|
|
}
|
|
}
|
|
|
|
//create missing folders
|
|
foreach (['backup', 'css'] as $folder) {
|
|
$dir = DIR_THEMES . $slug . DS . $folder;
|
|
if (! is_dir($dir)) {
|
|
@mkdir($dir);
|
|
}
|
|
}
|
|
|
|
//create missing files
|
|
foreach (['css' . DS . 'custom.css', 'css' . DS . 'fonts.css'] as $file) {
|
|
$path = DIR_THEMES . $slug . DS . $file;
|
|
if (! file_exists($path)) {
|
|
@touch($path);
|
|
}
|
|
}
|
|
}
|
|
|
|
static function install($extensionZipFile, $slug = false, $validate = false) {
|
|
$extension = static :: $extension;
|
|
$success = true;
|
|
$extractTo = static :: $baseDir;
|
|
$fileCheck = 'index.html';
|
|
$folder = false;
|
|
|
|
$zip = new \ZipArchive();
|
|
|
|
if ($zip->open($extensionZipFile) === true) {
|
|
$info = false;
|
|
$folderName = $zip->getNameIndex(0);
|
|
|
|
//search for top level index.html
|
|
for ($i = $zip->numFiles; ($i > 0 && $success == true); $i--) {
|
|
$file = $zip->getNameIndex($i);
|
|
|
|
if (strpos($file, $fileCheck) !== false) {
|
|
if (! $folder || strlen($file) < strlen($folder)) {
|
|
$folder = $file;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($folder) {
|
|
if ($folder == 'index.html') {
|
|
$extractTo .= DS . $slug;
|
|
}
|
|
|
|
if ($zip->extractTo($extractTo)) {
|
|
$success = $slug;
|
|
} else {
|
|
$success = false;
|
|
}
|
|
} else {
|
|
throw new \Exception(sprintf(__('No `%s` info found inside zip!'), $fileCheck));
|
|
}
|
|
|
|
$zip->close();
|
|
} else {
|
|
throw new \Exception(__('File is not a valid zip archive!'));
|
|
}
|
|
|
|
Event :: trigger(__CLASS__, __FUNCTION__, $extensionZipFile, $success);
|
|
|
|
return $success;
|
|
}
|
|
}
|