FEATURE: change directory structure
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Contracts;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Content\Content;
|
||||
|
||||
interface AppHandler extends BaseModuleHandler
|
||||
{
|
||||
/**
|
||||
* Render given module into visitor area.
|
||||
*
|
||||
* @param Content $content DB model from table contents
|
||||
* @param array $parameters parameters used for modifications/custom settings of given model
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render(Content $content, $parameters);
|
||||
|
||||
public static function getHistoryHandler();
|
||||
|
||||
/**
|
||||
* Load some extra data for content management form?
|
||||
*
|
||||
* @param Content $content
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function loadExtraData(Content $content);
|
||||
|
||||
/**
|
||||
* Save module-specific values into database
|
||||
*
|
||||
* @param Content $content
|
||||
* @param Request $request
|
||||
*
|
||||
* @return mixed
|
||||
* @internal param Widget $widget
|
||||
*/
|
||||
public static function createNew(Content &$content, Request $request);
|
||||
|
||||
/**
|
||||
* Method used for editing existing content page.
|
||||
*
|
||||
* Reason why it is separated from createNew() method is simple - we need to save history of changes.
|
||||
*
|
||||
* @param Content $content
|
||||
* @param Request $request
|
||||
*
|
||||
* @param $revisionID string ID of revision used
|
||||
*
|
||||
* @return int number of edited fields
|
||||
*/
|
||||
public static function edit(Content &$content, Request $request, $revisionID);
|
||||
|
||||
/**
|
||||
* Method called right after content page is marked as deleted
|
||||
*
|
||||
* This method is supposed to clean after "deleted" page.
|
||||
*
|
||||
* @param Content $content
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function delete(Content $content);
|
||||
|
||||
/**
|
||||
* Getter for section names in creating/editing content resource
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getExtendedFormSections();
|
||||
|
||||
/**
|
||||
* Getter for views used in extended part of form for creating new content
|
||||
*
|
||||
* This method should return pairs <section, view-name>. View is returned only as name in plain text
|
||||
*
|
||||
* @return array of views/templates/html codes divided into section
|
||||
*/
|
||||
public static function getExtendedFormInputsCreate();
|
||||
|
||||
/**
|
||||
* Getter for extended part of form for editing existing content
|
||||
*
|
||||
* Basically, this method may be
|
||||
*
|
||||
* @return array of views/templates/html codes divided into section
|
||||
*/
|
||||
public static function getExtendedFormInputsEdit();
|
||||
|
||||
/**
|
||||
* Does this module support categories?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function supportCategories();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Contracts;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
interface BaseModuleHandler
|
||||
{
|
||||
/**
|
||||
* Register admin menu (or multiple ones)
|
||||
*
|
||||
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
|
||||
* starting any middleware..
|
||||
*
|
||||
* @param User $user model of logged user
|
||||
*/
|
||||
public static function registerAdminMenu(User $user);
|
||||
|
||||
/**
|
||||
* Install module.
|
||||
*
|
||||
* This method is called after inserting info about module into database. It can be called only using Artisan in
|
||||
* CLI.
|
||||
*/
|
||||
public static function install();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Contracts;
|
||||
|
||||
use App\Models\Content\Content;
|
||||
|
||||
/**
|
||||
* Interface ContentTitles
|
||||
*
|
||||
* Classes which implement this interface get the ability to rewrite default text on edit/create/overview of content
|
||||
* page.
|
||||
*
|
||||
* @package App\CMS\Handlers\Contracts
|
||||
*/
|
||||
interface ContentTitles
|
||||
{
|
||||
/**
|
||||
* Get translated title for pages overview of given type.
|
||||
*
|
||||
* This value is used for rendering list of all content pages of given type in administration.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getOverviewTitle();
|
||||
|
||||
/**
|
||||
* Title displayed above for for creating new content page
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getCreateNewTitle();
|
||||
|
||||
/**
|
||||
* Title for form displayed for editin content page
|
||||
*
|
||||
* @param Content $content
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getEditTitle(Content $content);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Contracts;
|
||||
|
||||
interface HistoryHandler
|
||||
{
|
||||
public static function parseColumnName($name);
|
||||
|
||||
public static function parseChangedValue($changeset);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Contracts;
|
||||
|
||||
interface SearchHandler {
|
||||
public function getId();
|
||||
|
||||
public function getName();
|
||||
|
||||
/**
|
||||
* Search for given patttern/term
|
||||
*
|
||||
* @param string $term searched word
|
||||
*
|
||||
* @return array list of found objects
|
||||
*/
|
||||
public function search($term);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Contracts;
|
||||
|
||||
interface SearchPresenterHandler
|
||||
{
|
||||
/**
|
||||
* Method for rendering list of found results
|
||||
*
|
||||
* @param $foundItems
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($foundItems);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Contracts;
|
||||
|
||||
use App\Http\Requests\Request;
|
||||
use App\Models\Content\Content;
|
||||
use App\Models\Module;
|
||||
|
||||
/**
|
||||
* Interface TemplateHandler
|
||||
*
|
||||
* Inerface used for registering template into CMS core.
|
||||
*
|
||||
* @package App\CMS\Handlers\Contracts
|
||||
*/
|
||||
interface TemplateHandler extends BaseModuleHandler
|
||||
{
|
||||
/**
|
||||
* Uninstall template
|
||||
*
|
||||
* Delete some items in database, delete files etc.
|
||||
*
|
||||
* @param Module $template
|
||||
*/
|
||||
public static function uninstall(Module $template);
|
||||
|
||||
/**
|
||||
* Get list of registered templates and supported modules.
|
||||
*
|
||||
* Returned array is expected to be array of arrays with following items: module, namespace and templateName.
|
||||
* Example:
|
||||
* return [
|
||||
* ['module' => 'Article', 'templateName' => 'article::template.name']
|
||||
* ];
|
||||
*
|
||||
* When no "namespace" is specified, value strtolower(module) is used instaed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPublicTemplatePaths();
|
||||
|
||||
/**
|
||||
* Prepare Content object to be rendered using Blade template
|
||||
*
|
||||
* @param Content $content
|
||||
*/
|
||||
public static function beforeRender(Content & $content);
|
||||
|
||||
/**
|
||||
* Modify input data into format which can be understood by edit template
|
||||
*
|
||||
* @param Content $content
|
||||
*/
|
||||
public static function beforePopulatingEditForm(Content & $content);
|
||||
|
||||
/**
|
||||
* Slightly modify Content object before saving into database.
|
||||
*
|
||||
* This way we can do almost whatever we want - even in template
|
||||
*
|
||||
* @param Content $content
|
||||
* @param Request $request
|
||||
*/
|
||||
public static function beforeSave(Content & $content, Request $request);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace App\CMS\Contracts\Widgets;
|
||||
|
||||
interface AdminDashboardWidget extends PublicWidget
|
||||
{
|
||||
/**
|
||||
* Getter for list of all roles which are allowed to display the widget
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function renderForRoles();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
namespace App\CMS\Contracts\Widgets;
|
||||
|
||||
interface InstallableWidget extends PublicWidget {
|
||||
|
||||
/**
|
||||
* Function for installing given widget
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function install();
|
||||
|
||||
/**
|
||||
* Function for uninstalling widget
|
||||
*/
|
||||
public static function uninstall();
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\Contracts;
|
||||
|
||||
interface MenuExtensionHandler {
|
||||
|
||||
public function getName();
|
||||
public function getDescription();
|
||||
public function getId();
|
||||
|
||||
public function getPossibleValues();
|
||||
|
||||
public function getFormExtensionTemplate();
|
||||
|
||||
public function save();
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\CMS\Contracts\Widgets;
|
||||
|
||||
use App\Models\Widgets\Widget;
|
||||
|
||||
interface PublicWidget
|
||||
{
|
||||
/**
|
||||
* Name getter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName();
|
||||
|
||||
/**
|
||||
* Getter for description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDescription();
|
||||
|
||||
/**
|
||||
* Getter for presenter/renderer of this widget
|
||||
*
|
||||
* @return WidgetRenderer
|
||||
*/
|
||||
public static function getPresenter();
|
||||
|
||||
/**
|
||||
* @param Widget $widget
|
||||
* @param \stdClass $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function save(Widget $widget, \stdClass $data);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
namespace App\CMS\Contracts\Widgets;
|
||||
|
||||
use App\Models\Widgets\Widget;
|
||||
use App\Models\Widgets\WidgetType;
|
||||
|
||||
interface WidgetRenderer
|
||||
{
|
||||
/**
|
||||
* Method used for displaying widget.
|
||||
*
|
||||
* This method renders some HTML code for displaying.
|
||||
*
|
||||
* @param Widget $settings
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function render(Widget $settings);
|
||||
|
||||
/**
|
||||
* Display form for creating new instance of widget
|
||||
*
|
||||
* @param WidgetType $type
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderAddForm(WidgetType $type);
|
||||
|
||||
/**
|
||||
* Display form for editing already existing widget
|
||||
*
|
||||
* @param Widget $widget
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderEditForm(Widget $widget);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace App\CMS\CustomFields;
|
||||
|
||||
class BaseField {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace App\CMS\CustomFields;
|
||||
|
||||
class Date extends BaseField {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace App\CMS\CustomFields;
|
||||
|
||||
class Number extends BaseField {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace App\CMS\CustomFields;
|
||||
|
||||
class SelectboxList extends BaseField {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace App\CMS\CustomFields;
|
||||
|
||||
class String extends BaseField {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\ActionLogType;
|
||||
|
||||
class ActionLogTypes extends BaseEnumeration
|
||||
{
|
||||
/**
|
||||
* Init list of all action log types
|
||||
*
|
||||
* @throws Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
$types = ActionLogType::all(['id', 'name']);
|
||||
|
||||
foreach ($types as $type) {
|
||||
self::push($type->id, $type->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\ActionLog\ActionLogType;
|
||||
|
||||
class ActionLogTypesForLogger extends BaseEnumeration
|
||||
{
|
||||
protected static function init()
|
||||
{
|
||||
$types = ActionLogType::all(['string_id', 'id']);
|
||||
|
||||
foreach ($types as $type) {
|
||||
self::push($type->string_id, $type->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\CMS\Exceptions\Enumerations\EnumerationExistsException;
|
||||
|
||||
abstract class BaseEnumeration
|
||||
{
|
||||
protected static $initiliazed = [];
|
||||
public static $items = [];
|
||||
const ORDER_BY_KEY = 1;
|
||||
const ORDER_BY_KEY_DESC = 2;
|
||||
const ORDER_BY_TEXT = 4;
|
||||
const ORDER_BY_TEXT_DESC = 8;
|
||||
|
||||
/**
|
||||
* Init enumerations
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
$className = get_called_class();
|
||||
|
||||
if (!in_array($className, self::$initiliazed)) {
|
||||
|
||||
// try to call init() method
|
||||
if (method_exists($className, 'init')) {
|
||||
$className::init();
|
||||
}
|
||||
|
||||
// it can happen that even after init no enumerations are available
|
||||
if (empty(self::$items[$className])) {
|
||||
self::$items[$className] = [];
|
||||
}
|
||||
|
||||
self::$initiliazed[] = $className;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new item into enumeration
|
||||
*
|
||||
* @param $key
|
||||
* @param $translation
|
||||
* @param bool|false $overwrite
|
||||
*
|
||||
* @throws EnumerationExistsException
|
||||
*/
|
||||
public static function push($key, $translation, $overwrite = false)
|
||||
{
|
||||
// item exists and we do not want to overwrite items
|
||||
if (!$overwrite && !is_null($key) && isset(self::$items[get_called_class()][$key])) {
|
||||
throw new EnumerationExistsException(get_called_class() . ': ' . $key . ' already in ' . $translation);
|
||||
}
|
||||
|
||||
// if given collection does not exists, create empty one
|
||||
if (!isset(self::$items[get_called_class()])) {
|
||||
self::$items[get_called_class()] = [];
|
||||
}
|
||||
|
||||
// add to collection
|
||||
self::$items[get_called_class()][$key] = trans($translation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return count of all items in collection
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function getCount()
|
||||
{
|
||||
return count(self::getWithTranslations());
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for all enumeration items in iven collection.
|
||||
*
|
||||
* Return value is associative array indexed by item "name". Value of each field is its translation (translation
|
||||
* string, e.g. admin/mainMenu.something)
|
||||
*
|
||||
* @param string $orderBy
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getWithTranslations($orderBy = self::ORDER_BY_KEY)
|
||||
{
|
||||
// if not initialized yet, init this enumerration
|
||||
if (!in_array(get_called_class(), self::$initiliazed)) {
|
||||
self::init();
|
||||
}
|
||||
|
||||
$items = self::$items[get_called_class()];
|
||||
|
||||
// order results
|
||||
switch ($orderBy) {
|
||||
case self::ORDER_BY_KEY:
|
||||
ksort($items);
|
||||
break;
|
||||
case self::ORDER_BY_KEY_DESC:
|
||||
krsort($items);
|
||||
break;
|
||||
case self::ORDER_BY_TEXT:
|
||||
sort($items);
|
||||
break;
|
||||
case self::ORDER_BY_TEXT_DESC:
|
||||
rsort($items);
|
||||
break;
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for list of all enumeration items.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getSimple()
|
||||
{
|
||||
return array_keys(self::getWithTranslations());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\Content\Content;
|
||||
|
||||
class ContentStatuses extends BaseEnumeration
|
||||
{
|
||||
protected static function init()
|
||||
{
|
||||
$roles = [
|
||||
Content::STATUS_DRAFT => 'admin/contents.status_' . Content::STATUS_DRAFT,
|
||||
Content::STATUS_PROTECTED => 'admin/contents.status_' . Content::STATUS_PROTECTED,
|
||||
Content::STATUS_PUBLIC => 'admin/contents.status_' . Content::STATUS_PUBLIC
|
||||
];
|
||||
|
||||
foreach ($roles as $role => $translation) {
|
||||
self::push($role, $translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\CustomFieldResource;
|
||||
|
||||
class CustomFieldResources extends BaseEnumeration
|
||||
{
|
||||
public static $items = [];
|
||||
|
||||
public static function init()
|
||||
{
|
||||
// load items from database
|
||||
$types = CustomFieldResource::all(['id', 'name']);
|
||||
|
||||
// push items into collection
|
||||
foreach ($types as $type) {
|
||||
self::push($type->id, $type->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\CustomFieldType;
|
||||
|
||||
class CustomFieldTypes extends BaseEnumeration
|
||||
{
|
||||
public static $items = [];
|
||||
|
||||
public static function init()
|
||||
{
|
||||
|
||||
// load items from database
|
||||
$types = CustomFieldType::all(['id', 'name']);
|
||||
|
||||
// push items into collection
|
||||
foreach ($types as $type) {
|
||||
self::push($type->id, $type->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\Module;
|
||||
|
||||
class ModuleNamesWithIds extends BaseEnumeration
|
||||
{
|
||||
/**
|
||||
* Init list of all installed modules
|
||||
*
|
||||
* @throws Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
$modules = Module::all(['id', 'name']);
|
||||
|
||||
foreach ($modules as $module) {
|
||||
self::push($module->id, $module->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\Module;
|
||||
|
||||
class Modules extends BaseEnumeration
|
||||
{
|
||||
/**
|
||||
* Init list of all installed modules
|
||||
*
|
||||
* @throws Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
$modules = Module::all(['handler', 'name']);
|
||||
|
||||
foreach ($modules as $module) {
|
||||
self::push($module->handler, $module->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\Module;
|
||||
|
||||
class ModulesHandlerToId extends BaseEnumeration
|
||||
{
|
||||
/**
|
||||
* Init list of all installed modules
|
||||
*
|
||||
* @throws Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
$modules = Module::all(['handler', 'id']);
|
||||
|
||||
foreach ($modules as $module) {
|
||||
self::push($module->handler, $module->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: michal
|
||||
* Date: 18.2.16
|
||||
* Time: 10:33
|
||||
*/
|
||||
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\TemplatePath;
|
||||
|
||||
class TemplatePaths extends BaseEnumeration
|
||||
{
|
||||
protected static function init()
|
||||
{
|
||||
$paths = TemplatePath::all(['id', 'path']);
|
||||
|
||||
foreach ($paths as $path) {
|
||||
self::push($path->id, $path->path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: michal
|
||||
* Date: 18.2.16
|
||||
* Time: 10:33
|
||||
*/
|
||||
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\TemplatePath;
|
||||
|
||||
class TemplatePathsHumanReadable extends BaseEnumeration
|
||||
{
|
||||
protected static function init()
|
||||
{
|
||||
$paths = TemplatePath::all(['id', 'name']);
|
||||
|
||||
foreach ($paths as $path) {
|
||||
self::push($path->id, $path->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: michal
|
||||
* Date: 18.2.16
|
||||
* Time: 10:33
|
||||
*/
|
||||
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\TemplatePath;
|
||||
|
||||
class TemplatePathsHumanReadableRootOnly extends BaseEnumeration
|
||||
{
|
||||
protected static function init()
|
||||
{
|
||||
$paths = TemplatePath::where('parent_id', null)
|
||||
->select(['id', 'name'])
|
||||
->get();
|
||||
|
||||
foreach ($paths as $path) {
|
||||
self::push($path->id, $path->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: michal
|
||||
* Date: 18.2.16
|
||||
* Time: 15:50
|
||||
*/
|
||||
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\Template;
|
||||
|
||||
class Templates extends BaseEnumeration
|
||||
{
|
||||
protected static function init()
|
||||
{
|
||||
$templates = Template::all(['id', 'template_name']);
|
||||
|
||||
foreach ($templates as $template) {
|
||||
self::push($template->id, $template->template_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserRoles extends BaseEnumeration
|
||||
{
|
||||
public static function init()
|
||||
{
|
||||
$roles = [
|
||||
User::ROLE_ADMIN => 'admin/userManagement.role_' . User::ROLE_ADMIN,
|
||||
User::ROLE_EDITOR => 'admin/userManagement.role_' . User::ROLE_EDITOR,
|
||||
User::ROLE_VISITOR => 'admin/userManagement.role_' . User::ROLE_VISITOR
|
||||
];
|
||||
|
||||
foreach ($roles as $role => $translation) {
|
||||
self::push($role, $translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: michal
|
||||
* Date: 24.1.16
|
||||
* Time: 23:20
|
||||
*/
|
||||
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
class UserStates extends BaseEnumeration
|
||||
{
|
||||
public static function init()
|
||||
{
|
||||
$items = [
|
||||
User::STATE_BLOCKED => 'admin/userManagement.status_' . User::STATE_BLOCKED,
|
||||
User::STATE_ACTIVE => 'admin/userManagement.status_' . User::STATE_ACTIVE
|
||||
];
|
||||
|
||||
foreach ($items as $state => $translation) {
|
||||
self::push($state, $translation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\Widgets\WidgetType;
|
||||
|
||||
class WidgetTypes extends BaseEnumeration
|
||||
{
|
||||
/**
|
||||
* Init list of all installed modules
|
||||
*
|
||||
* @throws Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
$widgets = WidgetType::all(['id', 'name']);
|
||||
|
||||
foreach ($widgets as $widget) {
|
||||
self::push($widget->id, $widget->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\CMS\Enumerations;
|
||||
|
||||
use App\Models\Widgets\WidgetType;
|
||||
|
||||
class WidgetTypesWithHandlers extends BaseEnumeration
|
||||
{
|
||||
/**
|
||||
* Init list of all installed modules
|
||||
*
|
||||
* @throws Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected static function init()
|
||||
{
|
||||
$modules = WidgetType::all(['handler', 'name']);
|
||||
|
||||
foreach ($modules as $module) {
|
||||
self::push($module->handler, $module->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace App\CMS\Exceptions\Enumerations;
|
||||
|
||||
class EnumerationExistsException extends \Exception {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class MissingParameterException extends \Exception
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Exception $previous = null)
|
||||
{
|
||||
$message = trans('admin/widgets.missingValue', ['field' => $message]);
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class WidgetExistsException extends \Exception
|
||||
{
|
||||
public function __construct($message = "", $code = 0, Exception $previous = null)
|
||||
{
|
||||
$message = trans('admin/widgets.widgetExists', ['id' => $message]);
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers;
|
||||
|
||||
use App\CMS\Enumerations\TemplatePathsHumanReadableRootOnly;
|
||||
use App\CMS\Enumerations\WidgetTypes;
|
||||
use App\CMS\Handlers\Contracts\AppHandler;
|
||||
use App\CMS\Handlers\Contracts\BaseModuleHandler;
|
||||
use App\Models\User;
|
||||
|
||||
abstract class BaseHandler implements BaseModuleHandler
|
||||
{
|
||||
/**
|
||||
* Register admin menu (or multiple ones)
|
||||
*
|
||||
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
|
||||
* starting any middleware..
|
||||
*
|
||||
* @param User $user model of logged user
|
||||
*/
|
||||
public static function registerAdminMenu(User $user)
|
||||
{
|
||||
$menu = \Menu::instance('mainMenu');
|
||||
if (!is_null($menu)) {
|
||||
// menus were already defined
|
||||
return;
|
||||
}
|
||||
|
||||
// create instance of main menu
|
||||
\Menu::create('mainMenu', function ($menu) {
|
||||
// $menu->route('admin.dashboard', trans('admin/mainMenu.dashboard'), [], 10, ['icon' => 'fa fa-fw fa-dashboard']);
|
||||
|
||||
/**
|
||||
* Content pages
|
||||
*
|
||||
* Submenus can be registered later
|
||||
*/
|
||||
$menu->dropdown(trans('admin/mainMenu.contentPages'), function ($sub) {
|
||||
$sub->addDivider(9999);
|
||||
$sub->route('content.overview', trans('admin/mainMenu.contentPageOverview'), [], 10000, ['icon' => 'fa fa-fw fa-list']);
|
||||
}, 20, ['icon' => 'fa fa-fw fa-database']);
|
||||
|
||||
/**
|
||||
* File manager
|
||||
*/
|
||||
$menu->route('upload.overview', trans('admin/mainMenu.fileManager'), [], 40, ['icon' => 'fa fa-fw fa-folder']);
|
||||
|
||||
/**
|
||||
* Widgets and widget areas
|
||||
*/
|
||||
$menu->dropdown(trans('admin/mainMenu.widgets'), function ($sub) {
|
||||
// create list of all widget types
|
||||
$widgets = WidgetTypes::getWithTranslations();
|
||||
|
||||
if (!empty($widgets)) {
|
||||
$sub->dropdown(trans('admin/mainMenu.newWidget'), function ($sub) use ($widgets) {
|
||||
$i = 1;
|
||||
foreach ($widgets as $type => $name) {
|
||||
$sub->route('widgets.new', $name, ['type' => $type], $i++);
|
||||
}
|
||||
}, 10, ['icon' => 'fa fa-fw fa-plus']);
|
||||
}
|
||||
|
||||
$sub->route('widgets.overview', trans('admin/mainMenu.widgetsOverview'), [], 20, ['icon' => 'fa fa-fw fa-list']);
|
||||
|
||||
// menu for widget areas
|
||||
$sub->dropdown(trans('admin/mainMenu.widgetAreas'), function ($sub) {
|
||||
$sub->route('widgetareas.new', trans('admin/mainMenu.newWidgetArea'), [], 1, ['icon' => 'fa fa-fw fa-plus']);
|
||||
$sub->route('widgetareas.overview', trans('admin/mainMenu.widgetAreaOverview'), [], 2, ['icon' => 'fa fa-fw fa-list']);
|
||||
}, 50, ['icon' => 'fa fa-fw fa-object-group']);
|
||||
}, 50, ['icon' => 'fa fa-fw fa-puzzle-piece']);
|
||||
|
||||
/**
|
||||
* Divide system entries and other links in menu
|
||||
*/
|
||||
$menu->addDivider(9999);
|
||||
|
||||
$menu->dropdown(trans('admin/mainMenu.system'), function ($sub) {
|
||||
|
||||
/**
|
||||
* User management
|
||||
*/
|
||||
$sub->dropdown(trans('admin/mainMenu.userManagement'), function ($sub) {
|
||||
$sub->route('users.new', trans('admin/mainMenu.newUser'), [], 10, ['icon' => 'fa fa-fw fa-user-plus']);
|
||||
$sub->route('users.overview', trans('admin/mainMenu.usersOverview'), [], 30, ['icon' => 'fa fa-fw fa-users']);
|
||||
}, 20, ['icon' => 'fa fa-fw fa-users']);
|
||||
|
||||
/**
|
||||
* Templates
|
||||
*/
|
||||
$templatePaths = TemplatePathsHumanReadableRootOnly::getWithTranslations();
|
||||
if (!empty($templatePaths)) {
|
||||
$sub->dropdown(trans('admin/mainMenu.templates'), function ($sub) use ($templatePaths) {
|
||||
$i = 1;
|
||||
foreach ($templatePaths as $id => $name) {
|
||||
$sub->route('templates.overview', $name, ['id' => $id], $i++);
|
||||
}
|
||||
}, 60, ['icon' => 'fa fa-fw fa-file-code-o']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// $menu->dropdown(trans('admin/mainMenu.customFields'), function ($sub) {
|
||||
// $sub->route('customfields.new', trans('admin/mainMenu.customFieldsNew'), [], 10, ['icon' => 'fa fa-fw fa-code']);
|
||||
// $sub->route('customfields.overview', trans('admin/mainMenu.customFieldsOverview'), [], 50, ['icon' => 'fa fa-fw fa-code-fork']);
|
||||
// }, 30, ['icon' => 'fa fa-fw fa-code']);
|
||||
|
||||
$sub->route('log.overview', trans('admin/mainMenu.actionLog'), [], 70, ['icon' => 'fa fa-fw fa-history']);
|
||||
$sub->route('settings.overview', trans('admin/mainMenu.settings'), [], 80, ['icon' => 'fa fa-fw fa-gear']);
|
||||
}, 10000, ['icon' => 'fa fa-fw fa-gears']);
|
||||
|
||||
|
||||
});
|
||||
|
||||
// order
|
||||
|
||||
// create menu with user profile
|
||||
\Menu::create('profileMenu', function ($menu) {
|
||||
$menu->route('users.detail', trans('admin/userManagement.profile'), [], 10, ['icon' => 'fa fa-fw fa-user icon']);
|
||||
$menu->addDivider(999);
|
||||
$menu->route('logout', trans('admin/common.logout'), [], 1000, ['icon' => 'fa fa-fw fa-power-off icon']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers;
|
||||
|
||||
use App\CMS\Handlers\Contracts\AppHandler;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Content\Content;
|
||||
|
||||
/**
|
||||
* Class Handler
|
||||
*
|
||||
* Handler is a class which handles module-specific behaviour which cannot be done by module itself, resp. cannot be
|
||||
* done by some abstract magic.
|
||||
*
|
||||
* @package App\CMS\Handlers\
|
||||
*/
|
||||
abstract class Handler extends BaseHandler implements AppHandler
|
||||
{
|
||||
/**
|
||||
* todo: Temporary method, will be implemented for each Handler
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function supportCategories()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getHistoryHandler()
|
||||
{
|
||||
return History::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render given module into visitor area.
|
||||
*
|
||||
* @param Content $content DB model from table contents
|
||||
* @param array $parameters parameters used for modifications/custom settings of given model
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render(Content $content, $parameters)
|
||||
{
|
||||
return Controller::VisitorsView($content->template, ['page' => $content, 'extra' => $parameters]);
|
||||
}
|
||||
|
||||
public static function getExtendedFormSections()
|
||||
{
|
||||
return [
|
||||
'basicInfo' => trans('admin/contents.basicInfo'),
|
||||
'meta' => trans('admin/contents.metaOptions'),
|
||||
'publication' => trans('admin/contents.publicationOptions'),
|
||||
'appearance' => trans('admin/contents.appearance'),
|
||||
'files' => trans('admin/contents.files')
|
||||
];
|
||||
}
|
||||
|
||||
public static function getExtendedFormInputsCreate()
|
||||
{
|
||||
return [
|
||||
'basicInfo' => 'admin.content.formParts.basicInformation',
|
||||
'meta' => 'admin.content.formParts.metaInformation',
|
||||
'publication' => 'admin.content.formParts.publicationSetup',
|
||||
'appearance' => 'admin.content.formParts.appearance',
|
||||
'files' => 'admin.content.formParts.files'
|
||||
];
|
||||
}
|
||||
|
||||
public static function delete(Content $content)
|
||||
{
|
||||
// temporarily nothing to do
|
||||
}
|
||||
|
||||
public static function loadExtraData(Content $content) {
|
||||
// temporarily nothing to do
|
||||
}
|
||||
|
||||
public static function getExtendedFormInputsEdit()
|
||||
{
|
||||
return self::getExtendedFormInputsCreate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers;
|
||||
|
||||
use App\CMS\Enumerations\ContentStatuses;
|
||||
use App\CMS\Handlers\Contracts\HistoryHandler;
|
||||
use App\CMS\Helpers\Differ;
|
||||
|
||||
class History implements HistoryHandler
|
||||
{
|
||||
public static function parseColumnName($column)
|
||||
{
|
||||
return trans('admin/history.column' . ucfirst($column));
|
||||
}
|
||||
|
||||
public static function parseChangedValue($changeset)
|
||||
{
|
||||
switch ($changeset->column) {
|
||||
case 'pageContent':
|
||||
$route = route('history.diff', [
|
||||
'revision' => $changeset->edit_batch,
|
||||
'id' => $changeset->id
|
||||
]);
|
||||
|
||||
return "(<a href='" . $route . "'>" . trans('admin/history.diff') . "</a>)";
|
||||
break;
|
||||
case 'metaDescription':
|
||||
return Differ::htmlDiff($changeset->old_value, $changeset->new_value);
|
||||
break;
|
||||
case 'file':
|
||||
if (!$changeset->old_value) {
|
||||
// old value is null -> new file was uploaded
|
||||
return trans('admin/history.uploadedFile', ['file' => $changeset->new_value]);
|
||||
} else {
|
||||
return trans('admin/history.deletedFile', ['file' => $changeset->old_value]);
|
||||
}
|
||||
|
||||
break;
|
||||
case 'status':
|
||||
$statuses = ContentStatuses::getWithTranslations();
|
||||
|
||||
return trans('admin/history.changedFromTo', [
|
||||
'from' => $statuses[$changeset->old_value],
|
||||
'to' => $statuses[$changeset->new_value]
|
||||
]);
|
||||
break;
|
||||
case 'is_homepage':
|
||||
return trans('admin/history.setupAsHomepage');
|
||||
break;
|
||||
default:
|
||||
return trans('admin/history.changedFromTo', [
|
||||
'from' => is_null($changeset->old_value) ? trans('admin/history.emptyValue') : $changeset->old_value,
|
||||
'to' => is_null($changeset->new_value) ? trans('admin/history.emptyValue') : $changeset->new_value,
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Registrators\Items;
|
||||
|
||||
class SettingExtension
|
||||
{
|
||||
/**
|
||||
* @var string human readable ID of settings section (used e.g. as ID parameter in html)
|
||||
*/
|
||||
protected $id;
|
||||
/**
|
||||
* @var string translations string used for describing briefly settings section
|
||||
*/
|
||||
protected $name;
|
||||
/**
|
||||
* @var string view used for rendering given settings part
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
/**
|
||||
* SettingExtension constructor.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $name
|
||||
* @param string $view
|
||||
*/
|
||||
public function __construct($id, $name, $view)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->view = $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getView()
|
||||
{
|
||||
return $this->view;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Registrators;
|
||||
|
||||
use App\CMS\Widgets\Contracts\MenuExtensionHandler;
|
||||
|
||||
class MenuExtensionRegistrator {
|
||||
|
||||
protected $menuExtensions;
|
||||
|
||||
/**
|
||||
* @param MenuExtensionHandler $handler
|
||||
*/
|
||||
public function register(MenuExtensionHandler $handler) {
|
||||
$this->menuExtensions[] = $handler;
|
||||
}
|
||||
|
||||
public function get(){
|
||||
return $this->menuExtensions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Registrators;
|
||||
|
||||
use App\CMS\Enumerations\Exceptions\EnumerationExistsException;
|
||||
use App\CMS\Handlers\Contracts\SearchHandler;
|
||||
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
|
||||
use App\CMS\Handlers\Registrators\Items\SearchEngine;
|
||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||
|
||||
class SearchEngineRegistrator
|
||||
{
|
||||
const ADMIN = 'admin';
|
||||
const VISITOR = 'visitor';
|
||||
protected $searchEngines;
|
||||
|
||||
function __construct($app)
|
||||
{
|
||||
$this->searchEngines = [
|
||||
self::ADMIN => [],
|
||||
self::VISITOR => []
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for registering new settings extensions/parts
|
||||
*
|
||||
* @param SearchHandler $search
|
||||
* @param SearchPresenterHandler $presenter
|
||||
*
|
||||
* @param $type
|
||||
*
|
||||
* @throws EnumerationExistsException
|
||||
*/
|
||||
public function register(SearchHandler $search, SearchPresenterHandler $presenter, $type)
|
||||
{
|
||||
$this->checkIfRegistered($type, $search->getId());
|
||||
|
||||
// register new extension
|
||||
$this->searchEngines[$type][$search->getId()] = [$search, $presenter];
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for all registered extensions
|
||||
*
|
||||
* @param $type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get($type)
|
||||
{
|
||||
if (!isset($this->searchEngines[$type])) {
|
||||
throw new InvalidArgumentException('Invalid type ' . $type);
|
||||
}
|
||||
|
||||
return $this->searchEngines[$type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this section is not already defined
|
||||
*
|
||||
* @param $type
|
||||
* @param $id
|
||||
*
|
||||
* @throws EnumerationExistsException
|
||||
*/
|
||||
private function checkIfRegistered($type, $id)
|
||||
{
|
||||
if (isset($this->searchEngines[$type][$id])) {
|
||||
throw new EnumerationExistsException('Already existing search engine ' . $id . ' in ' . $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Registrators;
|
||||
|
||||
use App\CMS\Enumerations\Exceptions\EnumerationExistsException;
|
||||
use App\CMS\Handlers\Registrators\Items\SettingExtension;
|
||||
|
||||
class SettingsExtensionRegistrator
|
||||
{
|
||||
protected $settingsExtensions;
|
||||
|
||||
function __construct($app)
|
||||
{
|
||||
$this->settingsExtensions = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Method for registering new settings extensions/parts
|
||||
*
|
||||
* @param $sectionId
|
||||
* @param $sectionName
|
||||
* @param $sectionView
|
||||
*
|
||||
* @throws EnumerationExistsException
|
||||
*/
|
||||
public function register($sectionId, $sectionName, $sectionView)
|
||||
{
|
||||
$this->checkIfRegistered($sectionId);
|
||||
|
||||
// register new extension
|
||||
$this->settingsExtensions[$sectionId] = new SettingExtension($sectionId, $sectionName, $sectionView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new setting part - only as SettingExtension directly
|
||||
*
|
||||
* @param SettingExtension $extension
|
||||
*/
|
||||
public function registerObject(SettingExtension $extension)
|
||||
{
|
||||
$this->checkIfRegistered($extension->getId());
|
||||
|
||||
$this->settingsExtensions[$extension->getId()] = $extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for all registered extensions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get()
|
||||
{
|
||||
// sort registered extensions by key
|
||||
ksort($this->settingsExtensions);
|
||||
|
||||
return $this->settingsExtensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this section is not already defined
|
||||
*
|
||||
* @param $sectionId
|
||||
*
|
||||
* @throws EnumerationExistsException
|
||||
*/
|
||||
private function checkIfRegistered($sectionId)
|
||||
{
|
||||
if (isset($this->settingsExtensions[$sectionId])) {
|
||||
throw new EnumerationExistsException('Already existing key ' . $sectionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Registrators;
|
||||
|
||||
use App\CMS\Enumerations\TemplatePaths;
|
||||
use App\CMS\Enumerations\Templates;
|
||||
use App\Models\Template;
|
||||
use App\Models\TemplatePath;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||
|
||||
class TemplateRegistrator
|
||||
{
|
||||
/**
|
||||
* @var string absolute path to base directory of registered template paths
|
||||
*/
|
||||
protected $baseDirectory;
|
||||
/**
|
||||
* @var string namespace of registered templates
|
||||
*/
|
||||
protected $namespace;
|
||||
/**
|
||||
* @var string absolute path to currently registered directory
|
||||
* This variable is set in register() method as $baseDirectory/$path
|
||||
*/
|
||||
protected $registeredPath;
|
||||
/**
|
||||
* @var int ID of module
|
||||
*/
|
||||
protected $moduleId;
|
||||
/**
|
||||
* @var array list of all registered template paths
|
||||
*/
|
||||
protected $paths = [];
|
||||
|
||||
/**
|
||||
* Set base path
|
||||
*
|
||||
* @param mixed $baseDirectory
|
||||
*/
|
||||
public function setBaseDirectory($baseDirectory)
|
||||
{
|
||||
$baseDirectory = str_replace('/', DIRECTORY_SEPARATOR, $baseDirectory);
|
||||
$baseDirectory = base_path($baseDirectory);
|
||||
$baseDirectory = rtrim($baseDirectory, DIRECTORY_SEPARATOR);
|
||||
|
||||
if (!is_dir($baseDirectory)) {
|
||||
throw new InvalidArgumentException('Invalid path ' . $baseDirectory);
|
||||
}
|
||||
|
||||
$this->baseDirectory = $baseDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set module ID for registered path
|
||||
*
|
||||
* @param int $moduleId
|
||||
*/
|
||||
public function setModuleId($moduleId)
|
||||
{
|
||||
$this->moduleId = $moduleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set namespace for registered template path
|
||||
*
|
||||
* @param string $namespace
|
||||
*/
|
||||
public function setNamespace($namespace)
|
||||
{
|
||||
$this->namespace = $namespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets namespace
|
||||
*/
|
||||
public function unsetNamespace()
|
||||
{
|
||||
$this->namespace = null;
|
||||
$this->setModuleId(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers new template path.
|
||||
* This method registeres given path itself with all subdirectories
|
||||
*
|
||||
* @param $baseDirectory
|
||||
* @param string $path path relatively to root of the project
|
||||
* @param string $name human readable identification of given template path
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function register($baseDirectory, $path, $name)
|
||||
{
|
||||
$this->paths[] = [
|
||||
'namespace' => $this->namespace,
|
||||
'moduleId' => $this->moduleId,
|
||||
'baseDirectory' => $baseDirectory,
|
||||
'path' => $this->baseDirectory . DIRECTORY_SEPARATOR . $path,
|
||||
'name' => $name
|
||||
];
|
||||
$this->unsetNamespace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save templates into database
|
||||
*/
|
||||
public function saveTemplates()
|
||||
{
|
||||
if (!is_array($this->paths) || empty($this->paths)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->paths as $path) {
|
||||
if (!empty($path['namespace'])) {
|
||||
$this->setNamespace($path['namespace'] . '::');
|
||||
}
|
||||
$this->setModuleId($path['moduleId']);
|
||||
$this->setBaseDirectory($path['baseDirectory']);
|
||||
|
||||
$this->registeredPath = $this->baseDirectory . DIRECTORY_SEPARATOR . $path['path'];
|
||||
// register path
|
||||
$this->registerPath($this->registeredPath, $path['name']);
|
||||
$this->unsetNamespace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get relative path to project root
|
||||
*
|
||||
* @param $directory
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function relativePath($directory)
|
||||
{
|
||||
return trim(str_replace(base_path(), '', $directory), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Crawl subdirectories and register them
|
||||
*
|
||||
* @param string $directory path relative to $baseDirectory variable
|
||||
* @param string $name name of parent directory
|
||||
*/
|
||||
protected function scanForSubdirectories($directory, $name)
|
||||
{
|
||||
$directories = File::directories($directory);
|
||||
|
||||
foreach ($directories as $dir) {
|
||||
$base = basename($dir);
|
||||
$name = preg_replace('/\.(.+)/', '.' . $base, $name);
|
||||
|
||||
$this->registerPath($dir, $name, $directory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers template path and templates into system
|
||||
*
|
||||
* @param string $path relative path to $baseDirectory variable
|
||||
* @param string $name human readable name of this path (used in overview)
|
||||
* @param null|string $parent path to parent directory
|
||||
*/
|
||||
protected function registerPath($path, $name, $parent = null)
|
||||
{
|
||||
// skip custom directories (contains updated templates only)
|
||||
$dirName = basename($path);
|
||||
$ignoredDirectories = [
|
||||
Template::EDITED_TEMPLATES_DIRECTORY,
|
||||
Template::ASSETS_DIRECTORY,
|
||||
Template::MODULES_DIRECTORY
|
||||
];
|
||||
|
||||
if (in_array($dirName, $ignoredDirectories)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// save template path into database
|
||||
$templatePathId = $this->saveTemplatePath($path, $name, $parent);
|
||||
|
||||
// save all templates into database
|
||||
$this->registerTemplates($path, $templatePathId);
|
||||
|
||||
// try to find some subdirectories and other templates
|
||||
$this->scanForSubdirectories($path, $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all templates
|
||||
* This method takes all templates in given directory and registers them into database. Templates registered in
|
||||
* this way may be used for further manipulation.
|
||||
*
|
||||
* @param $path
|
||||
* @param $templatePathId
|
||||
*
|
||||
* @throws \App\CMS\Enumerations\Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected function registerTemplates($path, $templatePathId)
|
||||
{
|
||||
$templates = File::files($path);
|
||||
|
||||
foreach ($templates as $template) {
|
||||
|
||||
// skip all non-template files - we assume that every file with suffix ".blade.php" is Blade template
|
||||
if (!Str::endsWith($template, Template::TEMPLATE_SUFFIX)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get all templates and template name (path/to/template.blade.php -> path.to.template)
|
||||
$templateName = $this->getTemplateName($template);
|
||||
$registeredTemplates = Templates::getWithTranslations();
|
||||
|
||||
if (!in_array($templateName, $registeredTemplates)) {
|
||||
$params = [
|
||||
'template_name' => $templateName,
|
||||
'name' => $templateName,
|
||||
'path' => $templatePathId,
|
||||
'module_id' => $this->moduleId,
|
||||
'description' => '',
|
||||
'editable' => 1
|
||||
];
|
||||
|
||||
// save template into database
|
||||
$newTemplate = Template::create($params);
|
||||
|
||||
// push template into enumeration - so it will not be registered again
|
||||
Templates::push($newTemplate->id, $templateName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save template into database and return its ID
|
||||
*
|
||||
* @param $path
|
||||
* @param $name
|
||||
* @param null $parent
|
||||
*
|
||||
* @return mixed|null
|
||||
* @throws \App\CMS\Enumerations\Exceptions\EnumerationExistsException
|
||||
*/
|
||||
protected function saveTemplatePath($path, $name, $parent = null)
|
||||
{
|
||||
$registeredPaths = TemplatePaths::getWithTranslations();
|
||||
$relativePath = $this->relativePath($path);
|
||||
|
||||
if (!in_array($relativePath, $registeredPaths)) {
|
||||
$parentId = $this->getId($this->relativePath($parent));
|
||||
|
||||
$params = [
|
||||
'path' => $relativePath,
|
||||
'name' => $name,
|
||||
'namespace' => $this->namespace,
|
||||
'parent_id' => $parentId
|
||||
];
|
||||
|
||||
// save into database
|
||||
$path = TemplatePath::create($params);
|
||||
|
||||
// add to enumeration
|
||||
TemplatePaths::push($path->id, $relativePath);
|
||||
|
||||
return $path->id;
|
||||
}
|
||||
|
||||
return $this->getId($relativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ID of registered template
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return null|int null when parent not found, ID of parent otherwise
|
||||
*/
|
||||
private function getId($path)
|
||||
{
|
||||
// get registered paths
|
||||
$paths = TemplatePaths::getWithTranslations();
|
||||
$paths = array_flip($paths);
|
||||
|
||||
if (is_null($path) || !isset($paths[$path])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $paths[$path];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template name
|
||||
* Converts path to template to corresponding name
|
||||
*
|
||||
* @param $template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTemplateName($template)
|
||||
{
|
||||
$templateName = str_replace($this->registeredPath . DIRECTORY_SEPARATOR, '', $template);
|
||||
$templateName = str_replace(DIRECTORY_SEPARATOR, '.', $templateName);
|
||||
$templateName = str_replace(Template::TEMPLATE_SUFFIX, '', $templateName);
|
||||
|
||||
return $this->namespace . $templateName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Registrators;
|
||||
|
||||
use App\CMS\Enumerations\WidgetTypesWithHandlers;
|
||||
use App\Models\Widgets\WidgetType;
|
||||
|
||||
class WidgetRegistrator
|
||||
{
|
||||
protected $registeredWidgets = [];
|
||||
|
||||
|
||||
/**
|
||||
* Method used for registering new widgets
|
||||
*
|
||||
* @param $classname
|
||||
* @param null $templateId
|
||||
* @param null $moduleId
|
||||
*/
|
||||
public function register($classname, $templateId = null, $moduleId = null)
|
||||
{
|
||||
$this->registeredWidgets[] = [
|
||||
'class' => $classname,
|
||||
'templateId' => $templateId,
|
||||
'moduleId' => $moduleId
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Install all non-installed widgets
|
||||
*/
|
||||
public function installWidgets()
|
||||
{
|
||||
$installed = WidgetTypesWithHandlers::getSimple();
|
||||
foreach ($this->registeredWidgets as $registeredWidget) {
|
||||
$classname = $registeredWidget['class'];
|
||||
$templateId = $registeredWidget['templateId'];
|
||||
$moduleId = $registeredWidget['moduleId'];
|
||||
|
||||
// register widget as new widget type
|
||||
if (!in_array($classname, $installed)) {
|
||||
$widgetName = call_user_func($classname . '::getName');
|
||||
$widgetDescription = call_user_func($classname . '::getDescription');
|
||||
|
||||
// create row in widget types
|
||||
WidgetType::create([
|
||||
'handler' => $classname,
|
||||
'name' => $widgetName,
|
||||
'module_id' => $moduleId,
|
||||
'template_id' => $templateId,
|
||||
'description' => $widgetDescription
|
||||
]);
|
||||
|
||||
// install widget (if neccessary)
|
||||
call_user_func($classname . '::install');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Search;
|
||||
|
||||
use App\Models\Content\Content as ContentModel;
|
||||
|
||||
class Content extends Search
|
||||
{
|
||||
/**
|
||||
* Search for given patttern/term
|
||||
*
|
||||
* @param string $term searched word
|
||||
*
|
||||
* @return array list of found objects
|
||||
*/
|
||||
public function search($term)
|
||||
{
|
||||
$token = $this->tokenize($term);
|
||||
|
||||
return ContentModel::where('content', 'LIKE', $token)
|
||||
->orWhere('meta_description', 'LIKE', $token)
|
||||
->orWhere('meta_keywords', 'LIKE', $token)
|
||||
->orWhere('title', 'LIKE', $token)
|
||||
->orWhere('url', 'LIKE', $token)
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'content';
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return trans('search.content');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Search;
|
||||
|
||||
use App\Models\FileManager\File;
|
||||
|
||||
class Files extends Search
|
||||
{
|
||||
public function getId()
|
||||
{
|
||||
return "files";
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return trans('search.files');
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for given patttern/term
|
||||
*
|
||||
* @param string $term searched word
|
||||
*
|
||||
* @return array list of found objects
|
||||
*/
|
||||
public function search($term)
|
||||
{
|
||||
$token = $this->tokenize($term);
|
||||
|
||||
return File::where('original_filename', 'LIKE', $token)
|
||||
->orWhere('name', 'LIKE', $token)
|
||||
->orWhere('keywords', 'LIKE', $token)
|
||||
->orWhere('description', 'LIKE', $token)
|
||||
->orWhere('mime_type', 'LIKE', $token)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Search\Presenters;
|
||||
|
||||
use App\CMS\Enumerations\ContentStatuses;
|
||||
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
|
||||
|
||||
class AdminContent implements SearchPresenterHandler
|
||||
{
|
||||
public function render($foundItems)
|
||||
{
|
||||
return view('admin.search.results.content', [
|
||||
'pages' => $foundItems,
|
||||
'statuses' => ContentStatuses::getWithTranslations(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Search\Presenters;
|
||||
|
||||
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
|
||||
|
||||
class AdminFiles implements SearchPresenterHandler
|
||||
{
|
||||
/**
|
||||
* Method for rendering list of found results
|
||||
*
|
||||
* @param $foundItems
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render($foundItems)
|
||||
{
|
||||
return view('admin.fileManager.filesTiles', ['files' => $foundItems, 'hideDelete' => true]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
namespace App\CMS\Handlers\Search;
|
||||
|
||||
use App\CMS\Handlers\Contracts\SearchHandler;
|
||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||
|
||||
abstract class Search implements SearchHandler
|
||||
{
|
||||
/**
|
||||
* Tokenize string for usage in LIKE clausules
|
||||
*
|
||||
* @param $term
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function tokenize($term)
|
||||
{
|
||||
$term = trim($term);
|
||||
|
||||
if (empty($term)) {
|
||||
throw new InvalidArgumentException(trans('search.emptyString'));
|
||||
}
|
||||
|
||||
return '%' . str_replace(' ', '%', $term) . '%';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
use App\Models\Module;
|
||||
use DebugBar\Bridge\MonologCollector;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Monolog\Logger;
|
||||
|
||||
class CurrentTemplate
|
||||
{
|
||||
protected static $template;
|
||||
protected static $initialized = false;
|
||||
|
||||
/**
|
||||
* Getter for currently set template
|
||||
* @return Module
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public static function get()
|
||||
{
|
||||
if (!self::$initialized) {
|
||||
try {
|
||||
self::$template = Module::where('is_template', true)
|
||||
->where('enabled', true)
|
||||
->first();
|
||||
} catch (QueryException $e) {
|
||||
throw new \ErrorException('DB not migrated, please, do so!');
|
||||
}
|
||||
if (self::$template) {
|
||||
self::$template->module_settings = json_decode(self::$template->module_settings);
|
||||
}
|
||||
|
||||
self::$initialized = true;
|
||||
}
|
||||
|
||||
return self::$template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for getting template handler
|
||||
*
|
||||
* @return string
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public static function handler()
|
||||
{
|
||||
$template = self::get();
|
||||
|
||||
if (!$template) {
|
||||
throw new \ErrorException('No template selected, no handler available!');
|
||||
}
|
||||
|
||||
return $template->handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset currently set template and load another one on next call of get() method.
|
||||
*/
|
||||
public static function reset()
|
||||
{
|
||||
self::$initialized = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
class Date
|
||||
{
|
||||
/**
|
||||
* Print date in configured format
|
||||
*
|
||||
* @param $datestamp
|
||||
* @param bool $withTime
|
||||
*
|
||||
* @return false|string
|
||||
*/
|
||||
public static function date($datestamp, $withTime = true)
|
||||
{
|
||||
$timestamp = strtotime($datestamp);
|
||||
|
||||
if ($timestamp <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$format = $withTime ? config('app.datetime_format') : config('app.date_format');
|
||||
|
||||
return date($format, $timestamp);
|
||||
}
|
||||
|
||||
public static function dateFormatted($format, $datestamp)
|
||||
{
|
||||
$timestamp = strtotime($datestamp);
|
||||
|
||||
if ($timestamp <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return date($format, $timestamp);
|
||||
}
|
||||
|
||||
public static function monthName($datestamp) {
|
||||
$timestamp = strtotime($datestamp);
|
||||
|
||||
if ($timestamp <= 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$months = [
|
||||
trans('common.months.january'),
|
||||
trans('common.months.february'),
|
||||
trans('common.months.march'),
|
||||
trans('common.months.april'),
|
||||
trans('common.months.may'),
|
||||
trans('common.months.june'),
|
||||
trans('common.months.july'),
|
||||
trans('common.months.august'),
|
||||
trans('common.months.semptember'),
|
||||
trans('common.months.october'),
|
||||
trans('common.months.november'),
|
||||
trans('common.months.december'),
|
||||
];
|
||||
|
||||
$monthNumber = date('n', $timestamp);
|
||||
|
||||
return $months[$monthNumber - 1];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
/*
|
||||
Paul's Simple Differ Algorithm v 0.1
|
||||
(C) Paul Butler 2007 <http://www.paulbutler.org/>
|
||||
May be used and distributed under the zlib/libpng license.
|
||||
|
||||
This code is intended for learning purposes; it was written with short
|
||||
code taking priority over performance. It could be used in a practical
|
||||
application, but there are a few ways it could be optimized.
|
||||
|
||||
Given two arrays, the function diff will return an array of the changes.
|
||||
I won't describe the format of the array, but it will be obvious
|
||||
if you use print_r() on the result of a diff on some test data.
|
||||
|
||||
htmlDiff is a wrapper for the diff command, it takes two strings and
|
||||
returns the differences in HTML. The tags used are <ins> and <del>,
|
||||
which can easily be styled with CSS.
|
||||
|
||||
@url https://github.com/paulgb/simplediff/blob/master/php/simplediff.php
|
||||
|
||||
Sorry for this kind of magic, I have no idea how this works.. :(
|
||||
*/
|
||||
|
||||
class Differ
|
||||
{
|
||||
public static function diff($old, $new)
|
||||
{
|
||||
$matrix = [];
|
||||
$maxlen = 0;
|
||||
foreach ($old as $oindex => $ovalue) {
|
||||
$nkeys = array_keys($new, $ovalue);
|
||||
foreach ($nkeys as $nindex) {
|
||||
$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ? $matrix[$oindex - 1][$nindex - 1] + 1 : 1;
|
||||
if ($matrix[$oindex][$nindex] > $maxlen) {
|
||||
$maxlen = $matrix[$oindex][$nindex];
|
||||
$omax = $oindex + 1 - $maxlen;
|
||||
$nmax = $nindex + 1 - $maxlen;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($maxlen == 0) {
|
||||
return [['d' => $old, 'i' => $new]];
|
||||
}
|
||||
|
||||
return array_merge(self::diff(array_slice($old, 0, $omax), array_slice($new, 0, $nmax)), array_slice($new, $nmax, $maxlen), self::diff(array_slice($old, $omax + $maxlen), array_slice($new, $nmax + $maxlen)));
|
||||
}
|
||||
|
||||
public static function htmlDiff($old, $new)
|
||||
{
|
||||
$ret = '';
|
||||
$diff = self::diff(preg_split("/[\s]+/", $old), preg_split("/[\s]+/", $new));
|
||||
foreach ($diff as $k) {
|
||||
if (is_array($k)) {
|
||||
$ret .= (!empty($k['d']) ? "<del>" . implode(' ', $k['d']) . "</del> " : '') . (!empty($k['i']) ? "<ins>" . implode(' ', $k['i']) . "</ins> " : '');
|
||||
} else {
|
||||
$ret .= $k . ' ';
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
use App\Models\FileManager\File;
|
||||
|
||||
class FileManager
|
||||
{
|
||||
/**
|
||||
* @param File $file
|
||||
*
|
||||
* @return \Illuminate\Contracts\Routing\UrlGenerator|string
|
||||
*/
|
||||
public static function getPreview(File $file)
|
||||
{
|
||||
list($type, $subtype) = explode('/', $file->mime_type);
|
||||
|
||||
switch ($type) {
|
||||
case 'image':
|
||||
|
||||
$url = Path::thumbnail($file->filename);
|
||||
|
||||
return '<img src="' . $url . '" alt="' . $file->description . '" />';
|
||||
break;
|
||||
case 'text':
|
||||
return self::getIcon($file, 'fa-file-text-o');
|
||||
break;
|
||||
case 'application':
|
||||
switch ($subtype) {
|
||||
case 'pdf':
|
||||
return self::getIcon($file, 'fa-file-pdf-o');
|
||||
break;
|
||||
default:
|
||||
return self::getIcon($file, 'fa-newspaper-o');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return self::getIcon($file, 'fa-question');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for displaying icons
|
||||
*
|
||||
* @param $file
|
||||
* @param $icon
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getIcon($file, $icon)
|
||||
{
|
||||
return '<p><i class="fa fa-2x ' . $icon . '"></i><br /><span>' . e(str_limit($file->original_filename, 15)) . '</span></p>';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param File $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getFormattedSize(File $file)
|
||||
{
|
||||
$bytes = $file->file_size;
|
||||
|
||||
$label = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
|
||||
for ($i = 0; $bytes >= 1024 && $i < (count($label) - 1); $bytes /= 1024, $i++) {
|
||||
;
|
||||
}
|
||||
|
||||
return (round($bytes, 2) . " " . $label[$i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preview for file detail
|
||||
*
|
||||
* @param File $file
|
||||
*
|
||||
* @return \Illuminate\Contracts\Routing\UrlGenerator|string
|
||||
*/
|
||||
public static function getLargePreview(File $file)
|
||||
{
|
||||
list($type, $subtype) = explode('/', $file->mime_type);
|
||||
|
||||
$url = config('app.upload_url') . '/' . $file->filename;
|
||||
$path = config('app.upload_path') . DIRECTORY_SEPARATOR . $file->filename;
|
||||
|
||||
switch ($type) {
|
||||
case 'image':
|
||||
return '<img src="' . $url . '" alt="' . $file->description . '" />';
|
||||
break;
|
||||
case 'text':
|
||||
$string = '<pre><code>';
|
||||
$string .= htmlspecialchars(file_get_contents($path));
|
||||
$string .= '</pre></code>';
|
||||
|
||||
return $string;
|
||||
break;
|
||||
case 'application':
|
||||
return '<iframe src = "'.asset('resources/assets/admin/js/viewerJs/').'/#'.Template::upload($file->filename).'" style="width: 100%; height: 50em" allowfullscreen webkitallowfullscreen></iframe>';
|
||||
break;
|
||||
default:
|
||||
return self::getPreview($file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param File $file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getAdditionalInfo(File $file)
|
||||
{
|
||||
list($type, $subtype) = explode('/', $file->mime_type);
|
||||
|
||||
$path = config('app.upload_path') . DIRECTORY_SEPARATOR . $file->filename;
|
||||
|
||||
switch ($type) {
|
||||
case 'text':
|
||||
return [trans('admin/fileManager.encoding') => mb_detect_encoding(file_get_contents($path))];
|
||||
break;
|
||||
|
||||
case 'image':
|
||||
list ($width, $height) = getimagesize($path);
|
||||
return [trans('admin/fileManager.resolution') => $height . ' x ' . $width,];
|
||||
break;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
class Gravatar
|
||||
{
|
||||
public static function img($email, $size = 50)
|
||||
{
|
||||
return "//www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?s=" . $size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
use App\CMS\Handlers\Contracts\AppHandler;
|
||||
use App\Models\Content\Content;
|
||||
use Webwizo\Shortcodes\Facades\Shortcode;
|
||||
|
||||
/**
|
||||
* Class PageRenderer
|
||||
*
|
||||
* Simple class for rendering page for visitor
|
||||
*
|
||||
* @package App\CMS\Helpers
|
||||
*/
|
||||
class PageRenderer
|
||||
{
|
||||
/**
|
||||
* Render page
|
||||
*
|
||||
* @param Content $page
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function render(Content $page)
|
||||
{
|
||||
// decode module settings
|
||||
$page->module_settings = json_decode($page->module_settings);
|
||||
|
||||
// do something template-specific
|
||||
$parameters = call_user_func_array([CurrentTemplate::handler(), 'beforeRender'], [&$page]);
|
||||
|
||||
/**
|
||||
* @var $handler AppHandler
|
||||
*/
|
||||
// get handler
|
||||
$handler = new $page->module_handler;
|
||||
|
||||
$page->content = Shortcode::compile($page->content);
|
||||
|
||||
// render page
|
||||
return $handler->render($page, $parameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||
|
||||
class Path
|
||||
{
|
||||
/**
|
||||
* Get URL to uploaded file
|
||||
*
|
||||
* @param $filename
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function upload($filename)
|
||||
{
|
||||
// for debug environment check if file exists
|
||||
if (env('APP_DEBUG') && !file_exists(config('app.upload_path') . '/' . $filename)) {
|
||||
throw new NotFoundHttpException('File ' . $filename . ' cannot be found in ' . config('app.upload_path') . '.');
|
||||
}
|
||||
|
||||
// return url to uploaded file
|
||||
return config('app.upload_url') . '/' . $filename;
|
||||
}
|
||||
|
||||
public static function thumbnail($filename)
|
||||
{
|
||||
// try to check if file have thumbnail
|
||||
if (file_exists(config('app.thumbnail_path') . '/' . $filename)) {
|
||||
$url = config('app.thumbnail_url') . '/' . $filename;
|
||||
} else {
|
||||
$url = self::upload($filename);
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path to given asset
|
||||
*
|
||||
* @param $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function asset($path)
|
||||
{
|
||||
if (env('APP_DEBUG')) {
|
||||
if (empty($path)) {
|
||||
throw new InvalidArgumentException('No asset name defined!');
|
||||
}
|
||||
|
||||
// check if asset exists and is file
|
||||
if (!file_exists(public_path('assets/' . config('app.theme') . '/' . $path))) {
|
||||
throw new NotFoundHttpException('Cannot find any asset in ' . public_path('assets/' . config('app.theme') . '/' . $path) . '. Try to check your paths.');
|
||||
}
|
||||
}
|
||||
|
||||
return config('app.url') . '/assets/' . config('app.theme') . '/' . $path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
use App\Models\Settings as SettingsModel;
|
||||
|
||||
/**
|
||||
* Class Settings
|
||||
*
|
||||
* Helper class for easier obtaining system settings
|
||||
*
|
||||
* @package App\CMS\Helpers
|
||||
*/
|
||||
class Settings
|
||||
{
|
||||
/**
|
||||
* @var array List of all used settings
|
||||
*/
|
||||
protected static $settings;
|
||||
/**
|
||||
* @var bool Are data already initialized?
|
||||
*/
|
||||
protected static $initialized = false;
|
||||
|
||||
/**
|
||||
* Getter for settings determined with key.
|
||||
*
|
||||
* @param string $key settings key
|
||||
* @param string|null $default default value, which will be returned when given key does not exist
|
||||
*
|
||||
* @param null $exists
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function get($key, $default = null, & $exists = null)
|
||||
{
|
||||
self::init();
|
||||
|
||||
if (isset(self::$settings->$key)) {
|
||||
$exists = true;
|
||||
self::$initialized = true;
|
||||
return self::$settings->$key;
|
||||
}
|
||||
|
||||
$exists = false;
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for obtaining settings saved as JSON
|
||||
*
|
||||
* @param $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getJson($key)
|
||||
{
|
||||
return json_decode(self::get($key, '{}'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function all()
|
||||
{
|
||||
self::init();
|
||||
|
||||
return self::$settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize settings array
|
||||
*/
|
||||
private static function init()
|
||||
{
|
||||
if (!self::$initialized) {
|
||||
$model = new SettingsModel();
|
||||
self::$settings = $model->getAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||
|
||||
class Template
|
||||
{
|
||||
/**
|
||||
* Getter for real template name
|
||||
*
|
||||
* @param $template
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function name($template, $throwExceptions = true)
|
||||
{
|
||||
$namespace = null;
|
||||
if (strpos($template, '::')) {
|
||||
list($namespace, $template) = explode('::', $template);
|
||||
$namespace .= '::';
|
||||
}
|
||||
|
||||
// list of prefixes
|
||||
$prefixes = ['custom.', ''];
|
||||
|
||||
$view = null;
|
||||
foreach ($prefixes as $prefix) {
|
||||
if (view()->exists($namespace . 'visitor.' . $prefix . $template)) {
|
||||
$view = $namespace . 'visitor.' . $prefix . $template;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_null($view)) {
|
||||
if ($throwExceptions) {
|
||||
throw new InvalidArgumentException('Cannot find template for ' . $namespace . $template);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
class Widget
|
||||
{
|
||||
public static function render(\App\Models\Widgets\Widget $widget)
|
||||
{
|
||||
$handler = $widget->widget_type_handler;
|
||||
|
||||
if (!is_object($widget->settings)) {
|
||||
$widget->settings = json_decode($widget->settings);
|
||||
}
|
||||
|
||||
$presenter = call_user_func([$handler, 'getPresenter']);
|
||||
|
||||
return call_user_func([$presenter, 'render'], $widget);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace App\CMS\Helpers;
|
||||
|
||||
use App\Models\Widgets\WidgetArea;
|
||||
|
||||
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] = '';
|
||||
|
||||
self::$widgetAreas[$widget->widget_area_code] .= Widget::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.
|
||||
*
|
||||
* @param $uniqueCode
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function render($uniqueCode)
|
||||
{
|
||||
if (!self::$initialized) {
|
||||
self::initWidgetAreas();
|
||||
}
|
||||
|
||||
if (!isset(self::$widgetAreas[$uniqueCode])) {
|
||||
self::loadWidgetArea($uniqueCode);
|
||||
}
|
||||
|
||||
echo isset(self::$widgetAreas[$uniqueCode]) ? self::$widgetAreas[$uniqueCode] : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Define function for escaping characters.
|
||||
*
|
||||
* This funcion prevents of creating build-in function, which escapes also accents...
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function e($value)
|
||||
{
|
||||
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for \App\CMS\Helpers\Settings::get()
|
||||
*
|
||||
* @param $key
|
||||
* @param null $default
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
function setting($key, $default = null) {
|
||||
return \App\CMS\Helpers\Settings::get($key, $default);
|
||||
}
|
||||
|
||||
function asset_path($path) {
|
||||
return env('SITE_URL').'/assets/'.$path;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
namespace App\CMS\MenuPresenters;
|
||||
|
||||
use Pingpong\Menus\MenuItem;
|
||||
use Pingpong\Menus\Presenters\Presenter;
|
||||
|
||||
class FoundationDrilldownMenuPresenter extends Presenter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getOpenTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '<ul class="vertical menu" data-drilldown>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getCloseTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '</ul>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithoutDropdownWrapper($item)
|
||||
{
|
||||
return '<li' . $this->getActiveState($item) . '><a href="' . $item->getUrl() . '">' . $item->getIcon() . ' ' . $item->title . '</a></li>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getActiveState(MenuItem $item)
|
||||
{
|
||||
$active = ' class="active"';
|
||||
|
||||
if (empty($item->getChilds())) {
|
||||
// for direct menu input return if page is active
|
||||
return \Request::is($item->getRequest()) ? $active : null;
|
||||
} else {
|
||||
// on nested menu inputs loop over children and in case any of them is active, mark active also root level
|
||||
foreach ($item->getChilds() as $child) {
|
||||
if ($this->getActiveState($child)) {
|
||||
return $active;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getDividerWrapper()
|
||||
{
|
||||
return '<li class="divider"></li>' . PHP_EOL;
|
||||
}
|
||||
|
||||
public function getMultiLevelDropdownWrapper($item)
|
||||
{
|
||||
return $this->getMenuWithDropDownWrapper($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithDropDownWrapper($item)
|
||||
{
|
||||
$active = $this->getActiveState($item);
|
||||
|
||||
return '<li>
|
||||
<a ' . $active . ' href="#">' . $item->getIcon() . ' ' . $item->title . '</a>
|
||||
<ul class="vertical menu">
|
||||
' . $this->getChildMenuItems($item) . '
|
||||
</ul>
|
||||
</li>' . PHP_EOL;;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace App\CMS\MenuPresenters;
|
||||
|
||||
use Pingpong\Menus\Presenters\Presenter;
|
||||
|
||||
class FoundationDropdownMenuPresenter extends Presenter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getOpenTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '<ul class="vertical dropdown menu" data-dropdown-menu>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getCloseTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '</ul>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithoutDropdownWrapper($item)
|
||||
{
|
||||
$link = '<a href="' . $item->getUrl() . '">' . $item->getIcon() . ' ' . $item->title . '</a>';
|
||||
return '<li' . $this->getActiveState($item) . '>' . $link . '</li>'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getActiveState($item)
|
||||
{
|
||||
return \Request::is($item->getRequest()) || $item->hasActiveOnChild ? ' class="active"' : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getDividerWrapper()
|
||||
{
|
||||
return '<li class="divider"></li>'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithDropDownWrapper($item)
|
||||
{
|
||||
return '<li>
|
||||
<a href="#">' . $item->getIcon() . ' ' . $item->title . '</a>
|
||||
<ul class="vertical menu">
|
||||
' . $this->getChildMenuItems($item) . '
|
||||
</ul>
|
||||
</li>' . PHP_EOL;;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace App\CMS\MenuPresenters;
|
||||
|
||||
class FoundationInitializedDropdownMenuPresenter extends FoundationDropdownMenuPresenter
|
||||
{
|
||||
public function getOpenTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '<ul class="menu">' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace App\CMS\MenuPresenters;
|
||||
|
||||
use Pingpong\Menus\MenuItem;
|
||||
use Pingpong\Menus\Presenters\Presenter;
|
||||
|
||||
class MetismenuPresenter extends Presenter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getOpenTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '<ul class="nav metismenu" id="sidebar-menu">' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getCloseTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '</ul>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithoutDropdownWrapper($item)
|
||||
{
|
||||
return '<li' . $this->getActiveState($item) . '><a href="' . $item->getUrl() . '">' . $item->getIcon() . ' ' . $item->title . '</a></li>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getActiveState(MenuItem $item)
|
||||
{
|
||||
if ($item->isDivider()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$active = ' class="active"';
|
||||
|
||||
if (empty($item->getChilds())) {
|
||||
// for direct menu input return if page is active
|
||||
return \Request::is($item->getRequest()) ? $active : null;
|
||||
} else {
|
||||
// on nested menu inputs loop over children and in case any of them is active, mark active also root level
|
||||
foreach ($item->getChilds() as $child) {
|
||||
if ($this->getActiveState($child)) {
|
||||
return $active;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getDividerWrapper()
|
||||
{
|
||||
return '<li class="divider"></li>' . PHP_EOL;
|
||||
}
|
||||
|
||||
public function getMultiLevelDropdownWrapper($item)
|
||||
{
|
||||
return $this->getMenuWithDropDownWrapper($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithDropDownWrapper($item)
|
||||
{
|
||||
$active = $this->getActiveState($item);
|
||||
return '<li' . $active . '>
|
||||
<a href="#">' . $item->getIcon() . ' ' . $item->title . ' <i class="fa arrow"></i></a>
|
||||
<ul>
|
||||
' . $this->getChildMenuItems($item) . '
|
||||
</ul>
|
||||
</li>' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace App\CMS\MenuPresenters;
|
||||
|
||||
use Pingpong\Menus\MenuItem;
|
||||
use Pingpong\Menus\Presenters\Presenter;
|
||||
|
||||
class ProfileMenuPresenter extends Presenter
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getOpenTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '<div class="dropdown-menu profile-dropdown-menu">' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getCloseTagWrapper()
|
||||
{
|
||||
return PHP_EOL . '</div>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithoutDropdownWrapper($item)
|
||||
{
|
||||
return '<a href="' . $item->getUrl() . '" class="dropdown-item">' . $item->getIcon() . ' ' . $item->title . '</a>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getActiveState(MenuItem $item)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getDividerWrapper()
|
||||
{
|
||||
return '<div class="dropdown-divider"></div>' . PHP_EOL;
|
||||
}
|
||||
|
||||
public function getMultiLevelDropdownWrapper($item)
|
||||
{
|
||||
return null;//$this->getMenuWithDropDownWrapper($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc }
|
||||
*/
|
||||
public function getMenuWithDropDownWrapper($item)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
namespace App\CMS\Shortcodes;
|
||||
|
||||
use App\Models\Widgets\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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load one widget from database
|
||||
*
|
||||
* @param $containerId
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all frequently used widgets
|
||||
*
|
||||
* Frequency of loaded widgets is counted only using direct loading, widgets displayed in widget areas are omitted
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new shortcode
|
||||
*
|
||||
* Initfrequently used widgets and if not presented yet - load desired widget specified as content of shortcode
|
||||
*
|
||||
* @param $shortcode
|
||||
* @param $containerId
|
||||
* @param $compiler
|
||||
* @param $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function register($shortcode, $containerId, $compiler, $name)
|
||||
{
|
||||
$this->initWidgets();
|
||||
|
||||
if (!isset(self::$widgets[$containerId])) {
|
||||
$this->loadWidget($containerId);
|
||||
}
|
||||
|
||||
return self::$widgets[$containerId];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\HtmlCode;
|
||||
|
||||
use App\CMS\Contracts\Widgets\PublicWidget;
|
||||
use App\CMS\Widgets\Contracts\WidgetRenderer;
|
||||
use App\CMS\Widgets\Exceptions\MissingParameterException;
|
||||
use App\Models\Widgets\Widget;
|
||||
|
||||
class HtmlCode implements PublicWidget
|
||||
{
|
||||
/**
|
||||
* Name getter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName()
|
||||
{
|
||||
return 'widgets/htmlCode.widgetName';
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDescription()
|
||||
{
|
||||
return 'widgets/htmlCode.widgetDescription';
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for presenter/renderer of this widget
|
||||
*
|
||||
* @return WidgetRenderer
|
||||
*/
|
||||
public static function getPresenter()
|
||||
{
|
||||
return Presenters\HtmlCode::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Widget $widget
|
||||
* @param \stdClass $data
|
||||
*
|
||||
* @return Widget
|
||||
* @throws MissingParameterException
|
||||
*/
|
||||
public static function save(Widget $widget, \stdClass $data)
|
||||
{
|
||||
if (!isset($data->code) || empty($data->code)) {
|
||||
throw new MissingParameterException('code');
|
||||
}
|
||||
|
||||
$widgetSettings = [
|
||||
'code' => $data->code,
|
||||
'containerClass' => isset($data->containerClass) ? $data->containerClass : ''
|
||||
];
|
||||
|
||||
$widget->settings = json_encode($widgetSettings);
|
||||
|
||||
return $widget;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\HtmlCode\Presenters;
|
||||
|
||||
use App\Models\Widgets\Widget;
|
||||
use App\Models\Widgets\WidgetType;
|
||||
use App\CMS\Contracts\Widgets\WidgetRenderer;
|
||||
|
||||
class HtmlCode implements WidgetRenderer
|
||||
{
|
||||
/**
|
||||
* Method used for displaying widget.
|
||||
*
|
||||
* This method renders some HTML code for displaying.
|
||||
*
|
||||
* @param Widget $widget
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function render(Widget $widget)
|
||||
{
|
||||
$settings = $widget->settings;
|
||||
$code = '
|
||||
<div class="html-code-widget ' . $widget->container_class . '">
|
||||
' . $settings->code . '
|
||||
</div>';
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form for creating new instance of widget
|
||||
*
|
||||
* @param WidgetType $type
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderAddForm(WidgetType $type)
|
||||
{
|
||||
return view('admin.widgets.htmlCode.new', [
|
||||
'type' => $type,
|
||||
'widget' => new Widget(),
|
||||
'settings' => new \stdClass()
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form for editing already existing widget
|
||||
*
|
||||
* @param Widget $widget
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderEditForm(Widget $widget)
|
||||
{
|
||||
$settings = json_decode($widget->settings);
|
||||
return view('admin.widgets.htmlCode.edit', ['widget' => $widget, 'settings' => $settings]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\Menu\Extensions;
|
||||
|
||||
use App\CMS\Widgets\Contracts\MenuExtensionHandler;
|
||||
|
||||
class URL implements MenuExtensionHandler {
|
||||
public function getPossibleValues()
|
||||
{
|
||||
return '*';
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return 'url';
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return trans('widgets/menu.extensionURL');
|
||||
}
|
||||
|
||||
public function getDescription()
|
||||
{
|
||||
return trans('widgets/menu.extensionURLDescription');
|
||||
}
|
||||
|
||||
public function getFormExtensionTemplate()
|
||||
{
|
||||
return 'admin.widgets.menu.extensions.url';
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
// TODO: Implement save() method.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\Menu;
|
||||
|
||||
use App\CMS\Contracts\Widgets\PublicWidget;
|
||||
use App\CMS\Widgets\Contracts\WidgetRenderer;
|
||||
use App\CMS\Widgets\Exceptions\MissingParameterException;
|
||||
use App\Models\Content\Content;
|
||||
use App\Models\Widgets\Widget;
|
||||
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
|
||||
|
||||
class Menu implements PublicWidget
|
||||
{
|
||||
/**
|
||||
* Name getter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getName()
|
||||
{
|
||||
return 'widgets/menu.widgetName';
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDescription()
|
||||
{
|
||||
return 'widgets/menu.widgetDescription';
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for presenter/renderer of this widget
|
||||
*
|
||||
* @return WidgetRenderer
|
||||
*/
|
||||
public static function getPresenter()
|
||||
{
|
||||
return Presenters\Menu::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \App\Models\Widget $widget
|
||||
* @param \stdClass $data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function save(Widget $widget, \stdClass $data)
|
||||
{
|
||||
if (!isset($data->settings) || empty($data->settings) || !json_decode($data->settings)) {
|
||||
throw new MissingParameterException('settings');
|
||||
}
|
||||
|
||||
$links = json_decode($data->settings);
|
||||
$pages = self::selectContentPages(array_keys((array)$links));
|
||||
|
||||
foreach ($links as $link) {
|
||||
if (!isset($pages[$link->id])) {
|
||||
unset($links->{$link->id});
|
||||
}
|
||||
}
|
||||
|
||||
$settings = [
|
||||
'links' => $links,
|
||||
'containerClass' => $data->containerClass
|
||||
];
|
||||
|
||||
$widget->settings = json_encode($settings);
|
||||
|
||||
return $widget;
|
||||
}
|
||||
|
||||
public static function selectContentPages($ids)
|
||||
{
|
||||
$allowedStatuses = [Content::STATUS_PUBLIC];
|
||||
|
||||
if (\Auth::user()) {
|
||||
$allowedStatuses[] = Content::STATUS_PROTECTED;
|
||||
}
|
||||
|
||||
$pages = Content::where('language', LaravelLocalization::getCurrentLocale())
|
||||
->whereIn('id', $ids)
|
||||
->whereIn('status', $allowedStatuses)
|
||||
->get();
|
||||
$used = [];
|
||||
foreach ($pages as $page) {
|
||||
$used[$page->id] = $page;
|
||||
}
|
||||
|
||||
return $used;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
namespace App\CMS\Widgets\Menu\Presenters;
|
||||
|
||||
use App\CMS\Contracts\Widgets\WidgetRenderer;
|
||||
use App\CMS\Widgets\Menu\Menu as WidgetMenu;
|
||||
use App\Models\Content\Content;
|
||||
use App\Models\Widgets\Widget;
|
||||
use App\Models\Widgets\WidgetType;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class Menu implements WidgetRenderer
|
||||
{
|
||||
/**
|
||||
* Method used for displaying widget.
|
||||
*
|
||||
* This method renders some HTML code for displaying.
|
||||
*
|
||||
* @param Widget $widget
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function render(Widget $widget)
|
||||
{
|
||||
$settings = $widget->settings;
|
||||
$links = (array)$settings->links;
|
||||
$pageIds = array_keys($links);
|
||||
|
||||
// get pages
|
||||
$pages = WidgetMenu::selectContentPages($pageIds);
|
||||
|
||||
// sort links using "order"
|
||||
uasort($links, function ($a, $b) {
|
||||
return $a->order - $b->order;
|
||||
});
|
||||
|
||||
$route = Request::route()
|
||||
->getName();
|
||||
$parameters = Route::current()
|
||||
->parameters();
|
||||
|
||||
$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])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$page = $pages[$pageId];
|
||||
$active = ($page->is_homepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
|
||||
$route = $page->is_homepage ? route('page.index') : route('page.content', ['url' => $page->url]);
|
||||
|
||||
$code .= '<li';
|
||||
if ($active) {
|
||||
$code .= ' class="is-active active"';
|
||||
}
|
||||
$code .= '><a href="' . $route . '">' . e($page->title) . '</a></li>';
|
||||
}
|
||||
|
||||
$code .= "</ul>";
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form for creating new instance of widget
|
||||
*
|
||||
* @param WidgetType $type
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderAddForm(WidgetType $type)
|
||||
{
|
||||
$extensions = App::make('registerMenuExtension')
|
||||
->get();
|
||||
|
||||
$widget = new Widget();
|
||||
$content = new Content();
|
||||
|
||||
// get list of all pages
|
||||
$pages = $content->getOverview()
|
||||
->get();
|
||||
|
||||
$widget->settingsObj = new \stdClass();
|
||||
$widget->settingsObj->links = new \stdClass();
|
||||
|
||||
return view('admin.widgets.menu.new', [
|
||||
'type' => $type,
|
||||
'widget' => $widget,
|
||||
'pages' => $pages,
|
||||
'extensions' => $extensions
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display form for editing already existing widget
|
||||
*
|
||||
* @param Widget $widget
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function renderEditForm(Widget $widget)
|
||||
{
|
||||
$content = new Content();
|
||||
|
||||
// get list of all pages
|
||||
$pages = $content->getOverview()
|
||||
->get();
|
||||
|
||||
// make object from JSON
|
||||
if (!isset($widget->settings->links)) {
|
||||
$links = new \stdClass();
|
||||
} else {
|
||||
$links = (array)$widget->settings->links;
|
||||
}
|
||||
|
||||
// sort links using "order"
|
||||
uasort($links, function ($a, $b) {
|
||||
return $a->order - $b->order;
|
||||
});
|
||||
|
||||
$widget->settings->links = (object)$links;
|
||||
|
||||
return view('admin.widgets.menu.edit', ['widget' => $widget, 'pages' => $pages]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user