feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
- Base: wintercms/winter branch 1.2 (full framework) - Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS - Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication - Partials: hero (offline-first), features, modes (offline/nube toggle), screenshots, pricing (3 planes), comparison, FAQ, CTA - Plugin VivesPOS.Site with ContactForm - Dockerfile: PHP 8.2 Apache, port 80, healthcheck - Added winter/wn-pages, blog, sitemap, seo plugins - Active theme set to vivespos
This commit is contained in:
89
modules/system/controllers/EventLogs.php
Normal file
89
modules/system/controllers/EventLogs.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php namespace System\Controllers;
|
||||
|
||||
use App;
|
||||
use Lang;
|
||||
use Flash;
|
||||
use BackendMenu;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Classes\SettingsManager;
|
||||
use System\Models\EventLog;
|
||||
|
||||
/**
|
||||
* Event Logs controller
|
||||
*
|
||||
* @package winter\wn-system-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class EventLogs extends Controller
|
||||
{
|
||||
/**
|
||||
* @var array Extensions implemented by this controller.
|
||||
*/
|
||||
public $implement = [
|
||||
\Backend\Behaviors\FormController::class,
|
||||
\Backend\Behaviors\ListController::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array Permissions required to view this page.
|
||||
*/
|
||||
public $requiredPermissions = ['system.access_logs'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
BackendMenu::setContext('Winter.System', 'system', 'settings');
|
||||
SettingsManager::setContext('Winter.System', 'event_logs');
|
||||
}
|
||||
|
||||
public function index_onRefresh()
|
||||
{
|
||||
return $this->listRefresh();
|
||||
}
|
||||
|
||||
public function index_onEmptyLog()
|
||||
{
|
||||
EventLog::truncate();
|
||||
Flash::success(Lang::get('system::lang.event_log.empty_success'));
|
||||
return $this->listRefresh();
|
||||
}
|
||||
|
||||
public function index_onDelete()
|
||||
{
|
||||
if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {
|
||||
foreach ($checkedIds as $recordId) {
|
||||
if (!$record = EventLog::find($recordId)) {
|
||||
continue;
|
||||
}
|
||||
$record->delete();
|
||||
}
|
||||
|
||||
Flash::success(Lang::get('backend::lang.list.delete_selected_success'));
|
||||
}
|
||||
else {
|
||||
Flash::error(Lang::get('backend::lang.list.delete_selected_empty'));
|
||||
}
|
||||
|
||||
return $this->listRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview page action
|
||||
* @return void
|
||||
*/
|
||||
public function preview($id)
|
||||
{
|
||||
$this->addCss('/modules/system/assets/css/eventlogs/exception-beautifier.css', 'core');
|
||||
$this->addJs('/modules/system/assets/js/eventlogs/exception-beautifier.js', 'core');
|
||||
|
||||
if (in_array(App::environment(), ['dev', 'local'])) {
|
||||
$this->addJs('/modules/system/assets/js/eventlogs/exception-beautifier.links.js', 'core');
|
||||
}
|
||||
|
||||
return $this->asExtension('FormController')->preview($id);
|
||||
}
|
||||
}
|
||||
115
modules/system/controllers/MailBrandSettings.php
Normal file
115
modules/system/controllers/MailBrandSettings.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php namespace System\Controllers;
|
||||
|
||||
use Lang;
|
||||
use File;
|
||||
use Flash;
|
||||
use Config;
|
||||
use Redirect;
|
||||
use BackendMenu;
|
||||
use System\Models\MailBrandSetting;
|
||||
use System\Classes\SettingsManager;
|
||||
use System\Classes\MailManager;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Models\MailLayout;
|
||||
use System\Models\MailTemplate;
|
||||
|
||||
/**
|
||||
* Mail brand customization controller
|
||||
*
|
||||
* @package winter\wn-backend-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*
|
||||
*/
|
||||
class MailBrandSettings extends Controller
|
||||
{
|
||||
/**
|
||||
* @var array Extensions implemented by this controller.
|
||||
*/
|
||||
public $implement = [
|
||||
\Backend\Behaviors\FormController::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array Permissions required to view this page.
|
||||
*/
|
||||
public $requiredPermissions = ['system.manage_mail_templates'];
|
||||
|
||||
/**
|
||||
* @var string HTML body tag class
|
||||
*/
|
||||
public $bodyClass = 'compact-container';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->pageTitle = 'system::lang.mail_brand.page_title';
|
||||
|
||||
BackendMenu::setContext('Winter.System', 'system', 'settings');
|
||||
SettingsManager::setContext('Winter.System', 'mail_brand_settings');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->addJs('/modules/system/assets/js/mailbrandsettings/mailbrandsettings.js', 'core');
|
||||
|
||||
$setting = MailBrandSetting::instance();
|
||||
|
||||
$setting->resetCache();
|
||||
|
||||
return $this->create();
|
||||
}
|
||||
|
||||
public function index_onSave()
|
||||
{
|
||||
$setting = MailBrandSetting::instance();
|
||||
|
||||
return $this->create_onSave();
|
||||
}
|
||||
|
||||
public function index_onResetDefault()
|
||||
{
|
||||
$setting = MailBrandSetting::instance();
|
||||
|
||||
$setting->resetDefault();
|
||||
|
||||
Flash::success(Lang::get('backend::lang.form.reset_success'));
|
||||
|
||||
return Redirect::refresh();
|
||||
}
|
||||
|
||||
public function onUpdateSampleMessage()
|
||||
{
|
||||
$this->pageAction();
|
||||
|
||||
$this->formGetWidget()->setFormValues();
|
||||
|
||||
return ['previewHtml' => $this->renderSampleMessage()];
|
||||
}
|
||||
|
||||
public function renderSampleMessage()
|
||||
{
|
||||
$data = [
|
||||
'subject' => Config::get('app.name'),
|
||||
'appName' => Config::get('app.name'),
|
||||
'texts' => Lang::get('system::lang.mail_brand.sample_template')
|
||||
];
|
||||
|
||||
$layout = new MailLayout;
|
||||
$layout->fillFromCode('default');
|
||||
|
||||
$template = new MailTemplate;
|
||||
$template->layout = $layout;
|
||||
$template->content_html = File::get(base_path('modules/system/models/mailbrandsetting/sample_template.php'));
|
||||
|
||||
return MailManager::instance()->renderTemplate($template, $data);
|
||||
}
|
||||
|
||||
public function formCreateModelObject()
|
||||
{
|
||||
return MailBrandSetting::instance();
|
||||
}
|
||||
}
|
||||
52
modules/system/controllers/MailLayouts.php
Normal file
52
modules/system/controllers/MailLayouts.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php namespace System\Controllers;
|
||||
|
||||
use Lang;
|
||||
use Flash;
|
||||
use Redirect;
|
||||
use BackendMenu;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Classes\SettingsManager;
|
||||
|
||||
/**
|
||||
* Mail layouts controller
|
||||
*
|
||||
* @package winter\wn-system-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class MailLayouts extends Controller
|
||||
{
|
||||
/**
|
||||
* @var array Extensions implemented by this controller.
|
||||
*/
|
||||
public $implement = [
|
||||
\Backend\Behaviors\FormController::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array Permissions required to view this page.
|
||||
*/
|
||||
public $requiredPermissions = ['system.manage_mail_templates'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
BackendMenu::setContext('Winter.System', 'system', 'settings');
|
||||
SettingsManager::setContext('Winter.System', 'mail_templates');
|
||||
}
|
||||
|
||||
public function update_onResetDefault($recordId)
|
||||
{
|
||||
$model = $this->formFindModelObject($recordId);
|
||||
|
||||
$model->fillFromCode();
|
||||
$model->save();
|
||||
|
||||
Flash::success(Lang::get('backend::lang.form.reset_success'));
|
||||
|
||||
return Redirect::refresh();
|
||||
}
|
||||
}
|
||||
42
modules/system/controllers/MailPartials.php
Normal file
42
modules/system/controllers/MailPartials.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php namespace System\Controllers;
|
||||
|
||||
use BackendMenu;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Classes\SettingsManager;
|
||||
|
||||
/**
|
||||
* Mail partials controller
|
||||
*
|
||||
* @package winter\wn-system-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class MailPartials extends Controller
|
||||
{
|
||||
/**
|
||||
* @var array Extensions implemented by this controller.
|
||||
*/
|
||||
public $implement = [
|
||||
\Backend\Behaviors\FormController::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array Permissions required to view this page.
|
||||
*/
|
||||
public $requiredPermissions = ['system.manage_mail_templates'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
BackendMenu::setContext('Winter.System', 'system', 'settings');
|
||||
SettingsManager::setContext('Winter.System', 'mail_templates');
|
||||
}
|
||||
|
||||
public function formBeforeSave($model)
|
||||
{
|
||||
$model->is_custom = 1;
|
||||
}
|
||||
}
|
||||
80
modules/system/controllers/MailTemplates.php
Normal file
80
modules/system/controllers/MailTemplates.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php namespace System\Controllers;
|
||||
|
||||
use Mail;
|
||||
use Flash;
|
||||
use BackendMenu;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Models\MailTemplate;
|
||||
use System\Classes\SettingsManager;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Mail templates controller
|
||||
*
|
||||
* @package winter\wn-system-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class MailTemplates extends Controller
|
||||
{
|
||||
/**
|
||||
* @var array Extensions implemented by this controller.
|
||||
*/
|
||||
public $implement = [
|
||||
\Backend\Behaviors\FormController::class,
|
||||
\Backend\Behaviors\ListController::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array `ListController` configuration.
|
||||
*/
|
||||
public $listConfig = [
|
||||
'templates' => 'config_templates_list.yaml',
|
||||
'layouts' => 'config_layouts_list.yaml',
|
||||
'partials' => 'config_partials_list.yaml'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array Permissions required to view this page.
|
||||
*/
|
||||
public $requiredPermissions = ['system.manage_mail_templates'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
BackendMenu::setContext('Winter.System', 'system', 'settings');
|
||||
SettingsManager::setContext('Winter.System', 'mail_templates');
|
||||
}
|
||||
|
||||
public function index($tab = null)
|
||||
{
|
||||
MailTemplate::syncAll();
|
||||
$this->asExtension('ListController')->index();
|
||||
$this->bodyClass = 'compact-container';
|
||||
|
||||
$this->vars['activeTab'] = $tab ?: 'templates';
|
||||
}
|
||||
|
||||
public function formBeforeSave($model)
|
||||
{
|
||||
$model->is_custom = 1;
|
||||
}
|
||||
|
||||
public function onTest($recordId)
|
||||
{
|
||||
try {
|
||||
$model = $this->formFindModelObject($recordId);
|
||||
$user = $this->user;
|
||||
|
||||
Mail::sendTo([$user->email => $user->full_name], $model->code);
|
||||
|
||||
Flash::success(trans('system::lang.mail_templates.test_success'));
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
Flash::error($ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
72
modules/system/controllers/RequestLogs.php
Normal file
72
modules/system/controllers/RequestLogs.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php namespace System\Controllers;
|
||||
|
||||
use Lang;
|
||||
use Flash;
|
||||
use BackendMenu;
|
||||
use Backend\Classes\Controller;
|
||||
use System\Classes\SettingsManager;
|
||||
use System\Models\RequestLog;
|
||||
|
||||
/**
|
||||
* Request Logs controller
|
||||
*
|
||||
* @package winter\wn-system-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class RequestLogs extends Controller
|
||||
{
|
||||
/**
|
||||
* @var array Extensions implemented by this controller.
|
||||
*/
|
||||
public $implement = [
|
||||
\Backend\Behaviors\FormController::class,
|
||||
\Backend\Behaviors\ListController::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array Permissions required to view this page.
|
||||
*/
|
||||
public $requiredPermissions = ['system.access_logs'];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
BackendMenu::setContext('Winter.System', 'system', 'settings');
|
||||
SettingsManager::setContext('Winter.System', 'request_logs');
|
||||
}
|
||||
|
||||
public function index_onRefresh()
|
||||
{
|
||||
return $this->listRefresh();
|
||||
}
|
||||
|
||||
public function index_onEmptyLog()
|
||||
{
|
||||
RequestLog::truncate();
|
||||
Flash::success(Lang::get('system::lang.request_log.empty_success'));
|
||||
return $this->listRefresh();
|
||||
}
|
||||
|
||||
public function index_onDelete()
|
||||
{
|
||||
if (($checkedIds = post('checked')) && is_array($checkedIds) && count($checkedIds)) {
|
||||
foreach ($checkedIds as $recordId) {
|
||||
if (!$record = RequestLog::find($recordId)) {
|
||||
continue;
|
||||
}
|
||||
$record->delete();
|
||||
}
|
||||
|
||||
Flash::success(Lang::get('backend::lang.list.delete_selected_success'));
|
||||
}
|
||||
else {
|
||||
Flash::error(Lang::get('backend::lang.list.delete_selected_empty'));
|
||||
}
|
||||
|
||||
return $this->listRefresh();
|
||||
}
|
||||
}
|
||||
262
modules/system/controllers/Settings.php
Normal file
262
modules/system/controllers/Settings.php
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php namespace System\Controllers;
|
||||
|
||||
use Mail;
|
||||
use Lang;
|
||||
use Flash;
|
||||
use Config;
|
||||
use Request;
|
||||
use Backend;
|
||||
use BackendMenu;
|
||||
use System\Classes\SettingsManager;
|
||||
use System\Behaviors\SettingsModel;
|
||||
use Backend\Classes\Controller;
|
||||
use ApplicationException;
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Settings controller
|
||||
*
|
||||
* @package winter\wn-system-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*
|
||||
*/
|
||||
class Settings extends Controller
|
||||
{
|
||||
/**
|
||||
* @var WidgetBase Reference to the widget object.
|
||||
*/
|
||||
protected $formWidget;
|
||||
|
||||
/**
|
||||
* @var array Permissions required to view this page.
|
||||
*/
|
||||
public $requiredPermissions = [];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if ($this->action == 'backend_preferences') {
|
||||
$this->requiredPermissions = ['backend.manage_preferences'];
|
||||
}
|
||||
|
||||
$this->addCss('/modules/system/assets/css/settings/settings.css', 'core');
|
||||
|
||||
BackendMenu::setContext('Winter.System', 'system', 'settings');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->pageTitle = 'system::lang.settings.menu_label';
|
||||
$this->vars['items'] = SettingsManager::instance()->listItems('system');
|
||||
$this->bodyClass = 'compact-container sidenav-tree-root';
|
||||
}
|
||||
|
||||
public function mysettings()
|
||||
{
|
||||
BackendMenu::setContextSideMenu('mysettings');
|
||||
$this->pageTitle = 'backend::lang.mysettings.menu_label';
|
||||
$this->vars['items'] = SettingsManager::instance()->listItems('mysettings');
|
||||
$this->bodyClass = 'compact-container';
|
||||
}
|
||||
|
||||
//
|
||||
// Generated Form
|
||||
//
|
||||
|
||||
public function update($author, $plugin, $code = null)
|
||||
{
|
||||
SettingsManager::setContext($author.'.'.$plugin, $code);
|
||||
|
||||
$this->vars['parentLink'] = Backend::url('system/settings');
|
||||
$this->vars['parentLabel'] = Lang::get('system::lang.settings.menu_label');
|
||||
|
||||
try {
|
||||
if (!$item = $this->findSettingItem($author, $plugin, $code)) {
|
||||
throw new ApplicationException(Lang::get('system::lang.settings.not_found'));
|
||||
}
|
||||
|
||||
$this->pageTitle = $item->label;
|
||||
|
||||
if ($item->context == 'mysettings') {
|
||||
$this->vars['parentLink'] = Backend::url('system/settings/mysettings');
|
||||
$this->vars['parentLabel'] = Lang::get('backend::lang.mysettings.menu_label');
|
||||
}
|
||||
|
||||
$model = $this->createModel($item);
|
||||
$this->initWidgets($model);
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
$this->handleError($ex);
|
||||
}
|
||||
}
|
||||
|
||||
public function update_onSave($author, $plugin, $code = null)
|
||||
{
|
||||
$item = $this->findSettingItem($author, $plugin, $code);
|
||||
$model = $this->createModel($item);
|
||||
$this->initWidgets($model);
|
||||
|
||||
$saveData = $this->formWidget->getSaveData();
|
||||
foreach ($saveData as $attribute => $value) {
|
||||
$model->{$attribute} = $value;
|
||||
}
|
||||
$model->save(null, $this->formWidget->getSessionKey());
|
||||
|
||||
Flash::success(Lang::get('system::lang.settings.update_success', ['name' => Lang::get($item->label)]));
|
||||
|
||||
/*
|
||||
* Handle redirect
|
||||
*/
|
||||
if ($redirectUrl = post('redirect', true)) {
|
||||
$redirectUrl = ($item->context == 'mysettings')
|
||||
? 'system/settings/mysettings'
|
||||
: 'system/settings';
|
||||
|
||||
return Backend::redirect($redirectUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the current configuration and sends a test email to the current user
|
||||
*/
|
||||
public function update_onTest(string $author, string $plugin, $code = null)
|
||||
{
|
||||
try {
|
||||
$this->update_onSave($author, $plugin, $code);
|
||||
|
||||
SettingsModel::clearInternalCache();
|
||||
|
||||
Mail::raw(Lang::get('system::lang.settings.test_content'), function ($msg) {
|
||||
$msg->to([$this->user->email => $this->user->full_name]);
|
||||
$msg->subject(Lang::get('system::lang.settings.test_subject'));
|
||||
});
|
||||
|
||||
Flash::success(Lang::get('system::lang.mail_templates.test_success'));
|
||||
} catch (Exception $ex) {
|
||||
Flash::error($ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function update_onResetDefault($author, $plugin, $code = null)
|
||||
{
|
||||
$item = $this->findSettingItem($author, $plugin, $code);
|
||||
$model = $this->createModel($item);
|
||||
$model->resetDefault();
|
||||
|
||||
Flash::success(Lang::get('backend::lang.form.reset_success'));
|
||||
|
||||
return Backend::redirect('system/settings/update/'.$author.'/'.$plugin.'/'.$code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the form.
|
||||
*/
|
||||
public function formRender($options = [])
|
||||
{
|
||||
if (!$this->formWidget) {
|
||||
throw new ApplicationException(Lang::get('backend::lang.form.behavior_not_ready'));
|
||||
}
|
||||
|
||||
return $this->formWidget->render($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the form widget used by this behavior.
|
||||
*
|
||||
* @return \Backend\Widgets\Form
|
||||
*/
|
||||
public function formGetWidget()
|
||||
{
|
||||
if (is_null($this->formWidget)) {
|
||||
$item = $this->findSettingItem();
|
||||
$model = $this->createModel($item);
|
||||
$this->initWidgets($model);
|
||||
}
|
||||
|
||||
return $this->formWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the widgets used by this action
|
||||
* Model $model
|
||||
*/
|
||||
protected function initWidgets($model)
|
||||
{
|
||||
$config = $model->getFieldConfig();
|
||||
$config->model = $model;
|
||||
$config->arrayName = class_basename($model);
|
||||
$config->context = 'update';
|
||||
|
||||
$widget = $this->makeWidget('Backend\Widgets\Form', $config);
|
||||
$widget->bindToController();
|
||||
$this->formWidget = $widget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method, prepare the list model object
|
||||
*/
|
||||
protected function createModel($item)
|
||||
{
|
||||
if (!isset($item->class) || !strlen($item->class)) {
|
||||
throw new ApplicationException(Lang::get('system::lang.settings.missing_model'));
|
||||
}
|
||||
|
||||
$class = $item->class;
|
||||
return $class::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates a setting item for a module or plugin.
|
||||
*
|
||||
* If none of the parameters are provided, they will be auto-guessed from the URL.
|
||||
*
|
||||
* @param string|null $author
|
||||
* @param string|null $plugin
|
||||
* @param string|null $code
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function findSettingItem($author = null, $plugin = null, $code = null)
|
||||
{
|
||||
if (is_null($author) || is_null($plugin)) {
|
||||
[$author, $plugin, $code] = $this->guessSettingItem();
|
||||
}
|
||||
|
||||
$manager = SettingsManager::instance();
|
||||
|
||||
$moduleOwner = $author;
|
||||
$moduleCode = $plugin;
|
||||
$item = $manager->findSettingItem($moduleOwner, $moduleCode);
|
||||
|
||||
if (!$item) {
|
||||
$pluginOwner = $author . '.' . $plugin;
|
||||
$pluginCode = $code;
|
||||
$item = $manager->findSettingItem($pluginOwner, $pluginCode);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guesses the requested setting item from the current URL segments provided by the Request object.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function guessSettingItem()
|
||||
{
|
||||
$segments = Request::segments();
|
||||
|
||||
if (!empty(Config::get('cms.backendUri', 'backend'))) {
|
||||
array_splice($segments, 0, 4);
|
||||
} else {
|
||||
array_splice($segments, 0, 3);
|
||||
}
|
||||
|
||||
// Ensure there's at least 3 segments
|
||||
return array_pad($segments, 3, null);
|
||||
}
|
||||
}
|
||||
1043
modules/system/controllers/Updates.php
Normal file
1043
modules/system/controllers/Updates.php
Normal file
File diff suppressed because it is too large
Load Diff
529
modules/system/controllers/eventlogs/_field_details.php
Normal file
529
modules/system/controllers/eventlogs/_field_details.php
Normal file
@@ -0,0 +1,529 @@
|
||||
<?php
|
||||
if (!isset($value['logVersion']) || $value['logVersion'] !== 2) {
|
||||
if ($value ?? false) {
|
||||
printf(
|
||||
'<h4>DETAILS</h4><pre style="background: #fff; padding: 10px; border: 1px solid #ddd;">%s</pre>',
|
||||
e(print_r($value, true))
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights a line of php code with php syntax highlighting
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
function phpSyntaxHighlight(string $str): string
|
||||
{
|
||||
$regexes = [
|
||||
'control' => '/\b(for|foreach|while|class |extends|yield from|yield|echo|fn|implements|try|catch|finally|throw|new|instanceof| parent|final|function|return|unset|static|public|protected|private|count|global|if|else|else if|intval|int|array)\b/',
|
||||
'bool' => '/(\bnull\b|\btrue\b|\bfalse\b)/',
|
||||
'string' => [
|
||||
'pattern' => '/(\221[^\221]*\221|\222[^\222]*\222)/',
|
||||
'before' => fn ($s) => str_replace(''', "\221", str_replace('"', "\222", $s)),
|
||||
'after' => fn ($s) => str_replace("\221", ''', str_replace("\222", '"', $s)),
|
||||
],
|
||||
'number' => [
|
||||
'pattern' => '/(=\(\s)?(\d+)(?=(\s|;|,|\)|=))/',
|
||||
'replace' => '$2',
|
||||
'before' => fn ($s) => str_replace(''', '\'', $s),
|
||||
'after' => fn ($s) => str_replace('\'', ''', $s),
|
||||
],
|
||||
'bracket' => '/(\(|\)|\[|\]|\{|\})/',
|
||||
'variable' => '/(\$[a-z]\w*)/',
|
||||
];
|
||||
|
||||
if (preg_match('/(^\s*?\*|^\s*?\*\/|^\s*?\/\*|^\s*?\/\/|^\s*?#)/', $str)) {
|
||||
return sprintf('<span class="comment">%s</span>', $str);
|
||||
}
|
||||
|
||||
foreach ($regexes as $label => $regex) {
|
||||
if (is_string($regex)) {
|
||||
$str = preg_replace($regex, '<span class="' . $label . '">$1</span>', $str);
|
||||
continue;
|
||||
}
|
||||
|
||||
$str = preg_replace(
|
||||
$regex['pattern'],
|
||||
sprintf('<span class="%s">%s</span>', $label, $regex['replace'] ?? '$1'),
|
||||
isset($regex['before']) ? $regex['before']($str) : $str
|
||||
);
|
||||
|
||||
$str = isset($regex['after']) ? $regex['after']($str) : $str;
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an array of lines into a html snippet of code
|
||||
*
|
||||
* @param array $snippet
|
||||
* @param int|null $highlight
|
||||
* @return string
|
||||
*/
|
||||
function makeSnippet(array $snippet, string $file, ?int $highlight = null): string
|
||||
{
|
||||
return implode(
|
||||
"\n",
|
||||
array_reduce(
|
||||
array_keys($snippet),
|
||||
function (array $carry, $key) use ($snippet, $file, $highlight) {
|
||||
$carry[] = sprintf(
|
||||
'<div class="preview-line%s"><span class="line-number" data-idelink="idelink://%s&%3$d""><span class="icon wn-icon-file-pen"></span>%3$d</span>: %4$s</div>',
|
||||
($key + 1 === $highlight ? ' highlight' : ''),
|
||||
urlencode(str_replace('\\', '/', $file)),
|
||||
$key + 1,
|
||||
phpSyntaxHighlight(e($snippet[$key], true))
|
||||
);
|
||||
return $carry;
|
||||
},
|
||||
[]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all exceptions in the stack and returns them bottom up
|
||||
*
|
||||
* @param array $value
|
||||
* @return array
|
||||
*/
|
||||
function getOrderedExceptionList(array $value): array
|
||||
{
|
||||
$exceptions = [$value];
|
||||
$current = $value;
|
||||
while (isset($current['previous']) && ($current = $current['previous'])) {
|
||||
$exceptions[] = $current;
|
||||
}
|
||||
|
||||
return array_reverse($exceptions);
|
||||
}
|
||||
?>
|
||||
<style>
|
||||
div.plugin-exception-beautifier span.beautifier-message-container {
|
||||
display: none;
|
||||
}
|
||||
#winter-log-viewer {
|
||||
background: #fff;
|
||||
margin: -20px;
|
||||
padding: 20px;
|
||||
}
|
||||
#winter-log-viewer h1 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
#winter-log-viewer .btn[disabled] {
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
user-select: auto;
|
||||
}
|
||||
#winter-log-viewer .btn.btn-secondary[disabled] {
|
||||
color: #000;
|
||||
font-weight: normal;
|
||||
}
|
||||
#winter-log-viewer table.table tr:first-child td, #winter-log-viewer table.table tr:first-child th {
|
||||
border-top: 0;
|
||||
}
|
||||
#winter-log-viewer table.table tr td {
|
||||
font-family: monospace;
|
||||
}
|
||||
#winter-log-viewer .input-group.select-container {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
#winter-log-viewer .input-group.select-container .select2-container--default {
|
||||
width: auto;
|
||||
}
|
||||
#winter-log-viewer .input-group.select-container .select2-container--default .select2-selection {
|
||||
padding-right: 30px;
|
||||
}
|
||||
#winter-log-viewer .exception-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
#winter-log-viewer .exception-list.reverse {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
#winter-log-viewer .exception-list .exception {
|
||||
width: 100%;
|
||||
}
|
||||
#winter-log-viewer .btn-group:not(:last-of-type) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
p.message-log {
|
||||
font-family: monospace;
|
||||
margin: 15px auto;
|
||||
}
|
||||
div.snippet-preview-container {
|
||||
overflow-x: auto;
|
||||
background: #f5f5f5;
|
||||
margin-top: 15px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
div.snippet-preview {
|
||||
line-height: 0.7em;
|
||||
width: fit-content;
|
||||
min-width: 100%;
|
||||
padding-bottom: 5px;
|
||||
white-space: pre;
|
||||
font-family: monospace, monospace;
|
||||
}
|
||||
div.snippet-preview div.preview-line {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
background: #f5f5f5;
|
||||
width: 100%;
|
||||
padding: 7px 10px;
|
||||
margin: -5px 0;
|
||||
}
|
||||
div.snippet-preview div.preview-line:first-child {
|
||||
margin-top: -18px;
|
||||
}
|
||||
div.snippet-preview div.preview-line:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
div.snippet-preview div.preview-line.highlight {
|
||||
display: block;
|
||||
background: #fff;
|
||||
padding: 5px 10px;
|
||||
margin: -5px 0;
|
||||
}
|
||||
div.snippet-preview div.preview-line span.line-number {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
div.snippet-preview div.preview-line span.line-number .icon {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
left: calc(100% + 1em);
|
||||
transition: opacity linear .2s;
|
||||
}
|
||||
div.snippet-preview div.preview-line:hover span.line-number .icon {
|
||||
opacity: 1;
|
||||
}
|
||||
div.snippet-preview div.preview-line.highlight span.line-number {
|
||||
color: red;
|
||||
}
|
||||
div.snippet-preview span.bracket { color: #343434; }
|
||||
div.snippet-preview span.variable { color: #d3542f; }
|
||||
div.snippet-preview span.control { color: #7109e1; }
|
||||
div.snippet-preview span.string { color: #6a8d00; }
|
||||
div.snippet-preview span.number { color: #006ac0; }
|
||||
div.snippet-preview span.html { color: #cba604; }
|
||||
div.snippet-preview span.bool { color: #e1095c; }
|
||||
div.snippet-preview span.comment { color: #8c8c8c; }
|
||||
.trace-title {
|
||||
margin: 15px auto;
|
||||
display: block;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.trace-title small {
|
||||
font-size: 0.85em;
|
||||
font-weight: normal;
|
||||
}
|
||||
.trace {
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 6px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.trace-frame {
|
||||
background: #efefef;
|
||||
padding: 10px;
|
||||
}
|
||||
.trace-frame:first-child {
|
||||
border-top-right-radius: 6px;
|
||||
border-top-left-radius: 6px;
|
||||
}
|
||||
.trace-frame:last-child {
|
||||
border-bottom-right-radius: 6px;
|
||||
border-bottom-left-radius: 6px;
|
||||
}
|
||||
.trace-frame:not(:last-child) {
|
||||
border-bottom: 1px solid #dcdcdc;
|
||||
}
|
||||
.trace-frame .label {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
font-size: 0.95em;
|
||||
word-break: break-word;
|
||||
}
|
||||
.trace-frame .label .item {
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
}
|
||||
.trace-frame .label .app-icon{
|
||||
background: #73b2d0;
|
||||
color: #e9f3fa;
|
||||
border-radius: 6px;
|
||||
font-size: 0.8em;
|
||||
padding: 3px;
|
||||
font-weight: bold;
|
||||
float: right;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.trace-frame .folded {
|
||||
display: none;
|
||||
}
|
||||
/* The following are fixes for the TailwindUI plugin */
|
||||
#winter-log-viewer hr {
|
||||
margin-bottom: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
#winter-log-viewer h1 {
|
||||
font-size: 36px;
|
||||
}
|
||||
</style>
|
||||
<div id="winter-log-viewer">
|
||||
<div class="formatted">
|
||||
<div>
|
||||
<?php if (strtolower($value['environment']['context']) === 'web'): ?>
|
||||
<table class="table table-responsive">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><?= e(trans('system::lang.event_log.details.http_method')) ?></th>
|
||||
<td><?= e($value['environment']['method']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?= e(trans('system::lang.event_log.details.url')) ?></th>
|
||||
<td>
|
||||
<a href="<?= e($value['environment']['url']) ?>" target="_blank" rel="noopener">
|
||||
<span class="wn-icon-link"></span><?= e($value['environment']['url']) ?>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?= e(trans('system::lang.event_log.details.user_agent')) ?></th>
|
||||
<td><?= e($value['environment']['userAgent']) ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?= e(trans('system::lang.event_log.details.client_ip')) ?></th>
|
||||
<td><?= e($value['environment']['ip']) ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="btn-group" role="group" title="<?= e(trans('system::lang.event_log.details.exception_context')) ?>">
|
||||
<button type="button" disabled class="btn btn-sm btn-secondary"><?= e(trans('system::lang.event_log.details.context')) ?></button>
|
||||
<button type="button" disabled class="btn btn-sm btn-primary"><?= e($value['environment']['context']) ?></button>
|
||||
</div>
|
||||
<div class="btn-group" role="group" title="<?= e(trans('system::lang.event_log.details.exception_app_env')) ?>">
|
||||
<button type="button" disabled class="btn btn-sm btn-secondary"><?= e(trans('system::lang.event_log.details.environment')) ?></button>
|
||||
<button type="button" disabled class="btn btn-sm btn-primary"><?= e($value['environment']['env']) ?></button>
|
||||
</div>
|
||||
<?php if (strtolower($value['environment']['context']) === 'web'): ?>
|
||||
<div class="btn-group" role="group" title="<?= e(trans('system::lang.event_log.details.exception_encountered_backend')) ?>">
|
||||
<button type="button" disabled class="btn btn-sm btn-secondary"><?= e(trans('system::lang.event_log.details.backend')) ?></button>
|
||||
<button type="button" disabled class="btn btn-sm btn-primary"><?= $value['environment']['backend'] ? 'true' : 'false' ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="btn-group" role="group" title="<?= e(trans('system::lang.event_log.details.exception_encountered_unit_test')) ?>">
|
||||
<button type="button" disabled class="btn btn-sm btn-secondary"><?= e(trans('system::lang.event_log.details.testing')) ?></button>
|
||||
<button type="button" disabled class="btn btn-sm btn-primary"><?= $value['environment']['testing'] ? 'true' : 'false' ?></button>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<?php if ($value['exception']['previous']): ?>
|
||||
<div class="select-container input-group mb-3">
|
||||
<select class="custom-select" id="exception-sort-order">
|
||||
<option selected value="old"><?= e(trans('system::lang.event_log.details.oldest_first')) ?></option>
|
||||
<option value="new"><?= e(trans('system::lang.event_log.details.newest_first')) ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="exception-list">
|
||||
<?php foreach (getOrderedExceptionList($value['exception']) as $index => $exception): ?>
|
||||
<div class="exception">
|
||||
<h1><?= e($exception['type']) ?></h1>
|
||||
<p class="message-log"><?= e($exception['message']) ?></p>
|
||||
|
||||
<div>
|
||||
<div class="btn-group" role="group" title="<?= e(trans('system::lang.event_log.details.exception_index')) ?>">
|
||||
<button type="button" disabled class="btn btn-sm btn-secondary"><?= e(trans('system::lang.event_log.details.exception')) ?></button>
|
||||
<button type="button" disabled class="btn btn-sm btn-primary">#<?= e($index) ?></button>
|
||||
</div>
|
||||
<div class="btn-group" role="group" title="<?= e(trans('system::lang.event_log.details.exception_code')) ?>">
|
||||
<button type="button" disabled class="btn btn-sm btn-secondary"><?= e(trans('system::lang.event_log.details.code')) ?></button>
|
||||
<button type="button" disabled class="btn btn-sm btn-primary"><?= e($exception['code']) ?></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="trace">
|
||||
<div class="trace-frame">
|
||||
<div class="label">
|
||||
<span class="item"><?= e($exception['file']) ?></span>
|
||||
at line <span class="item"><?= e($exception['line']) ?></span>
|
||||
</div>
|
||||
<?php if ($exception['snippet']): ?>
|
||||
<div class="snippet-preview-container">
|
||||
<div class="snippet-preview">
|
||||
<?= makeSnippet($exception['snippet'], $exception['file'], $exception['line']) ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="trace-title"><?= trans('system::lang.event_log.details.stack_trace', ['count' => e(count($exception['trace']))]) ?></span>
|
||||
<div class="trace">
|
||||
<?php foreach ($exception['trace'] as $traceIndex => $frame): ?>
|
||||
<div class="trace-frame">
|
||||
<div class="label">
|
||||
<span class="item">#<?= e($traceIndex) ?> <?= e($frame['file']) ?></span>
|
||||
in <span class="item"><?= $frame['class'] && !str_contains($frame['function'], '{') ? e($frame['class']) . '::' : '' ?><?= e($frame['function']) ?></span>
|
||||
<?php if ($frame['line']): ?>
|
||||
at line <span class="item"><?= e($frame['line']) ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ($frame['arguments']): ?>
|
||||
with argument<?= count($frame['arguments']) > 1 ? 's' : '' ?>: (<span class="item"><?= implode('</span>, <span class="item">', array_map('e', $frame['arguments'])) ?></span>)
|
||||
<?php endif; ?>
|
||||
<?php if ($frame['in_app']): ?>
|
||||
<span class="app-icon"><?= e(trans('system::lang.event_log.details.in_app')) ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ($frame['snippet']): ?>
|
||||
<div class="snippet-preview-container <?= $frame['in_app'] ? 'unfolded' : 'folded' ?>">
|
||||
<div class="snippet-preview">
|
||||
<?= makeSnippet($frame['snippet'], $frame['file'], $frame['line']) ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="raw" style="display: none">
|
||||
<pre class="beautifier-raw-content"><?= e($value['exception']['stringTrace']) ?></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(() => {
|
||||
document.querySelectorAll('.trace-frame').forEach((frame) => {
|
||||
frame.querySelector('.label').addEventListener('click', () => {
|
||||
frame.querySelector('div.snippet-preview-container')?.classList.toggle('folded');
|
||||
});
|
||||
});
|
||||
window.addEventListener('load', () => {
|
||||
document.querySelector('.plugin-exception-beautifier a[href="#beautifier-tab-formatted"]').addEventListener('click', () => {
|
||||
document.querySelector('#winter-log-viewer .formatted').style.display = "block";
|
||||
document.querySelector('#winter-log-viewer .raw').style.display = "none";
|
||||
});
|
||||
document.querySelector('.plugin-exception-beautifier a[href="#beautifier-tab-raw"]').addEventListener('click', () => {
|
||||
document.querySelector('#winter-log-viewer .formatted').style.display = "none";
|
||||
document.querySelector('#winter-log-viewer .raw').style.display = "block";
|
||||
});
|
||||
// jQuery to tie in with select2
|
||||
$("select#exception-sort-order").on('change', (e) => {
|
||||
document.querySelector('#winter-log-viewer .exception-list').classList[e.target.value === 'old' ? 'remove' : 'add']('reverse');
|
||||
});
|
||||
|
||||
// Luke made me do it
|
||||
// Script to load files in editors
|
||||
(() => {
|
||||
const editors = {
|
||||
vscode: { scheme: 'vscode://file/%file:%line', name: 'VS Code (vscode://)' },
|
||||
phpstorm: { scheme: 'phpstorm://open?file=%file&line=%line', name: 'PhpStorm (phpstorm://)' },
|
||||
subl: { scheme: 'subl://open?url=file://%file&line=%line', name: 'Sublime (subl://)' },
|
||||
txmt: { scheme: 'txmt://open/?url=file://%file&line=%line', name: 'TextMate (txmt://)' },
|
||||
mvim: { scheme: 'mvim://open/?url=file://%file&line=%line', name: 'MacVim (mvim://)' },
|
||||
editor: { scheme: 'editor://open/?file=%file&line=%line', name: 'Custom (editor://)' }
|
||||
};
|
||||
|
||||
const ideLinkRegex = /idelink:\/\/([^#]+)&([0-9]+)?/;
|
||||
|
||||
function openWithEditor(link) {
|
||||
const matches = link.match(ideLinkRegex);
|
||||
|
||||
const open = function(value) {
|
||||
const editorScheme = editors[value].scheme
|
||||
.replace(/%file/, matches[1])
|
||||
.replace(/%line/, matches[2]);
|
||||
window.open(link.replace(ideLinkRegex, editorScheme), '_self');
|
||||
};
|
||||
|
||||
if (!matches) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sessionStorage && sessionStorage.getItem('wn-exception-beautifier-editor')) {
|
||||
open(sessionStorage.getItem('wn-exception-beautifier-editor'));
|
||||
return;
|
||||
}
|
||||
|
||||
const title = 'Select an Editor';
|
||||
const description = 'Choose an editor to open the file:';
|
||||
const openWith = 'Open with:';
|
||||
const rememberChoice = 'Remember choice for next time';
|
||||
const openString = 'Open';
|
||||
const cancel = 'Cancel';
|
||||
|
||||
$.popup({
|
||||
size: 'large idelink-popup',
|
||||
content: `
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h4 class="modal-title">${title}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>${description}</p>
|
||||
<div class="form-group">
|
||||
<label class="control-label">${openWith}:</label>
|
||||
<select class="form-control" name="select-exception-link-editor"></select>
|
||||
</div>
|
||||
<div class="checkbox custom-checkbox">
|
||||
<input name="checkbox" value="1" type="checkbox" id="editor-remember-choice" />
|
||||
<label for="editor-remember-choice">${rememberChoice}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" data-action="submit" data-dismiss="modal">${openString}</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="popup">${cancel}</button>
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
|
||||
const popup = document.querySelector('.idelink-popup');
|
||||
const select = popup.querySelector('select');
|
||||
|
||||
Object.entries(editors).forEach(([name, editor]) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = name;
|
||||
option.textContent = editor.name;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
const submitBtn = popup.querySelector('[data-action="submit"]');
|
||||
const closeBtn = popup.querySelector('[data-dismiss="popup"]');
|
||||
const rememberCheckbox = popup.querySelector('#editor-remember-choice');
|
||||
|
||||
submitBtn.addEventListener('click', function() {
|
||||
if (rememberCheckbox.checked && sessionStorage) {
|
||||
sessionStorage.setItem('wn-exception-beautifier-editor', select.value);
|
||||
}
|
||||
open(select.value);
|
||||
closeBtn.click();
|
||||
popup.remove();
|
||||
});
|
||||
}
|
||||
|
||||
document.querySelectorAll('div.snippet-preview div.preview-line span.line-number[data-idelink]').forEach((lineNumber) => {
|
||||
lineNumber.addEventListener('click', () => {
|
||||
openWithEditor(lineNumber.dataset.idelink);
|
||||
})
|
||||
});
|
||||
})();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
1
modules/system/controllers/eventlogs/_field_message.php
Normal file
1
modules/system/controllers/eventlogs/_field_message.php
Normal file
@@ -0,0 +1 @@
|
||||
<?= e($value, true); ?>
|
||||
4
modules/system/controllers/eventlogs/_hint.php
Normal file
4
modules/system/controllers/eventlogs/_hint.php
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
<p>
|
||||
<?= e(trans('system::lang.event_log.hint')) ?>
|
||||
</p>
|
||||
31
modules/system/controllers/eventlogs/_list_toolbar.php
Normal file
31
modules/system/controllers/eventlogs/_list_toolbar.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<div data-control="toolbar" class="loading-indicator-container">
|
||||
<a
|
||||
href="javascript:;"
|
||||
data-request="onRefresh"
|
||||
data-load-indicator="<?= e(trans('backend::lang.list.updating')) ?>"
|
||||
class="btn btn-primary wn-icon-refresh">
|
||||
<?= e(trans('backend::lang.list.refresh')) ?>
|
||||
</a>
|
||||
<a
|
||||
href="javascript:;"
|
||||
data-request="onEmptyLog"
|
||||
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')) ?>"
|
||||
data-load-indicator="<?= e(trans('system::lang.event_log.empty_loading')) ?>"
|
||||
class="btn btn-default wn-icon-eraser">
|
||||
<?= e(trans('system::lang.event_log.empty_link')) ?>
|
||||
</a>
|
||||
<button
|
||||
class="btn btn-danger wn-icon-trash-o"
|
||||
disabled="disabled"
|
||||
onclick="$(this).data('request-data', {
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request="onDelete"
|
||||
data-trigger-action="enable"
|
||||
data-trigger=".control-list input[type=checkbox]"
|
||||
data-trigger-condition="checked"
|
||||
data-request-success="$(this).prop('disabled', true)"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('backend::lang.list.delete_selected')) ?>
|
||||
</button>
|
||||
</div>
|
||||
1
modules/system/controllers/eventlogs/_message_column.php
Normal file
1
modules/system/controllers/eventlogs/_message_column.php
Normal file
@@ -0,0 +1 @@
|
||||
<?= e($record->summary) ?>
|
||||
10
modules/system/controllers/eventlogs/config_filter.yaml
Normal file
10
modules/system/controllers/eventlogs/config_filter.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
# ===================================
|
||||
# Filter Scope Definitions
|
||||
# ===================================
|
||||
|
||||
scopes:
|
||||
|
||||
created_at:
|
||||
label: backend::lang.access_log.created_at
|
||||
type: daterange
|
||||
conditions: created_at >= ':after' AND created_at <= ':before'
|
||||
19
modules/system/controllers/eventlogs/config_form.yaml
Normal file
19
modules/system/controllers/eventlogs/config_form.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
# ===================================
|
||||
# Form Behavior Config
|
||||
# ===================================
|
||||
|
||||
# Record name
|
||||
name: system::lang.event_log.menu_label
|
||||
|
||||
# Model Form Field configuration
|
||||
form: ~/modules/system/models/eventlog/fields.yaml
|
||||
|
||||
# Model Class name
|
||||
modelClass: System\Models\EventLog
|
||||
|
||||
# Default redirect location
|
||||
defaultRedirect: system/eventlogs
|
||||
|
||||
# Preview page
|
||||
preview:
|
||||
title: system::lang.event_log.preview_title
|
||||
19
modules/system/controllers/eventlogs/config_list.yaml
Normal file
19
modules/system/controllers/eventlogs/config_list.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
# ===================================
|
||||
# List Behavior Config
|
||||
# ===================================
|
||||
|
||||
title: system::lang.event_log.menu_label
|
||||
list: ~/modules/system/models/eventlog/columns.yaml
|
||||
modelClass: System\Models\EventLog
|
||||
recordUrl: system/eventlogs/preview/:id
|
||||
noRecordsMessage: backend::lang.list.no_records
|
||||
recordsPerPage: 30
|
||||
showSetup: true
|
||||
showCheckboxes: true
|
||||
|
||||
toolbar:
|
||||
buttons: list_toolbar
|
||||
search:
|
||||
prompt: backend::lang.list.search_prompt
|
||||
|
||||
filter: config_filter.yaml
|
||||
5
modules/system/controllers/eventlogs/index.php
Normal file
5
modules/system/controllers/eventlogs/index.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<div class="padded-container container-flush">
|
||||
<?= $this->makeHintPartial('system_eventlogs_hint', 'hint') ?>
|
||||
</div>
|
||||
|
||||
<?= $this->listRender() ?>
|
||||
41
modules/system/controllers/eventlogs/preview.php
Normal file
41
modules/system/controllers/eventlogs/preview.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/eventlogs') ?>"><?= e(trans('system::lang.event_log.menu_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<div class="scoreboard">
|
||||
<div data-control="toolbar">
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.event_log.id_label')) ?></h4>
|
||||
<p>#<?= $formModel->id ?></p>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.event_log.level')) ?></h4>
|
||||
<p><?= $formModel->level ?></p>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.event_log.created_at')) ?></h4>
|
||||
<p><?= Backend::dateTime($formModel->created_at) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-item stretch layout-column" style="padding-bottom: 1em;">
|
||||
<?= $this->formRenderPreview() ?>
|
||||
|
||||
<p>
|
||||
<a href="<?= Backend::url('system/eventlogs') ?>" class="btn btn-default wn-icon-chevron-left">
|
||||
<?= e(trans('system::lang.event_log.return_link')) ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
|
||||
<?php endif ?>
|
||||
@@ -0,0 +1,11 @@
|
||||
<div id="<?= $this->getId('mailPreviewContainer') ?>"></div>
|
||||
<script type="text/template" id="<?= $this->getId('mailPreviewTemplate') ?>"><?= $this->renderSampleMessage() ?></script>
|
||||
|
||||
<script>
|
||||
$(function(){
|
||||
var previewContents = $('#<?= $this->getId('mailPreviewTemplate') ?>').html()
|
||||
previewFrame = $('#<?= $this->getId('mailPreviewContainer') ?>').get(0)
|
||||
|
||||
createPreviewContainer(previewFrame, previewContents)
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,15 @@
|
||||
# ===================================
|
||||
# Form Behavior Config
|
||||
# ===================================
|
||||
|
||||
# Record name
|
||||
name: system::lang.mail_brand.menu_label
|
||||
|
||||
# Fields are defined by extension
|
||||
form: ~/modules/system/models/mailbrandsetting/fields.yaml
|
||||
|
||||
# Model Class name
|
||||
modelClass: System\Models\MailBrandSetting
|
||||
|
||||
# Default redirect location
|
||||
defaultRedirect: system/themes
|
||||
61
modules/system/controllers/mailbrandsettings/index.php
Normal file
61
modules/system/controllers/mailbrandsettings/index.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<?php Block::put('form-contents') ?>
|
||||
<div class="layout">
|
||||
|
||||
<div class="layout-row">
|
||||
<?= $this->formRenderOutsideFields() ?>
|
||||
<?= $this->formRenderPrimaryTabs() ?>
|
||||
</div>
|
||||
|
||||
<div class="form-buttons">
|
||||
<div class="loading-indicator-container">
|
||||
<button
|
||||
type="submit"
|
||||
data-request="onSave"
|
||||
data-browser-validate
|
||||
data-request-data="redirect:0"
|
||||
data-hotkey="ctrl+s, cmd+s"
|
||||
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
|
||||
class="btn btn-primary">
|
||||
<?= e(trans('backend::lang.form.save')) ?>
|
||||
</button>
|
||||
<span class="btn-text">
|
||||
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
|
||||
</span>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-danger pull-right"
|
||||
data-request="onResetDefault"
|
||||
data-load-indicator="<?= e(trans('backend::lang.form.resetting')) ?>"
|
||||
data-request-confirm="<?= e(trans('backend::lang.form.action_confirm')) ?>">
|
||||
<?= e(trans('backend::lang.form.reset_default')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php Block::put('form-sidebar') ?>
|
||||
<div class="hide-tabs"><?= $this->formRenderSecondaryTabs() ?></div>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php Block::put('body') ?>
|
||||
<?= Form::open(['id' => 'brandSettingsForm', 'class'=>'layout stretch']) ?>
|
||||
<?= $this->makeLayout('form-with-sidebar') ?>
|
||||
<?= Form::close() ?>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
<p><a href="<?= Backend::url('system/mailtemplates') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
|
||||
|
||||
<?php endif ?>
|
||||
16
modules/system/controllers/maillayouts/config_form.yaml
Normal file
16
modules/system/controllers/maillayouts/config_form.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# ===================================
|
||||
# Form Behavior Config
|
||||
# ===================================
|
||||
|
||||
name: system::lang.mail_templates.layout
|
||||
form: ~/modules/system/models/maillayout/fields.yaml
|
||||
modelClass: System\Models\MailLayout
|
||||
defaultRedirect: system/mailtemplates/index/layouts
|
||||
|
||||
create:
|
||||
redirect: system/maillayouts/update/:id
|
||||
redirectClose: system/mailtemplates/index/layouts
|
||||
|
||||
update:
|
||||
redirect: system/mailtemplates
|
||||
redirectClose: system/mailtemplates/index/layouts
|
||||
80
modules/system/controllers/maillayouts/update.php
Normal file
80
modules/system/controllers/maillayouts/update.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/mailtemplates/index/layouts') ?>"><?= e(trans('system::lang.mail_templates.menu_layouts_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<?= Form::open(['class'=>'layout']) ?>
|
||||
|
||||
<div class="layout-row min-size">
|
||||
<div class="scoreboard">
|
||||
<div data-control="toolbar">
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.mail_templates.layout')) ?></h4>
|
||||
<p><?= e($formModel->code) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-row">
|
||||
<?= $this->formRender() ?>
|
||||
</div>
|
||||
|
||||
<div class="form-buttons p-t">
|
||||
<div class="loading-indicator-container">
|
||||
<button
|
||||
type="submit"
|
||||
data-request="onSave"
|
||||
data-browser-validate
|
||||
data-request-data="redirect:0"
|
||||
data-hotkey="ctrl+s, cmd+s"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.saving_layout')) ?>"
|
||||
class="btn btn-primary">
|
||||
<?= e(trans('backend::lang.form.save')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-request="onSave"
|
||||
data-browser-validate
|
||||
data-request-data="close:1"
|
||||
data-hotkey="ctrl+enter, cmd+enter"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.saving_layout')) ?>"
|
||||
class="btn btn-default">
|
||||
<?= e(trans('backend::lang.form.save_and_close')) ?>
|
||||
</button>
|
||||
<?php if ($formModel->is_locked): ?>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-danger pull-right"
|
||||
data-request="onResetDefault"
|
||||
data-load-indicator="<?= e(trans('backend::lang.form.resetting')) ?>"
|
||||
data-request-confirm="<?= e(trans('backend::lang.form.action_confirm')) ?>">
|
||||
<?= e(trans('backend::lang.form.reset_default')) ?>
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<button
|
||||
type="button"
|
||||
class="wn-icon-trash-o btn-icon danger pull-right"
|
||||
data-request="onDelete"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.deleting_layout')) ?>"
|
||||
data-request-confirm="<?= e(trans('system::lang.mail_templates.delete_layout_confirm')) ?>">
|
||||
</button>
|
||||
<?php endif ?>
|
||||
<span class="btn-text">
|
||||
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('system/mailtemplates/index/layouts') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= Form::close() ?>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
<p><a href="<?= Backend::url('system/mailtemplates/index/layouts') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
|
||||
|
||||
<?php endif ?>
|
||||
16
modules/system/controllers/mailpartials/config_form.yaml
Normal file
16
modules/system/controllers/mailpartials/config_form.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# ===================================
|
||||
# Form Behavior Config
|
||||
# ===================================
|
||||
|
||||
name: system::lang.mail_templates.partial
|
||||
form: ~/modules/system/models/mailpartial/fields.yaml
|
||||
modelClass: System\Models\MailPartial
|
||||
defaultRedirect: system/mailtemplates/index/partials
|
||||
|
||||
create:
|
||||
redirect: system/mailpartials/update/:id
|
||||
redirectClose: system/mailtemplates/index/partials
|
||||
|
||||
update:
|
||||
redirect: system/mailtemplates/index/partials
|
||||
redirectClose: system/mailtemplates/index/partials
|
||||
69
modules/system/controllers/mailpartials/update.php
Normal file
69
modules/system/controllers/mailpartials/update.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/mailtemplates/index/partials') ?>"><?= e(trans('system::lang.mail_templates.menu_partials_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<?= Form::open(['class'=>'layout']) ?>
|
||||
|
||||
<div class="layout-row min-size">
|
||||
<div class="scoreboard">
|
||||
<div data-control="toolbar">
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.mail_templates.partial')) ?></h4>
|
||||
<p><?= e($formModel->code) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-row">
|
||||
<?= $this->formRender() ?>
|
||||
</div>
|
||||
|
||||
<div class="form-buttons p-t">
|
||||
<div class="loading-indicator-container">
|
||||
<button
|
||||
type="submit"
|
||||
data-request="onSave"
|
||||
data-browser-validate
|
||||
data-request-data="redirect:0"
|
||||
data-hotkey="ctrl+s, cmd+s"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.saving_layout')) ?>"
|
||||
class="btn btn-primary">
|
||||
<?= e(trans('backend::lang.form.save')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-request="onSave"
|
||||
data-browser-validate
|
||||
data-request-data="close:1"
|
||||
data-hotkey="ctrl+enter, cmd+enter"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.saving_layout')) ?>"
|
||||
class="btn btn-default">
|
||||
<?= e(trans('backend::lang.form.save_and_close')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="wn-icon-trash-o btn-icon danger pull-right"
|
||||
data-request="onDelete"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.deleting_layout')) ?>"
|
||||
data-request-confirm="<?= e(trans('system::lang.mail_templates.delete_layout_confirm')) ?>">
|
||||
</button>
|
||||
<span class="btn-text">
|
||||
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('system/mailtemplates/index/partials') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= Form::close() ?>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
<p><a href="<?= Backend::url('system/mailtemplates/index/partials') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
|
||||
|
||||
<?php endif ?>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div data-control="toolbar">
|
||||
<a
|
||||
href="<?= Backend::url('system/maillayouts/create') ?>"
|
||||
class="btn btn-primary wn-icon-plus">
|
||||
<?= e(trans('system::lang.mail_templates.new_layout')) ?>
|
||||
</a>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div data-control="toolbar">
|
||||
<a
|
||||
href="<?= Backend::url('system/mailpartials/create') ?>"
|
||||
class="btn btn-primary wn-icon-plus">
|
||||
<?= e(trans('system::lang.mail_templates.new_partial')) ?>
|
||||
</a>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
<div data-control="toolbar">
|
||||
<a
|
||||
href="<?= Backend::url('system/mailtemplates/create') ?>"
|
||||
class="btn btn-primary wn-icon-plus">
|
||||
<?= e(trans('system::lang.mail_templates.new_template')) ?>
|
||||
</a>
|
||||
</div>
|
||||
16
modules/system/controllers/mailtemplates/config_form.yaml
Normal file
16
modules/system/controllers/mailtemplates/config_form.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
# ===================================
|
||||
# Form Behavior Config
|
||||
# ===================================
|
||||
|
||||
name: system::lang.mail_templates.template
|
||||
form: ~/modules/system/models/mailtemplate/fields.yaml
|
||||
modelClass: System\Models\MailTemplate
|
||||
defaultRedirect: system/mailtemplates
|
||||
|
||||
create:
|
||||
redirect: system/mailtemplates/update/:id
|
||||
redirectClose: system/mailtemplates
|
||||
|
||||
update:
|
||||
redirect: system/mailtemplates
|
||||
redirectClose: system/mailtemplates
|
||||
@@ -0,0 +1,16 @@
|
||||
# ===================================
|
||||
# List Behavior Config
|
||||
# ===================================
|
||||
|
||||
title: system::lang.mail_templates.menu_label
|
||||
list: ~/modules/system/models/maillayout/columns.yaml
|
||||
modelClass: System\Models\MailLayout
|
||||
recordUrl: system/maillayouts/update/:id
|
||||
noRecordsMessage: backend::lang.list.no_records
|
||||
recordsPerPage: 20
|
||||
showSetup: true
|
||||
|
||||
toolbar:
|
||||
buttons: list_layouts_toolbar
|
||||
search:
|
||||
prompt: backend::lang.list.search_prompt
|
||||
@@ -0,0 +1,16 @@
|
||||
# ===================================
|
||||
# List Behavior Config
|
||||
# ===================================
|
||||
|
||||
title: system::lang.mail_partials.menu_label
|
||||
list: ~/modules/system/models/mailpartial/columns.yaml
|
||||
modelClass: System\Models\MailPartial
|
||||
recordUrl: system/mailpartials/update/:id
|
||||
noRecordsMessage: backend::lang.list.no_records
|
||||
recordsPerPage: 20
|
||||
showSetup: true
|
||||
|
||||
toolbar:
|
||||
buttons: list_partials_toolbar
|
||||
search:
|
||||
prompt: backend::lang.list.search_prompt
|
||||
@@ -0,0 +1,16 @@
|
||||
# ===================================
|
||||
# List Behavior Config
|
||||
# ===================================
|
||||
|
||||
title: system::lang.mail_templates.menu_label
|
||||
list: ~/modules/system/models/mailtemplate/columns.yaml
|
||||
modelClass: System\Models\MailTemplate
|
||||
recordUrl: system/mailtemplates/update/:id
|
||||
noRecordsMessage: backend::lang.list.no_records
|
||||
recordsPerPage: 20
|
||||
showSetup: true
|
||||
|
||||
toolbar:
|
||||
buttons: list_templates_toolbar
|
||||
search:
|
||||
prompt: backend::lang.list.search_prompt
|
||||
30
modules/system/controllers/mailtemplates/index.php
Normal file
30
modules/system/controllers/mailtemplates/index.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<div class="control-tabs content-tabs tabs-flush" data-control="tab">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="<?= $activeTab == 'templates' ? 'active' : '' ?>">
|
||||
<a href="#templates" data-tab-url="<?= Backend::url('system/mailtemplates/index/templates') ?>">
|
||||
<?= e(trans('system::lang.mail_templates.templates')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?= $activeTab == 'layouts' ? 'active' : '' ?>">
|
||||
<a href="#layouts" data-tab-url="<?= Backend::url('system/mailtemplates/index/layouts') ?>">
|
||||
<?= e(trans('system::lang.mail_templates.layouts')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?= $activeTab == 'partials' ? 'active' : '' ?>">
|
||||
<a href="#partials" data-tab-url="<?= Backend::url('system/mailtemplates/index/partials') ?>">
|
||||
<?= e(trans('system::lang.mail_templates.partials')) ?>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane <?= $activeTab == 'templates' ? 'active' : '' ?>">
|
||||
<?= $this->listRender('templates') ?>
|
||||
</div>
|
||||
<div class="tab-pane <?= $activeTab == 'layouts' ? 'active' : '' ?>">
|
||||
<?= $this->listRender('layouts') ?>
|
||||
</div>
|
||||
<div class="tab-pane <?= $activeTab == 'partials' ? 'active' : '' ?>">
|
||||
<?= $this->listRender('partials') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
77
modules/system/controllers/mailtemplates/update.php
Normal file
77
modules/system/controllers/mailtemplates/update.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<?= Form::open(['class'=>'layout']) ?>
|
||||
|
||||
<div class="layout-row min-size">
|
||||
<div class="scoreboard">
|
||||
<div data-control="toolbar">
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.mail_templates.template')) ?></h4>
|
||||
<p><?= e($formModel->code) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-row">
|
||||
<?= $this->formRender() ?>
|
||||
</div>
|
||||
|
||||
<div class="form-buttons p-t">
|
||||
<div class="loading-indicator-container">
|
||||
<button
|
||||
type="submit"
|
||||
data-request="onSave"
|
||||
data-browser-validate
|
||||
data-request-data="redirect:0"
|
||||
data-hotkey="ctrl+s, cmd+s"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.saving')) ?>"
|
||||
class="btn btn-primary">
|
||||
<?= e(trans('backend::lang.form.save')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-request="onSave"
|
||||
data-browser-validate
|
||||
data-request-data="close:1"
|
||||
data-hotkey="ctrl+enter, cmd+enter"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.saving')) ?>"
|
||||
class="btn btn-default">
|
||||
<?= e(trans('backend::lang.form.save_and_close')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-request="onTest"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.sending')) ?>"
|
||||
data-request-confirm="<?= e(trans('system::lang.mail_templates.test_confirm', [ 'email' => e(BackendAuth::getUser()->email)])) ?>"
|
||||
class="btn btn-info">
|
||||
<?= e(trans('system::lang.mail_templates.test_send')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="wn-icon-trash-o btn-icon danger pull-right"
|
||||
data-request="onDelete"
|
||||
data-load-indicator="<?= e(trans('system::lang.mail_templates.deleting')) ?>"
|
||||
data-request-confirm="<?= e(trans('system::lang.mail_templates.delete_confirm')) ?>">
|
||||
</button>
|
||||
<span class="btn-text">
|
||||
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= Form::close() ?>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
<p><a href="<?= Backend::url('system/mailtemplates') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
|
||||
|
||||
<?php endif ?>
|
||||
4
modules/system/controllers/requestlogs/_hint.php
Normal file
4
modules/system/controllers/requestlogs/_hint.php
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
<p>
|
||||
<?= e(trans('system::lang.request_log.hint')) ?>
|
||||
</p>
|
||||
31
modules/system/controllers/requestlogs/_list_toolbar.php
Normal file
31
modules/system/controllers/requestlogs/_list_toolbar.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<div data-control="toolbar" class="loading-indicator-container">
|
||||
<a
|
||||
href="javascript:;"
|
||||
data-request="onRefresh"
|
||||
data-load-indicator="<?= e(trans('backend::lang.list.updating')) ?>"
|
||||
class="btn btn-primary wn-icon-refresh">
|
||||
<?= e(trans('backend::lang.list.refresh')) ?>
|
||||
</a>
|
||||
<a
|
||||
href="javascript:;"
|
||||
data-request="onEmptyLog"
|
||||
data-request-confirm="<?= e(trans('backend::lang.list.delete_selected_confirm')) ?>"
|
||||
data-load-indicator="<?= e(trans('system::lang.request_log.empty_loading')) ?>"
|
||||
class="btn btn-default wn-icon-eraser">
|
||||
<?= e(trans('system::lang.request_log.empty_link')) ?>
|
||||
</a>
|
||||
<button
|
||||
class="btn btn-danger wn-icon-trash-o"
|
||||
disabled="disabled"
|
||||
onclick="$(this).data('request-data', {
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request="onDelete"
|
||||
data-trigger-action="enable"
|
||||
data-trigger=".control-list input[type=checkbox]"
|
||||
data-trigger-condition="checked"
|
||||
data-request-success="$(this).prop('disabled', true)"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('backend::lang.list.delete_selected')) ?>
|
||||
</button>
|
||||
</div>
|
||||
11
modules/system/controllers/requestlogs/_referer_field.php
Normal file
11
modules/system/controllers/requestlogs/_referer_field.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php if ($formModel->referer && count($formModel->referer) > 0): ?>
|
||||
<div class="form-control control-simplelist with-icons">
|
||||
<ul>
|
||||
<?php foreach ((array) $formModel->referer as $referer): ?>
|
||||
<li class="wn-icon-file-o"><?= e($referer) ?></li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="form-control"><em>There were no detected referers to this URL.</em></div>
|
||||
<?php endif ?>
|
||||
19
modules/system/controllers/requestlogs/config_form.yaml
Normal file
19
modules/system/controllers/requestlogs/config_form.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
# ===================================
|
||||
# Form Behavior Config
|
||||
# ===================================
|
||||
|
||||
# Record name
|
||||
name: system::lang.event_log.menu_label
|
||||
|
||||
# Model Form Field configuration
|
||||
form: ~/modules/system/models/requestlog/fields.yaml
|
||||
|
||||
# Model Class name
|
||||
modelClass: System\Models\RequestLog
|
||||
|
||||
# Default redirect location
|
||||
defaultRedirect: system/requestlogs
|
||||
|
||||
# Preview page
|
||||
preview:
|
||||
title: system::lang.request_log.preview_title
|
||||
20
modules/system/controllers/requestlogs/config_list.yaml
Normal file
20
modules/system/controllers/requestlogs/config_list.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
# ===================================
|
||||
# List Behavior Config
|
||||
# ===================================
|
||||
|
||||
title: system::lang.request_log.menu_label
|
||||
list: ~/modules/system/models/requestlog/columns.yaml
|
||||
modelClass: System\Models\RequestLog
|
||||
recordUrl: system/requestlogs/preview/:id
|
||||
noRecordsMessage: backend::lang.list.no_records
|
||||
recordsPerPage: 30
|
||||
showSetup: true
|
||||
showCheckboxes: true
|
||||
defaultSort:
|
||||
column: count
|
||||
direction: desc
|
||||
|
||||
toolbar:
|
||||
buttons: list_toolbar
|
||||
search:
|
||||
prompt: backend::lang.list.search_prompt
|
||||
5
modules/system/controllers/requestlogs/index.php
Normal file
5
modules/system/controllers/requestlogs/index.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<div class="padded-container container-flush">
|
||||
<?= $this->makeHintPartial('system_requestlogs_hint', 'hint') ?>
|
||||
</div>
|
||||
|
||||
<?= $this->listRender() ?>
|
||||
45
modules/system/controllers/requestlogs/preview.php
Normal file
45
modules/system/controllers/requestlogs/preview.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/requestlogs') ?>"><?= e(trans('system::lang.request_log.menu_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<div class="scoreboard">
|
||||
<div data-control="toolbar">
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.request_log.id_label')) ?></h4>
|
||||
<p>#<?= $formModel->id ?></p>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.request_log.status_code')) ?></h4>
|
||||
<p><?= $formModel->status_code ?></p>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.request_log.count')) ?></h4>
|
||||
<p><?= $formModel->count ?></p>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.request_log.referer')) ?></h4>
|
||||
<p><?= $formModel->referer ? count($formModel->referer) : 0 ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layout-item stretch layout-column">
|
||||
<?= $this->formRenderPreview() ?>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<p>
|
||||
<a href="<?= Backend::url('system/requestlogs') ?>" class="btn btn-default wn-icon-chevron-left">
|
||||
<?= e(trans('system::lang.request_log.return_link')) ?>
|
||||
</a>
|
||||
</p>
|
||||
16
modules/system/controllers/settings/index.php
Normal file
16
modules/system/controllers/settings/index.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="layout">
|
||||
<div class="layout-cell wn-logo-transparent">
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
var $search = $('#settings-search-input'),
|
||||
focusSearch = function() {
|
||||
setTimeout(function() { $search.focus().select() }, 10)
|
||||
}
|
||||
|
||||
$search.on('blur', focusSearch)
|
||||
focusSearch()
|
||||
})
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
24
modules/system/controllers/settings/mysettings.php
Normal file
24
modules/system/controllers/settings/mysettings.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<div class="control-settings">
|
||||
|
||||
<?php foreach ($items as $category => $items): ?>
|
||||
|
||||
<div class="settings-category">
|
||||
<h3><?= e(trans($category)) ?></h3>
|
||||
</div>
|
||||
|
||||
<div class="settings-items row">
|
||||
|
||||
<?php foreach ($items as $item): ?>
|
||||
<div class="settings-item col-xs-12 col-md-6 col-lg-4">
|
||||
<a href="<?= $item->url ?>">
|
||||
<div class="item-icon"><i class="<?= $item->icon ?>"></i></div>
|
||||
<h5><?= e(trans($item->label)) ?></h5>
|
||||
<p><?= e(trans($item->description)) ?></p>
|
||||
</a>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
|
||||
</div>
|
||||
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
48
modules/system/controllers/settings/update.php
Normal file
48
modules/system/controllers/settings/update.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<?= Form::open(['class' => 'layout']) ?>
|
||||
|
||||
<div class="layout-row">
|
||||
<?= $this->formRender() ?>
|
||||
</div>
|
||||
|
||||
<div class="form-buttons">
|
||||
<div class="loading-indicator-container">
|
||||
<button
|
||||
type="submit"
|
||||
data-request="onSave"
|
||||
data-request-data="redirect:0"
|
||||
data-hotkey="ctrl+s, cmd+s"
|
||||
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
|
||||
class="btn btn-primary">
|
||||
<?= e(trans('backend::lang.form.save')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
data-request="onSave"
|
||||
data-request-data="close:1"
|
||||
data-hotkey="ctrl+enter, cmd+enter"
|
||||
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
|
||||
class="btn btn-default">
|
||||
<?= e(trans('backend::lang.form.save_and_close')) ?>
|
||||
</button>
|
||||
<span class="btn-text">
|
||||
<?= e(trans('backend::lang.form.or')) ?> <a href="<?= Backend::url('system/settings') ?>"><?= e(trans('backend::lang.form.cancel')) ?></a>
|
||||
</span>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-danger pull-right"
|
||||
data-request="onResetDefault"
|
||||
data-load-indicator="<?= e(trans('backend::lang.form.resetting')) ?>"
|
||||
data-request-confirm="<?= e(trans('backend::lang.form.action_confirm')) ?>">
|
||||
<?= e(trans('backend::lang.form.reset_default')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<?= Form::close() ?>
|
||||
|
||||
<?php else: ?>
|
||||
<p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
|
||||
<p><a href="<?= $parentLink ?>" class="btn btn-default"><?= e(trans('system::lang.settings.return')) ?></a></p>
|
||||
<?php endif ?>
|
||||
48
modules/system/controllers/updates/_changelog_list.php
Normal file
48
modules/system/controllers/updates/_changelog_list.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title"><?= e(trans('system::lang.updates.changelog')) ?></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<?php if ($this->fatalError): ?>
|
||||
<p class="flash-message static error"><?= e($fatalError) ?></p>
|
||||
<?php else: ?>
|
||||
<div class="control-updatelist">
|
||||
<div class="control-scrollbar" style="height:400px" data-control="scrollbar">
|
||||
<div class="update-item">
|
||||
<dl>
|
||||
<?php foreach ($changelog as $item): ?>
|
||||
<?php
|
||||
$description = array_get($item, 'description');
|
||||
$build = array_get($item, 'build');
|
||||
$linkUrl = array_get($item, 'link_url');
|
||||
?>
|
||||
<dt><?= e($build) ?></dt>
|
||||
<?php if ($linkUrl): ?>
|
||||
<dd>
|
||||
<?= e($description) ?>
|
||||
<br>
|
||||
<a href="<?= $linkUrl ?>" target="_blank">
|
||||
<?= e(trans('system::lang.updates.changelog_view_details')) ?>
|
||||
<i class="icon-external-link"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<?php else: ?>
|
||||
<dd><?= e($description) ?></dd>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.close')) ?>
|
||||
</button>
|
||||
</div>
|
||||
16
modules/system/controllers/updates/_column_code.php
Normal file
16
modules/system/controllers/updates/_column_code.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
$icon = null;
|
||||
|
||||
if ($record->is_disabled) {
|
||||
$icon = 'eye-slash';
|
||||
} elseif ($record->disabledBySystem) {
|
||||
$icon = 'exclamation';
|
||||
} elseif ($record->orphaned) {
|
||||
$icon = 'question';
|
||||
} elseif ($record->is_frozen) {
|
||||
$icon = 'lock';
|
||||
}
|
||||
?>
|
||||
<span class="<?= $icon ? 'wn-icon-'.$icon : '' ?>">
|
||||
<?= $value ?>
|
||||
</span>
|
||||
70
modules/system/controllers/updates/_execute.php
Normal file
70
modules/system/controllers/updates/_execute.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<div id="executePopup">
|
||||
|
||||
<div id="executeActivity">
|
||||
<div class="modal-body modal-no-header">
|
||||
<div class="progress bar-loading-indicator" id="executeLoadingBar">
|
||||
<div class="progress-bar"></div>
|
||||
</div>
|
||||
|
||||
<div class="loading-indicator-container">
|
||||
<p> </p>
|
||||
<div class="loading-indicator transparent">
|
||||
<div id="executeMessage"></div>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="executeStatus"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/template" id="executeFailed">
|
||||
<div class="modal-body modal-no-header">
|
||||
<div class="callout callout-danger no-icon">
|
||||
<div class="header">
|
||||
<h3><?= e(trans('system::lang.updates.update_failed_label')) ?></h3>
|
||||
<p>{{ reason }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
onclick="$.wn.updateProcess.retryUpdate()">
|
||||
<?= e(trans('system::lang.updates.retry_label')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
$('#executePopup').on('popupComplete', function() {
|
||||
$.wn.updateProcess.execute(<?= json_encode($updateSteps) ?>)
|
||||
})
|
||||
</script>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div class="modal-body modal-no-header">
|
||||
<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 ?>
|
||||
104
modules/system/controllers/updates/_install_plugins.php
Normal file
104
modules/system/controllers/updates/_install_plugins.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<div>
|
||||
|
||||
<!-- Search -->
|
||||
<form
|
||||
role="form"
|
||||
id="installPluginsForm"
|
||||
data-handler="onInstallPlugin"
|
||||
onsubmit="$.wn.installProcess.searchSubmit(this); return false">
|
||||
<div class="product-search">
|
||||
<input
|
||||
name="code"
|
||||
id="pluginSearchInput"
|
||||
class="product-search-input search-input-lg typeahead"
|
||||
placeholder="<?= e(trans('system::lang.plugins.search')) ?>"
|
||||
data-search-type="plugins"
|
||||
/>
|
||||
<i class="icon icon-search"></i>
|
||||
<i class="icon loading" style="display: none"></i>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-7">
|
||||
|
||||
<!-- Installed plugins -->
|
||||
<div id="pluginList"
|
||||
class="product-list-manager">
|
||||
|
||||
<h4 class="section-header">
|
||||
<a href="<?= Backend::url('system/updates') ?>"><?= e(trans('system::lang.plugins.installed')) ?></a>
|
||||
<small>(<span class="product-counter"><?= count($installedPlugins) ?></span>)</small>
|
||||
</h4>
|
||||
|
||||
<?php if (!count($installedPlugins)): ?>
|
||||
<div class="product-list-empty">
|
||||
<p><?= e(trans('system::lang.plugins.no_plugins')) ?></p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<ul class="product-list plugin-list">
|
||||
<?php foreach ($installedPlugins as $plugin): ?>
|
||||
|
||||
<li data-code="<?= $plugin['code'] ?>">
|
||||
<div class="image">
|
||||
<img src="<?= $plugin['image'] ?>" alt="">
|
||||
</div>
|
||||
<div class="details">
|
||||
<h4><?= $plugin['name'] ?></h4>
|
||||
<p><?= e(trans('system::lang.plugin.by_author', ['name' => $plugin['author']])) ?></p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="close"
|
||||
aria-hidden="true"
|
||||
data-request="onRemovePlugin"
|
||||
data-request-data="code: '<?= $plugin['code'] ?>'"
|
||||
data-request-confirm="<?= e(trans('system::lang.plugins.remove_confirm')) ?>"
|
||||
data-stripe-load-indicator>
|
||||
×
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
<?php endif ?>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
|
||||
<!-- Recommended extras -->
|
||||
<div class="suggested-products-container">
|
||||
<h4 class="section-header"><?= e(trans('system::lang.plugins.recommended')) ?></h4>
|
||||
<div class="scroll-panel">
|
||||
<div
|
||||
id="suggestedPlugins"
|
||||
class="suggested-products suggested-plugins"
|
||||
data-handler="onGetPopularPlugins"
|
||||
data-view="plugin/suggestion"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/template" data-partial="plugin/suggestion">
|
||||
<div class="product">
|
||||
<a
|
||||
data-control="popup"
|
||||
data-handler="onInstallPlugin"
|
||||
data-request-data="code: '{{code}}'"
|
||||
href="javascript:;">
|
||||
<div class="image"><img src="{{image}}" alt=""></div>
|
||||
<div class="details">
|
||||
<h5 class="text-overflow">{{code}}</h5>
|
||||
<p>{{description}}</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</script>
|
||||
106
modules/system/controllers/updates/_install_themes.php
Normal file
106
modules/system/controllers/updates/_install_themes.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<div>
|
||||
|
||||
<!-- Search -->
|
||||
<form
|
||||
role="form"
|
||||
id="installThemesForm"
|
||||
data-handler="onInstallTheme"
|
||||
onsubmit="$.wn.installProcess.searchSubmit(this); return false">
|
||||
<div class="product-search">
|
||||
<input
|
||||
name="code"
|
||||
id="themeSearchInput"
|
||||
class="product-search-input search-input-lg typeahead"
|
||||
placeholder="<?= e(trans('system::lang.themes.search')) ?>"
|
||||
data-search-type="themes"
|
||||
/>
|
||||
<i class="icon icon-search"></i>
|
||||
<i class="icon loading" style="display: none"></i>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-md-7">
|
||||
|
||||
<!-- Installed themes -->
|
||||
<div id="themeList"
|
||||
class="product-list-manager"
|
||||
data-handler="onGetInstalledThemes"
|
||||
data-view="product/theme">
|
||||
|
||||
<h4 class="section-header">
|
||||
<a href="<?= Backend::url('cms/themes') ?>"><?= e(trans('system::lang.themes.installed')) ?></a>
|
||||
<small>(<span class="product-counter"><?= count($installedThemes) ?></span>)</small>
|
||||
</h4>
|
||||
|
||||
<?php if (!count($installedThemes)): ?>
|
||||
<div class="product-list-empty">
|
||||
<p><?= e(trans('system::lang.themes.no_themes')) ?></p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<ul class="product-list theme-list">
|
||||
<?php foreach ($installedThemes as $theme): ?>
|
||||
|
||||
<li data-code="<?= $theme['code'] ?>">
|
||||
<div class="image">
|
||||
<img src="<?= $theme['image'] ?>" alt="">
|
||||
</div>
|
||||
<div class="details">
|
||||
<h4><?= $theme['name'] ?></h4>
|
||||
<p><?= e(trans('cms::lang.theme.by_author', ['name' => $theme['author']])) ?></p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="close"
|
||||
aria-hidden="true"
|
||||
data-request="onRemoveTheme"
|
||||
data-request-data="code: '<?= $theme['dirName'] ?>'"
|
||||
data-request-confirm="<?= e(trans('system::lang.themes.remove_confirm')) ?>"
|
||||
data-stripe-load-indicator>
|
||||
×
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
<?php endif ?>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
|
||||
<!-- Recommended extras -->
|
||||
<div class="suggested-products-container">
|
||||
<h4 class="section-header"><?= e(trans('system::lang.themes.recommended')) ?></h4>
|
||||
<div class="scroll-panel">
|
||||
<div
|
||||
id="suggestedThemes"
|
||||
class="suggested-products suggested-themes"
|
||||
data-handler="onGetPopularThemes"
|
||||
data-view="theme/suggestion"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/template" data-partial="theme/suggestion">
|
||||
<div class="product">
|
||||
<a
|
||||
data-control="popup"
|
||||
data-handler="onInstallTheme"
|
||||
data-request-data="code: '{{code}}'"
|
||||
href="javascript:;">
|
||||
<div class="image"><img src="{{image}}" alt=""></div>
|
||||
<div class="details">
|
||||
<h5 class="text-overflow">{{code}}</h5>
|
||||
<p>{{description}}</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</script>
|
||||
20
modules/system/controllers/updates/_is_enabled.php
Normal file
20
modules/system/controllers/updates/_is_enabled.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php $action = $record->is_disabled ? 'enable' : 'disable'; ?>
|
||||
<label class="custom-switch" data-check="wn-disable-<?= $record->id ?>" style="margin-bottom:0">
|
||||
<input data-request="onBulkAction"
|
||||
data-request-data="action: '<?= $action ?>', checked: [<?= $record->id ?>]"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
type="checkbox"
|
||||
name="disable_<?= $record->id ?>"
|
||||
value="<?= !$record->is_disabled ?>"
|
||||
<?php if (!$record->is_disabled): ?>
|
||||
checked="checked"
|
||||
<?php endif ?>
|
||||
data-stripe-load-indicator
|
||||
>
|
||||
|
||||
<span>
|
||||
<span><?= e(trans('system::lang.plugins.check_yes')) ?></span>
|
||||
<span><?= e(trans('system::lang.plugins.check_no')) ?></span>
|
||||
</span>
|
||||
<a class="slide-button"></a>
|
||||
</label>
|
||||
20
modules/system/controllers/updates/_is_unfrozen.php
Normal file
20
modules/system/controllers/updates/_is_unfrozen.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php $action = $record->is_frozen ? 'unfreeze' : 'freeze'; ?>
|
||||
<label class="custom-switch" data-check="wn-freeze-<?= $record->id ?>" style="margin-bottom:0">
|
||||
<input data-request="onBulkAction"
|
||||
data-request-data="action: '<?= $action ?>', checked: [<?= $record->id ?>]"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
type="checkbox"
|
||||
name="freeze_<?= $record->id ?>"
|
||||
value="<?= !$record->is_frozen ?>"
|
||||
<?php if (!$record->is_frozen): ?>
|
||||
checked="checked"
|
||||
<?php endif; ?>
|
||||
data-stripe-load-indicator
|
||||
>
|
||||
|
||||
<span>
|
||||
<span><?= e(trans('system::lang.plugins.check_yes')) ?></span>
|
||||
<span><?= e(trans('system::lang.plugins.check_no')) ?></span>
|
||||
</span>
|
||||
<a class="slide-button"></a>
|
||||
</label>
|
||||
112
modules/system/controllers/updates/_list_manage_toolbar.php
Normal file
112
modules/system/controllers/updates/_list_manage_toolbar.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<div id="plugin-toolbar">
|
||||
<div data-control="toolbar">
|
||||
<a href="<?= Backend::url('system/updates') ?>" class="btn btn-default wn-icon-chevron-left">
|
||||
<?= e(trans('system::lang.updates.return_link')) ?>
|
||||
</a>
|
||||
|
||||
<div class="btn-group dropdown dropdown-fixed">
|
||||
<button
|
||||
data-primary-button
|
||||
type="button"
|
||||
class="btn btn-default wn-icon-caret-down dropdown-toggle"
|
||||
data-toggle="dropdown"
|
||||
data-trigger-action="enable"
|
||||
data-trigger=".control-list .list-checkbox input[type=checkbox]"
|
||||
data-trigger-condition="checked"
|
||||
data-request-success="$(this).prop('disabled', true).next().prop('disabled', true)">
|
||||
<?= e(trans('system::lang.plugins.select_label')) ?>
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu" data-dropdown-title="<?= e(trans('system::lang.plugins.bulk_actions_label')) ?>">
|
||||
<li>
|
||||
<a href="javascript:;" class="wn-icon-pause"
|
||||
data-request="onBulkAction"
|
||||
onclick="$(this).data('request-data', {
|
||||
action: 'freeze',
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
data-request-confirm="<?= e(trans('system::lang.plugins.action_confirm', ['action' => e(trans('system::lang.plugins.freeze'))])) ?>"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('system::lang.plugins.freeze_label')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" class="wn-icon-play"
|
||||
data-request="onBulkAction"
|
||||
onclick="$(this).data('request-data', {
|
||||
action: 'unfreeze',
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
data-request-confirm="<?= e(trans('system::lang.plugins.action_confirm', ['action' => e(trans('system::lang.plugins.unfreeze'))])) ?>"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('system::lang.plugins.unfreeze_label')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li>
|
||||
<a href="javascript:;" class="wn-icon-ban"
|
||||
data-request="onBulkAction"
|
||||
onclick="$(this).data('request-data', {
|
||||
action: 'disable',
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
data-request-confirm="<?= e(trans('system::lang.plugins.action_confirm', ['action' => e(trans('system::lang.plugins.disable'))])) ?>"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('system::lang.plugins.disable_label')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="javascript:;" class="wn-icon-check"
|
||||
data-request="onBulkAction"
|
||||
onclick="$(this).data('request-data', {
|
||||
action: 'enable',
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
data-request-confirm="<?= e(trans('system::lang.plugins.action_confirm', ['action' => e(trans('system::lang.plugins.enable'))])) ?>"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('system::lang.plugins.enable_label')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php if (\Config::get('app.debug', false) && \BackendAuth::getUser()->is_superuser): ?>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li>
|
||||
<a href="javascript:;" class="wn-icon-bomb"
|
||||
data-request="onBulkAction"
|
||||
onclick="$(this).data('request-data', {
|
||||
action: 'refresh',
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
data-request-confirm="<?= e(trans('system::lang.plugins.refresh_confirm')) ?>"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('system::lang.plugins.refresh_label')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button
|
||||
class="btn btn-danger wn-icon-trash-o"
|
||||
disabled="disabled"
|
||||
data-request="onBulkAction"
|
||||
onclick="$(this).data('request-data', {
|
||||
action: 'remove',
|
||||
checked: $('.control-list').listWidget('getChecked')
|
||||
})"
|
||||
data-request-update="list_manage_toolbar: '#plugin-toolbar'"
|
||||
data-request-confirm="<?= e(trans('system::lang.plugins.remove_confirm')) ?>"
|
||||
data-trigger-action="enable"
|
||||
data-trigger=".control-list .list-checkbox input[type=checkbox]"
|
||||
data-trigger-condition="checked"
|
||||
data-request-success="$(this).closest('.btn-group').find('button').prop('disabled', true)"
|
||||
data-stripe-load-indicator>
|
||||
<?= e(trans('system::lang.plugins.remove')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
24
modules/system/controllers/updates/_list_toolbar.php
Normal file
24
modules/system/controllers/updates/_list_toolbar.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<div data-control="toolbar">
|
||||
<a
|
||||
href="javascript:;"
|
||||
class="btn btn-primary wn-icon-refresh"
|
||||
data-control="popup"
|
||||
data-handler="onLoadUpdates">
|
||||
<?= e(trans('system::lang.updates.check_label')) ?>
|
||||
</a>
|
||||
<a
|
||||
href="<?= Backend::url('system/updates/install') ?>"
|
||||
class="btn btn-success wn-icon-plus">
|
||||
<?= e(trans('system::lang.plugins.install')) ?>
|
||||
</a>
|
||||
<a
|
||||
href="<?= Backend::url('system/updates/install/themes') ?>"
|
||||
class="btn btn-success wn-icon-plus">
|
||||
<?= e(trans('system::lang.themes.install')) ?>
|
||||
</a>
|
||||
<a
|
||||
href="<?= Backend::url('system/updates/manage') ?>"
|
||||
class="btn btn-default wn-icon-puzzle-piece">
|
||||
<?= e(trans('system::lang.plugins.manage')) ?>
|
||||
</a>
|
||||
</div>
|
||||
47
modules/system/controllers/updates/_plugin_form.php
Normal file
47
modules/system/controllers/updates/_plugin_form.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?= Form::open(['id' => 'pluginForm']) ?>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title"><?= e(trans('system::lang.install.plugin_label')) ?></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<?php if ($this->fatalError): ?>
|
||||
<p class="flash-message static error"><?= e($fatalError) ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="pluginCode"><?= e(trans('system::lang.plugin.name.label')) ?></label>
|
||||
<input
|
||||
name="code"
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="pluginCode"
|
||||
value="<?= e(post('code')) ?>" />
|
||||
<p class="help-block"><?= e(trans('system::lang.plugin.name.help')) ?></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
data-dismiss="popup"
|
||||
data-control="popup"
|
||||
data-handler="onInstallPlugin">
|
||||
<?= e(trans('system::lang.install.plugin_label')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(
|
||||
function(){ $('#pluginCode').select() },
|
||||
310
|
||||
)
|
||||
</script>
|
||||
<?= Form::close() ?>
|
||||
50
modules/system/controllers/updates/_project_form.php
Normal file
50
modules/system/controllers/updates/_project_form.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?= Form::open(['id' => 'projectForm']) ?>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title"><?= e(trans('system::lang.install.project_label')) ?></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<?php if ($this->fatalError): ?>
|
||||
<p class="flash-message static error"><?= e($fatalError) ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="form-group">
|
||||
<span class="help-block pull-right">
|
||||
<a target="_blank" href="https://wintercms.com/help/site/projects#project-id"><?= e(trans('system::lang.project.id.help')) ?></a>
|
||||
</span>
|
||||
<label for="projectId"><?= e(trans('system::lang.project.id.label')) ?></label>
|
||||
<input
|
||||
name="project_id"
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="projectId"
|
||||
value="<?= e(post('project_id')) ?>"
|
||||
autocomplete="off" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
data-dismiss="popup"
|
||||
data-control="popup"
|
||||
data-handler="onAttachProject">
|
||||
<?= e(trans('system::lang.install.project_label')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(
|
||||
function(){ $('#projectId').select() },
|
||||
310
|
||||
)
|
||||
</script>
|
||||
<?= Form::close() ?>
|
||||
47
modules/system/controllers/updates/_theme_form.php
Normal file
47
modules/system/controllers/updates/_theme_form.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?= Form::open(['id' => 'themeForm']) ?>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title"><?= e(trans('system::lang.install.theme_label')) ?></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<?php if ($this->fatalError): ?>
|
||||
<p class="flash-message static error"><?= e($fatalError) ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="themeCode"><?= e(trans('system::lang.theme.name.label')) ?></label>
|
||||
<input
|
||||
name="code"
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="themeCode"
|
||||
value="<?= e(post('code')) ?>" />
|
||||
<p class="help-block"><?= e(trans('system::lang.theme.name.help')) ?></p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
data-dismiss="popup"
|
||||
data-control="popup"
|
||||
data-handler="onInstallTheme">
|
||||
<?= e(trans('system::lang.install.theme_label')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(
|
||||
function(){ $('#themeCode').select() },
|
||||
310
|
||||
)
|
||||
</script>
|
||||
<?= Form::close() ?>
|
||||
37
modules/system/controllers/updates/_update_form.php
Normal file
37
modules/system/controllers/updates/_update_form.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<div id="checkUpdatesPopup">
|
||||
<?= Form::open(['id' => 'updateForm']) ?>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="popup">×</button>
|
||||
<h4 class="modal-title"><?= e(trans('system::lang.updates.name')) ?></h4>
|
||||
</div>
|
||||
|
||||
<div id="updateContainer">
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="loading-indicator-container">
|
||||
<p> </p>
|
||||
<div class="loading-indicator transparent">
|
||||
<div><?= e(trans('system::lang.updates.update_loading')) ?></div>
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.cancel')) ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?= Form::close() ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$('#checkUpdatesPopup').on('popupComplete', function() {
|
||||
$.wn.updateProcess.check()
|
||||
})
|
||||
</script>
|
||||
206
modules/system/controllers/updates/_update_list.php
Normal file
206
modules/system/controllers/updates/_update_list.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<?php if ($hasUpdates): ?>
|
||||
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
<strong><?= e(trans('system::lang.updates.found.label')) ?></strong>
|
||||
<?= e(trans('system::lang.updates.found.help')) ?>
|
||||
</p>
|
||||
|
||||
<div class="control-updatelist">
|
||||
<div class="control-scrollbar" style="height:400px" data-control="scrollbar">
|
||||
<?php if ($core): ?>
|
||||
<div class="update-item <?= $core['isImportant'] ? 'item-danger' : '' ?>">
|
||||
<div class="item-header">
|
||||
<?php if ($core['isImportant']): ?>
|
||||
<div class="important-update form-group form-group-sm">
|
||||
<select
|
||||
name="core_action"
|
||||
class="form-control custom-select select-no-search"
|
||||
data-important-update-select>
|
||||
<option value="">-- <?= e(trans('system::lang.updates.important_action.empty')) ?> --</option>
|
||||
<option value="confirm"><?= e(trans('system::lang.updates.important_action.confirm')) ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<h5>
|
||||
<i class="icon-cube"></i>
|
||||
<?= e(trans('system::lang.system.name')) ?>
|
||||
</h5>
|
||||
</div>
|
||||
<dl>
|
||||
<?php foreach (array_get($core, 'updates', []) as $build => $description): ?>
|
||||
<dt><?= e(trans('system::lang.updates.core_build', ['build'=>$build])) ?></dt>
|
||||
<?php if (is_array($description)): ?>
|
||||
<dd>
|
||||
<span class="important-update-label">
|
||||
<?= e(trans('system::lang.updates.important_action_required')) ?>
|
||||
</span>
|
||||
<?= e($description[0]) ?>
|
||||
<a href="<?= $description[1] ?>" target="_blank">
|
||||
<?= e(trans('system::lang.updates.important_view_release_notes')) ?>
|
||||
<i class="icon-external-link"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<?php else: ?>
|
||||
<dd><?= e($description) ?></dd>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
<?php if ($core['old_build']): ?>
|
||||
<dt class="text-muted"><?= e(trans('system::lang.updates.core_build', ['build'=>$core['old_build']])) ?></dt>
|
||||
<dd class="text-muted"><?= e(trans('system::lang.updates.core_current_build')) ?></dd>
|
||||
<?php endif ?>
|
||||
</dl>
|
||||
<input type="hidden" name="hash" value="<?= e($core['hash']) ?>" />
|
||||
<input type="hidden" name="build" value="<?= e($core['build']) ?>" />
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<?php foreach ($themeList as $code => $theme): ?>
|
||||
<div class="update-item">
|
||||
<div class="item-header">
|
||||
<h5>
|
||||
<i class="icon-picture-o"></i>
|
||||
<?= e(array_get($theme, 'name', 'Unknown')) ?>
|
||||
</h5>
|
||||
</div>
|
||||
<dl>
|
||||
<dt><?= e(array_get($theme, 'version', 'v1.0.0')) ?></dt>
|
||||
<dd><?= e(trans('system::lang.updates.theme_new_install')) ?></dd>
|
||||
</dl>
|
||||
|
||||
<input type="hidden" name="themes[<?= e($this->encodeCode($code)) ?>]" value="<?= e($theme['hash']) ?>" />
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
|
||||
<?php foreach ($pluginList as $code => $plugin): ?>
|
||||
<div class="update-item <?= $plugin['isImportant'] ? 'item-danger' : '' ?>">
|
||||
<div class="item-header">
|
||||
<?php if ($plugin['isImportant']): ?>
|
||||
<div class="important-update form-group form-group-sm">
|
||||
<select
|
||||
name="plugin_actions[<?= e($this->encodeCode($code)) ?>]"
|
||||
class="form-control custom-select select-no-search"
|
||||
data-important-update-select>
|
||||
<option value="">-- <?= e(trans('system::lang.updates.important_action.empty')) ?> --</option>
|
||||
<option value="confirm"><?= e(trans('system::lang.updates.important_action.confirm')) ?></option>
|
||||
<option value="skip"><?= e(trans('system::lang.updates.important_action.skip')) ?></option>
|
||||
<option value="ignore"><?= e(trans('system::lang.updates.important_action.ignore')) ?></option>
|
||||
</select>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<h5>
|
||||
<i class="<?= e($plugin['icon'] ?: 'icon-puzzle-piece') ?>"></i>
|
||||
<?= e($plugin['name']) ?>
|
||||
</h5>
|
||||
</div>
|
||||
<dl>
|
||||
<?php if (!$plugin['old_version']): ?>
|
||||
<dt>
|
||||
<?= $plugin['version'] ?>
|
||||
</dt>
|
||||
<dd>
|
||||
<?= e(trans('system::lang.updates.plugin_version_none')) ?>
|
||||
</dd>
|
||||
<?php else: ?>
|
||||
<?php foreach (array_get($plugin, 'updates', []) as $version => $description): ?>
|
||||
<dt><?= e($version) ?></dt>
|
||||
<?php if (is_array($description)): ?>
|
||||
<dd>
|
||||
<span class="important-update-label">
|
||||
<?= e(trans('system::lang.updates.important_action_required')) ?>
|
||||
</span>
|
||||
<?= e($description[0]) ?>
|
||||
<a href="<?= $description[1] ?>" target="_blank">
|
||||
<?= e(trans('system::lang.updates.important_view_guide')) ?>
|
||||
<i class="icon-external-link"></i>
|
||||
</a>
|
||||
</dd>
|
||||
<?php else: ?>
|
||||
<dd><?= e($description) ?></dd>
|
||||
<?php endif ?>
|
||||
<?php endforeach ?>
|
||||
|
||||
<dt class="text-muted">
|
||||
<?= e($plugin['old_version']) ?>
|
||||
</dt>
|
||||
<dd class="text-muted">
|
||||
<?= e(trans('system::lang.updates.plugin_current_version')) ?>
|
||||
</dd>
|
||||
<?php endif ?>
|
||||
</dl>
|
||||
|
||||
<input type="hidden" name="plugins[<?= e($this->encodeCode($code)) ?>]" value="<?= e($plugin['hash']) ?>" />
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<?php if ($hasImportantUpdates): ?>
|
||||
<p class="text-danger pull-left wn-icon-exclamation important-update-label" id="updateListImportantLabel">
|
||||
<?= e(trans('system::lang.updates.important_alert_text')) ?>
|
||||
</p>
|
||||
<?php endif ?>
|
||||
<button
|
||||
type="button"
|
||||
id="updateListUpdateButton"
|
||||
class="btn btn-primary"
|
||||
data-dismiss="popup"
|
||||
data-control="popup"
|
||||
data-handler="onApplyUpdates"
|
||||
data-keyboard="false">
|
||||
<?= e(trans('system::lang.updates.update_label')) ?>
|
||||
</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><?= e(trans('system::lang.updates.none.help')) ?></p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-default"
|
||||
data-dismiss="popup">
|
||||
<?= e(trans('backend::lang.form.close')) ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary"
|
||||
data-dismiss="popup"
|
||||
data-control="popup"
|
||||
data-handler="onForceUpdate"
|
||||
data-keyboard="false">
|
||||
<?= e(trans('system::lang.updates.force_label')) ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<?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 ?>
|
||||
12
modules/system/controllers/updates/config_list.yaml
Normal file
12
modules/system/controllers/updates/config_list.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
# ===================================
|
||||
# List Behavior Config
|
||||
# ===================================
|
||||
|
||||
title: system::lang.updates.title
|
||||
list: ~/modules/system/models/pluginversion/columns.yaml
|
||||
modelClass: System\Models\PluginVersion
|
||||
noRecordsMessage: backend::lang.list.no_records
|
||||
recordUrl: system/updates/details/:slug
|
||||
|
||||
toolbar:
|
||||
buttons: list_toolbar
|
||||
13
modules/system/controllers/updates/config_manage_list.yaml
Normal file
13
modules/system/controllers/updates/config_manage_list.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
# ===================================
|
||||
# List Behavior Config
|
||||
# ===================================
|
||||
|
||||
list: ~/modules/system/models/pluginversion/columns_manage.yaml
|
||||
modelClass: System\Models\PluginVersion
|
||||
noRecordsMessage: backend::lang.list.no_records
|
||||
showSetup: false
|
||||
showCheckboxes: true
|
||||
recordOnClick: $.wn.listToggleChecked(this)
|
||||
|
||||
toolbar:
|
||||
buttons: list_manage_toolbar
|
||||
117
modules/system/controllers/updates/details.php
Normal file
117
modules/system/controllers/updates/details.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/updates') ?>"><?= e(trans('system::lang.updates.menu_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<div class="scoreboard">
|
||||
<div data-control="toolbar">
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.plugin.label')) ?></h4>
|
||||
<p class="wn-<?= $pluginIcon ?>"><?= e(trans($pluginName)) ?></p>
|
||||
<?php if ($pluginHomepage): ?>
|
||||
<p class="description">
|
||||
<a href="<?= e($pluginHomepage) ?>" target="_blank">
|
||||
<?= e(trans('system::lang.updates.details_view_homepage')) ?>
|
||||
</a>
|
||||
</p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.updates.details_current_version')) ?></h4>
|
||||
<p><?= e($pluginVersion) ?></p>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.updates.details_author')) ?></h4>
|
||||
<p><?= e(trans($pluginAuthor)) ?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-tabs primary-tabs" data-control="tab">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="<?= $activeTab == 'readme' ? 'active' : '' ?>">
|
||||
<a
|
||||
href="#readme"
|
||||
data-tab-url="<?= Backend::url('system/updates/details/'.$urlCode.'/readme') ?>">
|
||||
<?= e(trans('system::lang.updates.details_readme')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?= $activeTab == 'changelog' ? 'active' : '' ?>">
|
||||
<a
|
||||
href="#changelog"
|
||||
data-tab-url="<?= Backend::url('system/updates/details/'.$urlCode.'/changelog') ?>">
|
||||
<?= e(trans('system::lang.updates.details_changelog')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?= $activeTab == 'upgrades' ? 'active' : '' ?>">
|
||||
<a
|
||||
href="#upgrades"
|
||||
data-tab-url="<?= Backend::url('system/updates/details/'.$urlCode.'/upgrades') ?>">
|
||||
<?= e(trans('system::lang.updates.details_upgrades')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?= $activeTab == 'licence' ? 'active' : '' ?>">
|
||||
<a
|
||||
href="#licence"
|
||||
data-tab-url="<?= Backend::url('system/updates/details/'.$urlCode.'/licence') ?>">
|
||||
<?= e(trans('system::lang.updates.details_licence')) ?>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane <?= $activeTab == 'readme' ? 'active' : '' ?>">
|
||||
<div class="plugin-details-content">
|
||||
<?php if ($readme): ?>
|
||||
<?= $readme ?>
|
||||
<?php else: ?>
|
||||
<p><?= e(trans('system::lang.updates.details_readme_missing')) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane <?= $activeTab == 'changelog' ? 'active' : '' ?>">
|
||||
<div class="plugin-details-content">
|
||||
<?php if ($changelog): ?>
|
||||
<dl>
|
||||
<?php foreach ($changelog as $version => $comments): ?>
|
||||
<?php foreach ($comments as $index => $comment): ?>
|
||||
<dt><?= !$index ? e($version): '' ?></dt>
|
||||
<dd><?= e($comment) ?></dd>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
</dl>
|
||||
<?php else: ?>
|
||||
<p><?= e(trans('system::lang.updates.details_changelog_missing')) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane <?= $activeTab == 'upgrades' ? 'active' : '' ?>">
|
||||
<div class="plugin-details-content">
|
||||
<?php if ($upgrades): ?>
|
||||
<?= $upgrades ?>
|
||||
<?php else: ?>
|
||||
<p><?= e(trans('system::lang.updates.details_upgrades_missing')) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane <?= $activeTab == 'licence' ? 'active' : '' ?>">
|
||||
<div class="plugin-details-content">
|
||||
<?php if ($licence): ?>
|
||||
<?= $licence ?>
|
||||
<?php else: ?>
|
||||
<p><?= e(trans('system::lang.updates.details_licence_missing')) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
|
||||
<p><a href="<?= Backend::url('system/updates') ?>" class="btn btn-default"><?= e(trans('system::lang.settings.return')) ?></a></p>
|
||||
|
||||
<?php endif ?>
|
||||
76
modules/system/controllers/updates/index.php
Normal file
76
modules/system/controllers/updates/index.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<div class="scoreboard">
|
||||
<div data-control="toolbar">
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.project.name')) ?></h4>
|
||||
<?php if ($projectId): ?>
|
||||
<p class="wn-icon-chain"><?= $projectName ?></p>
|
||||
<p class="description">
|
||||
<?= e(trans('system::lang.project.owner_label')) ?>: <?= $projectOwner ?>
|
||||
(<a
|
||||
href="javascript:;"
|
||||
data-request-confirm="<?= e(trans('system::lang.project.detach_confirm')) ?>"
|
||||
data-request="onDetachProject"
|
||||
data-stripe-load-indicator><?= e(trans('system::lang.project.detach')) ?></a>)
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<p class="wn-icon-chain-broken"><?= e(trans('system::lang.project.none')) ?></p>
|
||||
<p class="description">
|
||||
<a
|
||||
href="javascript:;"
|
||||
data-control="popup"
|
||||
data-handler="onLoadProjectForm">
|
||||
<?= e(trans('system::lang.project.attach')) ?>
|
||||
</a>
|
||||
</p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.updates.plugins')) ?></h4>
|
||||
<p><?= $pluginsCount ?></p>
|
||||
<p class="description">
|
||||
<?= e(trans('system::lang.updates.disabled')) ?>: <?= $pluginsCount - $pluginsActiveCount ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php if ($coreBuild): ?>
|
||||
<div class="scoreboard-item title-value">
|
||||
<h4><?= e(trans('system::lang.updates.core_current_build')) ?></h4>
|
||||
<?php if ($coreBuildModified): ?>
|
||||
<p
|
||||
class="oc-icon-exclamation-circle"
|
||||
data-toggle="tooltip"
|
||||
data-placement="bottom"
|
||||
title="This build has been modified"
|
||||
>
|
||||
<?= $coreBuild ?>
|
||||
</p>
|
||||
<?php else: ?>
|
||||
<p><?= $coreBuild ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<p class="description">
|
||||
<a
|
||||
href="javascript:;"
|
||||
data-control="popup"
|
||||
data-handler="onLoadChangelog">
|
||||
<?= e(trans('system::lang.updates.core_view_changelog')) ?>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (count($warnings)): ?>
|
||||
<div class="scoreboard">
|
||||
<div class="callout fade in callout-danger no-icon">
|
||||
<div class="header">
|
||||
<h3><?= e(trans('system::lang.updates.update_warnings_title')) ?></h3>
|
||||
<ul>
|
||||
<?php foreach ($warnings as $warning): ?>
|
||||
<li><?= $warning ?></li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
<?= $this->listRender() ?>
|
||||
49
modules/system/controllers/updates/install.php
Normal file
49
modules/system/controllers/updates/install.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/updates') ?>"><?= e(trans('system::lang.updates.menu_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?php if (!$this->fatalError): ?>
|
||||
|
||||
<div class="control-tabs content-tabs tabs-flush" data-control="tab">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="<?= $activeTab == 'plugins' ? 'active' : '' ?>">
|
||||
<a
|
||||
href="#tabPlugins"
|
||||
data-tab-url="<?= Backend::url('system/updates/install/plugins') ?>">
|
||||
<?= e(trans('system::lang.updates.plugins')) ?>
|
||||
</a>
|
||||
</li>
|
||||
<li class="<?= $activeTab == 'themes' ? 'active' : '' ?>">
|
||||
<a
|
||||
href="#tabThemes"
|
||||
data-tab-url="<?= Backend::url('system/updates/install/themes') ?>">
|
||||
<?= e(trans('system::lang.updates.themes')) ?>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane <?= $activeTab == 'plugins' ? 'active' : '' ?>">
|
||||
<div class="padded-container">
|
||||
<?= $this->makePartial('install_plugins') ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane <?= $activeTab == 'themes' ? 'active' : '' ?>">
|
||||
<div class="padded-container">
|
||||
<?= $this->makePartial('install_themes') ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div class="padded-container">
|
||||
<p class="flash-message static error"><?= e($this->fatalError) ?></p>
|
||||
<p><a href="<?= Backend::url('system/updates') ?>" class="btn btn-default"><?= e(trans('system::lang.settings.return')) ?></a></p>
|
||||
<p><a href="<?= Backend::url('cms/themes') ?>" class="btn btn-default"><?= e(trans('cms::lang.theme.return')) ?></a></p>
|
||||
</div>
|
||||
|
||||
<?php endif ?>
|
||||
28
modules/system/controllers/updates/manage.php
Normal file
28
modules/system/controllers/updates/manage.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php Block::put('breadcrumb') ?>
|
||||
<ul>
|
||||
<li><a href="<?= Backend::url('system/updates') ?>"><?= e(trans('system::lang.updates.menu_label')) ?></a></li>
|
||||
<li><?= e(trans($this->pageTitle)) ?></li>
|
||||
</ul>
|
||||
<?php Block::endPut() ?>
|
||||
|
||||
<?= $this->listRender('manage') ?>
|
||||
|
||||
<!-- Specific assets for this page only -->
|
||||
<style>
|
||||
td { vertical-align: middle !important; }
|
||||
</style>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
function checkSwitches() {
|
||||
$("[data-check|='oc']").each(function() {
|
||||
$(this).find('input').on('change', function() {
|
||||
this.value = this.checked ? 1 : 0;
|
||||
});
|
||||
});
|
||||
}
|
||||
checkSwitches();
|
||||
$(document).ajaxComplete(function() {
|
||||
checkSwitches();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user