Files
vivespos-landing/modules/backend/models/Preference.php
avives 1f72193a64
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
- 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
2026-08-21 19:29:00 -06:00

329 lines
12 KiB
PHP

<?php
namespace Backend\Models;
use Backend\Facades\BackendAuth;
use DateTime;
use DateTimeZone;
use DirectoryIterator;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Session;
use Winter\Storm\Database\Model;
use Winter\Storm\Support\Facades\Config;
/**
* Backend preferences for the backend user
*
* @package winter\wn-backend-module
* @author Alexey Bobkov, Samuel Georges
*/
class Preference extends Model
{
use \Winter\Storm\Database\Traits\Validation;
const DEFAULT_THEME = 'twilight.tmTheme';
/**
* @var array Behaviors implemented by this model.
*/
public $implement = [
\Backend\Behaviors\UserPreferencesModel::class
];
/**
* @var string Unique code
*/
public $settingsCode = 'backend::backend.preferences';
/**
* @var mixed Settings form field defitions
*/
public $settingsFields = 'fields.yaml';
/**
* @var array Validation rules
*/
public $rules = [];
/**
* Initialize the seed data for this model. This only executes when the
* model is first created or reset to default.
* @return void
*/
public function initSettingsData()
{
$config = App::make('config');
$this->locale = $config->get('app.locale', 'en');
$this->fallback_locale = $this->getFallbackLocale($this->locale);
$this->timezone = $config->get('cms.backendTimezone', $config->get('app.timezone'));
$this->editor_font_size = $config->get('editor.font_size', 12);
$this->editor_word_wrap = $config->get('editor.word_wrap', 'fluid');
$this->editor_code_folding = $config->get('editor.code_folding', 'manual');
// @deprecated v1.3.0
$this->editor_enable_folding = $config->get('editor.enable_folding', $config->get('editor.code_folding', 'manual') !== 'manual');
$this->editor_tab_size = $config->get('editor.tab_size', 4);
$this->editor_theme = $config->get('editor.theme', static::DEFAULT_THEME);
$this->editor_show_invisibles = $config->get('editor.show_invisibles', false);
$this->editor_highlight_active_line = $config->get('editor.highlight_active_line', true);
$this->editor_use_hard_tabs = $config->get('editor.use_hard_tabs', false);
$this->editor_show_gutter = $config->get('editor.show_gutter', true);
$this->editor_auto_closing = $config->get('editor.auto_closing', false);
$this->editor_autocompletion = $config->get('editor.editor_autocompletion', 'manual');
$this->editor_enable_snippets = $config->get('editor.enable_snippets', false);
$this->editor_display_indent_guides = $config->get('editor.display_indent_guides', false);
$this->editor_show_print_margin = $config->get('editor.show_print_margin', false);
$this->editor_show_minimap = $config->get('editor.show_minimap', true);
$this->editor_bracket_colors = $config->get('editor.bracket_colors', false);
$this->editor_show_colors = $config->get('editor.show_colors', true);
}
/**
* Set the application's locale based on the user preference.
* @return void
*/
public static function setAppLocale()
{
if (Session::has('locale')) {
App::setLocale(Session::get('locale'));
}
elseif (
($user = BackendAuth::getUser()) &&
($locale = static::get('locale'))
) {
Session::put('locale', $locale);
App::setLocale($locale);
}
}
/**
* Same as setAppLocale except for the fallback definition.
* @return void
*/
public static function setAppFallbackLocale()
{
if (Session::has('fallback_locale')) {
Lang::setFallback(Session::get('fallback_locale'));
}
elseif (
($user = BackendAuth::getUser()) &&
($locale = static::get('fallback_locale'))
) {
Session::put('fallback_locale', $locale);
Lang::setFallback($locale);
}
}
//
// Events
//
public function beforeValidate()
{
$this->fallback_locale = $this->getFallbackLocale($this->locale);
}
public function afterSave()
{
Session::put('locale', $this->locale);
Session::put('fallback_locale', $this->fallback_locale);
}
//
// Utils
//
/**
* Called when this model is reset to default by the user.
* @return void
*/
public function resetDefault()
{
parent::resetDefault();
Session::forget('locale');
Session::forget('fallback_locale');
}
/**
* Overrides the config with the user's preference.
* @return void
*/
public static function applyConfigValues()
{
$settings = self::instance();
Config::set('app.locale', $settings->locale);
Config::set('app.fallback_locale', $settings->fallback_locale);
}
//
// Getters
//
/**
* Attempt to extract the language from the locale,
* otherwise use the configuration.
* @return string
*/
protected function getFallbackLocale($locale)
{
if ($position = strpos($locale, '-')) {
$target = substr($locale, 0, $position);
$available = $this->getLocaleOptions();
if (isset($available[$target])) {
return $target;
}
}
return Config::get('app.fallback_locale');
}
/**
* Returns available options for the "locale" attribute.
* @return array
*/
public function getLocaleOptions()
{
$localeOptions = [
'ar' => [Lang::get('system::lang.locale.ar'), 'flag-sa'],
'be' => [Lang::get('system::lang.locale.be'), 'flag-by'],
'bg' => [Lang::get('system::lang.locale.bg'), 'flag-bg'],
'ca' => [Lang::get('system::lang.locale.ca'), 'flag-es-ct'],
'cs' => [Lang::get('system::lang.locale.cs'), 'flag-cz'],
'da' => [Lang::get('system::lang.locale.da'), 'flag-dk'],
'de' => [Lang::get('system::lang.locale.de'), 'flag-de'],
'el' => [Lang::get('system::lang.locale.el'), 'flag-gr'],
'en' => [Lang::get('system::lang.locale.en'), 'flag-us'],
'en-au' => [Lang::get('system::lang.locale.en-au'), 'flag-au'],
'en-ca' => [Lang::get('system::lang.locale.en-ca'), 'flag-ca'],
'en-gb' => [Lang::get('system::lang.locale.en-gb'), 'flag-gb'],
'es' => [Lang::get('system::lang.locale.es'), 'flag-es'],
'es-ar' => [Lang::get('system::lang.locale.es-ar'), 'flag-ar'],
'et' => [Lang::get('system::lang.locale.et'), 'flag-ee'],
'fa' => [Lang::get('system::lang.locale.fa'), 'flag-ir'],
'fi' => [Lang::get('system::lang.locale.fi'), 'flag-fi'],
'fr' => [Lang::get('system::lang.locale.fr'), 'flag-fr'],
'fr-ca' => [Lang::get('system::lang.locale.fr-ca'), 'flag-ca'],
'hu' => [Lang::get('system::lang.locale.hu'), 'flag-hu'],
'id' => [Lang::get('system::lang.locale.id'), 'flag-id'],
'it' => [Lang::get('system::lang.locale.it'), 'flag-it'],
'ja' => [Lang::get('system::lang.locale.ja'), 'flag-jp'],
'kr' => [Lang::get('system::lang.locale.kr'), 'flag-kr'],
'lt' => [Lang::get('system::lang.locale.lt'), 'flag-lt'],
'lv' => [Lang::get('system::lang.locale.lv'), 'flag-lv'],
'nb-no' => [Lang::get('system::lang.locale.nb-no'), 'flag-no'],
'nl' => [Lang::get('system::lang.locale.nl'), 'flag-nl'],
'pl' => [Lang::get('system::lang.locale.pl'), 'flag-pl'],
'pt-br' => [Lang::get('system::lang.locale.pt-br'), 'flag-br'],
'pt-pt' => [Lang::get('system::lang.locale.pt-pt'), 'flag-pt'],
'ro' => [Lang::get('system::lang.locale.ro'), 'flag-ro'],
'rs' => [Lang::get('system::lang.locale.rs'), 'flag-rs'],
'ru' => [Lang::get('system::lang.locale.ru'), 'flag-ru'],
'sk' => [Lang::get('system::lang.locale.sk'), 'flag-sk'],
'sl' => [Lang::get('system::lang.locale.sl'), 'flag-si'],
'sv' => [Lang::get('system::lang.locale.sv'), 'flag-se'],
'th' => [Lang::get('system::lang.locale.th'), 'flag-th'],
'tr' => [Lang::get('system::lang.locale.tr'), 'flag-tr'],
'uk' => [Lang::get('system::lang.locale.uk'), 'flag-ua'],
'vn' => [Lang::get('system::lang.locale.vn'), 'flag-vn'],
'zh-cn' => [Lang::get('system::lang.locale.zh-cn'), 'flag-cn'],
'zh-tw' => [Lang::get('system::lang.locale.zh-tw'), 'flag-tw'],
];
$locales = Config::get('app.localeOptions', $localeOptions);
// Sort locales alphabetically
asort($locales);
return $locales;
}
/**
* Returns all available timezone options.
* @return array
*/
public function getTimezoneOptions()
{
$timezoneIdentifiers = DateTimeZone::listIdentifiers();
$utcTime = new DateTime('now', new DateTimeZone('UTC'));
$tempTimezones = [];
foreach ($timezoneIdentifiers as $timezoneIdentifier) {
$currentTimezone = new DateTimeZone($timezoneIdentifier);
$tempTimezones[] = [
'offset' => (int) $currentTimezone->getOffset($utcTime),
'identifier' => $timezoneIdentifier
];
}
// Sort the array by offset, identifier ascending
usort($tempTimezones, function ($a, $b) {
return $a['offset'] === $b['offset']
? strcmp($a['identifier'], $b['identifier'])
: $a['offset'] - $b['offset'];
});
$timezoneList = [];
foreach ($tempTimezones as $tz) {
$sign = $tz['offset'] > 0 ? '+' : '-';
$offset = gmdate('H:i', abs($tz['offset']));
$timezoneList[$tz['identifier']] = '(UTC ' . $sign . $offset . ') ' . $tz['identifier'];
}
return $timezoneList;
}
/**
* Returns the theme options for the backend editor.
* Supports both legacy tmTheme (XML) and modern JSON theme formats.
*/
public function getEditorThemeOptions(): array
{
$themeDir = new DirectoryIterator('modules/backend/formwidgets/codeeditor/assets/themes/');
$themes = [];
// Iterate through the themes
foreach ($themeDir as $node) {
if (!$node->isFile()) {
continue;
}
$extension = $node->getExtension();
// Support both tmTheme (legacy) and JSON (modern) formats
if ($extension === 'tmTheme' || $extension === 'json') {
// Theme ID includes the file extension (e.g., "twilight.tmTheme", "one-dark-pro.json")
$themeId = $node->getBasename();
// Display name strips the extension for user-friendly presentation
$themeNameBase = $node->getBasename('.' . $extension);
$themeName = ucwords(str_replace(['_', '-'], ' ', $themeNameBase));
// Add the values to the themes array
if ($themeId != static::DEFAULT_THEME) {
$themes[$themeId] = $themeName;
}
}
}
// Sort the theme alphabetically, and push the default theme
asort($themes);
// Strip extension from default theme for display name
$defaultThemeName = ucwords(str_replace(['_', '-'], ' ', pathinfo(static::DEFAULT_THEME, PATHINFO_FILENAME)));
return [static::DEFAULT_THEME => $defaultThemeName] + $themes;
}
/**
* Returns the word wrap options for the backend editor.
*/
public function getEditorWordWrapOptions(): array
{
return [
'off' => Lang::get('backend::lang.editor.mode_off'),
'40' => Lang::get('backend::lang.editor.40_characters'),
'80' => Lang::get('backend::lang.editor.80_characters'),
'fluid' => Lang::get('backend::lang.editor.mode_fluid'),
];
}
}