BackendSettings -> BrandSettings

pageTitle is now translated at the end of the line
Fixed unit tests so they pass
SettingsModels are now cached
This commit is contained in:
Sam Georges 2014-10-15 19:53:44 +11:00
parent 82192c3e55
commit 9f5646d273
61 changed files with 402 additions and 322 deletions

View File

@ -1,5 +1,6 @@
* **Build 15x** (2014-10-x) * **Build 15x** (2014-10-x)
- Added twig filters `|trans` for `Lang::get(...)` and `|transchoice` for `Lang::choice(...)`. - Added twig filters `|trans` for `Lang::get(...)` and `|transchoice` for `Lang::choice(...)`.
- `SettingsModel` behavior now uses a cached database query.
* **Build 153** (2014-10-09) * **Build 153** (2014-10-09)
- Plugins are now updated in order of their dependency definitions. - Plugins are now updated in order of their dependency definitions.

View File

@ -79,12 +79,12 @@ class ServiceProvider extends ModuleServiceProvider
*/ */
SettingsManager::instance()->registerCallback(function($manager){ SettingsManager::instance()->registerCallback(function($manager){
$manager->registerSettingItems('October.Backend', [ $manager->registerSettingItems('October.Backend', [
'backend_settings' => [ 'branding' => [
'label' => 'backend::lang.backend_settings.menu_label', 'label' => 'backend::lang.branding.menu_label',
'description' => 'backend::lang.backend_settings.menu_description', 'description' => 'backend::lang.branding.menu_description',
'category' => SettingsManager::CATEGORY_SYSTEM, 'category' => SettingsManager::CATEGORY_SYSTEM,
'icon' => 'icon-paint-brush', 'icon' => 'icon-paint-brush',
'class' => 'Backend\Models\BackendSettings', 'class' => 'Backend\Models\BrandSettings',
'order' => 500, 'order' => 500,
], ],
'editor' => [ 'editor' => [

View File

@ -8257,7 +8257,7 @@ body.mainmenu-open .mainmenu-collapsed ul {
padding: 13px; padding: 13px;
display: block; display: block;
font-size: 12px; font-size: 12px;
color: #808b93; color: rgba(255, 255, 255, 0.35);
font-weight: normal; font-weight: normal;
} }
#layout-sidenav ul li a:hover { #layout-sidenav ul li a:hover {
@ -8268,7 +8268,7 @@ body.mainmenu-open .mainmenu-collapsed ul {
background: transparent; background: transparent;
} }
#layout-sidenav ul li a i { #layout-sidenav ul li a i {
color: #808b93; color: rgba(255, 255, 255, 0.35);
display: block; display: block;
margin-bottom: 5px; margin-bottom: 5px;
font-size: 28px; font-size: 28px;
@ -8331,7 +8331,7 @@ body.mainmenu-open .mainmenu-collapsed ul {
top: 0; top: 0;
height: 9px; height: 9px;
font-size: 10px; font-size: 10px;
color: #808b93; color: rgba(255, 255, 255, 0.35);
} }
#layout-sidenav .scroll-marker.before { #layout-sidenav .scroll-marker.before {
top: 0; top: 0;
@ -8350,11 +8350,11 @@ body.mainmenu-open .mainmenu-collapsed ul {
} }
#layout-sidenav.layout-sidenav ul.drag li:not(.active) a:hover, #layout-sidenav.layout-sidenav ul.drag li:not(.active) a:hover,
.touch #layout-sidenav.layout-sidenav li:not(.active) a:hover { .touch #layout-sidenav.layout-sidenav li:not(.active) a:hover {
color: #808b93 !important; color: rgba(255, 255, 255, 0.35) !important;
} }
#layout-sidenav.layout-sidenav ul.drag li:not(.active) a:hover i, #layout-sidenav.layout-sidenav ul.drag li:not(.active) a:hover i,
.touch #layout-sidenav.layout-sidenav li:not(.active) a:hover i { .touch #layout-sidenav.layout-sidenav li:not(.active) a:hover i {
color: #808b93 !important; color: rgba(255, 255, 255, 0.35) !important;
} }
#layout-sidenav.layout-sidenav ul.drag li:not(.active) a:hover:after, #layout-sidenav.layout-sidenav ul.drag li:not(.active) a:hover:after,
.touch #layout-sidenav.layout-sidenav li:not(.active) a:hover:after { .touch #layout-sidenav.layout-sidenav li:not(.active) a:hover:after {
@ -8418,7 +8418,7 @@ body.side-panel-fix-shadow #layout-side-panel {
border-top: 1px solid #dfdfdf; border-top: 1px solid #dfdfdf;
} }
#layout-footer .brand, #layout-footer .brand,
#layout-footer .motto { #layout-footer .tagline {
margin: 10px; margin: 10px;
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
@ -8430,10 +8430,10 @@ body.side-panel-fix-shadow #layout-side-panel {
#layout-footer .brand .logo { #layout-footer .brand .logo {
margin: 0 10px; margin: 0 10px;
} }
#layout-footer .motto { #layout-footer .tagline {
float: right; float: right;
} }
#layout-footer .motto p { #layout-footer .tagline p {
color: #999999; color: #999999;
} }
body.outer { body.outer {
@ -8513,10 +8513,10 @@ body.outer .layout > .layout-row > .layout-cell .outer-form-container .forgot-pa
top: 8px; top: 8px;
} }
body.outer .layout > .layout-row > .layout-cell .outer-form-container .forgot-password a { body.outer .layout > .layout-row > .layout-cell .outer-form-container .forgot-password a {
color: #8d969d; color: rgba(255, 255, 255, 0.44);
} }
body.outer .layout > .layout-row > .layout-cell .outer-form-container .forgot-password:before { body.outer .layout > .layout-row > .layout-cell .outer-form-container .forgot-password:before {
color: #8d969d; color: rgba(255, 255, 255, 0.44);
font-size: 14px; font-size: 14px;
position: relative; position: relative;
margin-right: 5px; margin-right: 5px;
@ -12650,7 +12650,7 @@ div.popover-overlay {
.fancy-layout.control-tabs.master:after { .fancy-layout.control-tabs.master:after {
top: 7px; top: 7px;
font-size: 14px; font-size: 14px;
color: #e39664; color: rgba(255, 255, 255, 0.35);
} }
.fancy-layout .control-tabs.master:before, .fancy-layout .control-tabs.master:before,
.fancy-layout.control-tabs.master:before { .fancy-layout.control-tabs.master:before {
@ -12705,7 +12705,7 @@ div.popover-overlay {
border-bottom: none; border-bottom: none;
background: transparent; background: transparent;
font-size: 14px; font-size: 14px;
color: #e39664; color: rgba(255, 255, 255, 0.35);
padding: 6px 0 0 0; padding: 6px 0 0 0;
overflow: visible; overflow: visible;
} }
@ -13007,7 +13007,7 @@ div.popover-overlay {
} }
.fancy-layout .form-tabless-fields label { .fancy-layout .form-tabless-fields label {
text-transform: uppercase; text-transform: uppercase;
color: #f4c69e; color: rgba(255, 255, 255, 0.5);
margin-bottom: 0; margin-bottom: 0;
} }
.fancy-layout .form-tabless-fields input[type=text] { .fancy-layout .form-tabless-fields input[type=text] {
@ -13093,7 +13093,7 @@ div.popover-overlay {
.fancy-layout .form-tabless-fields .loading-indicator-container .loading-indicator { .fancy-layout .form-tabless-fields .loading-indicator-container .loading-indicator {
background-color: #e67e22; background-color: #e67e22;
padding: 0 0 0 30px; padding: 0 0 0 30px;
color: #f4c69e; color: rgba(255, 255, 255, 0.5);
margin-top: 1px; margin-top: 1px;
height: 90%; height: 90%;
font-size: 12px; font-size: 12px;
@ -14438,7 +14438,7 @@ div[data-control="balloon-selector"]:not(.control-disabled) ul li:hover {
padding: 15px 15px 15px 40px; padding: 15px 15px 15px 40px;
background: #3d5265; background: #3d5265;
margin-bottom: 1px; margin-bottom: 1px;
color: #808c8d; color: rgba(255, 255, 255, 0.26);
text-decoration: none!important; text-decoration: none!important;
} }
.sidenav-tree ul.top-level > li > ul li a:hover { .sidenav-tree ul.top-level > li > ul li a:hover {
@ -14455,24 +14455,24 @@ div[data-control="balloon-selector"]:not(.control-disabled) ul li:hover {
line-height: 150%; line-height: 150%;
} }
.sidenav-tree ul.top-level > li > ul li a span.header { .sidenav-tree ul.top-level > li > ul li a span.header {
color: #cad5d8; color: rgba(255, 255, 255, 0.74);
font-size: 14px; font-size: 14px;
margin-bottom: 5px; margin-bottom: 5px;
} }
.sidenav-tree ul.top-level > li > ul li a span.description { .sidenav-tree ul.top-level > li > ul li a span.description {
color: #bdc3c7; color: rgba(255, 255, 255, 0.64);
font-size: 12px; font-size: 12px;
font-weight: 100; font-weight: 100;
} }
.sidenav-tree ul.top-level > li > ul li.active a { .sidenav-tree ul.top-level > li > ul li.active a {
background: #34495e; background: #34495e;
color: #ecf0f1; color: rgba(255, 255, 255, 0.91);
} }
.sidenav-tree ul.top-level > li > ul li.active a:before { .sidenav-tree ul.top-level > li > ul li.active a:before {
content: ' '; content: ' ';
position: absolute; position: absolute;
width: 4px; width: 4px;
background: #e6802b; background: #e67e22;
left: 0; left: 0;
top: 0; top: 0;
height: 100%; height: 100%;
@ -14481,7 +14481,7 @@ div[data-control="balloon-selector"]:not(.control-disabled) ul li:hover {
color: #ffffff; color: #ffffff;
} }
.sidenav-tree ul.top-level > li > ul li.active a span.description { .sidenav-tree ul.top-level > li > ul li.active a span.description {
color: #ecf0f1; color: rgba(255, 255, 255, 0.91);
} }
.sidenav-tree ul.top-level > li > ul li:last-child a { .sidenav-tree ul.top-level > li > ul li:last-child a {
margin-bottom: 0; margin-bottom: 0;
@ -14495,34 +14495,34 @@ div[data-control="balloon-selector"]:not(.control-disabled) ul li:hover {
@media (max-width: 768px) { @media (max-width: 768px) {
.sidenav-tree { .sidenav-tree {
width: 100%; width: 100%;
height: auto!important; height: auto !important;
display: block!important; display: block !important;
} }
.sidenav-tree > .layout { .sidenav-tree > .layout {
display: none; display: none;
} }
.sidenav-tree-root .sidenav-tree { .sidenav-tree-root .sidenav-tree {
width: 100%!important; width: 100% !important;
height: 100%!important; height: 100% !important;
display: table-cell !important; display: table-cell !important;
} }
.sidenav-tree-root .sidenav-tree .back-link { .sidenav-tree-root .sidenav-tree .back-link {
display: none!important; display: none !important;
} }
.sidenav-tree-root .sidenav-tree > .layout { .sidenav-tree-root .sidenav-tree > .layout {
display: table!important; display: table !important;
} }
.sidenav-tree-root #layout-body { .sidenav-tree-root #layout-body {
display: none; display: none;
} }
body.has-sidenav-tree .sidenav-tree .back-link { body.has-sidenav-tree .sidenav-tree .back-link {
display: block; display: block;
background: #2b3e50;
padding: 13px 15px; padding: 13px 15px;
background: #2b3e50;
color: #bdc3c7; color: #bdc3c7;
font-size: 14px; font-size: 14px;
text-transform: uppercase;
line-height: 14px; line-height: 14px;
text-transform: uppercase;
} }
body.has-sidenav-tree .sidenav-tree .back-link i { body.has-sidenav-tree .sidenav-tree .back-link i {
display: inline-block; display: inline-block;
@ -14532,6 +14532,6 @@ div[data-control="balloon-selector"]:not(.control-disabled) ul li:hover {
text-decoration: none; text-decoration: none;
} }
body.has-sidenav-tree #layout-body { body.has-sidenav-tree #layout-body {
display: block!important; display: block !important;
} }
} }

View File

@ -23,7 +23,7 @@
ul.top-level > li { ul.top-level > li {
&[data-status=collapsed] { &[data-status=collapsed] {
> div.group h3:before { > div.group h3:before {
.transform( ~'rotate(0deg) translate(3px, 0)' ); .transform(~'rotate(0deg) translate(3px, 0)');
} }
ul { ul {
@ -55,7 +55,7 @@
top: 15px; top: 15px;
color: @color-list-arrow; color: @color-list-arrow;
.icon(@caret-right); .icon(@caret-right);
.transform( ~'rotate(90deg) translate(5px, 0)' ); .transform(~'rotate(90deg) translate(5px, 0)');
.transition(all 0.1s ease); .transition(all 0.1s ease);
} }
} }
@ -137,16 +137,14 @@
.back-link { .back-link {
display: none; display: none;
} }
} }
@media (max-width: @screen-sm) { @media (max-width: @screen-sm) {
.sidenav-tree { .sidenav-tree {
width: 100%; width: 100%;
height: auto!important; height: auto !important;
display: block!important; display: block !important;
> .layout { > .layout {
display: none; display: none;
@ -155,16 +153,16 @@
.sidenav-tree-root { .sidenav-tree-root {
.sidenav-tree { .sidenav-tree {
width: 100%!important; width: 100% !important;
height: 100%!important; height: 100% !important;
display: table-cell!important; display: table-cell !important;
.back-link { .back-link {
display: none!important; display: none !important;
} }
> .layout { > .layout {
display: table!important; display: table !important;
} }
} }
@ -177,12 +175,12 @@
.sidenav-tree { .sidenav-tree {
.back-link { .back-link {
display: block; display: block;
background: @color-sidebarnav-back-link-bg;
padding: 13px 15px; padding: 13px 15px;
background: @color-sidebarnav-back-link-bg;
color: @color-sidebarnav-back-link-text; color: @color-sidebarnav-back-link-text;
font-size: 14px; font-size: 14px;
text-transform: uppercase;
line-height: 14px; line-height: 14px;
text-transform: uppercase;
i { i {
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 10px;
@ -194,7 +192,7 @@
} }
#layout-body { #layout-body {
display: block!important; display: block !important;
} }
} }
} }

View File

@ -69,23 +69,23 @@
@color-footer-text: #666666; @color-footer-text: #666666;
@color-sidebarnav-bg: #34495e; @color-sidebarnav-bg: #34495e;
@color-sidebarnav-inactive-text: #808b93;
@color-sidebarnav-inactive-icon: #808b93;
@color-sidebarnav-active-text: #ffffff; @color-sidebarnav-active-text: #ffffff;
@color-sidebarnav-active-icon: #ffffff; @color-sidebarnav-active-icon: #ffffff;
@color-sidebarnav-inactive-text: rgba(255,255,255,.35);
@color-sidebarnav-inactive-icon: rgba(255,255,255,.35);
@color-sidebarnav-counter-bg: #d9350f; @color-sidebarnav-counter-bg: #d9350f;
@color-sidebarnav-counter-text: #ffffff; @color-sidebarnav-counter-text: #ffffff;
@color-sidebarnav-tree-group: #ecf0f1; @color-sidebarnav-tree-group: #ecf0f1;
@color-sidebarnav-tree-group-bg: #2b3e50; @color-sidebarnav-tree-group-bg: #2b3e50;
@color-sidebarnav-tree-inactive-header: #CAD5D8; @color-sidebarnav-tree-inactive-header: rgba(255,255,255,.74);
@color-sidebarnav-tree-inactive-desc: #bdc3c7; @color-sidebarnav-tree-inactive-desc: rgba(255,255,255,.64);
@color-sidebarnav-tree-inactive-text: #808c8d; @color-sidebarnav-tree-inactive-text: rgba(255,255,255,.26);
@color-sidebarnav-tree-active-header: #ffffff; @color-sidebarnav-tree-active-header: #ffffff;
@color-sidebarnav-tree-inactive-bg: #3d5265; @color-sidebarnav-tree-inactive-bg: #3d5265;
@color-sidebarnav-tree-active-bg: #34495e; @color-sidebarnav-tree-active-bg: #34495e;
@color-sidebarnav-tree-active-text: #ecf0f1; @color-sidebarnav-tree-active-text: rgba(255,255,255,.91);
@color-sidebarnav-tree-active-marker: #e6802b; @color-sidebarnav-tree-active-marker: #e67e22;
@color-sidebarnav-back-link-bg: #2b3e50; @color-sidebarnav-back-link-bg: #2b3e50;
@color-sidebarnav-back-link-text: #bdc3c7; @color-sidebarnav-back-link-text: #bdc3c7;
@ -156,7 +156,7 @@
@color-ui-border: #d7d7d7; @color-ui-border: #d7d7d7;
@color-outer-muted-text: #8d969d; @color-outer-muted-text: rgba(255,255,255,.44);
@color-outer-heading: #feffff; @color-outer-heading: #feffff;
@color-outer-description: #999999; @color-outer-description: #999999;
@color-outer-bg: #2b3e50; @color-outer-bg: #2b3e50;
@ -229,7 +229,7 @@
@color-fancy-master-tabs-bg: #d35400; @color-fancy-master-tabs-bg: #d35400;
@color-fancy-master-tabs-active-text: #ffffff; @color-fancy-master-tabs-active-text: #ffffff;
@color-fancy-master-tabs-inactive-text: #e39664; @color-fancy-master-tabs-inactive-text: rgba(255, 255, 255, .35);
@color-fancy-master-panel-bg: #d35400; @color-fancy-master-panel-bg: #d35400;
@color-fancy-secondary-tabs-bg: #475354; @color-fancy-secondary-tabs-bg: #475354;
@ -243,7 +243,7 @@
@color-fancy-primary-tabs-inactive-bg: #d5d9d8; @color-fancy-primary-tabs-inactive-bg: #d5d9d8;
@color-fancy-form-tabless-fields-bg: #e67e22; @color-fancy-form-tabless-fields-bg: #e67e22;
@color-fancy-form-label: #f4c69e; @color-fancy-form-label: rgba(255, 255, 255, .5);
@color-fancy-form-text: #ffffff; @color-fancy-form-text: #ffffff;
@color-fancy-form-text-selection: #d35400; @color-fancy-form-text-selection: #d35400;
@color-fancy-form-placeholder: #f4c69e; @color-fancy-form-placeholder: #f4c69e;

View File

@ -11,7 +11,7 @@
background-color: @color-footer; background-color: @color-footer;
border-top: 1px solid @color-footer-border; border-top: 1px solid @color-footer-border;
.brand, .motto { .brand, .tagline {
margin: 10px; margin: 10px;
height: (@footer-height - 20) + 0px; height: (@footer-height - 20) + 0px;
line-height: (@footer-height - 20) + 0px; line-height: (@footer-height - 20) + 0px;
@ -24,7 +24,7 @@
.name { } .name { }
} }
.motto { .tagline {
float: right; float: right;
p { color: lighten(@color-footer-text, 20%); } p { color: lighten(@color-footer-text, 20%); }
} }

View File

@ -38,10 +38,7 @@ class UserPreferencesModel extends SettingsModel
if (isset(self::$instances[$this->recordCode])) if (isset(self::$instances[$this->recordCode]))
return self::$instances[$this->recordCode]; return self::$instances[$this->recordCode];
$item = UserPreferences::forUser(); if (!$item = $this->getSettingsRecord()) {
$item = $item->scopeFindRecord($this->model, $this->recordCode, $item->userContext)->first();
if (!$item) {
$this->model->initSettingsData(); $this->model->initSettingsData();
if (method_exists($this->model, 'forceSave')) if (method_exists($this->model, 'forceSave'))
@ -61,7 +58,21 @@ class UserPreferencesModel extends SettingsModel
*/ */
public function isConfigured() public function isConfigured()
{ {
return UserPreferences::forUser()->findRecord($this->recordCode, $item->userContext)->count() > 0; return $this->getSettingsRecord() !== null;
}
/**
* Returns the raw Model record that stores the settings.
* @return Model
*/
public function getSettingsRecord()
{
$item = UserPreferences::forUser();
$record = $item->scopeFindRecord($this->model, $this->recordCode, $item->userContext)
->remember(1440, $this->getCacheKey())
->first();
return $record ?: null;
} }
/** /**
@ -95,4 +106,12 @@ class UserPreferencesModel extends SettingsModel
return parent::isKeyAllowed($key); return parent::isKeyAllowed($key);
} }
/**
* Returns a cache key for this record.
*/
protected function getCacheKey()
{
return 'backend::userpreferences.'.$this->recordCode;
}
} }

View File

@ -276,10 +276,9 @@ class Controller extends Extendable
if ($result instanceof RedirectResponse) if ($result instanceof RedirectResponse)
return $result; return $result;
// Translate the page title // No page title
$this->pageTitle = $this->pageTitle if (!$this->pageTitle)
? Lang::get($this->pageTitle) $this->pageTitle = 'backend::lang.page.untitled';
: Lang::get('backend::lang.page.untitled');
// Load the view // Load the view
if (!$this->suppressView && is_null($result)) if (!$this->suppressView && is_null($result))

View File

@ -1,6 +1,5 @@
<?php namespace Backend\Controllers; <?php namespace Backend\Controllers;
use Lang;
use BackendMenu; use BackendMenu;
use Backend\Classes\Controller; use Backend\Classes\Controller;
use System\Classes\SettingsManager; use System\Classes\SettingsManager;
@ -56,7 +55,7 @@ class EditorPreferences extends Controller
$this->vars['margin'] = 0; $this->vars['margin'] = 0;
$this->asExtension('FormController')->update(); $this->asExtension('FormController')->update();
$this->pageTitle = Lang::get('backend::lang.editor.menu_label'); $this->pageTitle = 'backend::lang.editor.menu_label';
} }
public function index_onSave() public function index_onSave()

View File

@ -37,7 +37,7 @@ class Index extends Controller
public function index() public function index()
{ {
$this->pageTitle = trans('backend::lang.dashboard.menu_label'); $this->pageTitle = 'backend::lang.dashboard.menu_label';
BackendMenu::setContextMainMenu('dashboard'); BackendMenu::setContextMainMenu('dashboard');
} }
} }

View File

@ -1,6 +1,5 @@
<?php namespace Backend\Controllers; <?php namespace Backend\Controllers;
use Lang;
use Backend; use Backend;
use Redirect; use Redirect;
use BackendMenu; use BackendMenu;
@ -59,7 +58,7 @@ class Users extends Controller
{ {
SettingsManager::setContext('October.Backend', 'myaccount'); SettingsManager::setContext('October.Backend', 'myaccount');
$this->pageTitle = Lang::get('backend::lang.myaccount.menu_label'); $this->pageTitle = 'backend::lang.myaccount.menu_label';
return $this->update($this->user->id, 'myaccount'); return $this->update($this->user->id, 'myaccount');
} }

View File

@ -1,4 +1,4 @@
<h2><?= e(trans('system::lang.app.motto')) ?></h2> <h2><?= e(Backend\Models\BrandSettings::get('app_tagline')) ?></h2>
<?= Form::open() ?> <?= Form::open() ?>
<input type="hidden" name="postback" value="1" /> <input type="hidden" name="postback" value="1" />

View File

@ -52,6 +52,6 @@
<?= Form::close() ?> <?= Form::close() ?>
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('system/settings') ?>" class="btn btn-default"><?= e(trans('system::lang.settings.return')) ?></a></p> <p><a href="<?= Backend::url('system/settings') ?>" class="btn btn-default"><?= e(trans('system::lang.settings.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -2,7 +2,7 @@
<ul> <ul>
<li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li> <li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li>
<li><a href="<?= Backend::url('backend/groups') ?>"><?= e(trans('backend::lang.user.group.menu_label')) ?></a></li> <li><a href="<?= Backend::url('backend/groups') ?>"><?= e(trans('backend::lang.user.group.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -37,6 +37,6 @@
<?= Form::close() ?> <?= Form::close() ?>
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('backend/groups') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.group.return')) ?></a></p> <p><a href="<?= Backend::url('backend/groups') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.group.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li> <li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>

View File

@ -2,7 +2,7 @@
<ul> <ul>
<li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li> <li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li>
<li><a href="<?= Backend::url('backend/groups') ?>"><?= e(trans('backend::lang.user.group.menu_label')) ?></a></li> <li><a href="<?= Backend::url('backend/groups') ?>"><?= e(trans('backend::lang.user.group.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -46,6 +46,6 @@
<?= Form::close() ?> <?= Form::close() ?>
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('backend/groups') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.group.return')) ?></a></p> <p><a href="<?= Backend::url('backend/groups') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.group.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li> <li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -54,7 +54,7 @@
<?= Block::placeholder('breadcrumb') ?> <?= Block::placeholder('breadcrumb') ?>
</div> </div>
<div class="padded-container"> <div class="padded-container">
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('backend/users') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.return')) ?></a></p> <p><a href="<?= Backend::url('backend/users') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.return')) ?></a></p>
</div> </div>
<?php endif ?> <?php endif ?>

View File

@ -44,7 +44,7 @@
<?= Block::placeholder('breadcrumb') ?> <?= Block::placeholder('breadcrumb') ?>
</div> </div>
<div class="padded-container"> <div class="padded-container">
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('backend/users') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.return')) ?></a></p> <p><a href="<?= Backend::url('backend/users') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.return')) ?></a></p>
</div> </div>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li> <li><a href="<?= Backend::url('backend/users') ?>"><?= e(trans('backend::lang.user.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -62,7 +62,7 @@
<?= Block::placeholder('breadcrumb') ?> <?= Block::placeholder('breadcrumb') ?>
</div> </div>
<div class="padded-container"> <div class="padded-container">
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<p><a href="<?= Backend::url('backend/users') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.return')) ?></a></p> <p><a href="<?= Backend::url('backend/users') ?>" class="btn btn-default"><?= e(trans('backend::lang.user.return')) ?></a></p>
</div> </div>
<?php endif ?> <?php endif ?>

View File

@ -1,6 +1,9 @@
<?php <?php
return [ return [
'auth' => [
'title' => 'Administration Area',
],
'field' => [ 'field' => [
'invalid_type' => 'Invalid field type used :type.', 'invalid_type' => 'Invalid field type used :type.',
'options_method_not_exists' => 'The model class :model must define a method :method() returning options for the ":field" form field.', 'options_method_not_exists' => 'The model class :model must define a method :method() returning options for the ":field" form field.',
@ -211,7 +214,7 @@ return [
'extension' => 'The PHP extension :name is not installed. Please install this library and activate the extension.' 'extension' => 'The PHP extension :name is not installed. Please install this library and activate the extension.'
], ],
'editor' => [ 'editor' => [
'menu_label' => 'Code Editor Preferences', 'menu_label' => 'Code editor preferences',
'menu_description' => 'Customize your code editor preferences, such as font size and color scheme.', 'menu_description' => 'Customize your code editor preferences, such as font size and color scheme.',
'font_size' => 'Font size', 'font_size' => 'Font size',
'tab_size' => 'Tab size', 'tab_size' => 'Tab size',
@ -231,23 +234,23 @@ return [
'menu_description' => 'Settings relate to your administration account', 'menu_description' => 'Settings relate to your administration account',
], ],
'myaccount' => [ 'myaccount' => [
'menu_label' => 'My Account', 'menu_label' => 'My account',
'menu_description' => 'Update your account details such as name, email address and password.', 'menu_description' => 'Update your account details such as name, email address and password.',
'menu_keywords' => 'security login' 'menu_keywords' => 'security login'
], ],
'backend_settings' => [ 'branding' => [
'menu_label' => 'Backend Settings', 'menu_label' => 'Customize back-end',
'menu_description' => 'Customize the back-end area such as name, colors and logo.', 'menu_description' => 'Customize the administration area such as name, colors and logo.',
], ],
'backend_preferences' => [ 'backend_preferences' => [
'menu_label' => 'Backend Preferences', 'menu_label' => 'Back-end preferences',
'menu_description' => 'Manage your account preferences such as desired language.', 'menu_description' => 'Manage your account preferences such as desired language.',
'locale' => 'Language', 'locale' => 'Language',
'locale_comment' => 'Select your desired locale for language use.', 'locale_comment' => 'Select your desired locale for language use.',
], ],
'access_log' => [ 'access_log' => [
'hint' => 'This log displays a list of successful sign in attempts by administrators. Records are kept for a total of :days days.', 'hint' => 'This log displays a list of successful sign in attempts by administrators. Records are kept for a total of :days days.',
'menu_label' => 'Access Log', 'menu_label' => 'Access log',
'menu_description' => 'View a list of successful back-end user sign ins.', 'menu_description' => 'View a list of successful back-end user sign ins.',
'created_at' => 'Date & Time', 'created_at' => 'Date & Time',
'login' => 'Login', 'login' => 'Login',

View File

@ -1,24 +1,8 @@
<?php <?php
use Backend\Models\BackendSettings; use Backend\Models\BrandSettings;
?> ?>
<?php if (BackendSettings::isConfigured()): ?> <?php if (BrandSettings::isConfigured()): ?>
<?php
$logo = Backend\Models\BackendSettings::getLogo();
?>
<?php /*
<style> <style>
.oc-bg-logo { <?= BrandSettings::renderCss() ?>
background-image: linear-gradient(to bottom, rgba(249,249,249,0.7) 0%,rgba(249,249,249,0.7) 100%), url(<?= \Backend\Models\BackendSettings::getLogo() ?>); </style>
}
.oc-logo-white {
background-image: url(<?= $logo ?>);
height: 170px !important;
}
*/ ?>
<style>
<?= BackendSettings::instance()->renderCss() ?>
</style>
<?php endif ?> <?php endif ?>

View File

@ -3,7 +3,7 @@
<span class="logo"><i class="icon-leaf"></i></span> <span class="logo"><i class="icon-leaf"></i></span>
<span class="name"><?= e(trans('system::lang.app.name')) ?></span> <span class="name"><?= e(trans('system::lang.app.name')) ?></span>
</div> </div>
<div class="motto"> <div class="tagline">
<p><?= e(trans('system::lang.app.motto')) ?></p> <p><?= e(trans('system::lang.app.tagline')) ?></p>
</div> </div>
</footer> </footer>

View File

@ -2,8 +2,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0, minimal-ui"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0, minimal-ui">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">
<link rel="icon" type="image/png" href="<?= Backend::skinAsset('assets/images/favicon.png') ?>"> <link rel="icon" type="image/png" href="<?= Backend::skinAsset('assets/images/favicon.png') ?>">
<title data-title-template="<?= empty($this->pageTitleTemplate) ? '%s | October CMS' : e($this->pageTitleTemplate) ?>"> <title data-title-template="<?= empty($this->pageTitleTemplate) ? '%s' : e($this->pageTitleTemplate) ?> | <?= e(Backend\Models\BrandSettings::get('app_name')) ?>">
<?= $this->pageTitle ?> | October CMS <?= e(trans($this->pageTitle)) ?> | <?= e(Backend\Models\BrandSettings::get('app_name')) ?>
</title> </title>
<link href="<?= Backend::skinAsset('assets/vendor/select2/select2.css') ?>" rel="stylesheet"> <link href="<?= Backend::skinAsset('assets/vendor/select2/select2.css') ?>" rel="stylesheet">

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=0">
<title>Administration Area</title> <title><?= e(trans('backend::lang.auth.title')) ?></title>
<link href="<?= URL::to('modules/backend/assets/css/october.css') ?>" rel="stylesheet"> <link href="<?= URL::to('modules/backend/assets/css/october.css') ?>" rel="stylesheet">
<script src="<?= URL::to('modules/backend/assets/js/vendor/jquery-2.0.3.min.js') ?>"></script> <script src="<?= URL::to('modules/backend/assets/js/vendor/jquery-2.0.3.min.js') ?>"></script>
@ -28,7 +28,7 @@
<div class="layout-row min-size layout-head"> <div class="layout-row min-size layout-head">
<div class="layout-cell"> <div class="layout-cell">
<h1 class="oc-logo-white"><?= e(trans('system::lang.app.name')) ?></h1> <h1 class="oc-logo-white"><?= e(Backend\Models\BrandSettings::get('app_name')) ?></h1>
</div> </div>
</div> </div>
<div class="layout-row"> <div class="layout-row">

View File

@ -1,82 +0,0 @@
<?php namespace Backend\Models;
use File;
use Lang;
use Model;
use Less_Parser;
/**
* Backend settings that affect all users
*
* @package october\backend
* @author Alexey Bobkov, Samuel Georges
*/
class BackendSettings extends Model
{
use \System\Traits\ViewMaker;
use \October\Rain\Database\Traits\Validation;
public $implement = ['System.Behaviors.SettingsModel'];
public $settingsCode = 'backend_settings';
public $settingsFields = 'fields.yaml';
public $attachOne = [
'logo' => ['System\Models\File']
];
/**
* Validation rules
*/
public $rules = [
'app_name' => 'required',
'app_motto' => 'required',
];
public function initSettingsData()
{
$this->app_name = Lang::get('system::lang.app.name');
$this->app_motto = Lang::get('system::lang.app.motto');
// Carrot
$this->primary_color_dark = '#d35400';
// Pumpkin
$this->primary_color_light = '#e67e22';
// Midnight Blue
$this->secondary_color_dark = '#2b3e50';
// Wet Asphalt
$this->secondary_color_light = '#34495e';
}
public static function getLogo()
{
$settings = self::instance();
if (!$settings->logo)
return null;
return $settings->logo->getPath();
}
public function renderCss()
{
$parser = new Less_Parser(['compress' => true]);
$parser->ModifyVars([
'logo-image' => "'".self::getLogo()."'",
'primary-color-light' => $this->primary_color_light,
'primary-color-dark' => $this->primary_color_dark,
'secondary-color-light' => $this->secondary_color_light,
'secondary-color-dark' => $this->secondary_color_dark,
]);
$parser->parse(File::get(__DIR__.'/backendsettings/custom.less'));
$css = $parser->getCss();
return $css;
}
}

View File

@ -0,0 +1,87 @@
<?php namespace Backend\Models;
use File;
use Lang;
use Model;
use Less_Parser;
/**
* Backend settings that affect all users
*
* @package october\backend
* @author Alexey Bobkov, Samuel Georges
*/
class BrandSettings extends Model
{
use \System\Traits\ViewMaker;
use \October\Rain\Database\Traits\Validation;
public $implement = ['System.Behaviors.SettingsModel'];
public $settingsCode = 'backend_brand_settings';
public $settingsFields = 'fields.yaml';
public $attachOne = [
'logo' => ['System\Models\File']
];
// Pumpkin
const PRIMARY_LIGHT = '#e67e22';
// Carrot
const PRIMARY_DARK = '#d35400';
// Wet Asphalt
const SECONDARY_LIGHT = '#34495e';
// Midnight Blue
const SECONDARY_DARK = '#2b3e50';
/**
* Validation rules
*/
public $rules = [
'app_name' => 'required',
'app_tagline' => 'required',
];
public function initSettingsData()
{
$this->app_name = Lang::get('system::lang.app.name');
$this->app_tagline = Lang::get('system::lang.app.tagline');
$this->primary_color_light = self::PRIMARY_LIGHT;
$this->primary_color_dark = self::PRIMARY_DARK;
$this->secondary_color_light = self::SECONDARY_LIGHT;
$this->secondary_color_dark = self::SECONDARY_DARK;
}
public static function getLogo()
{
$settings = self::instance();
if (!$settings->logo)
return null;
return $settings->logo->getPath();
}
public static function renderCss()
{
$parser = new Less_Parser(['compress' => true]);
$parser->ModifyVars([
'logo-image' => "'".self::getLogo()."'",
'primary-color-light' => self::get('primary_color_light', self::PRIMARY_LIGHT),
'primary-color-dark' => self::get('primary_color_dark', self::PRIMARY_DARK),
'secondary-color-light' => self::get('secondary_color_light', self::SECONDARY_LIGHT),
'secondary-color-dark' => self::get('secondary_color_dark', self::SECONDARY_DARK),
]);
$parser->parse(File::get(__DIR__.'/brandsettings/custom.less'));
$css = $parser->getCss();
return $css;
}
}

View File

@ -1,43 +0,0 @@
# ===================================
# Field Definitions
# ===================================
fields:
logo:
label: Logo
type: fileupload
commentAbove: Upload a custom logo to use in the back-end.
mode: image
imageHeight: 170
imageWidth: 170
app_name:
label: App Name
commentAbove: This name is shown in the title area of the back-end.
app_motto:
label: App Motto
commentAbove: This name is shown on the sign in screen for the back-end.
primary_color_light:
label: Primary color light
type: colorpicker
span: auto
primary_color_dark:
label: Primary color dark
type: colorpicker
span: auto
secondary_color_light:
label: Secondary color light
type: colorpicker
span: auto
secondary_color_dark:
label: Secondary color dark
type: colorpicker
span: auto

View File

@ -39,27 +39,19 @@ body.outer .layout > .layout-row.layout-head {
// Side navigation bar // Side navigation bar
// //
//color-sidebarnav-bg: mix(white, saturate(@secondary-color, 6.25%), 5.75%);
@color-sidebarnav-bg: @secondary-color-light; @color-sidebarnav-bg: @secondary-color-light;
#layout-sidenav { #layout-sidenav {
background-color: @color-sidebarnav-bg; background-color: @color-sidebarnav-bg;
ul li a {
&, i { color: rgba(255, 255, 255, .35); }
}
} }
// //
// Fancy layout // Fancy layout
// //
//color-fancy-master-tabs-bg: mix(black, saturate(spin(@primary-color, -5.5), 100%), 17.25%);
//color-fancy-form-inactive-tab: mix(black, saturate(spin(@primary-color-light, -4.25), 11.25%), 24%);
@color-fancy-form-tabless-fields-bg: @primary-color-light; @color-fancy-form-tabless-fields-bg: @primary-color-light;
@color-fancy-master-tabs-bg: @primary-color-dark; @color-fancy-master-tabs-bg: @primary-color-dark;
@color-fancy-form-inactive-tab: mix(black, desaturate(@primary-color-dark, 14.5%), 5%); @color-fancy-form-inactive-tab: mix(black, desaturate(@primary-color-dark, 14.5%), 5%);
@tab-svg: escape('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="100px" height="110px" viewBox="0 0 100 110" enable-background="new 0 0 100 110" xml:space="preserve"><path d="M0,30C5,30,10,0,20,0c5,0,60,0,65,0c10,0,10,30,15,30"/><path fill="@{color-fancy-form-tabless-fields-bg}" d="M0,70c5,0,10-30,20-30c0,10,0,15,0,15v15"/><path fill="@{color-fancy-form-tabless-fields-bg}" d="M100,70c-5,0-10-30-20-30c0,10,0,15,0,15v15"/><path fill="@{color-fancy-form-inactive-tab}" d="M0,110c5,0,10-30,20-30c0,10,0,15,0,15v15"/><path fill="@{color-fancy-form-inactive-tab}" d="M100,110c-5,0-10-30-20-30c0,10,0,15,0,15v15"/></svg>'); @tab-svg: escape('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" width="100px" height="110px" viewBox="0 0 100 110" enable-background="new 0 0 100 110" xml:space="preserve"><path d="M0,30C5,30,10,0,20,0c5,0,60,0,65,0c10,0,10,30,15,30"/><path fill="@{color-fancy-form-tabless-fields-bg}" d="M0,70c5,0,10-30,20-30c0,10,0,15,0,15v15"/><path fill="@{color-fancy-form-tabless-fields-bg}" d="M100,70c-5,0-10-30-20-30c0,10,0,15,0,15v15"/><path fill="@{color-fancy-form-inactive-tab}" d="M0,110c5,0,10-30,20-30c0,10,0,15,0,15v15"/><path fill="@{color-fancy-form-inactive-tab}" d="M100,110c-5,0-10-30-20-30c0,10,0,15,0,15v15"/></svg>');
.fancy-layout { .fancy-layout {
@ -80,7 +72,6 @@ body.outer .layout > .layout-row.layout-head {
&.master { &.master {
> div > div.tabs-container > ul.nav-tabs > li { > div > div.tabs-container > ul.nav-tabs > li {
a { color: rgba(255, 255, 255, .35); }
a > span.title { a > span.title {
background-color: @color-fancy-form-inactive-tab; background-color: @color-fancy-form-inactive-tab;
&:before, &:after { &:before, &:after {
@ -88,21 +79,16 @@ body.outer .layout > .layout-row.layout-head {
} }
} }
&.active { &.active {
a { color: #fff; }
a > span.title { a > span.title {
background-color: @color-fancy-form-tabless-fields-bg; background-color: @color-fancy-form-tabless-fields-bg;
} }
} }
} }
} }
} }
.form-tabless-fields { .form-tabless-fields {
background: @color-fancy-form-tabless-fields-bg; background: @color-fancy-form-tabless-fields-bg;
label {
color: rgba(255, 255, 255, .5);
}
} }
} }
@ -124,8 +110,47 @@ div.control-componentlist {
// File List // File List
// //
@color-list-active-border: @primary-color-light;
.control-filelist { .control-filelist {
ul li.active a:after { ul li.active a:after {
background: @primary-color-light; background: @color-list-active-border;
}
}
//
// Sidenav Tree
//
@color-sidebarnav-bg: @secondary-color-light;
@color-sidebarnav-tree-group-bg: @secondary-color-dark;
@color-sidebarnav-tree-inactive-bg: mix(white, @secondary-color-light, 7%);
@color-sidebarnav-tree-active-bg: @secondary-color-light;
@color-sidebarnav-tree-active-marker: @primary-color-light;
.sidenav-tree {
background: @color-sidebarnav-bg;
ul.top-level > li {
> div.group h3 {
background: @color-sidebarnav-tree-group-bg;
}
> ul li {
a {
background: @color-sidebarnav-tree-inactive-bg;
}
&.active a {
background: @color-sidebarnav-tree-active-bg;
&:before {
background: @color-sidebarnav-tree-active-marker;
}
}
&:hover a {
background: @color-sidebarnav-tree-active-bg;
}
}
} }
} }

View File

@ -0,0 +1,58 @@
# ===================================
# Field Definitions
# ===================================
tabs:
fields:
logo:
label: Logo
type: fileupload
commentAbove: Upload a custom logo to use in the back-end.
mode: image
imageHeight: 170
imageWidth: 170
tab: Brand
app_name:
label: App Name
commentAbove: This name is shown in the title area of the back-end.
tab: Brand
app_tagline:
label: App Tagline
commentAbove: This name is shown on the sign in screen for the back-end.
tab: Brand
primary_color_light:
label: Primary (Light)
type: colorpicker
tab: Colors
availableColors: [#1abc9c, #2ecc71, #3498db, #9b59b6, #34495e, #f1c40f, #e67e22, #e74c3c, #ecf0f1, #95a5a6]
primary_color_dark:
label: Primary (Dark)
type: colorpicker
tab: Colors
availableColors: [#16a085, #27ae60, #2980b9, #8e44ad, #2b3e50, #f39c12, #d35400, #c0392b, #bdc3c7, #7f8c8d]
secondary_color_light:
label: Secondary (Light)
type: colorpicker
tab: Colors
availableColors: [#1abc9c, #2ecc71, #3498db, #9b59b6, #34495e, #f1c40f, #e67e22, #e74c3c, #ecf0f1, #95a5a6]
secondary_color_dark:
label: Secondary (Dark)
type: colorpicker
tab: Colors
availableColors: [#16a085, #27ae60, #2980b9, #8e44ad, #2b3e50, #f39c12, #d35400, #c0392b, #bdc3c7, #7f8c8d]
custom_css:
label: Custom stylesheet
type: codeeditor
tab: Styles
size: giant

View File

@ -101,8 +101,8 @@ class Index extends Controller
$this->addJs('/modules/backend/formwidgets/codeeditor/assets/vendor/ace/mode-'.$mode.'.js', 'core'); $this->addJs('/modules/backend/formwidgets/codeeditor/assets/vendor/ace/mode-'.$mode.'.js', 'core');
$this->bodyClass = 'compact-container side-panel-not-fixed'; $this->bodyClass = 'compact-container side-panel-not-fixed';
$this->pageTitle = Lang::get('cms::lang.cms.menu_label'); $this->pageTitle = 'cms::lang.cms.menu_label';
$this->pageTitleTemplate = '%s CMS | October'; $this->pageTitleTemplate = '%s CMS';
} }
public function index_onOpenTemplate() public function index_onOpenTemplate()

View File

@ -1,6 +1,5 @@
<?php namespace Cms\Controllers; <?php namespace Cms\Controllers;
use Lang;
use Config; use Config;
use BackendMenu; use BackendMenu;
use Input; use Input;
@ -30,7 +29,7 @@ class Themes extends Controller
$this->addCss('/modules/cms/assets/css/october.theme-selector.css', 'core'); $this->addCss('/modules/cms/assets/css/october.theme-selector.css', 'core');
$this->pageTitle = Lang::get('cms::lang.theme.settings_menu'); $this->pageTitle = 'cms::lang.theme.settings_menu';
BackendMenu::setContext('October.System', 'system', 'settings'); BackendMenu::setContext('October.System', 'system', 'settings');
SettingsManager::setContext('October.Cms', 'theme'); SettingsManager::setContext('October.Cms', 'theme');
} }

View File

@ -28,6 +28,6 @@
</div> </div>
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<?php endif ?> <?php endif ?>
<?= Block::endPut() ?> <?= Block::endPut() ?>

View File

@ -1,5 +1,6 @@
<?php namespace System\Behaviors; <?php namespace System\Behaviors;
use Cache;
use System\Classes\ModelBehavior; use System\Classes\ModelBehavior;
use System\Classes\ApplicationException; use System\Classes\ApplicationException;
@ -54,6 +55,7 @@ class SettingsModel extends ModelBehavior
*/ */
$this->model->bindEvent('model.afterFetch', [$this, 'afterModelFetch']); $this->model->bindEvent('model.afterFetch', [$this, 'afterModelFetch']);
$this->model->bindEvent('model.beforeSave', [$this, 'beforeModelSave']); $this->model->bindEvent('model.beforeSave', [$this, 'beforeModelSave']);
$this->model->bindEvent('model.afterSave', [$this, 'afterModelSave']);
$this->model->bindEvent('model.setAttribute', [$this, 'setModelAttribute']); $this->model->bindEvent('model.setAttribute', [$this, 'setModelAttribute']);
$this->model->bindEvent('model.saveInternal', [$this, 'saveModelInternal']); $this->model->bindEvent('model.saveInternal', [$this, 'saveModelInternal']);
@ -72,9 +74,7 @@ class SettingsModel extends ModelBehavior
if (isset(self::$instances[$this->recordCode])) if (isset(self::$instances[$this->recordCode]))
return self::$instances[$this->recordCode]; return self::$instances[$this->recordCode];
$item = $this->model->where('item', $this->recordCode)->first(); if (!$item = $this->getSettingsRecord()) {
if (!$item) {
$this->model->initSettingsData(); $this->model->initSettingsData();
if (method_exists($this->model, 'forceSave')) if (method_exists($this->model, 'forceSave'))
@ -94,7 +94,21 @@ class SettingsModel extends ModelBehavior
*/ */
public function isConfigured() public function isConfigured()
{ {
return $this->model->where('item', $this->recordCode)->count() > 0; return $this->getSettingsRecord() !== null;
}
/**
* Returns the raw Model record that stores the settings.
* @return Model
*/
public function getSettingsRecord()
{
$record = $this->model
->where('item', $this->recordCode)
->remember(1440, $this->getCacheKey())
->first();
return $record ?: null;
} }
/** /**
@ -108,17 +122,17 @@ class SettingsModel extends ModelBehavior
} }
/** /**
* Helper for getValue, intended as a static method * Helper for getSettingsValue, intended as a static method
*/ */
public function get($key, $default = null) public function get($key, $default = null)
{ {
return $this->instance()->getValue($key, $default); return $this->instance()->getSettingsValue($key, $default);
} }
/** /**
* Get a single setting value, or return a default value * Get a single setting value, or return a default value
*/ */
public function getValue($key, $default = null) public function getSettingsValue($key, $default = null)
{ {
if (array_key_exists($key, $this->fieldValues)) if (array_key_exists($key, $this->fieldValues))
return $this->fieldValues[$key]; return $this->fieldValues[$key];
@ -161,6 +175,15 @@ class SettingsModel extends ModelBehavior
$this->model->value = $this->fieldValues; $this->model->value = $this->fieldValues;
} }
/**
* After the model is saved, clear the cached query entry.
* @return void
*/
public function afterModelSave()
{
Cache::forget($this->getCacheKey());
}
/** /**
* Adulterate the model setter to use our field values instead. * Adulterate the model setter to use our field values instead.
*/ */
@ -200,4 +223,12 @@ class SettingsModel extends ModelBehavior
{ {
return $this->fieldConfig; return $this->fieldConfig;
} }
/**
* Returns a cache key for this record.
*/
protected function getCacheKey()
{
return 'system::settings.'.$this->recordCode;
}
} }

View File

@ -2,6 +2,7 @@
use Controller as BaseController; use Controller as BaseController;
use System\Classes\ApplicationException; use System\Classes\ApplicationException;
use System\Classes\CombineAssets;
use Exception; use Exception;
/** /**

View File

@ -37,7 +37,7 @@ class Settings extends Controller
public function index() public function index()
{ {
$this->pageTitle = Lang::get('system::lang.settings.menu_label'); $this->pageTitle = 'system::lang.settings.menu_label';
$this->vars['items'] = SettingsManager::instance()->listItems('system'); $this->vars['items'] = SettingsManager::instance()->listItems('system');
$this->bodyClass = 'compact-container sidenav-tree-root'; $this->bodyClass = 'compact-container sidenav-tree-root';
} }
@ -45,7 +45,7 @@ class Settings extends Controller
public function mysettings() public function mysettings()
{ {
BackendMenu::setContextSideMenu('mysettings'); BackendMenu::setContextSideMenu('mysettings');
$this->pageTitle = Lang::get('backend::lang.mysettings.menu_label'); $this->pageTitle = 'backend::lang.mysettings.menu_label';
$this->vars['items'] = SettingsManager::instance()->listItems('mysettings'); $this->vars['items'] = SettingsManager::instance()->listItems('mysettings');
$this->bodyClass = 'compact-container'; $this->bodyClass = 'compact-container';
} }
@ -58,18 +58,19 @@ class Settings extends Controller
{ {
SettingsManager::setContext($author.'.'.$plugin, $code); SettingsManager::setContext($author.'.'.$plugin, $code);
$this->vars['parentLink'] = Backend::url('system/settings');
$this->vars['parentLabel'] = Lang::get('system::lang.settings.menu_label');
try { try {
$item = $this->findSettingItem($author, $plugin, $code); if (!$item = $this->findSettingItem($author, $plugin, $code))
throw new ApplicationException(Lang::get('system::lang.settings.not_found'));
$this->pageTitle = $item->label; $this->pageTitle = $item->label;
if ($item->context == 'mysettings') { if ($item->context == 'mysettings') {
$this->vars['parentLink'] = Backend::url('system/settings/mysettings'); $this->vars['parentLink'] = Backend::url('system/settings/mysettings');
$this->vars['parentLabel'] = Lang::get('backend::lang.mysettings.menu_label'); $this->vars['parentLabel'] = Lang::get('backend::lang.mysettings.menu_label');
} }
else {
$this->vars['parentLink'] = Backend::url('system/settings');
$this->vars['parentLabel'] = Lang::get('system::lang.settings.menu_label');
}
$model = $this->createModel($item); $model = $this->createModel($item);
$this->initWidgets($model); $this->initWidgets($model);

View File

@ -67,7 +67,7 @@ class Updates extends Controller
*/ */
public function manage() public function manage()
{ {
$this->pageTitle = Lang::get('system::lang.plugins.manage'); $this->pageTitle = 'system::lang.plugins.manage';
PluginManager::instance()->clearDisabledCache(); PluginManager::instance()->clearDisabledCache();
return $this->asExtension('ListController')->index(); return $this->asExtension('ListController')->index();
} }

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('system/eventlogs') ?>"><?= e(trans('system::lang.event_log.menu_label')) ?></a></li> <li><a href="<?= Backend::url('system/eventlogs') ?>"><?= e(trans('system::lang.event_log.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -30,7 +30,7 @@
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_layouts_label')) ?></a></li> <li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_layouts_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -40,7 +40,7 @@
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <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> <p><a href="<?= Backend::url('system/mailtemplates') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_layouts_label')) ?></a></li> <li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_layouts_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -59,7 +59,7 @@
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <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> <p><a href="<?= Backend::url('system/mailtemplates') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_label')) ?></a></li> <li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -40,7 +40,7 @@
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <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> <p><a href="<?= Backend::url('system/mailtemplates') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_label')) ?></a></li> <li><a href="<?= Backend::url('system/mailtemplates') ?>"><?= e(trans('system::lang.mail_templates.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -65,7 +65,7 @@
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <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> <p><a href="<?= Backend::url('system/mailtemplates') ?>" class="btn btn-default"><?= e(trans('system::lang.mail_templates.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('system/requestlogs') ?>"><?= e(trans('system::lang.request_log.menu_label')) ?></a></li> <li><a href="<?= Backend::url('system/requestlogs') ?>"><?= e(trans('system::lang.request_log.menu_label')) ?></a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>
@ -34,7 +34,7 @@
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
<?php endif ?> <?php endif ?>

View File

@ -32,6 +32,6 @@
<?= Form::close() ?> <?= Form::close() ?>
<?php else: ?> <?php else: ?>
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <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> <p><a href="<?= $parentLink ?>" class="btn btn-default"><?= e(trans('system::lang.settings.return')) ?></a></p>
<?php endif ?> <?php endif ?>

View File

@ -136,7 +136,7 @@
<?php else: ?> <?php else: ?>
<div class="modal-body"> <div class="modal-body">
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button <button

View File

@ -113,7 +113,7 @@
<?php else: ?> <?php else: ?>
<div class="modal-body"> <div class="modal-body">
<p class="flash-message static error"><?= e($this->fatalError) ?></p> <p class="flash-message static error"><?= e(trans($this->fatalError)) ?></p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button <button

View File

@ -1,7 +1,7 @@
<?php Block::put('breadcrumb') ?> <?php Block::put('breadcrumb') ?>
<ul> <ul>
<li><a href="<?= Backend::url('system/updates') ?>">Updates</a></li> <li><a href="<?= Backend::url('system/updates') ?>">Updates</a></li>
<li><?= e($this->pageTitle) ?></li> <li><?= e(trans($this->pageTitle)) ?></li>
</ul> </ul>
<?php Block::endPut() ?> <?php Block::endPut() ?>

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Zurück zum Wesentlichen', 'tagline' => 'Zurück zum Wesentlichen',
], ],
'locale' => [ 'locale' => [
'en' => 'English', 'en' => 'English',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Getting back to basics', 'tagline' => 'Getting back to basics',
], ],
'locale' => [ 'locale' => [
'en' => 'English', 'en' => 'English',
@ -87,13 +87,14 @@ return [
], ],
'settings' => [ 'settings' => [
'menu_label' => 'Settings', 'menu_label' => 'Settings',
'not_found' => 'Unable to find the specified settings.',
'missing_model' => 'The settings page is missing a Model definition.', 'missing_model' => 'The settings page is missing a Model definition.',
'update_success' => 'Settings for :name have been updated successfully.', 'update_success' => 'Settings for :name have been updated successfully.',
'return' => 'Return to system settings', 'return' => 'Return to system settings',
'search' => 'Search' 'search' => 'Search'
], ],
'mail' => [ 'mail' => [
'menu_label' => 'Mail Configuration', 'menu_label' => 'Mail configuration',
'menu_description' => 'Manage email configuration.', 'menu_description' => 'Manage email configuration.',
'general' => 'General', 'general' => 'General',
'method' => 'Mail Method', 'method' => 'Mail Method',
@ -112,7 +113,7 @@ return [
'sendmail_path_comment' => 'Please specify the path of the sendmail program.', 'sendmail_path_comment' => 'Please specify the path of the sendmail program.',
], ],
'mail_templates' => [ 'mail_templates' => [
'menu_label' => 'Mail Templates', 'menu_label' => 'Mail templates',
'menu_description' => 'Modify the mail templates that are sent to users and administrators, manage email layouts.', 'menu_description' => 'Modify the mail templates that are sent to users and administrators, manage email layouts.',
'new_template' => 'New Template', 'new_template' => 'New Template',
'new_layout' => 'New Layout', 'new_layout' => 'New Layout',
@ -203,7 +204,7 @@ return [
], ],
'event_log' => [ 'event_log' => [
'hint' => 'This log displays a list of potential errors that occur in the application, such as exceptions and debugging information.', 'hint' => 'This log displays a list of potential errors that occur in the application, such as exceptions and debugging information.',
'menu_label' => 'Event Log', 'menu_label' => 'Event log',
'menu_description' => 'View system log messages with their recorded time and details.', 'menu_description' => 'View system log messages with their recorded time and details.',
'empty_link' => 'Empty event log', 'empty_link' => 'Empty event log',
'empty_loading' => 'Emptying event log...', 'empty_loading' => 'Emptying event log...',
@ -217,7 +218,7 @@ return [
], ],
'request_log' => [ 'request_log' => [
'hint' => 'This log displays a list of browser requests that may require attention. For example, if a visitor opens a CMS page that cannot be found, a record is created with the status code 404.', 'hint' => 'This log displays a list of browser requests that may require attention. For example, if a visitor opens a CMS page that cannot be found, a record is created with the status code 404.',
'menu_label' => 'Request Log', 'menu_label' => 'Request log',
'menu_description' => 'View bad or redirected requests, such as Page not found (404).', 'menu_description' => 'View bad or redirected requests, such as Page not found (404).',
'empty_link' => 'Empty request log', 'empty_link' => 'Empty request log',
'empty_loading' => 'Emptying request log...', 'empty_loading' => 'Emptying request log...',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Getting back to basics', 'tagline' => 'Getting back to basics',
], ],
'locale' => [ 'locale' => [
'en' => 'Inglés', 'en' => 'Inglés',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'مدیریت محتوی اکتبر', 'name' => 'مدیریت محتوی اکتبر',
'motto' => 'بازگشت به گذشته', 'tagline' => 'بازگشت به گذشته',
], ],
'locale' => [ 'locale' => [
'en' => 'انگلیسی', 'en' => 'انگلیسی',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Getting back to basics', 'tagline' => 'Getting back to basics',
], ],
'locale' => [ 'locale' => [
'en' => 'Anglais', 'en' => 'Anglais',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Getting back to basics', 'tagline' => 'Getting back to basics',
], ],
'locale' => [ 'locale' => [
'en' => 'Inglese', 'en' => 'Inglese',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => '基本に戻ろう!', 'tagline' => '基本に戻ろう!',
], ],
'locale' => [ 'locale' => [
'en' => 'English', 'en' => 'English',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Terug naar de basis', 'tagline' => 'Terug naar de basis',
], ],
'locale' => [ 'locale' => [
'en' => 'Engels', 'en' => 'Engels',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Voltando ao básico', 'tagline' => 'Voltando ao básico',
], ],
'locale' => [ 'locale' => [
'en' => 'Inglês', 'en' => 'Inglês',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Intoarcerea la elementele de baza', 'tagline' => 'Intoarcerea la elementele de baza',
], ],
'locale' => [ 'locale' => [
'en' => 'Engleza', 'en' => 'Engleza',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Возвращение к истокам', 'tagline' => 'Возвращение к истокам',
], ],
'locale' => [ 'locale' => [
'en' => 'English', 'en' => 'English',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Getting back to basics', 'tagline' => 'Getting back to basics',
], ],
'locale' => [ 'locale' => [
'en' => 'English', 'en' => 'English',

View File

@ -3,7 +3,7 @@
return [ return [
'app' => [ 'app' => [
'name' => 'October CMS', 'name' => 'October CMS',
'motto' => 'Basitliğe dönüş...', 'tagline' => 'Basitliğe dönüş...',
], ],
'locale' => [ 'locale' => [
'en' => 'English', 'en' => 'English',

View File

@ -1,7 +1,7 @@
<?php <?php
use Cms\Classes\Theme; use Cms\Classes\Theme;
use Cms\Classes\CombineAssets; use System\Classes\CombineAssets;
class CombineAssetsTest extends TestCase class CombineAssetsTest extends TestCase
{ {