diff --git a/app/Helpers/WidgetAreas.php b/app/Helpers/WidgetAreas.php index 27ac6924..fdb2cb4e 100644 --- a/app/Helpers/WidgetAreas.php +++ b/app/Helpers/WidgetAreas.php @@ -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]; } } \ No newline at end of file diff --git a/app/Http/Controllers/Admin/Widgets/Areas/EditWidgetArea.php b/app/Http/Controllers/Admin/Widgets/Areas/EditWidgetArea.php index e2a9b834..48bbb523 100644 --- a/app/Http/Controllers/Admin/Widgets/Areas/EditWidgetArea.php +++ b/app/Http/Controllers/Admin/Widgets/Areas/EditWidgetArea.php @@ -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 diff --git a/app/Models/Widget.php b/app/Models/Widget.php index 5836ff4d..e1779ace 100644 --- a/app/Models/Widget.php +++ b/app/Models/Widget.php @@ -19,6 +19,7 @@ class Widget extends Model 'settings', 'language', 'description', + 'viewed', 'deletable' ]; protected $guarded = []; diff --git a/app/Models/WidgetArea.php b/app/Models/WidgetArea.php index 1eaf2592..dbe3c57a 100644 --- a/app/Models/WidgetArea.php +++ b/app/Models/WidgetArea.php @@ -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; } } \ No newline at end of file diff --git a/app/Providers/GlobalViewDataProvider.php b/app/Providers/GlobalViewDataProvider.php index 58c943fb..234f8eeb 100644 --- a/app/Providers/GlobalViewDataProvider.php +++ b/app/Providers/GlobalViewDataProvider.php @@ -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 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); } ?> '; diff --git a/app/Shortcodes/Widget.php b/app/Shortcodes/Widget.php new file mode 100644 index 00000000..bad16564 --- /dev/null +++ b/app/Shortcodes/Widget.php @@ -0,0 +1,66 @@ +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]; + } +} \ No newline at end of file diff --git a/app/Widgets/Contracts/WidgetRenderer.php b/app/Widgets/Contracts/WidgetRenderer.php index 4e2457c8..d21e564d 100644 --- a/app/Widgets/Contracts/WidgetRenderer.php +++ b/app/Widgets/Contracts/WidgetRenderer.php @@ -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 diff --git a/app/Widgets/HtmlCode/Presenters/HtmlCode.php b/app/Widgets/HtmlCode/Presenters/HtmlCode.php index 570440d6..06bec4b7 100644 --- a/app/Widgets/HtmlCode/Presenters/HtmlCode.php +++ b/app/Widgets/HtmlCode/Presenters/HtmlCode.php @@ -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 = ' -
+
' . $settings->code . '
'; diff --git a/app/Widgets/Menu/Presenters/Menu.php b/app/Widgets/Menu/Presenters/Menu.php index f4e38029..d2edc8e8 100644 --- a/app/Widgets/Menu/Presenters/Menu.php +++ b/app/Widgets/Menu/Presenters/Menu.php @@ -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 = '