diff --git a/src/Contracts/Model.php b/src/Contracts/Model.php new file mode 100644 index 0000000..975e6f5 --- /dev/null +++ b/src/Contracts/Model.php @@ -0,0 +1,60 @@ +where('pages.id', (int) $pageId); - })->with('related')->get(); return static::buildWidgetCollection($widgets); diff --git a/src/Model/Widget.php b/src/Model/Widget.php index d38dd5a..3e54b8a 100644 --- a/src/Model/Widget.php +++ b/src/Model/Widget.php @@ -5,13 +5,16 @@ use DB; use KodiCMS\Pages\Model\Page; use Illuminate\Database\Eloquent\Model; -use KodiCMS\Widgets\Contracts\WidgetManager; +use KodiCMS\Widgets\Contracts\Model as WidgetContract; +use KodiCMS\Widgets\Manager\WidgetManagerDatabase; +use KodiCMS\Widgets\Traits\WidgetStates; use KodiCMS\Widgets\Widget\Temp as TempWidget; use KodiCMS\Widgets\Exceptions\WidgetException; -use KodiCMS\Widgets\Manager\WidgetManagerDatabase; -class Widget extends Model +class Widget extends Model implements WidgetContract { + use WidgetStates; + /** * @var array */ @@ -48,6 +51,31 @@ class Widget extends Model */ protected $widget = null; + /** + * @var WidgetManagerDatabase + */ + protected $manager; + + /** + * Widget constructor. + * + * @param array $attributes + */ + public function __construct(array $attributes = []) + { + parent::__construct($attributes); + + $this->manager = app('widget.manager'); + } + + /** + * @return string + */ + public function getWidgetClass() + { + return get_class($this->toWidget()); + } + /** * @param string $template */ @@ -61,7 +89,7 @@ public function setTemplateAttribute($template) */ public function getType() { - foreach (app('widget.manager')->getAvailableTypes() as $group => $types) { + foreach ($this->manager->getAvailableTypes() as $group => $types) { if (isset($types[$this->type])) { return $types[$this->type]; } @@ -86,7 +114,7 @@ public function toWidget() return $this->widget; } - if (! is_null($this->widget = app('widget.manager')->makeWidget($this->type, $this->name, $this->description, $this->settings))) { + if (! is_null($this->widget = $this->manager->makeWidget($this->type, $this->name, $this->description, $this->settings))) { $this->widget->setId($this->id); if ($this->isRenderable()) { @@ -95,7 +123,7 @@ public function toWidget() $this->widget->setRalatedWidgets($this->related); } else { - $this->widget = new TempWidget(app('widget.manager'), $this->name, $this->description); + $this->widget = new TempWidget($this->manager, $this->name, $this->description); } static::$cachedWidgets[$this->id] = $this->widget; @@ -103,54 +131,6 @@ public function toWidget() return $this->widget; } - /** - * @return bool - */ - public function isWidgetable() - { - return ($this->exists and app('widget.manager')->isWidgetable(get_class($this->toWidget()))); - } - - /** - * @return bool - */ - public function isHandler() - { - return app('widget.manager')->isHandler(get_class($this->toWidget())); - } - - /** - * @return bool - */ - public function isRenderable() - { - return app('widget.manager')->isRenderable(get_class($this->toWidget())); - } - - /** - * @return bool - */ - public function isCacheable() - { - return app('widget.manager')->isCacheable(get_class($this->toWidget())); - } - - /** - * @return bool - */ - public function isClassExists() - { - return app('widget.manager')->isClassExists(get_class($this->toWidget())); - } - - /** - * @return bool - */ - public function isCorrupt() - { - return app('widget.manager')->isCorrupt(get_class($this->toWidget())); - } - public function scopeFilterByType($query, array $types) { if (count($types) > 0) { diff --git a/src/Providers/EventsServiceProvider.php b/src/Providers/EventsServiceProvider.php index 86021f8..e0f3f26 100644 --- a/src/Providers/EventsServiceProvider.php +++ b/src/Providers/EventsServiceProvider.php @@ -46,7 +46,15 @@ public function boot(DispatcherContract $events) $events->listen('view.page.edit', function ($page) { if (acl_check('widgets::list') and $page->hasLayout()) { - echo view('widgets::widgets.page.iframe', compact('page'))->render(); + // echo view('widgets::widgets.page.iframe', compact('page'))->render(); + + echo view('widgets::widgets.page.list', [ + 'page' => $page, + 'widgetsCollection' => new PageWidgetCollection( + app('widget.manager'), + $page->id + ) + ])->render(); } }); diff --git a/src/Providers/ModuleServiceProvider.php b/src/Providers/ModuleServiceProvider.php index a1302ae..0d31461 100644 --- a/src/Providers/ModuleServiceProvider.php +++ b/src/Providers/ModuleServiceProvider.php @@ -11,16 +11,17 @@ class ModuleServiceProvider extends ServiceProvider { public function boot() { - $this->app->singleton('widget.manager', function () { - return new WidgetManagerDatabase(); - }); - - $this->app->alias('widget.manager', WidgetManager::class); $this->app['view']->addNamespace('snippets', snippets_path()); } public function register() { + $this->app->singleton('widget.manager', function () { + return new WidgetManagerDatabase(); + }); + + $this->app->alias('widget.manager', WidgetManager::class); + $this->registerProviders([ BladeServiceProvider::class, EventsServiceProvider::class, diff --git a/src/Repository/WidgetRepository.php b/src/Repository/WidgetRepository.php index d0431de..4695825 100644 --- a/src/Repository/WidgetRepository.php +++ b/src/Repository/WidgetRepository.php @@ -3,7 +3,6 @@ namespace KodiCMS\Widgets\Repository; use DB; -use Illuminate\Http\Request; use KodiCMS\Widgets\Model\Widget; use KodiCMS\CMS\Repository\BaseRepository; diff --git a/src/Traits/WidgetStates.php b/src/Traits/WidgetStates.php new file mode 100644 index 0000000..6cad830 --- /dev/null +++ b/src/Traits/WidgetStates.php @@ -0,0 +1,55 @@ +exists and $this->manager->isWidgetable($this->getWidgetClass())); + } + + /** + * @return bool + */ + public function isHandler() + { + return $this->manager->isHandler($this->getWidgetClass()); + } + + /** + * @return bool + */ + public function isRenderable() + { + return $this->manager->isRenderable($this->getWidgetClass()); + } + + /** + * @return bool + */ + public function isCacheable() + { + return $this->manager->isCacheable($this->getWidgetClass()); + } + + /** + * @return bool + */ + public function isClassExists() + { + return $this->manager->isClassExists($this->getWidgetClass()); + } + + /** + * @return bool + */ + public function isCorrupt() + { + return $this->manager->isCorrupt($this->getWidgetClass()); + } +} \ No newline at end of file diff --git a/src/resources/js/WidgetController.js b/src/resources/js/WidgetController.js index fa94b4a..6eb2eb9 100644 --- a/src/resources/js/WidgetController.js +++ b/src/resources/js/WidgetController.js @@ -1,216 +1,233 @@ CMS.controllers.add(['widget.get.index'], function () { - Api.get('/api.snippet.xeditable', {}, function(resp) { - $('.editable-template').editable({ - type: 'select2', - title: i18n.t('widgets.core.field.template'), - send: 'always', - defaultValue: 0, - highlight: false, - emptytext: i18n.t('cms.core.label.not_set'), - ajaxOptions: { - dataType: 'json' - }, - params: function(params) { - console.log($(this).closest('tr').data('id')); - params.widget_id = $(this).closest('tr').data('id'); - params.template = params.value; - - return params; - }, - url: function(params) { - var d = new $.Deferred; - var response = Api.post('/api.widget.set.template', params, null, false).responseJSON; - - if(response.code != 200) { - return d.reject(response.message); - } else { - d.resolve(); - return d.promise(); - } - }, - source: resp, - select2: { - width: 200 - }, - success: function(response, newValue) {} - }); - }); - + Api.get('/api.snippet.xeditable', {}, function (resp) { + $('.editable-template').editable({ + type: 'select2', + title: i18n.t('widgets.core.field.template'), + send: 'always', + defaultValue: 0, + highlight: false, + emptytext: i18n.t('cms.core.label.not_set'), + ajaxOptions: { + dataType: 'json' + }, + params: function (params) { + params.widget_id = $(this).closest('tr').data('id'); + params.template = params.value; + + return params; + }, + url: function (params) { + var d = new $.Deferred; + var response = Api.post('/api.widget.set.template', params, null, false).responseJSON; + + if (response.code != 200) { + return d.reject(response.message); + } else { + d.resolve(); + return d.promise(); + } + }, + source: resp, + select2: { + width: 200 + }, + success: function (response, newValue) { + } + }); + }); }); +CMS.controllers.add('page.get.edit', function () { + var layout_file = PAGE.layout; + + reload_blocks(layout_file); + $('body').on('get:api.layout.rebuild', function (e, response) { + reload_blocks(layout_file); + }); + + $('body').on('click', '.popup-widget-item', function () { + var widget_id = $(this).data('id'); + + Api.put('/api.widget', { + widget_id: widget_id, + page_id: PAGE.id + }, function (response) { + window.location = '#widgets'; + Popup.close(); + $('#widget-list tbody').append(response.content); + reload_blocks(layout_file); + }); + }); +}); -CMS.controllers.add('widget.get.edit', function() { - load_snippets(); - var cache_enabled = function() { - var $caching_input = $('#cache'); - var $cache_lifetime = $('#cache_lifetime'); +CMS.controllers.add('widget.get.edit', function () { + load_snippets(); + var cache_enabled = function () { + var $caching_input = $('#cache'); + var $cache_lifetime = $('#cache_lifetime'); - $cache_lifetime.prop('disabled', !$caching_input.prop('checked')); + $cache_lifetime.prop('disabled', !$caching_input.prop('checked')); - if($caching_input.prop('checked')) - $('#cache_settings_container').show(); - else - $('#cache_settings_container').hide(); + if ($caching_input.prop('checked')) + $('#cache_settings_container').show(); + else + $('#cache_settings_container').hide(); - higlight_cache_time(); - }; + higlight_cache_time(); + }; - $('#cache').on('change', cache_enabled).change(); + $('#cache').on('change', cache_enabled).change(); - $('#cache_lifetime').on('keyup', function() { - higlight_cache_time(); - }); + $('#cache_lifetime').on('keyup', function () { + higlight_cache_time(); + }); - function higlight_cache_time() { - $('#cache_lifetime_labels .label') - .each(function() { - if($('#cache_lifetime').val() == $(this).data('value')) - $(this).addClass('label-success'); - }); - }; + function higlight_cache_time() { + $('#cache_lifetime_labels .label') + .each(function () { + if ($('#cache_lifetime').val() == $(this).data('value')) + $(this).addClass('label-success'); + }); + }; }); -CMS.controllers.add('widget.get.location', function() { - reload_blocks(); +CMS.controllers.add('widget.get.location', function () { + reload_blocks(); - $('body').on('get:api.layout.rebuild', function(e, response) { - reload_blocks(); - }); + $('body').on('get:api.layout.rebuild', function (e, response) { + reload_blocks(); + }); - $('#select_for_all').on('click', function(){ - var value = $('input[name="select_for_all"]').val(); - if(!value.length) return false; + $('#select_for_all').on('click', function () { + var value = $('input[name="select_for_all"]').val(); + if (!value.length) return false; - $('select.widget-blocks').each(function() { - var $options = $(this).data('blocks'); - for(i in $options) { - var $option = $options[i]; - if($option['id'].indexOf(value) > -1 || $option['text'].indexOf(value) > -1) - $(this).val($option['id']).trigger('change'); - } - }); + $('select.widget-blocks').each(function () { + var $options = $(this).data('blocks'); + for (i in $options) { + var $option = $options[i]; + if ($option['id'].indexOf(value) > -1 || $option['text'].indexOf(value) > -1) + $(this).val($option['id']).trigger('change'); + } + }); - return false; - }); + return false; + }); - $('.set_to_inner_pages').on('click', function() { - var cont = $(this).closest('tr'); + $('.set_to_inner_pages').on('click', function () { + var cont = $(this).closest('tr'); - var block_name = cont.find('.widget-blocks').val(); - var position = cont.find('input.widget-position').val(); - var id = cont.data('id'); + var block_name = cont.find('.widget-blocks').val(); + var position = cont.find('input.widget-position').val(); + var id = cont.data('id'); - $('.table tbody tr[data-parent-id="'+id+'"]').each(function() { - var $select = $(this).find('select.widget-blocks'); - var $options = $select.data('blocks'); + $('.table tbody tr[data-parent-id="' + id + '"]').each(function () { + var $select = $(this).find('select.widget-blocks'); + var $options = $select.data('blocks'); - for(i in $options) { - var $option = $options[i]; - if($option['id'] == block_name) { - $select.val($option['id']).trigger('change'); - } + for (i in $options) { + var $option = $options[i]; + if ($option['id'] == block_name) { + $select.val($option['id']).trigger('change'); + } - } + } - $(this).find('input.widget-position').val(position); - }); - return false; - }); + $(this).find('input.widget-position').val(position); + }); + return false; + }); }); -CMS.controllers.add('widget.get.template', function() { - - $('#textarea_content').on('filter:switch:on', function(e, editor) { - $('#content').setHeightFor('#textarea_contentDiv', { - contentHeight: true, - updateOnResize: true, - offset: 30, - minHeight: 300, - onCalculate: function(a, h) { - CMS.filters.exec('textarea_content', 'changeHeight', h); - }, - onResize: function(a, h) { - CMS.filters.exec('textarea_content', 'changeHeight', h); - } - }); - }); - - CMS.filters.switchOn('textarea_content', DEFAULT_CODE_EDITOR, $('#textarea_content').data()); +CMS.controllers.add('widget.get.template', function () { + $('#textarea_content').on('filter:switch:on', function (e, editor) { + $('#content').setHeightFor('#textarea_contentDiv', { + contentHeight: true, + updateOnResize: true, + offset: 30, + minHeight: 300, + onCalculate: function (a, h) { + CMS.filters.exec('textarea_content', 'changeHeight', h); + }, + onResize: function (a, h) { + CMS.filters.exec('textarea_content', 'changeHeight', h); + } + }); + }); + + CMS.filters.switchOn('textarea_content', DEFAULT_CODE_EDITOR, $('#textarea_content').data()); }); function format_dropdown_block(state, container) { - if (!state.id) return state.text; // optgroup + if (!state.id) return state.text; // optgroup - if(state.id == -1 || state.id == 0 || state.id == 'PRE' || state.id == 'POST') { - container.css({'color': 'blue', 'fontWeight': 'bold'}); - } else { - container.css({'color': 'green', 'fontWeight': 'bold'}); - } + if (state.id == -1 || state.id == 0 || state.id == 'PRE' || state.id == 'POST') { + container.css({'color': 'blue', 'fontWeight': 'bold'}); + } else { + container.css({'color': 'green', 'fontWeight': 'bold'}); + } - return state.text; + return state.text; } function reload_blocks($layout) { - var FILLED_BLOCKS = []; - var LAYOUT_BLOCKS = {}; - var $layout_data = {}; - if($layout) { - $layout_data = {layout: $layout}; - } - - Api.get('/api.layout.blocks', $layout_data, function(resp) { - if( ! resp.content) return; - LAYOUT_BLOCKS = resp.content; - - $('.widget-blocks').each(function() { - var cb = $(this).data('value'); - var $layout = $(this).data('layout'); - if( ! LAYOUT_BLOCKS[$layout]) return; - - var blocks = []; - for(block in LAYOUT_BLOCKS[$layout]) { - if(!FILLED_BLOCKS[block] || (FILLED_BLOCKS[block] && block == cb) ) - blocks.push({id: block, text: LAYOUT_BLOCKS[$layout][block]}); - } - - found = false; - for(i in blocks) { - if(blocks[i].id == cb) - found = true; - } - - if(!found) { - cb = -1; - } - - $(this) - .select2({ - data: blocks, - formatSelection: format_dropdown_block, - formatResult: format_dropdown_block - }) - .val(cb) - .data('blocks', blocks) - .trigger('change'); - }); - }); + var FILLED_BLOCKS = [], + LAYOUT_BLOCKS = {}, + LAYOUT_DATA = $layout ? {layout: $layout} : {}; + + Api.get('/api.layout.blocks', LAYOUT_DATA, function (resp) { + if (!resp.content) return; + + LAYOUT_BLOCKS = resp.content; + + $('.widget-blocks').each(function () { + var cb = $(this).val(); + var layout_name = $(this).data('layout'); + if (!LAYOUT_BLOCKS[layout_name]) return; + + var blocks = []; + for (var block in LAYOUT_BLOCKS[layout_name]) { + if (!FILLED_BLOCKS[block] || (FILLED_BLOCKS[block] && block == cb)) + blocks.push({id: block, text: LAYOUT_BLOCKS[layout_name][block]}); + } + + var found = false; + for (var i in blocks) { + if (blocks[i].id == cb) + found = true; + } + + if (!found) { + cb = -1; + } + + $(this) + .select2({ + data: blocks, + formatSelection: format_dropdown_block, + formatResult: format_dropdown_block + }) + .val(cb) + .trigger('change.select2'); + }); + }); } function load_snippets(intervalID) { - clearInterval(intervalID); - $('#snippet-select').on('select2:opening', function(e, a) { - var response = Api.get('/api.snippet.list', {}, false, false).responseJSON; - var self = $(this); - if(response.content) { - $('option', this).remove(); - - for(key in response.content) - self.append($('', {value: key, text: response.content[key]})); - } - - self.off('select2:opening'); - var intervalID = setInterval(function() { - load_snippets(intervalID); - }, 10000); - }); + clearInterval(intervalID); + $('#snippet-select').on('select2:opening', function (e, a) { + var response = Api.get('/api.snippet.list', {}, false, false).responseJSON; + var self = $(this); + if (response.content) { + $('option', this).remove(); + + for (key in response.content) + self.append($('', {value: key, text: response.content[key]})); + } + + self.off('select2:opening'); + var intervalID = setInterval(function () { + load_snippets(intervalID); + }, 10000); + }); } \ No newline at end of file diff --git a/src/resources/views/widgets/page/row.blade.php b/src/resources/views/widgets/page/row.blade.php index e219581..cda4352 100644 --- a/src/resources/views/widgets/page/row.blade.php +++ b/src/resources/views/widgets/page/row.blade.php @@ -24,7 +24,7 @@ {!! link_to_route('backend.widget.location', '', [$widget->getId()], [ - 'data-icon' => 'sitemap', 'class' => 'btn btn-xs btn-primary popup' + 'data-icon' => 'sitemap', 'class' => 'btn btn-sm btn-primary popup' ]) !!}