Finish basic theme utilities: properties, import/export, duplicate, delete

This commit is contained in:
Samuel Georges 2015-03-16 19:00:39 +11:00
parent 9b8e1ce3c1
commit 77d3ab8b67
18 changed files with 855 additions and 19 deletions

View File

@ -317,7 +317,8 @@ class Controller extends Extendable
// Execute the action
$result = call_user_func_array([$this, $actionName], $parameters);
if ($result instanceof RedirectResponse) {
// Expecting \Response and \RedirectResponse
if ($result instanceof \Symfony\Component\HttpFoundation\Response) {
return $result;
}
@ -402,10 +403,10 @@ class Controller extends Extendable
*/
if ($result instanceof RedirectResponse) {
$responseContents['X_OCTOBER_REDIRECT'] = $result->getTargetUrl();
}
/*
* No redirect is used, look for any flash messages
*/
}
elseif (Flash::check()) {
$responseContents['#layout-flash-messages'] = $this->makeLayoutPartial('flash_messages');
}

View File

@ -95,6 +95,10 @@
.theme-selector-layout .layout-row.links .theme-description {
border-bottom: 1px solid #f2f3f4;
}
.theme-selector-layout .create-new-theme {
margin-bottom: 10px;
}
.theme-selector-layout .create-new-theme,
.theme-selector-layout .find-more-themes {
background: #ecf0f1;
color: #2b3e50;
@ -105,6 +109,7 @@
-moz-border-radius: 4px;
border-radius: 4px;
}
.theme-selector-layout .create-new-theme:hover,
.theme-selector-layout .find-more-themes:hover {
background: #1795f1;
color: white;

View File

@ -112,6 +112,11 @@
}
}
.create-new-theme {
margin-bottom: 10px;
}
.create-new-theme,
.find-more-themes {
background: #ecf0f1;
color: #2b3e50;

View File

@ -287,7 +287,7 @@ class Theme
public function writeConfig($values = [], $overwrite = false)
{
if (!$overwrite) {
$values = $values + $this->getConfig();
$values = $values + (array) $this->getConfig();
}
$path = $this->getPath().'/theme.yaml';

View File

@ -10,10 +10,18 @@ tabs:
label: Name
placeholder: New theme name
span: auto
required: true
attributes:
default-focus: 1
directory_name:
dir_name@create:
label: Directory name
span: auto
placeholder: The destination theme directory
preset: name
required: true
dir_name@update:
label: Directory name
disabled: true
span: auto

View File

@ -1,15 +1,20 @@
<?php namespace Cms\Controllers;
use File;
use Yaml;
use Flash;
use Config;
use Backend;
use Redirect;
use BackendMenu;
use ValidationException;
use ApplicationException;
use Cms\Models\ThemeData;
use Backend\Classes\Controller;
use Cms\Models\ThemeExport;
use Cms\Models\ThemeImport;
use Cms\Classes\Theme as CmsTheme;
use System\Classes\SettingsManager;
use Backend\Classes\Controller;
use Exception;
/**
@ -41,6 +46,13 @@ class Themes extends Controller
$this->pageTitle = 'cms::lang.theme.settings_menu';
BackendMenu::setContext('October.System', 'system', 'settings');
SettingsManager::setContext('October.Cms', 'theme');
/*
* Enable AJAX for Form widgets
*/
if (post('mode') == 'import') {
$this->makeImportFormWidget($this->findThemeObject())->bindToController();
}
}
public function index()
@ -57,41 +69,153 @@ class Themes extends Controller
];
}
public function index_onDelete()
{
$theme = $this->findThemeObject();
if ($theme->isActiveTheme()) {
throw new ApplicationException('Cannot delete the active theme, try making another theme active first.');
}
$themePath = $theme->getPath();
if (File::isDirectory($themePath)) {
File::deleteDirectory($themePath);
}
Flash::success('Deleted theme successfully!');
return Redirect::refresh();
}
//
// Theme properties
//
public function index_onLoadThemeFieldsForm()
public function index_onLoadFieldsForm()
{
$theme = $this->findThemeObject();
$this->vars['widget'] = $this->makeThemeFieldsFormWidget($theme);
$this->vars['widget'] = $this->makeFieldsFormWidget($theme);
$this->vars['themeDir'] = $theme->getDirName();
return $this->makePartial('theme_fields_form');
}
public function index_onSaveThemeFields()
public function index_onSaveFields()
{
$theme = $this->findThemeObject();
$widget = $this->makeThemeFieldsFormWidget($theme);
$widget = $this->makeFieldsFormWidget($theme);
$theme->writeConfig($widget->getSaveData());
return ['#themeListItem-'.$theme->getId() => $this->makePartial('theme_list_item', ['theme' => $theme])];
}
protected function makeThemeFieldsFormWidget($theme)
protected function makeFieldsFormWidget($theme)
{
$widgetConfig = $this->makeConfig('~/modules/cms/classes/theme/fields.yaml');
$widgetConfig->alias = 'form'.studly_case($theme->getDirName());
$widgetConfig->model = $theme;
$widgetConfig->data = $theme->getConfig();
$widgetConfig->data['directory_name'] = $theme->getDirName();
$widgetConfig->data['dir_name'] = $theme->getDirName();
$widgetConfig->arrayName = 'Theme';
$widgetConfig->context = 'update';
$widget = $this->makeWidget('Backend\Widgets\Form', $widgetConfig);
return $widget;
}
//
// Create theme
//
public function index_onLoadCreateForm()
{
$this->vars['widget'] = $this->makeCreateFormWidget();
return $this->makePartial('theme_create_form');
}
public function index_onCreate()
{
$widget = $this->makeCreateFormWidget();
$data = $widget->getSaveData();
$newDirName = trim(array_get($data, 'dir_name'));
$destinationPath = themes_path().'/'.$newDirName;
$data = array_except($data, 'dir_name');
if (!strlen(trim(array_get($data, 'name')))) {
throw new ValidationException(['name' => 'Please specify a name for the theme.']);
}
if (!preg_match('/^[a-z0-9\_\-]+$/i', $newDirName)) {
throw new ValidationException(['dir_name' => 'Name can contain only digits, Latin letters and the following symbols: _-']);
}
if (File::isDirectory($destinationPath)) {
throw new ValidationException(['dir_name' => 'Desired theme directory already exists.']);
}
File::makeDirectory($destinationPath);
File::makeDirectory($destinationPath.'/assets');
File::makeDirectory($destinationPath.'/content');
File::makeDirectory($destinationPath.'/layouts');
File::makeDirectory($destinationPath.'/pages');
File::makeDirectory($destinationPath.'/partials');
File::put($destinationPath.'/theme.yaml', '');
$theme = CmsTheme::load($newDirName);
$theme->writeConfig($data);
Flash::success('Created theme successfully!');
return Redirect::refresh();
}
protected function makeCreateFormWidget()
{
$widgetConfig = $this->makeConfig('~/modules/cms/classes/theme/fields.yaml');
$widgetConfig->alias = 'formCreateTheme';
$widgetConfig->model = new CmsTheme;
$widgetConfig->arrayName = 'Theme';
$widgetConfig->context = 'create';
$widget = $this->makeWidget('Backend\Widgets\Form', $widgetConfig);
return $widget;
}
//
// Duplicate
//
public function index_onLoadDuplicateForm()
{
$theme = $this->findThemeObject();
$this->vars['themeDir'] = $theme->getDirName();
return $this->makePartial('theme_duplicate_form');
}
public function index_onDuplicateTheme()
{
$theme = $this->findThemeObject();
$newDirName = trim(post('new_dir_name'));
$sourcePath = $theme->getPath();
$destinationPath = themes_path().'/'.$newDirName;
if (!preg_match('/^[a-z0-9\_\-]+$/i', $newDirName)) {
throw new ValidationException(['new_dir_name' => 'Name can contain only digits, Latin letters and the following symbols: _-']);
}
if (File::isDirectory($destinationPath)) {
throw new ValidationException(['new_dir_name' => 'Duplicate theme directory already exists.']);
}
File::copyDirectory($sourcePath, $destinationPath);
$newTheme = CmsTheme::load($newDirName);
$newName = $newTheme->getConfigValue('name') . ' - Copy';
$newTheme->writeConfig(['name' => $newName]);
Flash::success('Duplicated theme successfully!');
return Redirect::refresh();
}
//
// Theme customization
//
@ -149,6 +273,90 @@ class Themes extends Controller
}
}
//
// Theme export
//
public function index_onLoadExportForm()
{
$theme = $this->findThemeObject();
$this->vars['widget'] = $this->makeExportFormWidget($theme);
$this->vars['themeDir'] = $theme->getDirName();
return $this->makePartial('theme_export_form');
}
public function index_onExport()
{
$theme = $this->findThemeObject();
$widget = $this->makeExportFormWidget($theme);
$model = new ThemeExport;
$file = $model->export($theme, $widget->getSaveData());
return Backend::redirect('cms/themes/download/'.$file.'/'.$theme->getDirName().'.zip');
}
public function download($name, $outputName = null)
{
try {
$this->pageTitle = 'Download theme export archive';
return ThemeExport::download($name, $outputName);
}
catch (Exception $ex) {
$this->handleError($ex);
}
}
protected function makeExportFormWidget($theme)
{
$widgetConfig = $this->makeConfig('~/modules/cms/models/themeexport/fields.yaml');
$widgetConfig->alias = 'form'.studly_case($theme->getDirName());
$widgetConfig->model = new ThemeExport;
$widgetConfig->model->theme = $theme;
$widgetConfig->arrayName = 'ThemeExport';
$widget = $this->makeWidget('Backend\Widgets\Form', $widgetConfig);
return $widget;
}
//
// Theme import
//
public function index_onLoadImportForm()
{
$theme = $this->findThemeObject();
$this->vars['widget'] = $this->makeImportFormWidget($theme);
$this->vars['themeDir'] = $theme->getDirName();
return $this->makePartial('theme_import_form');
}
public function index_onImport()
{
$theme = $this->findThemeObject();
$widget = $this->makeImportFormWidget($theme);
$model = new ThemeImport;
$model->import($theme, $widget->getSaveData(), $widget->getSessionKey());
Flash::success('Imported theme successfully!');
return Redirect::refresh();
}
protected function makeImportFormWidget($theme)
{
$widgetConfig = $this->makeConfig('~/modules/cms/models/themeimport/fields.yaml');
$widgetConfig->alias = 'form'.studly_case($theme->getDirName());
$widgetConfig->model = new ThemeImport;
$widgetConfig->model->theme = $theme;
$widgetConfig->arrayName = 'ThemeImport';
$widget = $this->makeWidget('Backend\Widgets\Form', $widgetConfig);
return $widget;
}
//
// Helpers
//

