FEATURE: add functionality for rendering widgets via shortcode [widget]

This commit is contained in:
Michal Kváček
2016-10-11 19:10:03 +02:00
parent d5f9e1fc2b
commit 625bdbb2e2
14 changed files with 217 additions and 43 deletions
+45 -17
View File
@@ -9,6 +9,46 @@ class WidgetAreas
* @var array list of inicialized widget areas
*/
protected static $widgetAreas = [];
protected static $initialized = false;
protected static function saveRenderedWidgetArea($widgets)
{
foreach ($widgets as $widget) {
if (!isset(self::$widgetAreas[$widget->widget_area_code]))
self::$widgetAreas[$widget->widget_area_code] = '';
$handler = $widget->widget_type_handler;
$widget->settings = json_decode($widget->settings);
$presenter = call_user_func([$handler, 'getPresenter']);
self::$widgetAreas[$widget->widget_area_code] .= call_user_func([$presenter, 'render'], $widget);
}
}
protected static function loadWidgetArea($uniqueCode)
{
$widgetArea = new WidgetArea();
$widgets = $widgetArea->getWidgets($uniqueCode)
->get();
WidgetArea::where('code', $uniqueCode)
->increment('viewed');
self::saveRenderedWidgetArea($widgets);
}
protected static function initWidgetAreas()
{
if (self::$initialized)
return;
$widgetArea = new WidgetArea();
$widgets = $widgetArea->getWidgets()
->get();
self::saveRenderedWidgetArea($widgets);
self::$initialized = true;
}
/**
* Renderer for whole widget area.
@@ -19,26 +59,14 @@ class WidgetAreas
*/
public static function render($uniqueCode)
{
if (isset(self::$widgetAreas[$uniqueCode])) {
echo self::$widgetAreas[$uniqueCode];
return;
if (!self::$initialized) {
self::initWidgetAreas();
}
$widgetArea = new WidgetArea();
$widgets = $widgetArea->getWidgets($uniqueCode)
->get();
$content = '';
foreach ($widgets as $widget) {
$handler = $widget->widget_type_handler;
$presenter = call_user_func([$handler, 'getPresenter']);
$content .= call_user_func([$presenter, 'render'], json_decode($widget->settings));
if (!isset(self::$widgetAreas[$uniqueCode])) {
self::loadWidgetArea($uniqueCode);
}
// cache this widget area
self::$widgetAreas[$uniqueCode] = $content;
echo $content;
echo self::$widgetAreas[$uniqueCode];
}
}
@@ -51,6 +51,7 @@ class EditWidgetArea extends Controller
$area->name = $request->name;
$area->description = $request->description;
$area->timestamps = true;
$area->save();
// fire event with new widget area
+1
View File
@@ -19,6 +19,7 @@ class Widget extends Model
'settings',
'language',
'description',
'viewed',
'deletable'
];
protected $guarded = [];
+14 -10
View File
@@ -3,7 +3,6 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
/**
@@ -11,7 +10,7 @@ use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
*/
class WidgetArea extends Model
{
public $timestamps = true;
public $timestamps = false;
protected $fillable = [
'name',
'code',
@@ -20,14 +19,19 @@ class WidgetArea extends Model
];
protected $guarded = [];
public function getWidgets($uniqueCode)
public function getWidgets($uniqueCode = false)
{
return DB::table('widget_areas')
->select('widget_areas.*', 'widgets.widget_type_handler', 'widgets.name as widget_name', 'widgets.settings')
->where('code', $uniqueCode)
->join('widget_in_widget_area', 'widget_in_widget_area.widget_area_id', '=', 'widget_areas.id')
->join('widgets', 'widget_in_widget_area.widget_id', '=', 'widgets.id')
->where('language', LaravelLocalization::getCurrentLocale())
->orderBy('widget_in_widget_area.position');
$widgets = Widget::select('widgets.*', 'widgets.widget_type_handler', 'widget_areas.code as widget_area_code', 'widgets.name as widget_name', 'widgets.settings')
->join('widget_in_widget_area', 'widget_in_widget_area.widget_id', '=', 'widgets.id')
->join('widget_areas', 'widget_in_widget_area.widget_area_id', '=', 'widget_areas.id')
->where('language', LaravelLocalization::getCurrentLocale())
->orderBy('widget_in_widget_area.position');
if (!$uniqueCode) {
$widgets = $widgets->where('widget_areas.viewed', '>=', setting('preloadFrequentedWidgetAreasTreshold', 10));
} else {
$widgets = $widgets->where('code', $uniqueCode);
}
return $widgets;
}
}
+7 -1
View File
@@ -3,9 +3,11 @@
namespace App\Providers;
use App\Models\Settings;
use App\Shortcodes\Widget;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
use Webwizo\Shortcodes\Facades\Shortcode;
class GlobalViewDataProvider extends ServiceProvider
{
@@ -24,6 +26,8 @@ class GlobalViewDataProvider extends ServiceProvider
view()->share('currentUrl', \Request::url());
$this->extendBlade();
Shortcode::register('widget', Widget::class);
}
/**
@@ -129,9 +133,11 @@ class GlobalViewDataProvider extends ServiceProvider
<?php
if ($2 instanceof \App\Models\Widget) {
$handler = $2->widget_type_handler;
$2->settings = json_decode($2->settings);
$presenter = call_user_func([$handler, "getPresenter"]);
echo call_user_func([$presenter, "render"], json_decode($2->settings));
echo call_user_func([$presenter, "render"], $2);
}
?>
';
+66
View File
@@ -0,0 +1,66 @@
<?php
namespace App\Shortcodes;
use App\Models\Widget as WidgetModel;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class Widget
{
protected static $widgets = [];
protected static $initialized = false;
protected function getRenderedWidget(WidgetModel $widget)
{
$widget->settings = json_decode($widget->settings);
$handler = $widget->widget_type_handler;
$presenter = call_user_func([$handler, 'getPresenter']);
return call_user_func([$presenter, 'render'], $widget);
}
protected function loadWidget($containerId)
{
$widget = WidgetModel::where('container_id', $containerId)
->first();
if (!$widget) {
return;
}
$widget->timestamps = false;
$widget->viewed++;
$widget->save();
$widget->timestamps = true;
self::$widgets[$containerId] = $this->getRenderedWidget($widget);
}
protected function initWidgets()
{
if (self::$initialized) {
return;
}
$widgets = WidgetModel::where('viewed', '>=', setting('preloadFrequentedWidgetsTreshold', 10))
->where('language', LaravelLocalization::getCurrentLocale())
->get();
foreach ($widgets as $widget) {
self::$widgets[$widget->container_id] = $this->getRenderedWidget($widget);
}
self::$initialized = true;
}
public function register($shortcode, $containerId, $compiler, $name)
{
$this->initWidgets();
if (!isset(self::$widgets[$containerId])) {
$this->loadWidget($containerId);
}
return self::$widgets[$containerId];
}
}
+1 -1
View File
@@ -15,7 +15,7 @@ interface WidgetRenderer
*
* @return mixed
*/
public static function render($settings);
public static function render(Widget $settings);
/**
* Display form for creating new instance of widget
+4 -3
View File
@@ -12,14 +12,15 @@ class HtmlCode implements WidgetRenderer
*
* This method renders some HTML code for displaying.
*
* @param object $settings
* @param Widget $widget
*
* @return mixed
*/
public static function render($settings)
public static function render(Widget $widget)
{
$settings = $widget->settings;
$code = '
<div class="html-code-widget ' . $settings->containerClass . '">
<div class="html-code-widget ' . $widget->container_class . '">
' . $settings->code . '
</div>';
+9 -3
View File
@@ -18,12 +18,13 @@ class Menu implements WidgetRenderer
*
* This method renders some HTML code for displaying.
*
* @param object $settings
* @param Widget $widget
*
* @return mixed
*/
public static function render($settings)
public static function render(Widget $widget)
{
$settings = $widget->settings;
$links = (array)$settings->links;
$pageIds = array_keys($links);
@@ -40,7 +41,12 @@ class Menu implements WidgetRenderer
$parameters = Route::current()
->parameters();
$code = '<ul class="menu ' . $settings->containerClass . '">';
$code = '<ul class="menu ' . $widget->container_class . '"';
if ($widget->container_id)
$code .= ' id="'.e($widget->container_id).'"';
$code .= '>';
foreach ($links as $pageId => $link) {
if (!isset($pages[$pageId])) {
@@ -26,12 +26,13 @@ class OrbitSlider implements WidgetRenderer
*
* This method renders some HTML code for displaying.
*
* @param object $settings
* @param Widget $widget
*
* @return mixed
*/
public static function render($settings)
public static function render(Widget $widget)
{
$settings = $widget->settings;
$directoryId = $settings->directoryId;
$images = File::where('directory_id', $directoryId)