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:
315
modules/backend/formwidgets/RichEditor.php
Normal file
315
modules/backend/formwidgets/RichEditor.php
Normal file
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
|
||||
namespace Backend\FormWidgets;
|
||||
|
||||
use Backend\Classes\FormWidgetBase;
|
||||
use Backend\Facades\Backend;
|
||||
use Backend\Facades\BackendAuth;
|
||||
use Backend\Models\EditorSetting;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Lang;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Winter\Storm\Support\Facades\Config;
|
||||
use Winter\Storm\Support\Facades\Event;
|
||||
use Winter\Storm\Support\Facades\File;
|
||||
|
||||
/**
|
||||
* Rich Editor
|
||||
* Renders a rich content editor field.
|
||||
*
|
||||
* @package winter\wn-backend-module
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
class RichEditor extends FormWidgetBase
|
||||
{
|
||||
use \Backend\Traits\UploadableWidget;
|
||||
|
||||
//
|
||||
// Configurable properties
|
||||
//
|
||||
|
||||
/**
|
||||
* @var boolean Determines whether content has HEAD and HTML tags.
|
||||
*/
|
||||
public $fullPage = false;
|
||||
|
||||
/**
|
||||
* @var boolean Determines whether content has HEAD and HTML tags.
|
||||
*/
|
||||
public $toolbarButtons;
|
||||
|
||||
/**
|
||||
* @var boolean If true, the editor is set to read-only mode
|
||||
*/
|
||||
public $readOnly = false;
|
||||
|
||||
/**
|
||||
* @var string|null Path in the Media Library where uploaded files should be stored. If null it will be pulled from Request::input('path');
|
||||
*/
|
||||
public $uploadPath = '/uploaded-files';
|
||||
|
||||
//
|
||||
// Object properties
|
||||
//
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected $defaultAlias = 'richeditor';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($this->formField->disabled) {
|
||||
$this->readOnly = true;
|
||||
}
|
||||
|
||||
$this->fillFromConfig([
|
||||
'fullPage',
|
||||
'readOnly',
|
||||
'toolbarButtons',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$this->prepareVars();
|
||||
return $this->makePartial('richeditor');
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the list data
|
||||
*/
|
||||
public function prepareVars()
|
||||
{
|
||||
$this->vars['field'] = $this->formField;
|
||||
$this->vars['editorLang'] = $this->getValidEditorLang();
|
||||
$this->vars['fullPage'] = $this->fullPage;
|
||||
$this->vars['stretch'] = $this->formField->stretch;
|
||||
$this->vars['size'] = $this->formField->size;
|
||||
$this->vars['readOnly'] = $this->readOnly;
|
||||
$this->vars['name'] = $this->getFieldName();
|
||||
$this->vars['value'] = $this->getLoadValue();
|
||||
$this->vars['toolbarButtons'] = $this->evalToolbarButtons();
|
||||
$this->vars['useMediaManager'] = BackendAuth::getUser()->hasAccess('media.manage_media');
|
||||
|
||||
$this->vars['globalToolbarButtons'] = EditorSetting::getConfigured('html_toolbar_buttons');
|
||||
$this->vars['allowEmptyTags'] = EditorSetting::getConfigured('html_allow_empty_tags');
|
||||
$this->vars['allowTags'] = EditorSetting::getConfigured('html_allow_tags');
|
||||
$this->vars['allowAttributes'] = EditorSetting::getConfigured('html_allow_attributes');
|
||||
$this->vars['noWrapTags'] = EditorSetting::getConfigured('html_no_wrap_tags');
|
||||
$this->vars['removeTags'] = EditorSetting::getConfigured('html_remove_tags');
|
||||
$this->vars['lineBreakerTags'] = EditorSetting::getConfigured('html_line_breaker_tags');
|
||||
|
||||
$this->vars['imageStyles'] = EditorSetting::getConfiguredStyles('html_style_image');
|
||||
$this->vars['linkStyles'] = EditorSetting::getConfiguredStyles('html_style_link');
|
||||
$this->vars['paragraphStyles'] = EditorSetting::getConfiguredStyles('html_style_paragraph');
|
||||
$this->vars['paragraphFormats'] = EditorSetting::getConfiguredFormats('html_paragraph_formats');
|
||||
$this->vars['tableStyles'] = EditorSetting::getConfiguredStyles('html_style_table');
|
||||
$this->vars['tableCellStyles'] = EditorSetting::getConfiguredStyles('html_style_table_cell');
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the toolbar buttons to use based on config.
|
||||
* @return string
|
||||
*/
|
||||
protected function evalToolbarButtons()
|
||||
{
|
||||
$buttons = $this->toolbarButtons;
|
||||
|
||||
if (is_string($buttons)) {
|
||||
$buttons = array_map(function ($button) {
|
||||
return strlen($button) ? $button : '|';
|
||||
}, explode('|', $buttons));
|
||||
}
|
||||
|
||||
return $buttons;
|
||||
}
|
||||
|
||||
public function onLoadPageLinksForm()
|
||||
{
|
||||
$this->vars['links'] = $this->getPageLinksArray();
|
||||
return $this->makePartial('page_links_form');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function loadAssets()
|
||||
{
|
||||
$this->addCss('css/richeditor.css', 'core');
|
||||
$this->addJs('js/build-min.js', 'core');
|
||||
|
||||
if (Config::get('develop.decompileBackendAssets', false)) {
|
||||
$scripts = Backend::decompileAsset($this->getAssetPath('js/build-plugins.js'));
|
||||
foreach ($scripts as $script) {
|
||||
$this->addJs($script, 'core');
|
||||
}
|
||||
} else {
|
||||
$this->addJs('js/build-plugins-min.js', 'core');
|
||||
}
|
||||
|
||||
$this->addJs('/modules/backend/assets/vendor/ace-codeeditor/build-min.js', 'core');
|
||||
|
||||
if ($lang = $this->getValidEditorLang()) {
|
||||
$this->addJs('vendor/froala/js/languages/'.$lang.'.js', 'core');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a valid language code for Redactor.
|
||||
* @return string|mixed
|
||||
*/
|
||||
protected function getValidEditorLang()
|
||||
{
|
||||
$locale = App::getLocale();
|
||||
|
||||
// English is baked in
|
||||
if ($locale == 'en') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$locale = str_replace('-', '_', strtolower($locale));
|
||||
$path = base_path('modules/backend/formwidgets/richeditor/assets/vendor/froala/js/languages/'.$locale.'.js');
|
||||
|
||||
return File::exists($path) ? $locale : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of registered page link types.
|
||||
* This is reserved functionality for separating the links by type.
|
||||
* @return array Returns an array of registered page link types
|
||||
*/
|
||||
protected function getPageLinkTypes()
|
||||
{
|
||||
$result = [];
|
||||
|
||||
/**
|
||||
* @event backend.richeditor.listTypes
|
||||
* Register additional "page link types" to the RichEditor FormWidget
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* Event::listen('backend.richeditor.listTypes', function () {
|
||||
* return [
|
||||
* 'my-identifier' => 'author.plugin::lang.richeditor.link_types.my_identifier',
|
||||
* ];
|
||||
* });
|
||||
*
|
||||
*/
|
||||
$apiResult = Event::fire('backend.richeditor.listTypes');
|
||||
if (is_array($apiResult)) {
|
||||
foreach ($apiResult as $typeList) {
|
||||
if (!is_array($typeList)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($typeList as $typeCode => $typeName) {
|
||||
$result[$typeCode] = $typeName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getPageLinks($type)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
/**
|
||||
* @event backend.richeditor.getTypeInfo
|
||||
* Register additional "page link types" to the RichEditor FormWidget
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* Event::listen('backend.richeditor.getTypeInfo', function ($type) {
|
||||
* if ($type === 'my-identifier') {
|
||||
* return [
|
||||
* 'https://example.com/page1' => 'Page 1',
|
||||
* 'https://example.com/parent-page' => [
|
||||
* 'title' => 'Parent Page',
|
||||
* 'links' => [
|
||||
* 'https://example.com/child-page' => 'Child Page',
|
||||
* ],
|
||||
* ],
|
||||
* ];
|
||||
* }
|
||||
* });
|
||||
*
|
||||
*/
|
||||
$apiResult = Event::fire('backend.richeditor.getTypeInfo', [$type]);
|
||||
if (is_array($apiResult)) {
|
||||
foreach ($apiResult as $typeInfo) {
|
||||
if (!is_array($typeInfo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($typeInfo as $name => $value) {
|
||||
$result[$name] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single collection of available page links.
|
||||
* This implementation has room to place links under
|
||||
* different groups based on the link type.
|
||||
* @return array
|
||||
*/
|
||||
protected function getPageLinksArray()
|
||||
{
|
||||
$links = [];
|
||||
$types = $this->getPageLinkTypes();
|
||||
|
||||
$links[] = ['name' => Lang::get('backend::lang.pagelist.select_page'), 'url' => false];
|
||||
|
||||
$iterator = function ($links, $level = 0) use (&$iterator) {
|
||||
$result = [];
|
||||
|
||||
foreach ($links as $linkUrl => $link) {
|
||||
/*
|
||||
* Remove scheme and host from URL
|
||||
*/
|
||||
$baseUrl = Request::getSchemeAndHttpHost();
|
||||
if (strpos($linkUrl, $baseUrl) === 0) {
|
||||
$linkUrl = substr($linkUrl, strlen($baseUrl));
|
||||
}
|
||||
|
||||
/*
|
||||
* Root page fallback.
|
||||
*/
|
||||
if (strlen($linkUrl) === 0) {
|
||||
$linkUrl = '/';
|
||||
}
|
||||
|
||||
$linkName = str_repeat(' ', $level * 4);
|
||||
$linkName .= is_array($link) ? array_get($link, 'title', '') : $link;
|
||||
$result[] = ['name' => $linkName, 'url' => $linkUrl];
|
||||
|
||||
if (is_array($link)) {
|
||||
$result = array_merge(
|
||||
$result,
|
||||
$iterator(array_get($link, 'links', []), $level + 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
};
|
||||
|
||||
foreach ($types as $typeCode => $typeName) {
|
||||
$links = array_merge($links, $iterator($this->getPageLinks($typeCode)));
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user