View File

@ -0,0 +1,54 @@
<?= Form::ajax('onCreate', [
'id' => 'themeCreateForm',
'data-popup-load-indicator' => true
]) ?>
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title">Create theme</h4>
</div>
<?php if (!$this->fatalError): ?>
<div class="modal-body">
<?= $widget->render() ?>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-primary">
Create
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
<?php else: ?>
<div class="modal-body">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.close')) ?>
</button>
</div>
<?php endif ?>
<script>
setTimeout(
function(){ $('#themeCreateForm input.form-control:first').focus() },
310
)
</script>
<?= Form::close() ?>

View File

@ -0,0 +1,75 @@
<?= Form::ajax('onDuplicateTheme', [
'id' => 'themeDuplicateForm',
'data-popup-load-indicator' => true,
]) ?>
<input type="hidden" name="theme" value="<?= $themeDir ?>" />
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title">Duplicate theme: <?= $themeDir ?></h4>
</div>
<?php if (!$this->fatalError): ?>
<div class="modal-body">
<div class="form-group text-field span-full">
<label for="Form-ThemeDuplicate-newDirName">
Theme directory
</label>
<input
type="text"
name="new_dir_name"
id="Form-ThemeDuplicate-newDirName"
value="<?= $themeDir ?>"
placeholder=""
class="form-control"
autocomplete="off"
maxlength="255" />
<p class="help-block">
Provide a new directory name for the duplicated theme.
</p>
</div>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-success">
Duplicate
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
<?php else: ?>
<div class="modal-body">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.close')) ?>
</button>
</div>
<?php endif ?>
<script>
setTimeout(
function(){ $('#themeDuplicateForm input.form-control:first').focus() },
310
)
</script>
<?= Form::close() ?>

