Author SHA1 Message Date
Michal Kváček e262473f36 FEATURE #2042: refactorize widgets 2017-04-24 00:01:03 +02:00
Michal Kváček 4a5c9ab1e6 FEATURE #1831: add recaptcha module 2017-04-24 00:00:42 +02:00
Michal Kváček e41c589225 FEATURE: move recaptcha config into core application 2017-04-05 02:01:20 +02:00
Michal Kváček 870ca540c4 FEATURE: make content list in admin nicer 2017-04-05 01:40:47 +02:00
Michal Kváček 2e8f8dca1f Merge branch 'pragtenniscamp.eu' into dev 2017-03-24 01:51:02 +01:00
Michal Kváček 8167b151d5 FIX: upload all title photos into root directory 2017-03-24 01:38:23 +01:00
Michal Kváček ad8a6e3c61 FEATURE: add title photo to contact template and change background image 2017-03-23 08:06:02 +01:00
Michal Kváček 74f1501af6 Merge branch 'pragtenniscamp.eu' into dev 2017-03-23 01:34:06 +01:00
Michal Kváček 217d78f214 FIX: fix year in footer in binarity template 2017-03-23 01:11:43 +01:00
Michal Kváček 16532faa5b FEATURE: remove trainer team from homepage 2017-03-23 01:04:53 +01:00
Michal Kváček ead55a8165 FIX: fix comments overview 2017-03-23 01:01:26 +01:00
Michal Kváček e943120dc6 FIX: fix blog overview template 2017-03-23 00:52:51 +01:00
Michal Kváček dd978c05f7 FIX: fix blog overview template 2017-03-23 00:51:28 +01:00
Michal Kváček 348883603a FIX: fix blocked javascript with ad block 2017-03-23 00:43:59 +01:00
Michal Kváček 5de8e01d77 FIX: fix year in footer 2017-03-23 00:38:08 +01:00
Michal Kváček 5d623a1a62 FIX: fix typo in service provider name 2017-03-23 00:21:09 +01:00
Michal Kváček 69253693ce FEATURE: add shortcodes into binarity template 2017-03-23 00:19:05 +01:00
Michal Kváček 42066d4ae9 FIX: fix paginated results in root pages in content editor 2017-03-23 00:01:47 +01:00
Michal Kváček 52f39fda0c FIX: fix reference list 2017-03-22 23:51:39 +01:00
Michal Kváček 9cb4deecd4 FEATURE: add success message after sending e-mail from contact form 2017-03-13 21:55:56 +01:00
Michal Kváček fcd7651841 FEATURE: add template for email from contactform 2017-03-13 21:48:34 +01:00
Michal Kváček 09daba1dc1 FEATURE: style little bit contact form for pragtenniscamp.eu 2017-03-13 19:41:25 +01:00
Michal Kváček 66e5d649be FEATURE: make smaller line height in trainee team 2017-03-13 13:55:56 +01:00
Michal Kváček 78532a6832 FIX: fix typos in template 2017-03-13 13:50:26 +01:00
Michal Kváček 1f633c3281 FEATURE: add template for hotels 2017-03-13 13:27:49 +01:00
Michal Kváček 8658ea1d39 FEATURE: prepare hotels template 2017-03-13 12:08:45 +01:00
Michal Kváček ce58b325c8 FIX: fix latent bug in save pipeline - trim backslashes from handler name 2017-03-13 12:08:26 +01:00
Michal Kváček ed8e2565ff FIX: fix template edit 2017-03-13 11:48:32 +01:00
Michal Kváček 87af6a018c FEATURE #2351 @45m: minor UI tweaks, add error templates 2017-03-10 13:42:55 +01:00
Michal Kváček 0e2aecb529 FEATURE: add pipeline for saving also into prague-tennis-camp template 2017-03-10 09:52:31 +01:00
Michal Kváček 9bec808d38 FEATURE #2354 @2h30m: add pipeline for edit and create new content 2017-03-10 09:52:12 +01:00
Michal Kváček 55f9c0a679 FEATURE #2350 @1h: move beforeRender methods into pipeline 2017-03-09 00:09:26 +01:00
Michal Kváček 03ce64a731 FEATURE #2350: remove not-used functions from handlers 2017-03-09 00:09:03 +01:00
Michal Kváček 450000fadd FEATURE #2350 @2h: add pipeline for displaying content 2017-03-08 23:38:37 +01:00
Michal Kváček 44fb6b1be5 Merge branch 'praguetenniscamp.cz' into dev 2017-03-08 19:54:50 +01:00
Michal Kváček 09c87661d3 FEATURE: temporarily load trainees into all pages 2017-03-03 00:17:17 +01:00
Michal Kváček 0007425c86 FEATURE #2351 @10m: add template for photo as background on homepage 2017-03-03 00:16:10 +01:00
Michal Kváček 2a15f3eab5 FEATURE #2351 @30m: modify responsive version 2017-03-02 23:47:27 +01:00
Michal Kváček 57f9c21a43 FIX: fix saving address widget 2017-03-02 23:16:58 +01:00
Michal Kváček eff61a1481 FEATURE #2351 @3h: add colors 2017-03-02 23:16:42 +01:00
Michal Kváček 4128fcf88e FEATURE: move creating thumbnails into event listener 2017-03-02 10:33:45 +01:00
Michal Kváček 4353345b3e FEATURE: try to color template 2017-03-02 10:27:22 +01:00
Michal Kváček 455b9d6d4e FIX: fix creating widgets 2017-02-23 18:26:59 +01:00
Michal Kváček 77685b491e Merge some fix into praguetenniscamp.cz 2017-02-23 18:26:43 +01:00
Michal Kváček f90df0f4bc FIX: fix unassigning related files 2017-02-23 18:24:35 +01:00
Michal Kváček 93fc9316a4 FEATURE: add command for displaying info about currently set template 2017-02-23 18:23:59 +01:00
Michal Kváček 26854b7207 FIX: fix contact form widget 2017-02-23 18:23:30 +01:00
Michal Kváček 8db748089b FIX: fix unassigning related files 2017-02-23 18:23:06 +01:00
Michal Kváček 507e186713 FEATURE #2341 @4h: add basics for template 2017-02-23 18:22:33 +01:00
Michal Kváček 5132278ee1 FIX: fix installer 2017-02-22 02:33:43 +01:00
Michal Kváček c64f825886 FIX: fix saving 'viewed' column with updated_at 2017-02-22 01:46:13 +01:00
Michal Kváček f3b1951d25 FEATURE: cache most used SQL queries 2017-02-22 01:40:26 +01:00
Michal Kváček cad205960d Merge branch 'dobrotyzpece.cz' into dev 2017-02-22 01:17:29 +01:00
Michal Kváček 73e049e47d Merge branch 'binarity.cz' into refactoring 2017-02-22 01:16:42 +01:00
Michal Kváček 0ae3e4fe08 FEATURE: improve little bit update script 2017-02-11 01:24:28 +01:00
Michal Kváček 28addf5e33 FIX: fix typos 2017-02-10 14:20:49 +01:00
Michal Kváček d5a33b382e Merge branch 'refactoring' into binarity.cz 2017-02-10 14:01:49 +01:00
Michal Kváček 2fdec0a65f FIX: add dependencies into bower.json and package.json 2017-02-10 14:01:37 +01:00
Michal Kváček 6fb6aef199 Merge branch 'refactoring' into binarity.cz 2017-02-10 13:49:36 +01:00
Michal Kváček f69b8f39ad FEATURE: rename alias in database 2017-02-10 13:49:17 +01:00
Michal Kváček 35bda2828c FEATURE: merge template namespace and module alias 2017-02-10 13:45:41 +01:00
Michal Kváček bda659b910 FIX: fix article detail 2017-02-10 13:45:23 +01:00
Michal Kváček c8ec9c4eeb Merge branch 'refactoring' into binarity.cz 2017-02-10 11:41:40 +01:00
Michal Kváček 9451357e02 FIX: fix registering template paths 2017-02-10 11:41:17 +01:00
Michal Kváček 727e449ebc FIX: fix path to blog templates in binarity template 2017-02-10 11:41:03 +01:00
Michal Kváček b5425423d6 Merge branch 'refactoring' into binarity.cz 2017-02-10 02:49:20 +01:00
Michal Kváček 66e78aff6a FIX: fix content edit 2017-02-10 02:49:14 +01:00
Michal Kváček 497ff1b96d FIX: fix few minor bugs 2017-02-10 02:48:13 +01:00
Michal Kváček c429024a54 FIX: fix typo in template 2017-02-10 02:27:08 +01:00
Michal Kváček 0778a1d30c FIX: fix template handler according to refactoring 2017-02-10 02:24:38 +01:00
Michal Kváček 3748d00c2f FEATURE: hide user name when empty 2017-02-10 02:19:44 +01:00
Michal Kváček a525d9c085 REFACTORING: delete old admin assets 2017-02-10 02:16:35 +01:00
Michal Kváček dff8dcf565 FIX: fix typo in content search handler 2017-02-10 02:15:50 +01:00
Michal Kváček 0d22a14604 FEATURE: add scripts and styles into gulpfile 2017-02-10 02:13:03 +01:00
Michal Kváček 724478d0c9 Merge branch 'refactoring' into elixir 2017-02-09 23:42:23 +01:00
Michal Kváček 0ba0d1c15d FIX: fix few minor bugs 2017-02-09 23:42:07 +01:00
Michal Kváček 9593b6502e FIX: fix file manager 2017-02-09 23:25:21 +01:00
Michal Kváček e53283da65 FIX: fix logging 2017-02-09 23:25:08 +01:00
Michal Kváček f0d1cb8020 FIX: add middleware for queuing cookies 2017-02-09 23:24:50 +01:00
Michal Kváček 9076f81185 FEATURE: add widget for social buttons 2017-02-09 23:24:30 +01:00
Michal Kváček b7d4ab9515 FIX: lots of bugfixes, sorry for ugly commit 2017-02-09 23:10:11 +01:00
Michal Kváček 2b98c60d2a FIX #2228: change font from Lato to Open Sans 2017-02-03 01:32:57 +01:00
Michal Kváček 99ed8806da REFACTORING #2039 @1h: clean a little bit file manager 2016-11-28 01:46:05 +01:00
Michal Kváček d0fbce13fb REFACTORING #1880 @15m: remove custom fields 2016-11-23 03:21:23 +01:00
Michal Kváček 675aec669b REFACTORING #1880 @40m: move creating new directory into interaction 2016-11-23 01:30:28 +01:00
Michal Kváček ca718a5efe Merge branch 'dev' into refactoring 2016-11-23 01:05:22 +01:00
Michal Kváček 3aabb8fa7b REFACTORING #1880 @20m: move action log logic into repository 2016-11-23 01:03:37 +01:00
Michal Kváček 2fffea39fa FIX: fix content observer - ignore viewed 2016-11-23 00:49:55 +01:00
Michal Kvacek 7584491ff5 FIX: fix html widget 2016-11-21 11:16:44 +01:00
Michal Kvacek 84b2902613 FIX: fix one page menu widget 2016-11-21 11:13:39 +01:00
Michal Kvacek 2d6be0cb2e Merge branch 'dobrotyzpece.cz' of binarity.cz:/opt/git/internal/cms/minicms into dobrotyzpece.cz 2016-11-21 11:09:38 +01:00
Michal Kváček e6c02617e6 Merge branch 'dev' into dobrotyzpece.cz 2016-11-21 11:02:34 +01:00
root 0b56b41c3c Merge remote-tracking branch 'origin/dev' into dobrotyzpece.cz 2016-11-21 09:38:12 +01:00
Peter Hrdlica f89e11b5fb FEATURE: dobrotyzpece stylings 2016-11-03 22:06:55 +01:00
Michal Kváček 785168ecc2 FEATURE: somehow glued Elixir and SASS. Still not even nearly finished, still really experimental 2016-10-27 11:26:15 +02:00
Michal Kváček 9f430cee11 FEATURE #1933 @1h: add basic SASS structure and configure gulp/elixir 2016-10-26 03:31:20 +02:00
Michal Kváček 785387b796 FIX: fix gallery handler 2016-10-25 20:13:46 +02:00
Michal Kváček f940930c66 FEATURE: improve logging 2016-10-25 20:13:34 +02:00
Michal Kváček 8cb06bf641 REFACTORING #1880 @1h: move content actions into interactions 2016-10-25 20:13:12 +02:00
Michal Kváček 000352052d FEATURE: make nicer URL uniqueness check 2016-10-25 20:11:58 +02:00
Michal Kváček 988f153d9f FEATURE: add line breaks into diff 2016-10-25 19:55:07 +02:00
Michal Kváček 6dd452317b Merge branch 'dev' into refactoring 2016-10-25 19:16:18 +02:00
Michal Kváček 34feaac2ac FIX: fix editing menu widget 2016-10-25 18:04:07 +02:00
Michal Kváček e25f47a511 TESTING #1931 @1h: add few tests 2016-10-25 16:51:11 +02:00
Michal Kváček cc999dd24e REFACTORING #1880 @4h30m: another ugly refactoring commit 2016-10-25 16:50:04 +02:00
Michal Kváček 28f67ffe3c REFACTORING: another ugly commit full of refactored code 2016-10-19 00:28:44 +02:00
Michal Kváček 4f6a006ad9 FEATURE: add another repositories 2016-10-18 22:35:06 +02:00
Michal Kváček 662700b4f2 REFACTORING: move part of content business logic into repository 2016-10-18 15:36:26 +02:00
Michal Kváček eabbf48ee0 REFACTORING: move content update and create logic into separate interactions 2016-10-17 02:52:30 +02:00
Michal Kváček 6ec692bd1c FIX: fix uploading file without directory 2016-10-17 01:10:04 +02:00
Michal Kváček aa0ef7ccc6 REFACTORING: remove gravatar from user model 2016-10-17 01:07:25 +02:00
Michal Kváček e26e6fd460 FEATURE: move bussiness logic out of models 2016-10-17 01:05:20 +02:00
Michal Kváček 2ded2924a1 FEATURE: change directory structure 2016-10-17 00:07:21 +02:00
Michal Kváček 87f1920373 FEATURE: temporarily display large image as thumbnail in reference detail 2016-10-13 01:14:24 +02:00
Michal Kváček b7f911c9b8 FIX: fix encoding in translations 2016-10-13 01:06:08 +02:00
Michal Kváček 84aea5c847 FEATURE: add missing czech translations 2016-10-13 00:58:04 +02:00
Michal Kváček 98fc287f10 FIX: remove comments overview from submenu 2016-10-12 21:24:27 +02:00
Michal Kváček 686edf1c6f FIX: fix error on comments overview when article was deleted 2016-10-12 21:22:28 +02:00
578 changed files with 33715 additions and 117918 deletions
+1 -1
View File
@@ -16,4 +16,4 @@ MAIL_PASSWORD=
SITE_URL=/
UPLOAD_URL=/public/uploads
THUMBNAILS_URL=/uploads/thumbnails
THUMBNAIL_URL=/public/uploads/thumbnails
+6
View File
@@ -27,3 +27,9 @@
# meta information created by installer
.install
/node_modules/
/public/css/
/public/js
/public/fonts
/bower_components
.sass-cache
@@ -0,0 +1,18 @@
<?php
namespace App\CMS\Contracts\Content;
use App\Http\Requests\Request;
use App\Models\Content\Content;
interface AdvancedContentModifier {
/**
* 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);
}
@@ -1,7 +1,7 @@
<?php
namespace App\Handlers\Contracts;
namespace App\CMS\Contracts\Content;
use App\Models\Content;
use App\Models\Content\Content;
/**
* Interface ContentTitles
@@ -9,7 +9,7 @@ use App\Models\Content;
* Classes which implement this interface get the ability to rewrite default text on edit/create/overview of content
* page.
*
* @package App\Handlers\Contracts
* @package App\CMS\Handlers\Contracts
*/
interface ContentTitles
{
@@ -0,0 +1,16 @@
<?php
namespace App\CMS\Contracts\Content\DisplayPipeline;
use App\Models\Content\Content;
interface Pipeline {
/**
* Add new process into pipeline
*
* @param string $process
*
* @return void
*/
function add($process);
function run(Content $page);
}
@@ -0,0 +1,15 @@
<?php
namespace App\CMS\Contracts\Content\DisplayPipeline;
use App\Models\Content\Content;
interface Process {
/**
* Process and modify given page
*
* @param Content $page
*
* @return mixed
*/
function handle(Content & $page);
}
@@ -1,5 +1,5 @@
<?php
namespace App\Handlers\Contracts;
namespace App\CMS\Handlers\Contracts;
interface HistoryHandler
{
@@ -0,0 +1,25 @@
<?php
namespace App\CMS\Contracts\Content\SavePipeline;
use App\Models\Content\Content;
interface Pipeline {
/**
* Add new process into pipeline
*
* @param string $process
*
* @return void
*/
function add($process);
/**
* Save content page
*
* @param Content $page
* @param array $input
*
* @return Content
*/
function run(Content & $page, array $input);
}
@@ -0,0 +1,16 @@
<?php
namespace App\CMS\Contracts\Content\SavePipeline;
use App\Models\Content\Content;
interface Process {
/**
* Process and modify given page
*
* @param Content $page
* @param array $input
*
* @return mixed
*/
function handle(Content & $page, array & $input);
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\CMS\Contracts;
interface Interaction {
/**
* Perform given action
*
* @param $data array input data
* @param $parameters array parameters
*
* @return mixed
*/
public function handle($data, $parameters);
/**
* @param $data array input data
*
* @return array
*/
public function getValidationRules($data = []);
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace App\CMS\Contracts\Modules;
use App\Http\Requests\Request;
use App\Models\Content\Content;
interface AppHandler extends BaseModuleHandler
{
public static function getHistoryHandler();
/**
* 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();
}
@@ -1,5 +1,5 @@
<?php
namespace App\Handlers\Contracts;
namespace App\CMS\Contracts\Modules;
use App\Models\User;
@@ -15,11 +15,4 @@ interface BaseModuleHandler
*/
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,23 @@
<?php
namespace App\CMS\Contracts\Modules;
use App\Models\Module;
interface InstallableModule {
/**
* 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();
/**
* Uninstalls module
*
* @param Module $module
*
* @return mixed
*/
public static function uninstall(Module $module);
}
@@ -0,0 +1,30 @@
<?php
namespace App\CMS\Contracts\Modules;
use App\Http\Requests\Request;
use App\Models\Content\Content;
/**
* Interface TemplateHandler
*
* Inerface used for registering template into CMS core.
*
* @package App\CMS\Handlers\Contracts
*/
interface TemplateHandler extends BaseModuleHandler
{
/**
* 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();
}
@@ -0,0 +1,7 @@
<?php
namespace App\CMS\Contracts\Repositories;
interface BaseRepository {
public function getOne($id = null);
public function all();
}
@@ -0,0 +1,15 @@
<?php
namespace App\CMS\Contracts\Repositories;
interface Content extends BaseRepository
{
const STATUS_DRAFT = 'draft';
const STATUS_PROTECTED = 'protected';
const STATUS_PUBLIC = 'public';
public function getOverview($handler = null, $statuses = null);
public function getHomepage();
public function getByURL($url);
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\CMS\Contracts\Repositories;
use App\Models\Content\Content as ContentModel;
use App\Models\Module as ModuleModel;
interface Module extends BaseRepository
{
public function getCreateContentTitle(ModuleModel $module);
public function getUpdateContentTitle(ModuleModel $module, ContentModel $content = null);
public function getOverviewTitle(ModuleModel $module);
public function getByHandler($handler);
public function call(ModuleModel $module, $method, $parameters = []);
public function callOnString($moduleHandler, $method, $parameters = []);
}
@@ -0,0 +1,21 @@
<?php
namespace App\CMS\Contracts\Repositories;
use App\Models\Module as ModuleModel;
use App\Models\Templates\Template as TemplateModel;
interface Template
{
const EDITED_TEMPLATES_DIRECTORY = 'custom';
const ASSETS_DIRECTORY = 'assets';
const MODULES_DIRECTORY = 'modules';
const TEMPLATE_SUFFIX = '.blade.php';
const CUSTOM_EDIT_DIRECTORY = 1;
const ORIGINAL_DIRECTORY = 2;
public function setModel(TemplateModel $model);
public function getPathToTemplate($mode = null);
public function getForModule(ModuleModel $module);
}
@@ -1,5 +1,5 @@
<?php
namespace App\Handlers\Contracts;
namespace App\CMS\Handlers\Contracts;
interface SearchHandler {
public function getId();
@@ -1,5 +1,5 @@
<?php
namespace App\Handlers\Contracts;
namespace App\CMS\Handlers\Contracts;
interface SearchPresenterHandler
{
@@ -1,5 +1,5 @@
<?php
namespace App\Widgets\Contracts;
namespace App\CMS\Contracts\Widgets;
interface AdminDashboardWidget extends PublicWidget
{
@@ -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();
}
@@ -1,5 +1,5 @@
<?php
namespace App\Widgets\Contracts;
namespace App\CMS\Widgets\Contracts;
interface MenuExtensionHandler {
@@ -1,8 +1,8 @@
<?php
namespace App\Widgets\Contracts;
namespace App\CMS\Contracts\Widgets;
use App\Http\Requests\Request;
use App\Models\Widget;
use App\Models\Widgets\Widget;
interface PublicWidget
{
@@ -28,22 +28,11 @@ interface PublicWidget
public static function getPresenter();
/**
* @param Widget $widget
* @param \stdClass $data
* Get widget settings for saving into database
*
* @return mixed
*/
public static function save(Widget $widget, \stdClass $data);
/**
* Function for installing given widget
* @param Request $request
*
* @return mixed
* @return array
*/
public static function install();
/**
* Function for uninstalling widget
*/
public static function uninstall();
public static function save(Request $request);
}
@@ -1,8 +1,8 @@
<?php
namespace App\Widgets\Contracts;
namespace App\CMS\Contracts\Widgets;
use App\Models\Widget;
use App\Models\WidgetType;
use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetType;
interface WidgetRenderer
{
@@ -11,7 +11,7 @@ interface WidgetRenderer
*
* This method renders some HTML code for displaying.
*
* @param object $settings
* @param Widget $settings
*
* @return mixed
*/
@@ -1,5 +1,5 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\ActionLogType;
@@ -1,7 +1,7 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\ActionLogType;
use App\Models\ActionLog\ActionLogType;
class ActionLogTypesForLogger extends BaseEnumeration
{
@@ -1,7 +1,7 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Enumerations\Exceptions\EnumerationExistsException;
use App\CMS\Exceptions\Enumerations\EnumerationExistsException;
abstract class BaseEnumeration
{
@@ -1,7 +1,8 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\Content;
use App\CMS\Contracts\Repositories\Content;
class ContentStatuses extends BaseEnumeration
{
@@ -1,5 +1,5 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\Module;
@@ -1,5 +1,5 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\Module;
@@ -1,7 +1,8 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\Module;
use Illuminate\Support\Facades\Cache;
class ModulesHandlerToId extends BaseEnumeration
{
@@ -12,7 +13,9 @@ class ModulesHandlerToId extends BaseEnumeration
*/
protected static function init()
{
$modules = Module::all(['handler', 'id']);
$modules = Cache::rememberForever('module-handler-to-id-enumeration', function () {
return Module::all(['handler', 'id']);
});
foreach ($modules as $module) {
self::push($module->handler, $module->id);
@@ -6,9 +6,9 @@
* Time: 10:33
*/
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\TemplatePath;
use App\Models\Templates\TemplatePath;
class TemplatePaths extends BaseEnumeration
{
@@ -6,9 +6,9 @@
* Time: 10:33
*/
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\TemplatePath;
use App\Models\Templates\TemplatePath;
class TemplatePathsHumanReadable extends BaseEnumeration
{
@@ -6,9 +6,9 @@
* Time: 10:33
*/
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\TemplatePath;
use App\Models\Templates\TemplatePath;
class TemplatePathsHumanReadableRootOnly extends BaseEnumeration
{
@@ -6,9 +6,9 @@
* Time: 15:50
*/
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\Template;
use App\Models\Templates\Template;
class Templates extends BaseEnumeration
{
@@ -1,5 +1,5 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\User;
@@ -6,7 +6,7 @@
* Time: 23:20
*/
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\User;
@@ -1,7 +1,7 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\WidgetType;
use App\Models\Widgets\WidgetType;
class WidgetTypes extends BaseEnumeration
{
@@ -1,7 +1,7 @@
<?php
namespace App\Enumerations;
namespace App\CMS\Enumerations;
use App\Models\WidgetType;
use App\Models\Widgets\WidgetType;
class WidgetTypesWithHandlers extends BaseEnumeration
{
@@ -1,5 +1,5 @@
<?php
namespace App\Enumerations\Exceptions;
namespace App\CMS\Exceptions\Enumerations;
class EnumerationExistsException extends \Exception {
@@ -0,0 +1,6 @@
<?php
namespace App\CMS\Exceptions\FileManager;
class SubdirectoryExistsInDirectory extends \Exception
{
}
@@ -0,0 +1,19 @@
<?php
namespace App\CMS\Exceptions\Validation;
use Exception;
class ValidationFailedException extends \Exception {
protected $validator;
public function __construct($validator, $message = null, $code = null, Exception $previous = null)
{
parent::__construct($message, $code, $previous);
$this->validator = $validator;
}
public function getValidator(){
return $this->validator;
}
}
@@ -1,5 +1,5 @@
<?php
namespace App\Widgets\Exceptions;
namespace App\CMS\Widgets\Exceptions;
use Exception;
@@ -1,5 +1,5 @@
<?php
namespace App\Widgets\Exceptions;
namespace App\CMS\Widgets\Exceptions;
use Exception;
@@ -1,10 +1,9 @@
<?php
namespace App\Handlers;
namespace App\CMS\Handlers;
use App\Enumerations\TemplatePathsHumanReadableRootOnly;
use App\Enumerations\WidgetTypes;
use App\Handlers\Contracts\AppHandler;
use App\Handlers\Contracts\BaseModuleHandler;
use App\CMS\Contracts\Modules\BaseModuleHandler;
use App\CMS\Enumerations\TemplatePathsHumanReadableRootOnly;
use App\CMS\Enumerations\WidgetTypes;
use App\Models\User;
abstract class BaseHandler implements BaseModuleHandler
@@ -35,7 +34,6 @@ abstract class BaseHandler implements BaseModuleHandler
* 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']);
@@ -97,22 +95,11 @@ abstract class BaseHandler implements BaseModuleHandler
}, 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']);
@@ -1,9 +1,9 @@
<?php
namespace App\Handlers;
namespace App\CMS\Handlers;
use App\Handlers\Contracts\AppHandler;
use App\CMS\Contracts\Modules\AppHandler;
use App\Http\Controllers\Controller;
use App\Models\Content;
use App\Models\Content\Content;
/**
* Class Handler
@@ -11,38 +11,15 @@ use App\Models\Content;
* 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\Handlers
* @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 [
@@ -64,16 +41,7 @@ abstract class Handler extends BaseHandler implements AppHandler
'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();
@@ -1,9 +1,9 @@
<?php
namespace App\Handlers;
namespace App\CMS\Handlers;
use App\Enumerations\ContentStatuses;
use App\Handlers\Contracts\HistoryHandler;
use App\Helpers\Differ;
use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Handlers\Contracts\HistoryHandler;
use App\CMS\Helpers\Differ;
class History implements HistoryHandler
{
@@ -43,7 +43,7 @@ class History implements HistoryHandler
'to' => $statuses[$changeset->new_value]
]);
break;
case 'is_homepage':
case 'isHomepage':
return trans('admin/history.setupAsHomepage');
break;
default:
+39
View File
@@ -0,0 +1,39 @@
<?php
namespace App\Cms\Handlers\Interactions;
use App\CMS\Contracts\Interaction as InteractionContract;
use App\CMS\Exceptions\Validation\ValidationFailedException;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Validator;
class Interaction
{
/**
* Handle interaction with application
*
* @param string $interactionClass
* @param array $data
* @param array $extraParameters
*
* @return mixed
* @throws ValidationFailedException
*/
public static function handle($interactionClass, $data, ...$extraParameters)
{
/**
* @var $interaction InteractionContract
*/
$interaction = app($interactionClass);
// validate interaction
$validator = Validator::make($data, $interaction->getValidationRules($extraParameters));
if ($validator->fails()) {
throw new ValidationFailedException($validator);
}
// handle it
return $interaction->handle($data, $extraParameters);
}
}
@@ -1,5 +1,5 @@
<?php
namespace App\Handlers\Registrators\Items;
namespace App\CMS\Handlers\Registrators\Items;
class SettingExtension
{
@@ -1,7 +1,7 @@
<?php
namespace App\Handlers\Registrators;
namespace App\CMS\Handlers\Registrators;
use App\Widgets\Contracts\MenuExtensionHandler;
use App\CMS\Widgets\Contracts\MenuExtensionHandler;
class MenuExtensionRegistrator {
@@ -1,10 +1,10 @@
<?php
namespace App\Handlers\Registrators;
namespace App\CMS\Handlers\Registrators;
use App\Enumerations\Exceptions\EnumerationExistsException;
use App\Handlers\Contracts\SearchHandler;
use App\Handlers\Contracts\SearchPresenterHandler;
use App\Handlers\Registrators\Items\SearchEngine;
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
@@ -1,8 +1,8 @@
<?php
namespace App\Handlers\Registrators;
namespace App\CMS\Handlers\Registrators;
use App\Enumerations\Exceptions\EnumerationExistsException;
use App\Handlers\Registrators\Items\SettingExtension;
use App\CMS\Enumerations\Exceptions\EnumerationExistsException;
use App\CMS\Handlers\Registrators\Items\SettingExtension;
class SettingsExtensionRegistrator
{
@@ -1,10 +1,11 @@
<?php
namespace App\Handlers\Registrators;
namespace App\CMS\Handlers\Registrators;
use App\Enumerations\TemplatePaths;
use App\Enumerations\Templates;
use App\Models\Template;
use App\Models\TemplatePath;
use App\CMS\Contracts\Repositories\Template;
use App\CMS\Enumerations\TemplatePaths;
use App\CMS\Enumerations\Templates;
use App\Models\Templates\Template as TemplateModel;
use App\Models\Templates\TemplatePath;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Symfony\Component\Process\Exception\InvalidArgumentException;
@@ -134,7 +135,10 @@ class TemplateRegistrator
*/
protected function relativePath($directory)
{
return trim(str_replace(base_path(), '', $directory), '/');
$directory = str_replace('/', DIRECTORY_SEPARATOR, $directory);
$directory = str_replace('\\', DIRECTORY_SEPARATOR, $directory);
return trim(str_replace(base_path(), '', $directory), '\\/');
}
/**
@@ -145,6 +149,10 @@ class TemplateRegistrator
*/
protected function scanForSubdirectories($directory, $name)
{
if (!is_dir($directory)) {
return;
}
$directories = File::directories($directory);
foreach ($directories as $dir) {
@@ -194,7 +202,7 @@ class TemplateRegistrator
* @param $path
* @param $templatePathId
*
* @throws \App\Enumerations\Exceptions\EnumerationExistsException
* @throws \App\CMS\Enumerations\Exceptions\EnumerationExistsException
*/
protected function registerTemplates($path, $templatePathId)
{
@@ -222,7 +230,7 @@ class TemplateRegistrator
];
// save template into database
$newTemplate = Template::create($params);
$newTemplate = TemplateModel::create($params);
// push template into enumeration - so it will not be registered again
Templates::push($newTemplate->id, $templateName);
@@ -238,7 +246,7 @@ class TemplateRegistrator
* @param null $parent
*
* @return mixed|null
* @throws \App\Enumerations\Exceptions\EnumerationExistsException
* @throws \App\CMS\Enumerations\Exceptions\EnumerationExistsException
*/
protected function saveTemplatePath($path, $name, $parent = null)
{
@@ -295,12 +303,17 @@ class TemplateRegistrator
*
* @return string
*/
private function getTemplateName($template)
protected function getTemplateName($template)
{
$templateName = str_replace($this->registeredPath . DIRECTORY_SEPARATOR, '', $template);
$templateName = $template;
$templateName = str_replace($this->registeredPath, '', $templateName);
$templateName = str_replace('\\', DIRECTORY_SEPARATOR, $templateName);
$templateName = str_replace('/', DIRECTORY_SEPARATOR, $templateName);
$templateName = str_replace(DIRECTORY_SEPARATOR, '.', $templateName);
$templateName = str_replace(Template::TEMPLATE_SUFFIX, '', $templateName);
$templateName = preg_replace('/\.{2,}/', '.', $templateName);
return $this->namespace . $templateName;
return $this->namespace . trim($templateName, '.');
}
}
@@ -1,14 +1,13 @@
<?php
namespace App\Handlers\Registrators;
namespace App\CMS\Handlers\Registrators;
use App\Enumerations\WidgetTypesWithHandlers;
use App\Models\WidgetType;
use App\CMS\Enumerations\WidgetTypesWithHandlers;
use App\Models\Widgets\WidgetType;
class WidgetRegistrator
{
protected $registeredWidgets = [];
/**
* Method used for registering new widgets
*
@@ -51,7 +50,9 @@ class WidgetRegistrator
]);
// install widget (if neccessary)
call_user_func($classname . '::install');
if (is_callable([$classname, 'install'])) {
call_user_func($classname . '::install');
}
}
}
}
@@ -1,7 +1,7 @@
<?php
namespace App\Handlers\Search;
namespace App\CMS\Handlers\Search;
use App\Models\Content as ContentModel;
use App\Models\Content\Content as ContentModel;
class Content extends Search
{
@@ -16,9 +16,9 @@ class Content extends Search
{
$token = $this->tokenize($term);
return ContentModel::where('content', 'LIKE', $token)
->orWhere('meta_description', 'LIKE', $token)
->orWhere('meta_keywords', 'LIKE', $token)
return ContentModel::where('pageContent', 'LIKE', $token)
->orWhere('metaDescription', 'LIKE', $token)
->orWhere('metaKeywords', 'LIKE', $token)
->orWhere('title', 'LIKE', $token)
->orWhere('url', 'LIKE', $token)
->get();
@@ -1,7 +1,7 @@
<?php
namespace App\Handlers\Search;
namespace App\CMS\Handlers\Search;
use App\Models\File;
use App\Models\FileManager\File;
class Files extends Search
{
@@ -1,8 +1,8 @@
<?php
namespace App\Handlers\Search\Presenters;
namespace App\CMS\Handlers\Search\Presenters;
use App\Enumerations\ContentStatuses;
use App\Handlers\Contracts\SearchPresenterHandler;
use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
class AdminContent implements SearchPresenterHandler
{
@@ -1,7 +1,7 @@
<?php
namespace App\Handlers\Search\Presenters;
namespace App\CMS\Handlers\Search\Presenters;
use App\Handlers\Contracts\SearchPresenterHandler;
use App\CMS\Handlers\Contracts\SearchPresenterHandler;
class AdminFiles implements SearchPresenterHandler
{
@@ -1,7 +1,7 @@
<?php
namespace App\Handlers\Search;
namespace App\CMS\Handlers\Search;
use App\Handlers\Contracts\SearchHandler;
use App\CMS\Handlers\Contracts\SearchHandler;
use Symfony\Component\Process\Exception\InvalidArgumentException;
abstract class Search implements SearchHandler
+99
View File
@@ -0,0 +1,99 @@
<?php
namespace App\CMS\Helpers;
use App\CMS\Contracts\Modules\TemplateHandler;
use App\Models\Content\Content;
use App\Models\Module;
use App\Models\User;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Cache;
class CurrentTemplate implements TemplateHandler
{
protected static $template;
protected static $initialized = false;
/**
* Getter for currently set template
* @return Module
* @throws \ErrorException
*/
public static function get()
{
if (!self::$initialized) {
self::$template = Cache::rememberForever('current-template', function () {
$template = Module::where('is_template', true)
->where('enabled', true)
->first();
// todo remove after adding $casts into Module model
if ($template) {
$template->module_settings = json_decode($template->module_settings);
}
return $template;
});
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;
}
/**
* 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)
{
call_user_func_array([self::handler(), 'registerAdminMenu'], [$user]);
}
/**
* 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()
{
return call_user_func([self::handler(), 'getPublicTemplatePaths']);
}
}
@@ -1,5 +1,5 @@
<?php
namespace App\Helpers;
namespace App\CMS\Helpers;
class Date
{
@@ -1,5 +1,5 @@
<?php
namespace App\Helpers;
namespace App\CMS\Helpers;
/*
Paul's Simple Differ Algorithm v 0.1
@@ -1,7 +1,7 @@
<?php
namespace App\Helpers;
namespace App\CMS\Helpers;
use App\Models\File;
use App\Models\FileManager\File;
class FileManager
{
@@ -17,7 +17,7 @@ class FileManager
switch ($type) {
case 'image':
$url = Template::thumbnail($file->filename);
$url = Path::thumbnail($file->filename);
return '<img src="' . $url . '" alt="' . $file->description . '" />';
break;
@@ -98,7 +98,7 @@ class FileManager
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>';
return '<iframe src = "'.asset('resources/assets/admin/js/viewerJs/').'/#'.Path::upload($file->filename).'" style="width: 100%; height: 50em" allowfullscreen webkitallowfullscreen></iframe>';
break;
default:
return self::getPreview($file);
@@ -1,5 +1,5 @@
<?php
namespace App\Helpers;
namespace App\CMS\Helpers;
class Gravatar
{
@@ -1,8 +1,8 @@
<?php
namespace App\Helpers;
namespace App\CMS\Helpers;
use App\Handlers\Contracts\AppHandler;
use App\Models\Content;
use App\CMS\Handlers\Contracts\AppHandler;
use App\Models\Content\Content;
use Webwizo\Shortcodes\Facades\Shortcode;
/**
@@ -10,7 +10,7 @@ use Webwizo\Shortcodes\Facades\Shortcode;
*
* Simple class for rendering page for visitor
*
* @package App\Helpers
* @package App\CMS\Helpers
*/
class PageRenderer
{
@@ -23,19 +23,13 @@ class PageRenderer
*/
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);
$handler = new $page->moduleHandler;
// render page
return $handler->render($page, $parameters);
@@ -1,48 +1,11 @@
<?php
namespace App\Helpers;
namespace App\CMS\Helpers;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Process\Exception\InvalidArgumentException;
class Template
class Path
{
/**
* 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;
}
/**
* Get URL to uploaded file
*
@@ -95,25 +58,4 @@ class Template
return config('app.url') . '/assets/' . config('app.theme') . '/' . $path;
}
/**
* 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);
}
}
+49
View File
@@ -0,0 +1,49 @@
<?php
namespace App\CMS\Helpers;
use App\Models\FileManager\Directory;
use App\Models\FileManager\File;
class RootDirectory
{
protected static $directory;
/**
* Create root directory
*
* @return Directory
*/
protected static function create()
{
$directory = new Directory();
$directory->name = 'Root';
$directory->is_root = true;
$directory->save();
Directory::whereNull('parent_id')
->where('is_root', false)
->update(['parent_id' => $directory->id]);
File::where('directory_id', null)
->update(['directory_id' => $directory->id]);
return $directory;
}
/**
* Get root directory
*
* @return Directory
*/
public static function get()
{
self::$directory = Directory::where('is_root', true)
->first();
if (is_null(self::$directory)) {
self::$directory = self::create();
}
return self::$directory;
}
}
@@ -1,15 +1,16 @@
<?php
namespace App\Helpers;
namespace App\CMS\Helpers;
use App\Models\Settings as SettingsModel;
use Illuminate\Support\Facades\Cache;
/**
* Class Settings
*
* Helper class for easier obtaining system settings
*
* @package App\Helpers
* @package App\CMS\Helpers
*/
class Settings
{
@@ -76,8 +77,10 @@ class Settings
private static function init()
{
if (!self::$initialized) {
$model = new SettingsModel();
self::$settings = $model->getAll();
self::$settings = Cache::remember('settings', config('cache.settingCacheLifetime'), function () {
$model = new SettingsModel();
return $model->getAll();
});
}
}
}
+49
View File
@@ -0,0 +1,49 @@
<?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
*
* @param bool $throwExceptions
*
* @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;
}
}
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\CMS\Helpers\Traits;
use Carbon\Carbon;
/**
* Class Nullable
*
* @package App\CMS\Helpers\Traits
*/
trait Nullable {
/**
* Get null or parsed date
*
* @param $date
*
* @return null|string
*/
public function nullableDate($date) {
return empty($date) ? null : Carbon::parse($date)->toDateTimeString();
}
/**
* Get null or input value
*
* @param $string
*
* @return null
*/
public function nullable($string) {
return empty($string) ? null : $string;
}
}
+18
View File
@@ -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_string($widget->settings)) {
$widget->settings = json_decode($widget->settings);
}
$presenter = call_user_func([$handler, 'getPresenter']);
return call_user_func([$presenter, 'render'], $widget);
}
}
@@ -1,7 +1,10 @@
<?php
namespace App\Helpers;
use App\Models\WidgetArea;
namespace App\CMS\Helpers;
use App\CMS\Repositories\Widgets\WidgetArea as WidgetAreaRepository;
use App\Models\Widgets\WidgetArea;
use Illuminate\Support\Facades\Cache;
class WidgetAreas
{
@@ -14,37 +17,40 @@ class WidgetAreas
protected static function saveRenderedWidgetArea($widgets)
{
foreach ($widgets as $widget) {
if (!isset(self::$widgetAreas[$widget->widget_area_code]))
if (!isset(self::$widgetAreas[$widget->widget_area_code])) {
self::$widgetAreas[$widget->widget_area_code] = '';
}
$handler = $widget->widget_type_handler;
$widget->settings = json_decode($widget->settings);
$presenter = call_user_func([$handler, 'getPresenter']);
self::$widgetAreas[$widget->widget_area_code] .= call_user_func([$presenter, 'render'], $widget);
self::$widgetAreas[$widget->widget_area_code] .= Widget::render($widget);
}
}
protected static function loadWidgetArea($uniqueCode)
{
$widgetArea = new WidgetArea();
$widgets = $widgetArea->getWidgets($uniqueCode)
->get();
dd($uniqueCode);
WidgetArea::where('code', $uniqueCode)
->increment('viewed');
$widgets = Cache::remember('widget-area-' . $uniqueCode, setting('widgetCacheLifetime', 5), function () use ($uniqueCode) {
$widgetArea = new WidgetArea();
return $widgetArea->getWidgets($uniqueCode)
->get();
});
self::saveRenderedWidgetArea($widgets);
}
protected static function initWidgetAreas()
{
if (self::$initialized)
if (self::$initialized) {
return;
}
$widgetArea = new WidgetArea();
$widgets = $widgetArea->getWidgets()
$widgets = Cache::remember('widgets', setting('widgetCacheLifetime', 5), function () {
$widgetArea = app(WidgetAreaRepository::class);
return $widgetArea->getWidgets()
->get();
});
self::saveRenderedWidgetArea($widgets);
self::$initialized = true;
@@ -55,7 +61,7 @@ class WidgetAreas
*
* @param $uniqueCode
*
* @return mixed
* @return void
*/
public static function render($uniqueCode)
{
@@ -14,7 +14,7 @@ function e($value)
}
/**
* Shortcut for \App\Helpers\Settings::get()
* Shortcut for \App\CMS\Helpers\Settings::get()
*
* @param $key
* @param null $default
@@ -22,9 +22,13 @@ function e($value)
* @return null|string
*/
function setting($key, $default = null) {
return \App\Helpers\Settings::get($key, $default);
return \App\CMS\Helpers\Settings::get($key, $default);
}
function asset_path($path) {
return env('SITE_URL').'/assets/'.$path;
}
function template_name($name, $throwExceptions = true) {
return \App\CMS\Helpers\Template::name($name, $throwExceptions);
}
@@ -0,0 +1,38 @@
<?php
namespace App\CMS\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Enumerations\ContentStatuses;
class ChangeStatus implements Interaction
{
/**
* Change status of content page
*
* @param array $data
* @param array $parameters
*
* @return mixed|void
*/
public function handle($data, $parameters)
{
list ($page) = $parameters;
$page->status = $data['status'];
$page->save();
}
/**
* Check if status is valid
*
* @param array $parameters
*
* @return array
*/
public function getValidationRules($parameters = [])
{
$statuses = ContentStatuses::getWithTranslations();
return ['status' => 'in:' . implode(',', array_keys($statuses))];
}
}
@@ -0,0 +1,45 @@
<?php
namespace App\CMS\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Contracts\Repositories\Module;
use App\Models\Content\Content;
use Illuminate\Support\Facades\App;
class DeletePage implements Interaction
{
/**
* Perform given action
*
* @param $data array input data
* @param $parameters array parameters
*
* @return void
*/
public function handle($data, $parameters)
{
/**
* @var $page Content
* @var $module Module
*/
$module = App::make(Module::class);
list ($page) = $parameters;
// delete page
$page->delete();
// let module to delete some extra content created during page's life
$module->callOnString($page->moduleHandler, 'delete', [$page]);
}
/**
* @param $data array input data
*
* @return array
*/
public function getValidationRules($data = [])
{
return [];
}
}
@@ -0,0 +1,78 @@
<?php
namespace App\Cms\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Contracts\Repositories\Module;
use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Helpers\CurrentTemplate;
use App\Events\EditContent as EditContentEvent;
use App\Http\Requests\Request;
use App\Models\Content\Content;
use App\Models\FileManager\File;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class EditContent implements Interaction
{
/**
* @var Module
*/
protected $module;
/**
* @var File
*/
protected $file;
public function __construct()
{
$this->module = App::make(Module::class);
$this->file = App::make(File::class);
}
/**
* Edit page
*
* @param array $data
* @param array $parameters
*
* @return mixed
*/
public function handle($data, $parameters)
{
/**
* @var $page Content
*/
list($page) = $parameters;
app('saveContentPipeline')->run($page, $data);
return $page;
}
/**
* Validate this interaction
*
* @param array $parameters
*
* @return array
*/
public function getValidationRules($parameters = [])
{
$id = $parameters[0]->id;
// get all available statuses
$statuses = ContentStatuses::getSimple();
$statuses = implode(',', $statuses);
return [
'title' => 'required',
'url' => 'required|unique:contents,url,' . $id.',id,deleted_at,NULL,language,' . LaravelLocalization::getCurrentLocale(),
'publishedFrom' => 'date',
'publishedTo' => 'date',
'status' => 'required|in:' . $statuses,
'parentPage' => 'exists:contents,id'
];
}
}
@@ -0,0 +1,74 @@
<?php
namespace App\Cms\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Contracts\Repositories\Content as ContentRepository;
use App\CMS\Contracts\Repositories\Module;
use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Helpers\CurrentTemplate;
use App\Models\Content\Content;
use App\Models\FileManager\File;
use Illuminate\Support\Facades\App;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class NewContent implements Interaction
{
/**
* @var ContentRepository
*/
protected $content;
/**
* @var File
*/
protected $file;
/**
* @var Module
*/
protected $module;
public function __construct()
{
$this->content = App::make(ContentRepository::class);
$this->module = App::make(Module::class);
$this->file = App::make(File::class);
}
/**
* Create new content page
*
* @param array $data
* @param $parameters
*
* @return Content
*/
public function handle($data, $parameters)
{
list($moduleHandler) = $parameters;
$data['userId'] = \Auth::user()->id;
$data['language'] = LaravelLocalization::getCurrentLocale();
$data['moduleHandler'] = $moduleHandler;
$page = new Content();
app('saveContentPipeline')->run($page, $data);
return $page;
}
public function getValidationRules($parameters = [])
{
// get all available statuses
$statuses = ContentStatuses::getSimple();
$statuses = implode(',', $statuses);
return [
'titlePhoto' => 'image',
'title' => 'required',
'url' => 'required|unique:contents,url,NULL,id,deleted_at,NULL,language,' . LaravelLocalization::getCurrentLocale(),
'status' => 'required|in:'.$statuses,
'parentPage' => 'exists:contents,id',
'publishedFrom' => 'date',
'publishedTo' => 'date',
];
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\CMS\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Enumerations\ContentStatuses;
use App\Models\Content\Content;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class SetHomepage implements Interaction
{
/**
* Set homepage of given page
*
* @param array $data
* @param array $parameters
*
* @return void
*/
public function handle($data, $parameters)
{
list ($page) = $parameters;
// disable any other existing homepage
Content::where('isHomepage', true)
->where('language', LaravelLocalization::getCurrentLocale())
->update(['isHomepage' => false]);
// set new homepage
$page->isHomepage = true;
$page->save();
}
/**
* Check if status is valid
*
* @param array $parameters
*
* @return array
*/
public function getValidationRules($parameters = [])
{
return [];
}
}
@@ -0,0 +1,65 @@
<?php
namespace App\CMS\Interactions\Admin\FileManager;
use App\CMS\Contracts\Interaction;
use App\CMS\Exceptions\FileManager\SubdirectoryExistsInDirectory;
use App\CMS\Repositories\FileManager\Directory as DirectoryRepository;
use App\Models\FileManager\Directory;
class CreateDirectory implements Interaction
{
/**
* @var DirectoryRepository
*/
private $repository;
public function __construct(DirectoryRepository $repository)
{
$this->repository = $repository;
}
/**
* Perform given action
*
* @param $data array input data
* @param $parameters array parameters
*
* @return Directory
* @throws SubdirectoryExistsInDirectory
*/
public function handle($data, $parameters)
{
$data['parentDirectory'] = isset($data['parentDirectory']) ? $data['parentDirectory'] : null;
// todo this should probably go into validation, but we are not able to get $data in getValidationRules
// check if created folder does not exist in current directory
if ($this->repository->checkIfNameExists($data['name'], $data['parentDirectory'])) {
throw new SubdirectoryExistsInDirectory();
}
// todo use Directory::create() and rename columns/fields in request
// create new database entry
$directory = new Directory();
$directory->name = $data['name'];
$directory->parent_id = $data['parentDirectory'];
$directory->user_id = \Auth::user()->id;
$directory->description = $data['description'];
$directory->save();
return $directory;
}
/**
* @param $data array input data
*
* @return array
* @throws SubdirectoryExistsInDirectory
*/
public function getValidationRules($data = [])
{
return [
'name' => 'required|max:255',
'parentDirectory' => 'exists:directories,id'
];
}
}
@@ -1,5 +1,5 @@
<?php
namespace App\MenuPresenters;
namespace App\CMS\MenuPresenters;
use Pingpong\Menus\MenuItem;
use Pingpong\Menus\Presenters\Presenter;
@@ -77,6 +77,6 @@ class FoundationDrilldownMenuPresenter extends Presenter
<ul class="vertical menu">
' . $this->getChildMenuItems($item) . '
</ul>
</li>' . PHP_EOL;;
</li>' . PHP_EOL;
}
}
@@ -1,5 +1,5 @@
<?php
namespace App\MenuPresenters;
namespace App\CMS\MenuPresenters;
use Pingpong\Menus\Presenters\Presenter;
@@ -56,6 +56,6 @@ class FoundationDropdownMenuPresenter extends Presenter
<ul class="vertical menu">
' . $this->getChildMenuItems($item) . '
</ul>
</li>' . PHP_EOL;;
</li>' . PHP_EOL;
}
}
@@ -1,5 +1,5 @@
<?php
namespace App\MenuPresenters;
namespace App\CMS\MenuPresenters;
class FoundationInitializedDropdownMenuPresenter extends FoundationDropdownMenuPresenter
{
@@ -1,5 +1,5 @@
<?php
namespace App\MenuPresenters;
namespace App\CMS\MenuPresenters;
use Pingpong\Menus\MenuItem;
use Pingpong\Menus\Presenters\Presenter;
@@ -1,5 +1,5 @@
<?php
namespace App\MenuPresenters;
namespace App\CMS\MenuPresenters;
use Pingpong\Menus\MenuItem;
use Pingpong\Menus\Presenters\Presenter;
+168
View File
@@ -0,0 +1,168 @@
<?php
namespace App\CMS\Observers;
use App\CMS\Contracts\Repositories\Content as ContentContract;
use App\Events\CreateNewContent;
use App\Events\DeleteContent;
use App\Events\EditContent;
use App\Events\MakeDraftFromContent;
use App\Events\PublishContent;
use App\Events\SetHomepage;
use App\Models\Content\Content as ContentModel;
use App\Models\Content\ContentHistory;
use Illuminate\Support\Facades\Event;
/**
* Class Content
*
* Model observer for logging changes on content page.
*
* @package App\CMS\Observers
*/
class Content
{
/**
* @var string
*/
protected $changeset;
public function __construct()
{
$this->changeset = uniqid();
}
/**
* Log changes on edit
*
* @param ContentModel $content
*/
public function updated(ContentModel $content)
{
$fields = $this->getDirtyFields($content->getDirty(), $content->getOriginal());
$normalFieldsEdited = 0;
foreach ($fields as $field => $change) {
if ($field == 'viewed')
continue;
$history = [
'user_id' => \Auth::user()->id,
'content_id' => $content->id,
'edit_batch' => $this->changeset,
'column' => $field,
'old_value' => $change['old'],
'new_value' => $change['new']
];
// save history
ContentHistory::create($history);
// fire event
$this->fireEvent($field, $change, $content, $normalFieldsEdited);
}
if ($normalFieldsEdited > 0) {
Event::fire(new EditContent($content, $this->changeset));
}
}
/**
* Fire event when new instance of model is stored into database
*
* @param ContentModel $content
*/
public function created(ContentModel $content)
{
Event::fire(new CreateNewContent($content));
}
/**
* @param ContentModel $content
*/
public function deleted(ContentModel $content)
{
Event::fire(new DeleteContent($content));
}
/**
* Get all dirty changed from model.
*
* If user did not change moduleSettings column, return result from ContentModel::getDirty(). Otherwise append all
* changed columns from module settings.
*
* @param $changed
* @param $original
*
* @return array
*/
protected function getDirtyFields($changed, $original)
{
unset($changed['updated_at']);
$changes = $this->getNewAndOldValues(array_keys($changed), $changed, $original);
if (!isset($changed['moduleSettings'])) {
return $changes;
}
$moduleSettings = (array)json_decode($changed['moduleSettings']);
$originalSettings = isset($original['moduleSettings']) ? (array)json_decode($original['moduleSettings']) : [];
unset($changed['moduleSettings']);
$settingChanged = array_keys(array_diff_assoc($moduleSettings, $originalSettings));
$changesInSettings = $this->getNewAndOldValues($settingChanged, $moduleSettings, $originalSettings);
return array_merge($changes, $changesInSettings);
}
/**
* Get original and changed values in one array
*
* @param $fields
* @param $new
* @param $original
*
* @return array
*/
protected function getNewAndOldValues($fields, $new, $original)
{
$changes = [];
foreach ($fields as $field) {
$changes[$field] = [
'new' => isset($new[$field]) ? $new[$field] : null,
'old' => isset($original[$field]) ? $original[$field] : null
];
}
return $changes;
}
/**
* Fire events for publishing/making draft and setting homepage
*
* @param $field
* @param $change
* @param ContentModel $content
* @param $normalFieldsEdited
*/
protected function fireEvent($field, $change, ContentModel $content, &$normalFieldsEdited)
{
switch ($field) {
case 'status':
if ($change['new'] !== ContentContract::STATUS_DRAFT) {
Event::fire(new PublishContent($content, $this->changeset));
} else {
Event::fire(new MakeDraftFromContent($content, $this->changeset));
}
break;
case 'isHomepage':
Event::fire(new SetHomepage($content, $this->changeset));
break;
default:
$normalFieldsEdited++;
}
}
}
+71
View File
@@ -0,0 +1,71 @@
<?php
namespace App\CMS\Pipeline;
use App\CMS\Pipeline\Exceptions\InvalidProcessType;
abstract class AbstractPipeline {
protected $processes = [];
protected $beforeStart = null;
protected $beforeRender = null;
protected $acceptedProcessInterface = null;
/**
* check if given classname implements valid Process interface
*
* @param $classname
*
* @throws InvalidProcessType
*/
protected function checkValidProcess($classname)
{
if (is_null($this->acceptedProcessInterface))
return;
if (!in_array($this->acceptedProcessInterface, class_implements($classname))) {
throw new InvalidProcessType($classname);
}
}
/**
* Add new process into pipeline
*
* @param $process
*
* @return void
* @throws InvalidProcessType
*/
function add($process)
{
$this->checkValidProcess($process);
$this->processes[] = $process;
}
/**
* @param null $beforeStart
*/
public function setBeforeStart($beforeStart)
{
$this->checkValidProcess($beforeStart);
if (!is_null($this->beforeStart)) {
array_unshift($this->processes, $this->beforeStart);
}
$this->beforeStart = $beforeStart;
}
/**
* @param null $beforeRender
*/
public function setBeforeRender($beforeRender)
{
$this->checkValidProcess($beforeRender);
if (!is_null($this->beforeRender)) {
array_push($this->processes, $this->beforeRender);
}
$this->beforeRender = $beforeRender;
}
}
@@ -0,0 +1,58 @@
<?php
namespace App\CMS\Pipeline\DisplayPipeline;
use App\CMS\Contracts\Content\DisplayPipeline\Pipeline;
use App\CMS\Contracts\Content\DisplayPipeline\Process;
use App\CMS\Pipeline\AbstractPipeline;
use App\Models\Content\Content;
class DisplayPipeline extends AbstractPipeline implements Pipeline
{
/**
* DisplayPipeline constructor.
*/
public function __construct()
{
$this->acceptedProcessInterface = Process::class;
}
/**
* Run pipeline
*
* @param Content $page
*
* @return Content
*/
function run(Content $page)
{
$this->runBeforeStart($page);
foreach ($this->processes as $process) {
/**
* @var $run Process
*/
$run = new $process;
$run->handle($page);
}
$this->runBeforeRender($page);
return $page;
}
protected function runBeforeStart($page)
{
if (!is_null($this->beforeStart)) {
$process = new $this->beforeStart;
$process->handle($page);
}
}
protected function runBeforeRender($page)
{
if (!is_null($this->beforeRender)) {
$process = new $this->beforeRender;
$process->handle($page);
}
}
}
@@ -0,0 +1,19 @@
<?php
namespace App\CMS\Pipeline\DisplayPipeline\Process;
use App\CMS\Contracts\Content\DisplayPipeline\Process;
use App\Models\Content\Content;
class AddViewedToPage implements Process {
/**
* Process and modify given page
*
* @param Content $page
*
* @return mixed
*/
function handle(Content & $page)
{
$page->view();
}
}
@@ -0,0 +1,20 @@
<?php
namespace App\CMS\Pipeline\DisplayPipeline\Process;
use App\CMS\Contracts\Content\DisplayPipeline\Process;
use App\Models\Content\Content;
use Webwizo\Shortcodes\Facades\Shortcode;
class CompileShortcodes implements Process {
/**
* Process and modify given page
*
* @param Content $page
*
* @return mixed
*/
function handle(Content & $page)
{
$page->pageContent = Shortcode::compile($page->pageContent);
}
}
@@ -0,0 +1,6 @@
<?php
namespace App\CMS\Pipeline\Exceptions;
class InvalidProcessType extends \Exception
{
}
@@ -0,0 +1,20 @@
<?php
namespace App\CMS\Pipeline\SavePipeline\Process;
use App\CMS\Contracts\Content\SavePipeline\Process;
use App\Models\Content\Content;
class SaveCommonFields implements Process {
/**
* Process and modify given page
*
* @param Content $page
* @param array $input
*
* @return void
*/
function handle(Content & $page, array &$input)
{
($page->exists == false) ? $page = Content::create($input): $page->update($input);
}
}
@@ -0,0 +1,75 @@
<?php
namespace App\CMS\Pipeline\SavePipeline\Process;
use App\CMS\Contracts\Content\SavePipeline\Process;
use App\Models\Content\Content;
use App\Models\Content\ContentHasFile;
use App\Models\FileManager\Directory;
use App\Models\FileManager\File;
class UploadRelatedFiles implements Process
{
/**
* Process and modify given page
*
* @param Content $page
* @param array $input
*
* @return void
*/
function handle(Content & $page, array & $input)
{
$files = $input['files'];
$assignedFiles = isset($input['keepAssigned']) ? $input['keepAssigned'] : [];
// check if any file was removed
$this->removeRelatedFiles($page, $assignedFiles);
// allow uploading only on created pages
if (!$page->id || !$files[0]) {
return;
}
// find or create new directory for files assigned to content
$directory = Directory::firstOrCreate([
'name' => '.content_files',
'hidden' => true
]);
$data = new \stdClass();
$data->directoryId = $directory->id;
$fileModel = app(File::class);
foreach ($files as $file) {
if (!$file) {
continue;
}
$uploaded = $fileModel->upload($file, $data);
// add assignement
ContentHasFile::create([
'file_id' => $uploaded['id'],
'content_id' => $page->id
]);
}
}
/**
* Delete files from association
*
* @param Content $page
* @param $assignedFiles
*/
private function removeRelatedFiles(Content $page, $assignedFiles)
{
$allFiles = $page->files()
->whereNotIn('id', array_keys($assignedFiles))
->get();
foreach ($allFiles as $file) {
ContentHasFile::where('content_id', $page->id)
->where('file_id', $file->id)
->delete();
}
}
}
@@ -0,0 +1,38 @@
<?php
namespace App\CMS\Pipeline\SavePipeline\Process;
use App\CMS\Contracts\Content\SavePipeline\Process;
use App\CMS\Helpers\RootDirectory;
use App\Models\Content\Content;
use App\Models\FileManager\File;
class UploadTitlePhoto implements Process
{
/**
* Process and modify given page
*
* @param Content $page
* @param array $input
*
* @return void
*/
function handle(Content & $page, array & $input)
{
$fileModel = app(File::class);
$titlePhoto = isset($input['titlePhotoFile']) ? $input['titlePhotoFile'] : null;
// upload file - if provided
$page->titlePhoto = isset($input['existingTitlePhoto']) ? $input['existingTitlePhoto'] : null;
if (!is_null($titlePhoto)) {
$root = RootDirectory::get();
$data = ['directoryId' => $root->id];
$file = $fileModel->upload($titlePhoto, (object)$data);
$page->titlePhoto = $file ? $file['filename'] : null;
}
$page->save();
}
}
@@ -0,0 +1,69 @@
<?php
namespace App\CMS\Pipeline\SavePipeline;
use App\CMS\Contracts\Content\SavePipeline\Pipeline;
use App\CMS\Contracts\Content\SavePipeline\Process;
use App\CMS\Pipeline\AbstractPipeline;
use App\Models\Content\Content;
class SavePipeline extends AbstractPipeline implements Pipeline
{
/**
* SavePipeline constructor.
*/
public function __construct()
{
$this->acceptedProcessInterface = Process::class;
}
/**
* Save content page
*
* @param Content $page
* @param array $input
*
* @return Content
*/
function run(Content & $page, array $input)
{
$this->runBeforeStart($page, $input);
foreach ($this->processes as $process) {
/**
* @var $run Process
*/
$run = new $process;
$run->handle($page, $input);
}
$this->runAfter($page, $input);
return $page;
}
/**
* Run process as first - if specified
*
* @param Content $page
* @param array $input
*/
protected function runBeforeStart(Content $page, array $input)
{
if (!is_null($this->beforeStart)) {
app($this->beforeStart)->handle($page, $input);
}
}
/**
* Run some process in the end - if exists
*
* @param Content $page
* @param array $input
*/
protected function runAfter(Content $page, array $input)
{
if (!is_null($this->beforeRender)) {
app($this->beforeRender)->handle($page, $input);
}
}
}

Some files were not shown because too many files have changed in this diff Show More