View File

@ -0,0 +1,63 @@
<?= Form::ajax('onExport', [
'id' => 'themeExportForm',
'data-popup-load-indicator' => true,
'data-request-success' => 'closeExportThemePopup()'
]) ?>
<input type="hidden" name="theme" value="<?= $themeDir ?>" />
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title">Export theme</h4>
</div>
<?php if (!$this->fatalError): ?>
<div class="modal-body">
<?= $widget->render() ?>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-success">
Export
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
<?php else: ?>
<div class="modal-body">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.close')) ?>
</button>
</div>
<?php endif ?>
<script>
setTimeout(
function(){ $('#themeExportForm input.form-control:first').focus() },
310
)
function closeExportThemePopup() {
$('#themeExportForm')
.closest('.control-popup')
.popup('hideLoading')
}
</script>
<?= Form::close() ?>

View File

@ -1,4 +1,4 @@
<?= Form::ajax('onSaveThemeFields', [
<?= Form::ajax('onSaveFields', [
'id' => 'themeFieldsForm',
'data-popup-load-indicator' => true
]) ?>

View File

@ -0,0 +1,57 @@
<?= Form::ajax('onImport', [
'id' => 'themeImportForm',
'data-popup-load-indicator' => true,
]) ?>
<input type="hidden" name="theme" value="<?= $themeDir ?>" />
<input type="hidden" name="mode" value="import" />
<div class="modal-header">
<button type="button" class="close" data-dismiss="popup">&times;</button>
<h4 class="modal-title">Import theme</h4>
</div>
<?php if (!$this->fatalError): ?>
<div class="modal-body">
<?= $widget->render() ?>
</div>
<div class="modal-footer">
<button
type="submit"
class="btn btn-success">
Import
</button>
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.cancel')) ?>
</button>
</div>
<?php else: ?>
<div class="modal-body">
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-default"
data-dismiss="popup">
<?= e(trans('backend::lang.form.close')) ?>
</button>
</div>
<?php endif ?>
<script>
setTimeout(
function(){ $('#themeImportForm input.form-control:first').focus() },
310
)
</script>
<?= Form::close() ?>

View File

@ -14,6 +14,15 @@
<!-- Spacer -->
</div>
<div class="layout-cell theme-description">
<a
class="create-new-theme"
data-control="popup"
data-handler="onLoadCreateForm"
data-size="huge"
href="javascript:;"
target="_blank">
Create a new blank theme
</a>
<a
class="find-more-themes"
href="http://octobercms.com/themes"

View File

@ -56,30 +56,47 @@
tabindex="-1"
data-control="popup"
data-size="huge"
data-handler="onLoadThemeFieldsForm"
data-handler="onLoadFieldsForm"
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
href="javascript:;"
class="oc-icon-pencil">
Edit properties
</a>
</li>
<!--
<li role="presentation">
<a
role="menuitem"
tabindex="-1"
data-control="popup"
data-handler="onLoadDuplicateForm"
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
href="javascript:;"
class="oc-icon-download">
Download
class="oc-icon-copy">
Duplicate
</a>
</li>
<li role="presentation">
<a
role="menuitem"
tabindex="-1"
data-control="popup"
data-handler="onLoadImportForm"
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
href="javascript:;"
class="oc-icon-copy">
Duplicate
class="oc-icon-upload">
Import
</a>
</li>
<li role="presentation">
<a
role="menuitem"
tabindex="-1"
data-control="popup"
data-handler="onLoadExportForm"
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
href="javascript:;"
class="oc-icon-download">
Export
</a>
</li>
<li role="presentation" class="divider"></li>
@ -87,12 +104,14 @@
<a
role="menuitem"
tabindex="-1"
data-request="onDelete"
data-request-confirm="Are you sure you want to delete this theme? It cannot be undone!"
data-request-data="theme: '<?= e($theme->getDirName()) ?>'"
href="javascript:;"
class="oc-icon-trash">
Delete
</a>
</li>
-->
</ul>
</div>
</div>

View File

@ -0,0 +1,13 @@
<?php Block::put('breadcrumb') ?>
<ul>
<li><a href="<?= Backend::url('cms/themes') ?>">Themes</a></li>
<li><?= e(trans($this->pageTitle)) ?></li>
</ul>
<?php Block::endPut() ?>
<?php if ($this->fatalError): ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
<p><a href="<?= Backend::url('cms/themes') ?>" class="btn btn-default">Return to themes list</a></p>
<?php endif ?>

View File

@ -0,0 +1,141 @@
<?php namespace Cms\Models;
use File;
use Lang;
use Model;
use Response;
use ApplicationException;
use October\Rain\Filesystem\Zip;
use Cms\Classes\Theme as CmsTheme;
use Exception;
/**
* Theme export model
*
* @package october\cms
* @author Alexey Bobkov, Samuel Georges
*/
class ThemeExport extends Model
{
use \October\Rain\Database\Traits\Validation;
/**
* @var string The database table used by the model.
*/
public $table = 'cms_theme_data';
/**
* @var array The rules to be applied to the data.
*/
public $rules = [];
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array Fillable fields
*/
protected $fillable = [];
/**
* @var array Make the model's attributes public so behaviors can modify them.
*/
public $attributes = [
'theme' => null,
'themeName' => null,
'dirName' => null,
'folders' => [
'assets' => true,
'pages' => true,
'layouts' => true,
'partials' => true,
'content' => true,
]
];
public function getFoldersOptions()
{
return [
'assets' => 'Assets',
'pages' => 'Pages',
'layouts' => 'Layouts',
'partials' => 'Partials',
'content' => 'Content',
];
}
public function setThemeAttribute($theme)
{
if (!$theme instanceof CmsTheme) return;
$this->attributes['themeName'] = $theme->getConfigValue('name', $theme->getDirName());
$this->attributes['dirName'] = $theme->getDirName();
$this->attributes['theme'] = $theme;
}
public function export($theme, $data = [])
{
$this->theme = $theme;
$this->fill($data);
try {
$themePath = $this->theme->getPath();
$tempPath = temp_path() . '/'.uniqid('oc');
$zipName = uniqid('oc');
$zipPath = temp_path().'/'.$zipName;
if (!@mkdir($tempPath))
throw new ApplicationException('Unable to create directory '.$tempPath);
if (!@mkdir($metaPath = $tempPath . '/meta'))
throw new ApplicationException('Unable to create directory '.$metaPath);
File::copy($themePath.'/theme.yaml', $tempPath.'/theme.yaml');
File::copyDirectory($themePath.'/meta', $metaPath);
foreach ($this->folders as $folder) {
if (!array_key_exists($folder, $this->getFoldersOptions())) continue;
File::copyDirectory($themePath.'/'.$folder, $tempPath.'/'.$folder);
}
Zip::make($zipPath, $tempPath);
File::deleteDirectory($tempPath);
}
catch (Exception $ex) {
if (strlen($tempPath) && File::isDirectory($tempPath)) {
File::deleteDirectory($tempPath);
}
if (strlen($zipPath) && File::isFile($zipPath)) {
File::delete($zipPath);
}
throw $ex;
}
return $zipName;
}
public static function download($name, $outputName = null)
{
if (!preg_match('/^oc[0-9a-z]*$/i', $name)) {
throw new ApplicationException('File not found');
}
$zipPath = temp_path() . '/' . $name;
if (!file_exists($zipPath)) {
throw new ApplicationException('File not found');
}
$headers = Response::download($zipPath, $outputName)->headers->all();
$result = Response::make(File::get($zipPath), 200, $headers);
@unlink($zipPath);
return $result;
}
}

View File

@ -0,0 +1,139 @@
<?php namespace Cms\Models;
use File;
use Lang;
use Model;
use ApplicationException;
use October\Rain\Filesystem\Zip;
use Cms\Classes\Theme as CmsTheme;
use Exception;
/**
* Theme import model
*
* @package october\cms
* @author Alexey Bobkov, Samuel Georges
*/
class ThemeImport extends Model
{
use \October\Rain\Database\Traits\Validation;
/**
* @var string The database table used by the model.
*/
public $table = 'cms_theme_data';
/**
* @var array The rules to be applied to the data.
*/
public $rules = [];
/**
* @var array Guarded fields
*/
protected $guarded = [];
/**
* @var array Fillable fields
*/
protected $fillable = [];
public $attachOne = [
'uploaded_file' => ['System\Models\File']
];
/**
* @var array Make the model's attributes public so behaviors can modify them.
*/
public $attributes = [
'theme' => null,
'themeName' => null,
'dirName' => null,
'overwrite' => true,
'folders' => [
'assets' => true,
'pages' => true,
'layouts' => true,
'partials' => true,
'content' => true,
]
];
public function getFoldersOptions()
{
return [
'assets' => 'Assets',
'pages' => 'Pages',
'layouts' => 'Layouts',
'partials' => 'Partials',
'content' => 'Content',
];
}
public function setThemeAttribute($theme)
{
if (!$theme instanceof CmsTheme) return;
$this->attributes['themeName'] = $theme->getConfigValue('name', $theme->getDirName());
$this->attributes['dirName'] = $theme->getDirName();
$this->attributes['theme'] = $theme;
}
public function import($theme, $data = [], $sessionKey = null)
{
@set_time_limit(3600);
$this->theme = $theme;
$this->fill($data);
try
{
$file = $this->uploaded_file()->withDeferred($sessionKey)->first();
if (!$file) {
throw new ApplicationException('There is no file attached to import!');
}
$themePath = $this->theme->getPath();
$tempPath = temp_path() . '/'.uniqid('oc');
$zipName = uniqid('oc');
$zipPath = temp_path().'/'.$zipName;
File::put($zipPath, $file->getContents());
if (!@mkdir($tempPath))
throw new ApplicationException('Unable to create directory '.$tempPath);
Zip::extract($zipPath, $tempPath);
// if (File::isFile($tempPath.'/theme.yaml')) {
// File::copy($tempPath.'/theme.yaml', $themePath.'/theme.yaml');
// }
if (File::isDirectory($tempPath.'/meta')) {
File::copyDirectory($tempPath.'/meta', $themePath.'/meta');
}
foreach ($this->folders as $folder) {
if (!array_key_exists($folder, $this->getFoldersOptions())) continue;
File::copyDirectory($tempPath.'/'.$folder, $themePath.'/'.$folder);
}
File::deleteDirectory($tempPath);
File::delete($zipPath);
$file->delete();
}
catch (Exception $ex) {
if (!empty($tempPath) && File::isDirectory($tempPath)) {
File::deleteDirectory($tempPath);
}
if (!empty($zipPath) && File::isFile($zipPath)) {
File::delete($zipPath);
}
throw $ex;
}
}
}

View File

@ -0,0 +1,14 @@
# ===================================
# Field Definitions
# ===================================
fields:
themeName:
label: Theme
disabled: true
folders:
label: Folders
commentAbove: Please select the theme folders you would like to export
type: checkboxlist

View File

@ -0,0 +1,25 @@
# ===================================
# Field Definitions
# ===================================
fields:
themeName:
label: Theme
disabled: true
uploaded_file:
label: Theme archive file
type: fileupload
mode: file
fileTypes: zip
overwrite:
label: Overwrite existing files
comment: Untick this box to only import new files
type: checkbox
folders:
label: Folders
commentAbove: Please select the theme folders you would like to import
type: checkboxlist