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
149 changed files with 25491 additions and 1524 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
@@ -5,27 +5,6 @@ use App\Http\Requests\Request;
use App\Models\Content\Content;
interface AdvancedContentModifier {
/**
* Save module-specific values into database
*
* @param Content $content
* @param array $inputData
*
* @return mixed
*/
public static function createNew(Content &$content, array $inputData);
/**
* 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
*
* @return mixed
*/
public static function edit(Content $content, $request);
/**
* Method called right after content page is marked as deleted
*
@@ -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);
}
@@ -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);
}
-10
View File
@@ -6,16 +6,6 @@ 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();
/**
@@ -27,28 +27,4 @@ interface TemplateHandler extends BaseModuleHandler
* @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
*/
public static function beforeSave(Content & $content, $request);
}
+1 -1
View File
@@ -15,7 +15,7 @@ interface Template
public function setModel(TemplateModel $model);
public function getPathToTemplate();
public function getPathToTemplate($mode = null);
public function getForModule(ModuleModel $module);
}
-13
View File
@@ -20,19 +20,6 @@ abstract class Handler extends BaseHandler implements AppHandler
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 [
-33
View File
@@ -96,37 +96,4 @@ class CurrentTemplate implements TemplateHandler
{
return call_user_func([self::handler(), 'getPublicTemplatePaths']);
}
/**
* Prepare Content object to be rendered using Blade template
*
* @param Content $content
*/
public static function beforeRender(Content & $content)
{
call_user_func_array([self::handler(), 'beforeRender'], [&$content]);
}
/**
* Modify input data into format which can be understood by edit template
*
* @param Content $content
*/
public static function beforePopulatingEditForm(Content & $content)
{
call_user_func_array([self::handler(), 'beforePopulatingEditForm'], [&$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
*/
public static function beforeSave(Content & $content, $request)
{
call_user_func_array([self::handler(), 'beforeSave'], [&$content, $request]);
}
}
-3
View File
@@ -29,11 +29,8 @@ class PageRenderer
/**
* @var $handler AppHandler
*/
// get handler
$handler = new $page->moduleHandler;
$page->content = Shortcode::compile($page->content);
// render page
return $handler->render($page, $parameters);
}
+9 -6
View File
@@ -1,6 +1,8 @@
<?php
namespace App\CMS\Helpers;
use App\CMS\Repositories\Widgets\WidgetArea as WidgetAreaRepository;
use App\Models\Widgets\WidgetArea;
use Illuminate\Support\Facades\Cache;
@@ -25,15 +27,16 @@ class WidgetAreas
protected static function loadWidgetArea($uniqueCode)
{
$widgets = Cache::remember('widget-' . $uniqueCode, setting('widgetCacheLifetime', 5), function () use ($uniqueCode) {
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();
});
WidgetArea::where('code', $uniqueCode)
->increment('viewed');
self::saveRenderedWidgetArea($widgets);
}
@@ -44,7 +47,7 @@ class WidgetAreas
}
$widgets = Cache::remember('widgets', setting('widgetCacheLifetime', 5), function () {
$widgetArea = new WidgetArea();
$widgetArea = app(WidgetAreaRepository::class);
return $widgetArea->getWidgets()
->get();
});
@@ -58,7 +61,7 @@ class WidgetAreas
*
* @param $uniqueCode
*
* @return mixed
* @return void
*/
public static function render($uniqueCode)
{
@@ -37,32 +37,18 @@ class EditContent implements Interaction
* @param array $data
* @param array $parameters
*
* @return mixed|void
* @return mixed
*/
public function handle($data, $parameters)
{
/**
* @var $page Content
*/
list($page, $titlePhoto, $relatedFiles) = $parameters;
list($page) = $parameters;
// let template to modify request and content page
CurrentTemplate::beforeSave($page, $data);
app('saveContentPipeline')->run($page, $data);
// upload file - if provided
$data['titlePhoto'] = isset($data['existingTitlePhoto']) ? $data['existingTitlePhoto'] : null;
if (!is_null($titlePhoto)) {
$file = $this->file->upload($titlePhoto);
$data['titlePhoto'] = $file ? $file['filename'] : null;
}
$page->update($data);
$this->module->callOnString($page->moduleHandler, 'edit', [$page, $data]);
// move to interaction
$keepAssigned = isset($data->keepAssigned) ? $data->keepAssigned : [];
$page->uploadRelatedFiles($relatedFiles, $keepAssigned);
return $page;
}
/**
@@ -43,29 +43,14 @@ class NewContent implements Interaction
*/
public function handle($data, $parameters)
{
list($moduleHandler, $titlePhoto, $relatedFiles) = $parameters;
// upload file - if provided
$file = !is_null($titlePhoto) ? $this->file->upload($titlePhoto) : null;
list($moduleHandler) = $parameters;
$data['userId'] = \Auth::user()->id;
$data['language'] = LaravelLocalization::getCurrentLocale();
$data['titlePhoto'] = $file ? $file['filename'] : null;
$data['moduleHandler'] = $moduleHandler;
$page = Content::create($data);
// save module-specific stuff
$this->module->callOnString($moduleHandler, 'createNew', [&$page, $data]);
// let template to modify data and content page
CurrentTemplate::beforeSave($page, $data);
// save content of page before (possible) uploading related files
$page->save();
// upload files assigned to content page
$page->uploadRelatedFiles($relatedFiles);
$page = new Content();
app('saveContentPipeline')->run($page, $data);
return $page;
}
+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);
}
}
}
+1 -4
View File
@@ -78,7 +78,6 @@ class Content extends Repository implements IContent
return $this->getPageQuery()
->where('isHomepage', 1)
->first();
}
/**
@@ -126,8 +125,6 @@ class Content extends Repository implements IContent
$query = $query->whereIn('contents.status', $statuses);
}
$pages = $query->paginate(setting('paginatedResults', 20));
return $pages;
return $query;
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
namespace App\CMS\Repositories\Widgets;
use App\Http\Requests\Request;
use App\Models\Widgets\Widget as WidgetModel;
use App\Models\Widgets\WidgetType;
use Illuminate\Support\Facades\Event;
class Widget
{
public function createNew(WidgetType $widgetType, Request $request)
{
$data = $request->except('_token');
// create new widget
$widget = new WidgetModel();
$widget->widget_type_handler = $widgetType->handler;
$widget->user_id = \Auth::user()->id;
$widget->name = $data['name'];
$widget->description = $data['description'];
$widget->container_class = $data['containerClass'];
$widget->container_id = empty($data['containerId']) ? null : $data['containerId'];
$widget->settings = call_user_func([$widgetType->handler, 'save'], $request);
// save into database
$widget->save();
// fire event with newly created widget
Event::fire(new \App\Events\CreateNewWidget($widget));
return $widget;
}
public function edit(WidgetModel $widget, Request $request)
{
// update name
$widget->name = $request->name;
$widget->container_class = $request->containerClass;
$widget->container_id = empty($request->containerId) ? null : $request->containerId;
$widget->description = $request->description;
// try to save this widget
$widget->settings = call_user_func([$widget->widget_type_handler, 'save'], $request);
// save into database
$widget->save();
// fire event with editing widget
Event::fire(new \App\Events\EditWidget($widget));
}
}
@@ -0,0 +1,55 @@
<?php
namespace App\CMS\Repositories\Widgets;
use App\Events\CreateNewWidgetArea;
use App\Http\Requests\Request;
use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetArea as WidgetAreaModel;
use Illuminate\Support\Facades\Event;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class WidgetArea
{
public function getWidgets($uniqueCode = false)
{
$widgets = Widget::select('widgets.*', 'widgets.widget_type_handler', 'widget_areas.code as widget_area_code', 'widgets.name as widget_name', 'widgets.settings')
->join('widget_in_widget_area', 'widget_in_widget_area.widget_id', '=', 'widgets.id')
->join('widget_areas', 'widget_in_widget_area.widget_area_id', '=', 'widget_areas.id')
->where('language', LaravelLocalization::getCurrentLocale())
->orderBy('widget_in_widget_area.position');
if (!$uniqueCode) {
$widgets = $widgets->where('widget_areas.viewed', '>=', setting('preloadFrequentedWidgetAreasTreshold', 10));
} else {
$widgets = $widgets->where('code', $uniqueCode);
}
return $widgets;
}
public function update(\App\Models\Widgets\WidgetArea $area, Request $request) {
$area->name = $request->name;
$area->description = $request->description;
$area->save();
// fire event with new widget area
Event::fire(new \App\Events\EditWidgetArea($area));
}
/**
* Create new instance of widget area
*
* @param Request $request
*/
public function create(Request $request)
{
$area = WidgetAreaModel::create([
'code' => $request->code,
'name' => $request->name,
'description' => $request->description
]);
// fire event with new widget area
Event::fire(new CreateNewWidgetArea($area));
}
}
+5 -2
View File
@@ -1,13 +1,15 @@
<?php
namespace App\CMS\Widgets\Menu;
use App\CMS\Contracts\Repositories\Content as IContent;
use App\CMS\Contracts\Widgets\PublicWidget;
use App\CMS\Widgets\Contracts\WidgetRenderer;
use App\CMS\Contracts\Widgets\WidgetRenderer;
use App\CMS\Widgets\Exceptions\MissingParameterException;
use App\Http\Requests\Request;
use App\Models\Content\Content;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use App\CMS\Contracts\Repositories\Content as IContent;
use Modules\Blog\Article\Handlers\Article;
class Menu implements PublicWidget
{
@@ -76,6 +78,7 @@ class Menu implements PublicWidget
$pages = Content::where('language', LaravelLocalization::getCurrentLocale())
->whereIn('id', $ids)
->whereIn('status', $allowedStatuses)
->where('moduleHandler', '!=', Article::class)
->get();
$used = [];
foreach ($pages as $page) {
+9 -12
View File
@@ -1,4 +1,5 @@
<?php
namespace App\CMS\Widgets\Menu\Presenters;
use App\CMS\Contracts\Repositories\Content as ContentContract;
@@ -6,9 +7,7 @@ use App\CMS\Contracts\Widgets\WidgetRenderer;
use App\CMS\Widgets\Menu\Menu as WidgetMenu;
use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetType;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Route;
class Menu implements WidgetRenderer
@@ -36,7 +35,7 @@ class Menu implements WidgetRenderer
return $a->order - $b->order;
});
$route = Request::route()
$routeName = Route::current()
->getName();
$parameters = Route::current()
->parameters();
@@ -55,7 +54,7 @@ class Menu implements WidgetRenderer
}
$page = $pages[$pageId];
$active = ($page->isHomepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
$active = ($page->isHomepage && $routeName == 'page.index') || ($routeName == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
$route = $page->isHomepage ? route('page.index') : route('page.content', ['url' => $page->url]);
$code .= '<li';
@@ -83,15 +82,14 @@ class Menu implements WidgetRenderer
$content = app(ContentContract::class);
// get list of all pages
$pages = $content->getOverview();
$widget->settings = new \stdClass();
$widget->settings->links = [];
$pages = $content->getOverview()
->get();
return view('admin.widgets.menu.new', [
'type' => $type,
'widget' => $widget,
'pages' => $pages,
'links' => []
]);
}
@@ -110,7 +108,8 @@ class Menu implements WidgetRenderer
$content = App::make(ContentContract::class);
// get list of all pages
$pages = $content->getOverview();
$pages = $content->getOverview()
->get();
// make object from JSON
if (!isset($widget->settings->links)) {
@@ -124,8 +123,6 @@ class Menu implements WidgetRenderer
return $a->order - $b->order;
});
$widget->settings->links = (object)$links;
return view('admin.widgets.menu.edit', ['widget' => $widget, 'pages' => $pages]);
return view('admin.widgets.menu.edit', ['widget' => $widget, 'pages' => $pages, 'links' => (object)$links]);
}
}
@@ -12,7 +12,6 @@ class PublishTemplateResources extends Command
* @var string
*/
protected $signature = 'template:publish';
/**
* The console command description.
*
@@ -27,6 +26,7 @@ class PublishTemplateResources extends Command
*/
public function handle()
{
$this->call('cache:clear');
$this->call('vendor:publish', ['--tag' => 'module-views', '--force' => true]);
$this->call('vendor:publish', ['--tag' => 'public-assets', '--force' => true]);
}
+41
View File
@@ -0,0 +1,41 @@
<?php
namespace App\Console\Commands;
use App\CMS\Helpers\CurrentTemplate;
use Illuminate\Console\Command;
class TemplateInfo extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'template:info';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Show details about currently set template';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$template = CurrentTemplate::get();
if (is_null($template)) {
$this->error('No template set.');
return;
}
$this->line($template->name);
$this->line($template->handler);
}
}
+3 -1
View File
@@ -3,6 +3,7 @@
namespace App\Console;
use App\Console\Commands\PublishTemplateResources;
use App\Console\Commands\TemplateInfo;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
@@ -23,7 +24,8 @@ class Kernel extends ConsoleKernel
Commands\InitDatabaseSchema::class,
Commands\SetTemplate::class,
Commands\AddLanguage::class,
PublishTemplateResources::class
PublishTemplateResources::class,
TemplateInfo::class
];
/**
+1 -2
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\WidgetArea;
use App\Models\Widgets\WidgetArea;
use Illuminate\Queue\SerializesModels;
class DeleteWidgetArea extends Event
@@ -20,7 +20,6 @@ class DeleteWidgetArea extends Event
*/
public function __construct(WidgetArea $widgetArea)
{
//
$this->widgetArea = $widgetArea;
}
}
+1 -3
View File
@@ -2,10 +2,8 @@
namespace App\Events;
use App\Events\Event;
use App\Models\WidgetArea;
use App\Models\Widgets\WidgetArea;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class EditWidgetArea extends Event
{
+2 -2
View File
@@ -12,11 +12,11 @@ class UploadFile extends Event
/**
* @var UploadedFile
*/
private $uploadedFile;
public $uploadedFile;
/**
* @var
*/
private $id;
public $id;
/**
* Create a new event instance.
@@ -39,7 +39,8 @@ class ContentOverview extends Controller
// get pages for overview
$handler = $module !== null ? $module->handler : null;
$pages = $this->content->getOverview($handler, [$status]);
$pages = $this->content->getOverview($handler, [$status])
->paginate(setting('paginatedResults', 20));
// get homepage - for checking if homepage is set and available
$homepage = $this->content->getHomepage();
@@ -4,13 +4,13 @@ namespace App\Http\Controllers\Admin\Contents;
use App\CMS\Contracts\Repositories\Content as IContent;
use App\CMS\Contracts\Repositories\Module as IModuleRepository;
use App\CMS\Contracts\Repositories\Template as ITemplate;
use Modules\Categories\Contracts\Repositories\Category as ICategory;
use App\CMS\Enumerations\ContentStatuses;
use App\Cms\Handlers\Interactions\Interaction;
use App\Cms\Interactions\Admin\Content\NewContent;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\CreateNewContentRequest;
use App\Http\Requests\Request;
use Modules\Categories\Contracts\Repositories\Category as ICategory;
/**
* Class CreateNewContent
@@ -85,7 +85,8 @@ class CreateNewContent extends Controller
'module' => $module,
'categories' => $categories,
'page' => $page,
'rootPages' => $this->content->getOverview(),
'rootPages' => $this->content->getOverview()
->get(),
'formSectionNames' => call_user_func([$module->handler, 'getExtendedFormSections']),
'formSections' => call_user_func([$module->handler, 'getExtendedFormInputsCreate']),
]);
@@ -103,11 +104,8 @@ class CreateNewContent extends Controller
{
$module = $this->module->getOne($moduleId);
$titlePhoto = $request->file('titlePhoto');
$relatedFiles = $request->all()['files'];
// create new page
Interaction::handle(NewContent::class, $request->all(), $module->handler, $titlePhoto, $relatedFiles);
Interaction::handle(NewContent::class, $request->all(), $module->handler);
return redirect()
->route('content.overview')
@@ -87,9 +87,6 @@ class EditContent extends Controller
$categories = $this->category->getForModule($module);
$history = $this->history->getStructuredHistoryOf($page);
// modify data for edit form according to installed template
CurrentTemplate::beforePopulatingEditForm($page);
// render view
return view('admin.content.edit', [
'pageHeading' => $pageHeading,
@@ -97,7 +94,7 @@ class EditContent extends Controller
'page' => $page,
'module' => $module,
'categories' => $categories,
'rootPages' => $this->content->getOverview(),
'rootPages' => $this->content->getOverview()->get(),
'templates' => $templates,
'formSectionNames' => $this->module->call($module, 'getExtendedFormSections'),
'formSections' => $this->module->call($module, 'getExtendedFormInputsEdit'),
@@ -132,10 +129,7 @@ class EditContent extends Controller
}
// edit page
$titlePhoto = $request->file('titlePhoto');
$relatedFiles = $request->all()['files'];
Interaction::handle(EditContentInteraction::class, $request->all(), $page, $titlePhoto, $relatedFiles);
Interaction::handle(EditContentInteraction::class, $request->all(), $page);
// something was changed, inform user
return redirect()
@@ -12,6 +12,21 @@ use Illuminate\Support\Facades\File;
class EditTemplate extends Controller
{
/**
* @var TemplateRepositoryContract
*/
private $templateRepository;
/**
* EditTemplate constructor.
*
* @param TemplateRepositoryContract $templateRepository
*/
public function __construct(TemplateRepositoryContract $templateRepository)
{
$this->templateRepository = $templateRepository;
}
/**
* Render form for editing template
*
@@ -26,11 +41,10 @@ class EditTemplate extends Controller
*/
$template = Template::findOrFail($template);
$repo = app(TemplateRepositoryContract::class);
$repo->setModel($template);
$this->templateRepository->setModel($template);
// load template content
$absolutePath = $repo->getPathToTemplate();
$absolutePath = $this->templateRepository->getPathToTemplate();
$content = @file_get_contents($absolutePath);
return view('admin.templates.edit', [
@@ -78,9 +92,11 @@ class EditTemplate extends Controller
*/
private function saveContent(Template $template, EditTemplateRequest $request)
{
$this->templateRepository->setModel($template);
// get templates with paths
$originalTemplate = $template->getPathToTemplate();
$customTemplate = $template->getPathToTemplate(Template::CUSTOM_EDIT_DIRECTORY);
$originalTemplate = $this->templateRepository->getPathToTemplate();
$customTemplate = $this->templateRepository->getPathToTemplate(TemplateRepositoryContract::CUSTOM_EDIT_DIRECTORY);
// get paths
$originalDir = dirname($originalTemplate);
@@ -2,19 +2,34 @@
namespace App\Http\Controllers\Admin\Widgets\Areas;
use App\CMS\Repositories\Widgets\WidgetArea as WidgetAreaRepository;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\NewWidgetAreaRequest;
use App\Models\Widgets\WidgetArea;
use Illuminate\Support\Facades\Event;
class CreateNewWidgetArea extends Controller
{
/**
* @var WidgetAreaRepository
*/
private $widgetAreaRepository;
/**
* CreateNewWidgetArea constructor.
*
* @param WidgetAreaRepository $widgetAreaRepository
*/
public function __construct(WidgetAreaRepository $widgetAreaRepository)
{
$this->widgetAreaRepository = $widgetAreaRepository;
}
/**
* Form for new widget area
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function getNew()
public function create()
{
return view('admin.widgets.area.new', ['area' => new WidgetArea()]);
}
@@ -24,18 +39,9 @@ class CreateNewWidgetArea extends Controller
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postNew(NewWidgetAreaRequest $request)
public function store(NewWidgetAreaRequest $request)
{
$parameters = [
'code' => $request->code,
'name' => $request->name,
'description' => $request->description
];
$area = WidgetArea::create($parameters);
// fire event with new widget area
Event::fire(new \App\Events\CreateNewWidgetArea($area));
$this->widgetAreaRepository->create($request);
// redirect with success notification
return redirect()
@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Admin\Widgets\Areas;
use App\CMS\Repositories\Widgets\WidgetArea as WidgetAreaRepository;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\EditWidgetAreaRequest;
use App\Models\Widgets\Widget;
@@ -13,22 +14,37 @@ use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class EditWidgetArea extends Controller
{
/**
* @var WidgetAreaRepository
*/
private $widgetAreaRepository;
/**
* EditWidgetArea constructor.
*
* @param WidgetAreaRepository $widgetAreaRepository
*/
public function __construct(WidgetAreaRepository $widgetAreaRepository)
{
$this->widgetAreaRepository = $widgetAreaRepository;
}
/**
* Display form for editing given widget area
*
* @param $id
* @param WidgetArea $widgetArea
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*
*/
public function getEdit($id)
public function edit(WidgetArea $widgetArea)
{
$area = WidgetArea::findOrFail($id);
$associatedWidgetIds = WidgetInWidgetArea::getWidgetIdsFromArea($area->id);
$associatedWidgetIds = WidgetInWidgetArea::getWidgetIdsFromArea($widgetArea->id);
$widgets = Widget::where('language', LaravelLocalization::getCurrentLocale())
->paginate(25);
return view('admin.widgets.area.edit', [
'area' => $area,
'area' => $widgetArea,
'widgets' => $widgets,
'associatedWidgetIds' => $associatedWidgetIds
]);
@@ -36,26 +52,14 @@ class EditWidgetArea extends Controller
/**
* @param EditWidgetAreaRequest $request
* @param $id
* @param WidgetArea $widgetArea
*
* @return \Illuminate\Http\RedirectResponse
*
*/
public function postEdit(EditWidgetAreaRequest $request, $id)
public function update(EditWidgetAreaRequest $request, WidgetArea $widgetArea)
{
try {
$area = WidgetArea::findOrFail($id);
} catch (ModelNotFoundException $e) {
return $this->invalidArea();
}
$area->name = $request->name;
$area->description = $request->description;
$area->timestamps = true;
$area->save();
// fire event with new widget area
Event::fire(new \App\Events\EditWidgetArea($area));
$this->widgetAreaRepository->update($widgetArea, $request);
return redirect()
->route('widgetareas.overview')
@@ -65,21 +69,14 @@ class EditWidgetArea extends Controller
/**
* Hard deletes widget area
*
* @param $id
* @param WidgetArea $widgetArea
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteArea($id)
public function delete(WidgetArea $widgetArea)
{
// try to find area
try {
$area = WidgetArea::findOrFail($id);
} catch (ModelNotFoundException $e) {
return $this->invalidArea();
}
// check if widget area is deletable
if (!$area->deletable) {
if (!$widgetArea->deletable) {
return redirect()
->back()
->with('error', trans('admin/widgetAreas.notDeletableArea'));
@@ -2,11 +2,11 @@
namespace App\Http\Controllers\Admin\Widgets;
use App\CMS\Repositories\Widgets\Widget;
use App\CMS\Widgets\Exceptions\MissingParameterException;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\NewWidgetRequest;
use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetType;
use App\CMS\Widgets\Exceptions\MissingParameterException;
class CreateNewWidget extends Controller
{
@@ -23,14 +23,13 @@ class CreateNewWidget extends Controller
/**
* Form for new widget area
*
* @param $type
* @param WidgetType $widgetType
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*
*/
public function getNew($type)
public function getNew(WidgetType $widgetType)
{
$widgetType = WidgetType::findOrFail($type);
$presenter = call_user_func([$widgetType->handler, 'getPresenter']);
return call_user_func([$presenter, 'renderAddForm'], $widgetType);
@@ -40,23 +39,22 @@ class CreateNewWidget extends Controller
* Create new instance of given widget type
*
* @param NewWidgetRequest $request
* @param $type
*
* @param WidgetType $widgetType
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postNew(NewWidgetRequest $request, $type)
public function postNew(NewWidgetRequest $request, WidgetType $widgetType)
{
$widgetType = WidgetType::findOrFail($type);
// try to save this widget
try {
$this->widget->createNew($widgetType, $request);
} catch (MissingParameterException $e) {
// user omitted some value
return $this->invalidWidget($type, $e->getMessage());
} catch (\Exception $e) {
// something went wrong
return $this->invalidWidget($type, trans('admin/widgets.cannotSave', ['exception' => $e->getMessage()]));
return redirect()
->back()
->withInput()
->with('error', $e->getMessage());
}
// redirect with success notification
@@ -64,12 +62,4 @@ class CreateNewWidget extends Controller
->route('widgets.overview')
->with('success', trans('admin/widgets.successfullyCreated'));
}
private function invalidWidget($widgetType, $error)
{
return redirect()
->route('widgets.new', ['type' => $widgetType])
->withInput()
->with('error', $error);
}
}
@@ -1,26 +1,39 @@
<?php
namespace App\Http\Controllers\Admin\Widgets;
use App\CMS\Repositories\Widgets\Widget as WidgetRepository;
use App\CMS\Widgets\Exceptions\MissingParameterException;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\EditWidgetRequest;
use App\Models\Widgets\Widget;
use Illuminate\Support\Facades\Event;
class EditWidget extends Controller
{
/**
* @var WidgetRepository
*/
private $widgetRepository;
/**
* EditWidget constructor.
*
* @param WidgetRepository $widgetRepository
*/
public function __construct(WidgetRepository $widgetRepository)
{
$this->widgetRepository = $widgetRepository;
}
/**
* Render edit form
*
* @param $id
* @param Widget $widget
*
* @return mixed
*/
public function getEdit($id)
public function getEdit(Widget $widget)
{
$widget = Widget::findOrFail($id);
$widget->settings = json_decode($widget->settings);
$presenter = call_user_func([$widget->widget_type_handler, 'getPresenter']);
return call_user_func([$presenter, 'renderEditForm'], $widget);
@@ -30,24 +43,14 @@ class EditWidget extends Controller
* Save changes into database
*
* @param EditWidgetRequest $request
* @param $widget
* @param Widget $widget
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postEdit(EditWidgetRequest $request, $widget)
public function postEdit(EditWidgetRequest $request, Widget $widget)
{
// create new widget
$widget = Widget::findOrFail($widget);
// update name
$widget->name = $request->name;
$widget->container_class = $request->containerClass;
$widget->container_id = empty($request->containerId) ? null : $request->containerId;
$widget->description = $request->description;
// try to save this widget
try {
$widget->settings = json_encode(call_user_func([$widget->widget_type_handler, 'save'], $request));
$this->widgetRepository->edit($widget, $request);
} catch (MissingParameterException $e) {
// user omitted some value
return $this->invalidWidget($e->getMessage());
@@ -56,12 +59,6 @@ class EditWidget extends Controller
return $this->invalidWidget(trans('admin/widgets.cannotSave', ['exception' => $e->getMessage()]));
}
// save into database
$widget->save();
// fire event with editing widget
Event::fire(new \App\Events\EditWidget($widget));
// redirect with success notification
return redirect()
->back()
@@ -71,15 +68,12 @@ class EditWidget extends Controller
/**
* Deletes widget
*
* @param $id
* @param Widget $widget
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deleteWidget($id)
public function deleteWidget(Widget $widget)
{
// create new widget
$widget = Widget::findOrFail($id);
// check if widget area is deletable
if (!$widget->deletable) {
return redirect()
@@ -7,7 +7,7 @@ use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class WidgetsOverview extends Controller
{
public function getOverview()
public function index()
{
$widgets = Widget::where('language', LaravelLocalization::getCurrentLocale())
->paginate(25);
+17 -8
View File
@@ -3,7 +3,6 @@
namespace App\Http\Controllers\Visitor;
use App\CMS\Contracts\Repositories\Content;
use App\CMS\Helpers\PageRenderer;
use App\Http\Controllers\Controller;
use App\Models\Content\Content as ContentModel;
use Illuminate\Support\Facades\Auth;
@@ -24,11 +23,20 @@ class ContentPage extends Controller
$this->content = $content;
}
/**
* Load page by URL
*
* This method also caches content
*
* @param $url
*
* @return mixed
*/
public function getPage($url)
{
$contentModel = $this->content;
$page = Cache::remember('content-' . $url, setting('contentCacheLifetime', 5), function () use ($contentModel, $url) {
return $contentModel->getByURL($url);
$contentRepository = $this->content;
$page = Cache::remember('content-' . $url, setting('contentCacheLifetime', 5), function () use ($contentRepository, $url) {
return $contentRepository->getByURL($url);
});
// no page available
@@ -42,7 +50,7 @@ class ContentPage extends Controller
/**
* Method used for rendering page for visitor
*
* @param Content $page
* @param ContentModel $page
*
* @return mixed
* @throws \Exception
@@ -54,9 +62,10 @@ class ContentPage extends Controller
abort(404);
}
// add one new "view" for page
$page->view();
$displayPipeline = app('displayPipeline');
$page = $displayPipeline->run($page);
return Controller::VisitorsView($page->template, ['page' => $page]);
return PageRenderer::render($page);
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ class Homepage extends ContentPage
{
// try to find some homepage
$contentModel = $this->content;
$page = Cache::remember('hp', setting('homepageCacheLifetime', 5), function () use ($contentModel) {
$page = Cache::remember('homepage', setting('homepageCacheLifetime', 5), function () use ($contentModel) {
return $contentModel->getHomepage();
});
+13 -13
View File
@@ -3,35 +3,35 @@
Route::group(['namespace' => 'Widgets'], function () {
// list of all installed widget types
Route::get('widgets/overview', 'WidgetsOverview@getOverview')
Route::get('widgets', 'WidgetsOverview@index')
->name('widgets.overview');
// create new instance of widget of given type
Route::get('widgets/new/{type}', 'CreateNewWidget@getNew')
Route::get('widgets/new/{widgetType}', 'CreateNewWidget@getNew')
->name('widgets.new');
Route::post('widgets/new/{type}', 'CreateNewWidget@postNew')
Route::post('widgets/new/{widgetType}', 'CreateNewWidget@postNew')
->name('widgets.postNew');
// edit widget settings
Route::get('widgets/edit/{id}', 'EditWidget@getEdit')
Route::get('widgets/edit/{widget}', 'EditWidget@getEdit')
->name('widgets.edit');
// delete widget settings
Route::get('widgets/delete/{id}', 'EditWidget@deleteWidget')
Route::get('widgets/delete/{widget}', 'EditWidget@deleteWidget')
->name('widgets.delete');
Route::post('widgets/edit/{id}', 'EditWidget@postEdit')
Route::post('widgets/edit/{widget}', 'EditWidget@postEdit')
->name('widgets.postEdit');
// display form for association of widget and widget area
Route::get('widgets/associate/{widgetArea}', 'AssociateWidget@getList')
->name('widgets.associate');
Route::get('widgets/deassociate/{widgetId}/{widgetArea}', 'AssociateWidget@deleteAssociation')
Route::get('widgets/deassociate/{widget}/{widgetArea}', 'AssociateWidget@deleteAssociation')
->name('widgets.deleteAssociation');
Route::get('widgets/associate/{widgetId}/{widgetArea}', 'AssociateWidget@makeAssociation')
Route::get('widgets/associate/{widget}/{widgetArea}', 'AssociateWidget@makeAssociation')
->name('widgets.makeAssociation');
Route::group(['namespace' => 'Areas'], function () {
@@ -39,22 +39,22 @@ Route::group(['namespace' => 'Widgets'], function () {
->name('widgetareas.overview');
// form for new widget area
Route::get('widgets/areas/new', 'CreateNewWidgetArea@getNew')
Route::get('widgets/areas/new', 'CreateNewWidgetArea@create')
->name('widgetareas.new');
// form for new widget area
Route::post('widgets/areas/new', 'CreateNewWidgetArea@postNew')
Route::post('widgets/areas/new', 'CreateNewWidgetArea@store')
->name('widgetareas.postNew');
// edit form for widget area
Route::get('widgets/areas/edit/{id}', 'EditWidgetArea@getEdit')
Route::get('widgets/areas/edit/{widgetArea}', 'EditWidgetArea@edit')
->name('widgetareas.edit');
Route::post('widgets/areas/edit/{id}', 'EditWidgetArea@postEdit')
Route::post('widgets/areas/edit/{widgetArea}', 'EditWidgetArea@update')
->name('widgetareas.postEdit');
// edit form for widget area
Route::get('widgets/areas/delete/{id}', 'EditWidgetArea@deleteArea')
Route::get('widgets/areas/delete/{widgetArea}', 'EditWidgetArea@delete')
->name('widgetareas.delete');
});
});
+66
View File
@@ -0,0 +1,66 @@
<?php
namespace App\Listeners;
use App\Events\UploadFile;
use Illuminate\Support\Facades\File as FileFacade;
use Illuminate\Support\Str;
use Intervention\Image\Constraint;
use Intervention\Image\Facades\Image;
use Symfony\Component\HttpFoundation\File\File as SymphonyFile;
class CreateImageThumbnail
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
}
/**
* Handle the event.
*
* @param UploadFile $event
*
* @return void
*/
public function handle(UploadFile $event)
{
$uploadedFile = $event->uploadedFile;
// is uploaded file an image?
if (!Str::startsWith($uploadedFile->getMimeType(), 'image')) {
return;
}
// yes, create thumbnail
$this->createThumbnail($uploadedFile);
}
/**
* Create thumbnail of given image
*
* @param SymphonyFile $file
*/
private function createThumbnail(SymphonyFile $file)
{
// does thumbnail directory exist?
if (!is_dir(config('app.thumbnail_path'))) {
FileFacade::makeDirectory(config('app.thumbnail_path'));
}
// get image instance
$image = Image::make(config('app.upload_path') . DIRECTORY_SEPARATOR . $file->getFilename());
// resize image and keep aspect ration
$image->resize(env('THUMBNAIL_WIDTH', setting('previewSize', 300)), null, function (Constraint $constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
// save thumbnail with lower quality
$image->save(config('app.thumbnail_path') . DIRECTORY_SEPARATOR . $file->getFilename(), 75);
}
}
+7 -1
View File
@@ -17,7 +17,7 @@ use Modules\Categories\Entities\Category;
*/
class Content extends Model
{
use SoftDeletes, ModelTraits\Content, Nullable;
use SoftDeletes, Nullable;
public $timestamps = true;
protected $fillable = [
'userId',
@@ -163,4 +163,10 @@ class Content extends Model
return parent::save($options);
}
public function view()
{
$this->timestamps = false;
$this->increment('viewed');
}
}
@@ -1,95 +0,0 @@
<?php
namespace App\Models\Content\ModelTraits;
use App\Models\Content\ContentHasFile;
use App\Models\FileManager\Directory;
use App\Models\FileManager\File;
use Illuminate\Support\Facades\App;
trait Content
{
/**
* Upload and assign files to newly created content page
*
* @param $files
* @param $assignedFiles
* @param null $revisionId
*
* @return int
*/
public function uploadRelatedFiles($files, $assignedFiles = [], $revisionId = null)
{
$changed = 0;
// check if any file was removed
if ($revisionId) {
$changed += $this->removeRelatedFiles($revisionId, $assignedFiles);
}
// allow uploading only on created pages
if (!$this->id || !$files[0]) {
return $changed;
}
// 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::make(File::class);
foreach ($files as $file) {
if (!$file) {
continue;
}
$uploaded = $fileModel->upload($file, $data);
// add assignement
ContentHasFile::create([
'file_id' => $uploaded['id'],
'content_id' => $this->id
]);
if ($revisionId) {
$this->saveHistory($revisionId, 'file', null, ['file' => $uploaded['file']->getClientOriginalName()]);
}
$changed++;
}
return $changed;
}
/**
* Delete files from association
*
* @param $revisionId
*
* @return int
*/
private function removeRelatedFiles($revisionId, $assignedFiles)
{
$allFiles = $this->files()
->whereNotIn('id', $assignedFiles)
->get();
foreach ($allFiles as $file) {
$this->saveHistory($revisionId, 'file', $file->original_filename, ['file' => null]);
ContentHasFile::where('content_id', $this->id)
->where('file_id', $file->id)
->delete();
}
return count($allFiles);
}
public function view()
{
$this->viewed++;
$this->save(['timestamps' => false]);
}
}
@@ -10,7 +10,7 @@ trait ContentHistory
/**
* Returns history grouped by revisions (edit_batches)
*
* @param Content $content
* @param ContentModel $content
*
* @return array
*/
-41
View File
@@ -1,41 +0,0 @@
<?php
namespace App\Models\Widgets\ModelTraits;
use App\Events\CreateNewWidget;
use App\Http\Requests\Request;
use App\Models\Widgets\Widget as WidgetModel;
use App\Models\Widgets\WidgetType;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
trait Widget
{
/**
* Create new widget of given type
*
* @param WidgetType $widgetType
* @param Request $request
*
* @return WidgetModel
*/
public function createNew(WidgetType $widgetType, Request $request)
{
$settings = call_user_func([$widgetType->handler, 'save'], $request);
// create new widget
$widget = WidgetModel::create([
'widget_type_handler' => $widgetType->handler,
'language' => LaravelLocalization::getCurrentLocale(),
'user_id' => \Auth::user()->id,
'name' => $request->name,
'container_class' => $request->containerClass,
'container_id' => empty($request->containerId) ? null : $request->containerId,
'description' => $request->description,
'settings' => json_encode($settings),
]);
// fire event with newly created widget
\Event::fire(new CreateNewWidget($widget));
return $widget;
}
}
@@ -1,24 +0,0 @@
<?php
namespace App\Models\Widgets\ModelTraits;
use App\Models\Widgets\Widget;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
trait WidgetArea
{
public function getWidgets($uniqueCode = false)
{
$widgets = Widget::select('widgets.*', 'widgets.widget_type_handler', 'widget_areas.code as widget_area_code', 'widgets.name as widget_name', 'widgets.settings')
->join('widget_in_widget_area', 'widget_in_widget_area.widget_id', '=', 'widgets.id')
->join('widget_areas', 'widget_in_widget_area.widget_area_id', '=', 'widget_areas.id')
->where('language', LaravelLocalization::getCurrentLocale())
->orderBy('widget_in_widget_area.position');
if (!$uniqueCode) {
$widgets = $widgets->where('widget_areas.viewed', '>=', setting('preloadFrequentedWidgetAreasTreshold', 10));
} else {
$widgets = $widgets->where('code', $uniqueCode);
}
return $widgets;
}
}
+5
View File
@@ -22,4 +22,9 @@ class Widget extends Model
'viewed',
'deletable'
];
protected $casts = [
'settings' => 'object',
'deletable' => 'boolean',
];
}
+8 -3
View File
@@ -3,19 +3,24 @@
namespace App\Models\Widgets;
use Illuminate\Database\Eloquent\Model;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
/**
* Class WidgetArea
*/
class WidgetArea extends Model
{
use ModelTraits\WidgetArea;
public $timestamps = false;
public $timestamps = true;
protected $fillable = [
'name',
'code',
'description',
'deletable'
];
public function widgets()
{
return $this->hasMany(Widget::class)
->where('language', LaravelLocalization::getCurrentLocale());
}
}
+36
View File
@@ -13,6 +13,13 @@ use App\CMS\Handlers\Search\Content;
use App\CMS\Handlers\Search\Files;
use App\CMS\Handlers\Search\Presenters\AdminContent as AdminContentPresenter;
use App\CMS\Handlers\Search\Presenters\AdminFiles;
use App\CMS\Pipeline\DisplayPipeline\DisplayPipeline;
use App\CMS\Pipeline\DisplayPipeline\Process\AddViewedToPage;
use App\CMS\Pipeline\DisplayPipeline\Process\CompileShortcodes;
use App\CMS\Pipeline\SavePipeline\Process\SaveCommonFields;
use App\CMS\Pipeline\SavePipeline\Process\UploadRelatedFiles;
use App\CMS\Pipeline\SavePipeline\Process\UploadTitlePhoto;
use App\CMS\Pipeline\SavePipeline\SavePipeline;
use App\CMS\Repositories\Content\Content as ContentRepository;
use App\CMS\Repositories\Module as ModuleRepository;
use App\CMS\Repositories\Templates\Template as TemplateRepository;
@@ -41,6 +48,8 @@ class AppServiceProvider extends ServiceProvider
$this->registerWidgets();
$this->registerSettings();
$this->registerSearch();
$this->registerDisplayPipeline();
$this->registerSavePipeline();
}
}
@@ -64,6 +73,16 @@ class AppServiceProvider extends ServiceProvider
return new WidgetRegistrator($app);
});
// create singleton for display pipeline - pipeline used for displaying visitor pages
$this->app->singleton('displayPipeline', function ($app) {
return new DisplayPipeline();
});
// create singleton for display pipeline - pipeline used for displaying visitor pages
$this->app->singleton('saveContentPipeline', function ($app) {
return new SavePipeline();
});
// create registrator for template directories
$this->app->singleton('registerTemplateDir', function ($app) {
return new TemplateRegistrator($app);
@@ -115,4 +134,21 @@ class AppServiceProvider extends ServiceProvider
$registrator->register(new Content(), new AdminContentPresenter(), SearchEngineRegistrator::ADMIN);
$registrator->register(new Files(), new AdminFiles(), SearchEngineRegistrator::ADMIN);
}
private function registerDisplayPipeline()
{
$registrator = $this->app->make('displayPipeline');
$registrator->add(AddViewedToPage::class);
$registrator->add(CompileShortcodes::class);
}
private function registerSavePipeline()
{
$pipeline = $this->app->make('saveContentPipeline');
$pipeline->add(SaveCommonFields::class);
$pipeline->add(UploadTitlePhoto::class);
$pipeline->add(UploadRelatedFiles::class);
}
}
+86 -55
View File
@@ -2,6 +2,49 @@
namespace App\Providers;
use App\Events\AssignWidget;
use App\Events\AttemptToEditInvalidContent;
use App\Events\ChangeSettings;
use App\Events\CreateNewContent;
use App\Events\CreateNewUser;
use App\Events\CreateNewWidget;
use App\Events\CreateNewWidgetArea;
use App\Events\DeleteContent;
use App\Events\DeleteWidgetArea;
use App\Events\EditContent;
use App\Events\EditFile;
use App\Events\EditUser;
use App\Events\EditWidget;
use App\Events\EditWidgetArea;
use App\Events\MakeDraftFromContent;
use App\Events\PublishContent;
use App\Events\RemoveWidgetFromArea;
use App\Events\SetHomepage;
use App\Events\UploadFile;
use App\Listeners\CreateImageThumbnail;
use App\Listeners\Loggers\LogAssignWidget;
use App\Listeners\Loggers\LogAttemptToInvalidContentEdit;
use App\Listeners\Loggers\LogChangeSettings;
use App\Listeners\Loggers\LogCreatedUser;
use App\Listeners\Loggers\LogCreateNewContent;
use App\Listeners\Loggers\LogDeleteContent;
use App\Listeners\Loggers\LogDeleteWidgetArea;
use App\Listeners\Loggers\LogDraftFromContent;
use App\Listeners\Loggers\LogEditContent;
use App\Listeners\Loggers\LogEditFile;
use App\Listeners\Loggers\LogEditUser;
use App\Listeners\Loggers\LogEditWidget;
use App\Listeners\Loggers\LogEditWidgetArea;
use App\Listeners\Loggers\LogLogin;
use App\Listeners\Loggers\LogLogout;
use App\Listeners\Loggers\LogNewWidget;
use App\Listeners\Loggers\LogNewWidgetArea;
use App\Listeners\Loggers\LogPublishContent;
use App\Listeners\Loggers\LogRemoveWidgetFromArea;
use App\Listeners\Loggers\LogSetHomepage;
use App\Listeners\Loggers\LogUploadFile;
use Illuminate\Auth\Events\Login;
use Illuminate\Auth\Events\Logout;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
@@ -13,83 +56,71 @@ class EventServiceProvider extends ServiceProvider
* @var array
*/
protected $listen = [
'App\Events\CreateNewUser' => [
'App\Listeners\Loggers\LogCreatedUser',
CreateNewUser::class => [
LogCreatedUser::class,
],
'App\Events\EditUser' => [
'App\Listeners\Loggers\LogEditUser',
EditUser::class => [
LogEditUser::class,
],
'App\Events\CreateNewContent' => [
'App\Listeners\Loggers\LogCreateNewContent'
CreateNewContent::class => [
LogCreateNewContent::class
],
'App\Events\EditContent' => [
'App\Listeners\Loggers\LogEditContent'
EditContent::class => [
LogEditContent::class
],
'App\Events\PublishContent' => [
'App\Listeners\Loggers\LogPublishContent'
PublishContent::class => [
LogPublishContent::class
],
'App\Events\MakeDraftFromContent' => [
'App\Listeners\Loggers\LogDraftFromContent'
MakeDraftFromContent::class => [
LogDraftFromContent::class
],
'App\Events\SetHomepage' => [
'App\Listeners\Loggers\LogSetHomepage'
SetHomepage::class => [
LogSetHomepage::class
],
'App\Events\AttemptToEditInvalidContent' => [
'App\Listeners\Loggers\LogAttemptToInvalidContentEdit'
AttemptToEditInvalidContent::class => [
LogAttemptToInvalidContentEdit::class
],
'App\Events\DeleteContent' => [
'App\Listeners\Loggers\LogDeleteContent'
DeleteContent::class => [
LogDeleteContent::class
],
'App\Events\ChangeSettings' => [
'App\Listeners\Loggers\LogChangeSettings',
ChangeSettings::class => [
LogChangeSettings::class,
],
'App\Events\UploadFile' => [
'App\Listeners\Loggers\LogUploadFile'
UploadFile::class => [
LogUploadFile::class,
CreateImageThumbnail::class
],
'App\Events\EditFile' => [
'App\Listeners\Loggers\LogEditFile'
EditFile::class => [
LogEditFile::class
],
'App\Events\CreateNewWidgetArea' => [
'App\Listeners\Loggers\LogNewWidgetArea'
CreateNewWidgetArea::class => [
LogNewWidgetArea::class
],
'App\Events\EditWidgetArea' => [
'App\Listeners\Loggers\LogEditWidgetArea'
EditWidgetArea::class => [
LogEditWidgetArea::class
],
'App\Events\DeleteWidgetArea' => [
'App\Listeners\Loggers\LogDeleteWidgetArea'
DeleteWidgetArea::class => [
LogDeleteWidgetArea::class
],
'App\Events\CreateNewWidget' => [
'App\Listeners\Loggers\LogNewWidget'
CreateNewWidget::class => [
LogNewWidget::class
],
'App\Events\EditWidget' => [
'App\Listeners\Loggers\LogEditWidget'
EditWidget::class => [
LogEditWidget::class
],
'App\Events\AssignWidget' => [
'App\Listeners\Loggers\LogAssignWidget'
AssignWidget::class => [
LogAssignWidget::class
],
'App\Events\RemoveWidgetFromArea' => [
'App\Listeners\Loggers\LogRemoveWidgetFromArea'
RemoveWidgetFromArea::class => [
LogRemoveWidgetFromArea::class
],
// internal Laravel events - should work as auth.login and auth.logout, however it doesn't...
'Illuminate\Auth\Events\Login' => [
'App\Listeners\Loggers\LogLogin'
Login::class => [
LogLogin::class
],
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\Loggers\LogLogout'
Logout::class => [
LogLogout::class
],
];
/**
* Register any other events for your application.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
*
* @return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
//
}
}
+2 -1
View File
@@ -15,7 +15,8 @@
"mcamara/laravel-localization": "^1.1",
"franzose/closure-table": "^4.1",
"intervention/image": "^2.3",
"webwizo/laravel-shortcodes": "1.0.4"
"webwizo/laravel-shortcodes": "1.0.4",
"greggilbert/recaptcha": "^2.2@dev"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
Generated
+132 -79
View File
@@ -4,8 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "1d486fb23e76c7af1daf00bee207919c",
"content-hash": "957b49e5a2e691ad8dbc0e665a87d6c7",
"content-hash": "b986e3e1805bf5cb028c24818beeb9a4",
"packages": [
{
"name": "classpreloader/classpreloader",
@@ -59,7 +58,7 @@
"class",
"preload"
],
"time": "2016-01-24 12:28:38"
"time": "2016-01-24T12:28:38+00:00"
},
{
"name": "dnoegel/php-xdg-base-dir",
@@ -92,7 +91,7 @@
"MIT"
],
"description": "implementation of xdg base directory specification for php",
"time": "2014-10-24 07:27:01"
"time": "2014-10-24T07:27:01+00:00"
},
{
"name": "doctrine/annotations",
@@ -160,7 +159,7 @@
"docblock",
"parser"
],
"time": "2016-08-31 09:31:57"
"time": "2016-08-31T09:31:57+00:00"
},
{
"name": "doctrine/cache",
@@ -229,7 +228,7 @@
"cache",
"caching"
],
"time": "2016-07-15 15:57:08"
"time": "2016-07-15T15:57:08+00:00"
},
{
"name": "doctrine/collections",
@@ -295,7 +294,7 @@
"collections",
"iterator"
],
"time": "2016-09-01 10:39:08"
"time": "2016-09-01T10:39:08+00:00"
},
{
"name": "doctrine/common",
@@ -368,7 +367,7 @@
"persistence",
"spl"
],
"time": "2016-07-20 15:39:51"
"time": "2016-07-20T15:39:51+00:00"
},
{
"name": "doctrine/dbal",
@@ -440,7 +439,7 @@
"persistence",
"queryobject"
],
"time": "2016-08-25 23:11:10"
"time": "2016-08-25T23:11:10+00:00"
},
{
"name": "doctrine/inflector",
@@ -507,7 +506,7 @@
"singularize",
"string"
],
"time": "2016-05-12 17:23:41"
"time": "2016-05-12T17:23:41+00:00"
},
{
"name": "doctrine/lexer",
@@ -561,7 +560,7 @@
"lexer",
"parser"
],
"time": "2014-09-09 13:34:57"
"time": "2014-09-09T13:34:57+00:00"
},
{
"name": "erusev/parsedown",
@@ -600,7 +599,7 @@
"markdown",
"parser"
],
"time": "2015-10-04 16:44:32"
"time": "2015-10-04T16:44:32+00:00"
},
{
"name": "erusev/parsedown-extra",
@@ -644,7 +643,7 @@
"parsedown",
"parser"
],
"time": "2015-11-01 10:19:22"
"time": "2015-11-01T10:19:22+00:00"
},
{
"name": "franzose/closure-table",
@@ -702,7 +701,59 @@
"laravel",
"pages"
],
"time": "2016-07-08 08:19:46"
"time": "2016-07-08T08:19:46+00:00"
},
{
"name": "greggilbert/recaptcha",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/greggilbert/recaptcha.git",
"reference": "298cbc072e8ba734df2b8af798f848dacd27a4c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/greggilbert/recaptcha/zipball/298cbc072e8ba734df2b8af798f848dacd27a4c9",
"reference": "298cbc072e8ba734df2b8af798f848dacd27a4c9",
"shasum": ""
},
"require": {
"illuminate/support": "~5.1",
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.2-dev"
}
},
"autoload": {
"classmap": [
"src/migrations"
],
"psr-4": {
"Greggilbert\\Recaptcha\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Greg Gilbert",
"email": "greg@greg-gilbert.com"
}
],
"description": "reCAPTCHA Validator for Laravel 5",
"homepage": "http://github.com/greggilbert/recaptcha",
"keywords": [
"captcha",
"laravel",
"laravel5",
"recaptcha"
],
"time": "2017-04-06 17:10:49"
},
{
"name": "guzzlehttp/psr7",
@@ -872,7 +923,7 @@
"homepage": "http://www.acci.cz"
}
],
"time": "2014-04-08 15:00:19"
"time": "2014-04-08T15:00:19+00:00"
},
{
"name": "jakub-onderka/php-console-highlighter",
@@ -916,7 +967,7 @@
"homepage": "http://www.acci.cz/"
}
],
"time": "2015-04-20 18:58:01"
"time": "2015-04-20T18:58:01+00:00"
},
{
"name": "jeremeamia/SuperClosure",
@@ -974,7 +1025,7 @@
"serialize",
"tokenizer"
],
"time": "2016-02-29 04:36:50"
"time": "2016-02-29T04:36:50+00:00"
},
{
"name": "laravel/framework",
@@ -1104,7 +1155,7 @@
"framework",
"laravel"
],
"time": "2016-08-26 16:26:18"
"time": "2016-08-26T16:26:18+00:00"
},
{
"name": "laravelcollective/html",
@@ -1158,7 +1209,7 @@
],
"description": "HTML and Form Builders for the Laravel Framework",
"homepage": "http://laravelcollective.com",
"time": "2016-07-12 14:16:43"
"time": "2016-07-12T14:16:43+00:00"
},
{
"name": "league/flysystem",
@@ -1241,7 +1292,7 @@
"sftp",
"storage"
],
"time": "2016-08-26 20:18:09"
"time": "2016-08-26T20:18:09+00:00"
},
{
"name": "mcamara/laravel-localization",
@@ -1289,7 +1340,7 @@
"localization",
"php"
],
"time": "2016-08-25 18:28:07"
"time": "2016-08-25T18:28:07+00:00"
},
{
"name": "monolog/monolog",
@@ -1367,7 +1418,7 @@
"logging",
"psr-3"
],
"time": "2016-07-29 03:23:52"
"time": "2016-07-29T03:23:52+00:00"
},
{
"name": "mtdowling/cron-expression",
@@ -1411,7 +1462,7 @@
"cron",
"schedule"
],
"time": "2016-01-26 21:23:30"
"time": "2016-01-26T21:23:30+00:00"
},
{
"name": "nesbot/carbon",
@@ -1464,7 +1515,7 @@
"datetime",
"time"
],
"time": "2016-07-22 14:20:35"
"time": "2016-07-22T14:20:35+00:00"
},
{
"name": "nikic/php-parser",
@@ -1515,7 +1566,7 @@
"parser",
"php"
],
"time": "2016-08-30 20:37:51"
"time": "2016-08-30T20:37:51+00:00"
},
{
"name": "paragonie/random_compat",
@@ -1563,7 +1614,7 @@
"pseudorandom",
"random"
],
"time": "2016-04-03 05:47:09"
"time": "2016-04-03T05:47:09+00:00"
},
{
"name": "pingpong/generators",
@@ -1612,7 +1663,7 @@
"laravel",
"pingpong"
],
"time": "2016-02-26 04:53:40"
"time": "2016-02-26T04:53:40+00:00"
},
{
"name": "pingpong/menus",
@@ -1664,7 +1715,7 @@
"navigation",
"pingpong"
],
"time": "2016-08-23 05:51:55"
"time": "2016-08-23T05:51:55+00:00"
},
{
"name": "pingpong/modules",
@@ -1715,7 +1766,7 @@
"modules",
"pingpong"
],
"time": "2016-01-29 04:39:40"
"time": "2016-01-29T04:39:40+00:00"
},
{
"name": "pingpong/support",
@@ -1757,7 +1808,7 @@
}
],
"description": "Support Component of Pingpong Sky Package",
"time": "2016-01-07 08:23:04"
"time": "2016-01-07T08:23:04+00:00"
},
{
"name": "psr/http-message",
@@ -1854,7 +1905,7 @@
"psr",
"psr-3"
],
"time": "2016-01-06 21:40:42"
"time": "2016-01-06T21:40:42+00:00"
},
{
"name": "psy/psysh",
@@ -1926,7 +1977,7 @@
"interactive",
"shell"
],
"time": "2016-03-09 05:03:14"
"time": "2016-03-09T05:03:14+00:00"
},
{
"name": "swiftmailer/swiftmailer",
@@ -1979,7 +2030,7 @@
"mail",
"mailer"
],
"time": "2016-08-19 20:47:22"
"time": "2016-08-19T20:47:22+00:00"
},
{
"name": "symfony/console",
@@ -2039,7 +2090,7 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2016-07-30 07:22:48"
"time": "2016-07-30T07:22:48+00:00"
},
{
"name": "symfony/debug",
@@ -2096,7 +2147,7 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2016-07-30 07:22:48"
"time": "2016-07-30T07:22:48+00:00"
},
{
"name": "symfony/event-dispatcher",
@@ -2156,7 +2207,7 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2016-07-19 10:47:02"
"time": "2016-07-19T10:47:02+00:00"
},
{
"name": "symfony/finder",
@@ -2205,7 +2256,7 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:40:00"
"time": "2016-06-29T05:40:00+00:00"
},
{
"name": "symfony/http-foundation",
@@ -2258,7 +2309,7 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2016-07-17 13:54:30"
"time": "2016-07-17T13:54:30+00:00"
},
{
"name": "symfony/http-kernel",
@@ -2340,7 +2391,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2016-07-30 09:29:03"
"time": "2016-07-30T09:29:03+00:00"
},
{
"name": "symfony/polyfill-mbstring",
@@ -2399,7 +2450,7 @@
"portable",
"shim"
],
"time": "2016-08-30 17:06:17"
"time": "2016-08-30T17:06:17+00:00"
},
{
"name": "symfony/polyfill-php56",
@@ -2455,7 +2506,7 @@
"portable",
"shim"
],
"time": "2016-08-17 08:39:54"
"time": "2016-08-17T08:39:54+00:00"
},
{
"name": "symfony/polyfill-util",
@@ -2507,7 +2558,7 @@
"polyfill",
"shim"
],
"time": "2016-05-18 14:26:46"
"time": "2016-05-18T14:26:46+00:00"
},
{
"name": "symfony/process",
@@ -2556,7 +2607,7 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2016-07-28 11:13:34"
"time": "2016-07-28T11:13:34+00:00"
},
{
"name": "symfony/routing",
@@ -2631,7 +2682,7 @@
"uri",
"url"
],
"time": "2016-06-29 05:40:00"
"time": "2016-06-29T05:40:00+00:00"
},
{
"name": "symfony/translation",
@@ -2695,7 +2746,7 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2016-07-30 07:22:48"
"time": "2016-07-30T07:22:48+00:00"
},
{
"name": "symfony/var-dumper",
@@ -2758,7 +2809,7 @@
"debug",
"dump"
],
"time": "2016-07-26 08:03:56"
"time": "2016-07-26T08:03:56+00:00"
},
{
"name": "vlucas/phpdotenv",
@@ -2808,7 +2859,7 @@
"env",
"environment"
],
"time": "2016-09-01 10:05:43"
"time": "2016-09-01T10:05:43+00:00"
},
{
"name": "watson/sitemap",
@@ -2854,7 +2905,7 @@
"laravel",
"sitemaps"
],
"time": "2016-08-18 23:27:53"
"time": "2016-08-18T23:27:53+00:00"
},
{
"name": "webwizo/laravel-shortcodes",
@@ -2915,7 +2966,7 @@
"shortcodes",
"wordpress"
],
"time": "2016-08-25 06:02:46"
"time": "2016-08-25T06:02:46+00:00"
}
],
"packages-dev": [
@@ -2971,7 +3022,7 @@
"profiler",
"webprofiler"
],
"time": "2016-08-25 20:55:54"
"time": "2016-08-25T20:55:54+00:00"
},
{
"name": "doctrine/instantiator",
@@ -3025,7 +3076,7 @@
"constructor",
"instantiate"
],
"time": "2016-03-31 10:24:22"
"time": "2016-03-31T10:24:22+00:00"
},
{
"name": "fzaninotto/faker",
@@ -3075,7 +3126,7 @@
"faker",
"fixtures"
],
"time": "2016-09-01 09:55:47"
"time": "2016-09-01T09:55:47+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@@ -3126,7 +3177,7 @@
"keywords": [
"test"
],
"time": "2016-01-19 12:08:55"
"time": "2016-01-19T12:08:55+00:00"
},
{
"name": "ignasbernotas/laravel-model-generator",
@@ -3169,7 +3220,7 @@
"model",
"schema"
],
"time": "2016-05-24 16:57:40"
"time": "2016-05-24T16:57:40+00:00"
},
{
"name": "maximebf/debugbar",
@@ -3230,7 +3281,7 @@
"debug",
"debugbar"
],
"time": "2016-08-28 15:57:48"
"time": "2016-08-28T15:57:48+00:00"
},
{
"name": "mockery/mockery",
@@ -3295,7 +3346,7 @@
"test double",
"testing"
],
"time": "2016-09-03 07:05:34"
"time": "2016-09-03T07:05:34+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -3349,7 +3400,7 @@
"reflection",
"static analysis"
],
"time": "2015-12-27 11:43:31"
"time": "2015-12-27T11:43:31+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
@@ -3394,7 +3445,7 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"time": "2016-06-10 09:48:41"
"time": "2016-06-10T09:48:41+00:00"
},
{
"name": "phpdocumentor/type-resolver",
@@ -3441,7 +3492,7 @@
"email": "me@mikevanriel.com"
}
],
"time": "2016-06-10 07:14:17"
"time": "2016-06-10T07:14:17+00:00"
},
{
"name": "phpspec/prophecy",
@@ -3503,7 +3554,7 @@
"spy",
"stub"
],
"time": "2016-07-19 16:08:43"
"time": "2016-07-19T16:08:43+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -3565,7 +3616,7 @@
"testing",
"xunit"
],
"time": "2015-10-06 15:47:00"
"time": "2015-10-06T15:47:00+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -3612,7 +3663,7 @@
"filesystem",
"iterator"
],
"time": "2015-06-21 13:08:43"
"time": "2015-06-21T13:08:43+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -3653,7 +3704,7 @@
"keywords": [
"template"
],
"time": "2015-06-21 13:50:34"
"time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
@@ -3697,7 +3748,7 @@
"keywords": [
"timer"
],
"time": "2016-05-12 18:03:57"
"time": "2016-05-12T18:03:57+00:00"
},
{
"name": "phpunit/php-token-stream",
@@ -3746,7 +3797,7 @@
"keywords": [
"tokenizer"
],
"time": "2015-09-23 14:46:55"
"time": "2015-09-23T14:46:55+00:00"
},
{
"name": "phpunit/phpunit",
@@ -3818,7 +3869,7 @@
"testing",
"xunit"
],
"time": "2016-08-28 06:58:45"
"time": "2016-08-28T06:58:45+00:00"
},
{
"name": "phpunit/phpunit-mock-objects",
@@ -3874,7 +3925,7 @@
"mock",
"xunit"
],
"time": "2015-10-02 06:51:40"
"time": "2015-10-02T06:51:40+00:00"
},
{
"name": "sebastian/comparator",
@@ -3938,7 +3989,7 @@
"compare",
"equality"
],
"time": "2015-07-26 15:48:44"
"time": "2015-07-26T15:48:44+00:00"
},
{
"name": "sebastian/diff",
@@ -3990,7 +4041,7 @@
"keywords": [
"diff"
],
"time": "2015-12-08 07:14:41"
"time": "2015-12-08T07:14:41+00:00"
},
{
"name": "sebastian/environment",
@@ -4040,7 +4091,7 @@
"environment",
"hhvm"
],
"time": "2016-08-18 05:49:44"
"time": "2016-08-18T05:49:44+00:00"
},
{
"name": "sebastian/exporter",
@@ -4107,7 +4158,7 @@
"export",
"exporter"
],
"time": "2016-06-17 09:04:28"
"time": "2016-06-17T09:04:28+00:00"
},
{
"name": "sebastian/global-state",
@@ -4158,7 +4209,7 @@
"keywords": [
"global state"
],
"time": "2015-10-12 03:26:01"
"time": "2015-10-12T03:26:01+00:00"
},
{
"name": "sebastian/recursion-context",
@@ -4211,7 +4262,7 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"time": "2016-01-28 05:39:29"
"time": "2016-01-28T05:39:29+00:00"
},
{
"name": "sebastian/version",
@@ -4246,7 +4297,7 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"time": "2015-06-21 13:59:46"
"time": "2015-06-21T13:59:46+00:00"
},
{
"name": "symfony/css-selector",
@@ -4299,7 +4350,7 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2016-06-29 05:40:00"
"time": "2016-06-29T05:40:00+00:00"
},
{
"name": "symfony/dom-crawler",
@@ -4355,7 +4406,7 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"time": "2016-07-30 07:22:48"
"time": "2016-07-30T07:22:48+00:00"
},
{
"name": "symfony/yaml",
@@ -4410,7 +4461,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"time": "2016-09-02 02:14:06"
"time": "2016-09-02T02:14:06+00:00"
},
{
"name": "webmozart/assert",
@@ -4460,12 +4511,14 @@
"check",
"validate"
],
"time": "2016-08-18 09:30:53"
"time": "2016-08-18T09:30:53+00:00"
}
],
"aliases": [],
"minimum-stability": "dev",
"stability-flags": [],
"stability-flags": {
"greggilbert/recaptcha": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
+1
View File
@@ -19,3 +19,4 @@
!sitemap.php
!image.php
!view.php
!recaptcha.php
+2
View File
@@ -172,6 +172,7 @@ return [
App\Providers\RouteServiceProvider::class,
App\Providers\BladeExtender::class,
\App\Providers\TemplateServiceProvider::class,
\Greggilbert\Recaptcha\RecaptchaServiceProvider::class,
],
/*
@@ -221,6 +222,7 @@ return [
'Validator' => Illuminate\Support\Facades\Validator::class,
'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class,
'View' => Illuminate\Support\Facades\View::class,
'Recaptcha' => Greggilbert\Recaptcha\Facades\Recaptcha::class,
'Shortcode' => Webwizo\Shortcodes\Facades\Shortcode::class,
],
+4 -1
View File
@@ -54,7 +54,10 @@ return [
|
*/
'from' => ['address' => null, 'name' => null],
'from' => [
'address' => env('MAIL_FROM_ADDRESS', env('MAIL_USERNAME')),
'name' => env('MAIL_FROM_NAME', '')
],
/*
|--------------------------------------------------------------------------
+66
View File
@@ -0,0 +1,66 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| API Keys
|--------------------------------------------------------------------------
|
| Set the public and private API keys as provided by reCAPTCHA.
|
| In version 2 of reCAPTCHA, public_key is the Site key,
| and private_key is the Secret key.
|
*/
'public_key' => env('RECAPTCHA_PUBLIC_KEY', ''),
'private_key' => env('RECAPTCHA_PRIVATE_KEY', ''),
/*
|--------------------------------------------------------------------------
| Template
|--------------------------------------------------------------------------
|
| Set a template to use if you don't want to use the standard one.
|
*/
'template' => '',
/*
|--------------------------------------------------------------------------
| Driver
|--------------------------------------------------------------------------
|
| Determine how to call out to get response; values are 'curl' or 'native'.
| Only applies to v2.
|
*/
'driver' => 'curl',
/*
|--------------------------------------------------------------------------
| Options
|--------------------------------------------------------------------------
|
| Various options for the driver
|
*/
'options' => [
'curl_timeout' => 1,
'curl_verify' => true,
],
/*
|--------------------------------------------------------------------------
| Version
|--------------------------------------------------------------------------
|
| Set which version of ReCaptcha to use.
|
*/
'version' => 2,
];
-68
View File
@@ -16,28 +16,6 @@ use Modules\Blog\Article\Entities\Comment;
class Article extends Handler implements ContentTitles, AdvancedContentModifier, InstallableModule
{
/**
* 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)
{
$content->comments = new Collection();
if (isset($content->moduleSettings['allowComments']) && $content->moduleSettings['allowComments']) {
$content->comments = Comment::where('content_id', $content->id)
->with('author')
->where('approved', 1)
->orderBy('created_at')
->get();
}
return Controller::VisitorsView($content->template, ['page' => $content, 'extra' => $parameters]);
}
public static function getExtendedFormInputsCreate()
{
$sections = parent::getExtendedFormInputsCreate();
@@ -52,41 +30,6 @@ class Article extends Handler implements ContentTitles, AdvancedContentModifier,
return self::getExtendedFormInputsCreate();
}
/**
* Save module-specific values into database
*
* @param Content $content
* @param Request $request
*
* @return mixed|void
*/
public static function createNew(Content &$content, array $inputData)
{
$content->moduleSettings = ['allowComments' => (int)isset($inputData['allowComments'])];
}
/**
* 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
*
* @return void
*/
public static function edit(Content $content, $request)
{
$settings = $content->moduleSettings;
if (!is_object($settings))
$settings = new \stdClass();
$settings->allowComments = isset($request['allowComments']) ? (int)$request['allowComments'] : 0;
$content->moduleSettings = $settings;
$content->save();
}
/**
* Register admin menu
*
@@ -198,17 +141,6 @@ class Article extends Handler implements ContentTitles, AdvancedContentModifier,
{
}
/**
* Load some extra data for content management form?
*
* @param Content $content
*
* @return mixed
*/
public static function loadExtraData(Content $content)
{
}
/**
* Does this module support categories?
*
@@ -0,0 +1,33 @@
<?php
namespace Modules\Blog\Article\Pipeline\DisplayContent;
use App\CMS\Contracts\Content\DisplayPipeline\Process;
use App\Models\Content\Content;
use Illuminate\Support\Collection;
use Modules\Blog\Article\Entities\Comment;
use Modules\Blog\Article\Handlers\Article;
class LoadCommentsForBlogpost implements Process
{
/**
* Process and modify given page
*
* @param Content $content
*
* @return void
*/
function handle(Content & $content)
{
if ($content->moduleHandler != Article::class)
return;
$content->comments = new Collection();
if (isset($content->moduleSettings['allowComments']) && $content->moduleSettings['allowComments']) {
$content->comments = Comment::where('content_id', $content->id)
->with('author')
->where('approved', 1)
->orderBy('created_at')
->get();
}
}
}
@@ -0,0 +1,29 @@
<?php
namespace Modules\Blog\Article\Pipeline\SaveContent;
use App\CMS\Contracts\Content\SavePipeline\Process;
use App\Models\Content\Content;
use Modules\Blog\Article\Handlers\Article;
class TurnCommentsOnOrOff implements Process
{
/**
* Process and modify given page
*
* @param Content $content
* @param array $input
*
* @return void
*/
function handle(Content & $content, array & $input)
{
if (trim($content->moduleHandler, '\\') !== Article::class) {
return;
}
$settings = $content->moduleSettings;
$settings['allowComments'] = isset($input['allowComments']) ? (int)$input['allowComments'] : 0;
$content->moduleSettings = $settings;
$content->save();
}
}
@@ -1,6 +1,8 @@
<?php namespace Modules\Blog\Article\Providers;
use App\Providers\ModuleServiceProvider;
use Modules\Blog\Article\Pipeline\DisplayContent\LoadCommentsForBlogpost;
use Modules\Blog\Article\Pipeline\SaveContent\TurnCommentsOnOrOff;
class ArticleServiceProvider extends ModuleServiceProvider
{
@@ -14,6 +16,11 @@ class ArticleServiceProvider extends ModuleServiceProvider
parent::boot();
$this->app->register(ArticleEventServiceProvider::class);
// load comments for blogpost
app('displayPipeline')->add(LoadCommentsForBlogpost::class);
app('saveContentPipeline')->add(TurnCommentsOnOrOff::class);
}
protected function setModuleAlias()
@@ -10,8 +10,8 @@
<div class="card-header">
<div class="header-block">
<p class="title">
<img src="@gravatar($comment->author->email, 25)" class="img-rounded" alt="">
{{$comment->author->name}} ({{$comment->author->email}})
<img src="@gravatar($comment->email, 25)" class="img-rounded" alt="">
{{$comment->name}} ({{$comment->email}})
</p>
</div>
</div>
@@ -21,12 +21,12 @@
</p>
</div>
<div class="card-footer">
@lang('article::comments.createdAt', ['date' => \App\CMS\Helpers\Template::date($comment->created_at)])
@lang('article::comments.createdAt', ['date' => \App\CMS\Helpers\Date::date($comment->created_at)])
|
@lang('article::comments.commentedArticle'):
@if($comment->article)
@if(!is_null($comment->article))
<a href="{{route('page.content', ['url' => $comment->article->url])}}" target="_blank">
{{$comment->article->title}}
</a>
@@ -1,18 +1,8 @@
<?php
namespace Modules\Blog\ArticleList\Handlers;
use App\CMS\Contracts\Repositories\Content as IContent;
use App\CMS\Handlers\Handler;
use App\Http\Controllers\Controller;
use App\Models\Content\Content;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Modules\Blog\Article\Entities\Article as ArticleModel;
use Modules\Blog\Article\Handlers\Article;
use Modules\Categories\Entities\Category;
class ArticleList extends Handler
{
@@ -28,114 +18,7 @@ class ArticleList extends Handler
}, 20, ['icon' => 'fa fa-fw fa-book']);
}
$blogSubmenu->route('content.new', trans('articlelist::module.name'), ['id' => 'blog-articlelist'], 100, ['icon' => 'fa fa-fw fa-list-alt']);
}
/**
* Filter articles on article list using archive
*
* @param $articles
*/
protected static function archive(&$articles)
{
$year = Input::get('y');
$month = Input::get('m');
$day = Input::get('d');
if ($year) {
$articles = $articles->where(DB::raw('YEAR(created_at)'), $year);
}
if ($month) {
$articles = $articles->where(DB::raw('MONTH(created_at)'), $month);
}
if ($day) {
$articles = $articles->where(DB::raw('DAY(created_at)'), $day);
}
}
/**
* Filter article list to some specified category
*
* Category URL is specified as GET attribute "category"
*
* @param $articles
*/
protected static function category(&$articles)
{
$categoryUrl = Input::get('category');
$categoriesEnabled = \Module::get('Categories')
->enabled();
if ($categoryUrl && $categoriesEnabled) {
$category = Category::where('url', $categoryUrl)
->firstOrFail();
$subcategories = $category->getChildren()
->toArray();
$categories = [$category->id];
$categories = array_merge($categories, array_map(function ($cat) {
return $cat['id'];
}, $subcategories));
$articles = $articles->whereIn('category_id', $categories);
}
}
/**
* 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)
{
$articles = ArticleModel::where('moduleHandler', Article::class)
->with('comments')
->with('category')
->where(function ($query) {
$query->where('publishedFrom', '<', Carbon::now())
->orWhereNull('publishedFrom');
})
->where(function ($query) {
$query->where('publishedTo', '>', Carbon::now())
->orWhereNull('publishedTo');
})
->orderBy('publishedFrom', 'DESC')
->orderBy('created_at', 'DESC');
// show articles for not-logged users of even for logged onew?
$articles = !Auth::user() ? $articles->where('status', IContent::STATUS_PUBLIC) : $articles->whereIn('status', [
IContent::STATUS_PUBLIC,
IContent::STATUS_PROTECTED
]);
// selected articles from archive?
self::archive($articles);
// is given any category?
self::category($articles);
// show articles only from specified user
$author = Input::get('author');
if ($author) {
$user = User::findOrFail($author);
$articles = $articles->where('user_id', $user->id);
}
$articles = $articles->paginate(setting('articlesPerPage', 20));
return Controller::VisitorsView($content->template, [
'page' => $content,
'articles' => $articles,
'extra' => $parameters
]);
$blogSubmenu->route('content.new', trans('articlelist::module.name'), ['id' => config('articlelist.alias')], 100, ['icon' => 'fa fa-fw fa-list-alt']);
}
public static function supportCategories()
@@ -0,0 +1,120 @@
<?php
namespace Modules\Blog\ArticleList\Pipeline\DisplayContent;
use App\CMS\Contracts\Content\DisplayPipeline\Process;
use App\CMS\Contracts\Repositories\Content as IContent;
use App\Models\Content\Content;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Input;
use Modules\Blog\Article\Entities\Article as ArticleModel;
use Modules\Blog\Article\Handlers\Article;
use Modules\Blog\ArticleList\Handlers\ArticleList;
class LoadArticlesForList implements Process
{
/**
* Process and modify given page
*
* @param Content $page
*
* @return mixed
*/
function handle(Content & $page)
{
// load articles only for article list
if ($page->moduleHandler != ArticleList::class)
return;
$articles = ArticleModel::where('moduleHandler', Article::class)
->with('comments')
->with('category')
->where(function ($query) {
$query->where('publishedFrom', '<', Carbon::now())
->orWhereNull('publishedFrom');
})
->where(function ($query) {
$query->where('publishedTo', '>', Carbon::now())
->orWhereNull('publishedTo');
})
->orderBy('publishedFrom', 'DESC')
->orderBy('created_at', 'DESC');
// show articles for not-logged users of even for logged onew?
$articles = !Auth::user() ? $articles->where('status', IContent::STATUS_PUBLIC) : $articles->whereIn('status', [
IContent::STATUS_PUBLIC,
IContent::STATUS_PROTECTED
]);
// selected articles from archive?
$this->archive($articles);
// is given any category?
$this->category($articles);
// show articles only from specified user
$author = Input::get('author');
if ($author) {
$user = User::findOrFail($author);
$articles = $articles->where('user_id', $user->id);
}
$page->articles = $articles->paginate(setting('articlesPerPage', 20));
}
/**
* Filter articles on article list using archive
*
* @param $articles
*/
protected function archive(&$articles)
{
$year = Input::get('y');
$month = Input::get('m');
$day = Input::get('d');
if ($year) {
$articles = $articles->where(DB::raw('YEAR(created_at)'), $year);
}
if ($month) {
$articles = $articles->where(DB::raw('MONTH(created_at)'), $month);
}
if ($day) {
$articles = $articles->where(DB::raw('DAY(created_at)'), $day);
}
}
/**
* Filter article list to some specified category
*
* Category URL is specified as GET attribute "category"
*
* @param $articles
*/
protected function category(&$articles)
{
$categoryUrl = Input::get('category');
$categoriesEnabled = \Module::get('Categories')
->enabled();
if ($categoryUrl && $categoriesEnabled) {
$category = Category::where('url', $categoryUrl)
->firstOrFail();
$subcategories = $category->getChildren()
->toArray();
$categories = [$category->id];
$categories = array_merge($categories, array_map(function ($cat) {
return $cat['id'];
}, $subcategories));
$articles = $articles->whereIn('category_id', $categories);
}
}
}
@@ -1,6 +1,7 @@
<?php namespace Modules\Blog\ArticleList\Providers;
use App\Providers\ModuleServiceProvider;
use Modules\Blog\ArticleList\Pipeline\DisplayContent\LoadArticlesForList;
class ArticleListServiceProvider extends ModuleServiceProvider
{
@@ -13,4 +14,11 @@ class ArticleListServiceProvider extends ModuleServiceProvider
{
$this->path = __DIR__;
}
public function boot()
{
parent::boot();
app('displayPipeline')->add(LoadArticlesForList::class);
}
}
+1 -1
View File
@@ -28,6 +28,6 @@ class Category extends Entity
public function content()
{
return $this->hasMany(Content::class);
return $this->hasMany(Content::class, 'categoryId');
}
}
@@ -16,47 +16,6 @@ class ContactForm extends Handler implements ContentTitles, AdvancedContentModif
return ContactFormHistory::class;
}
/**
* Save module-specific values into database
*
* @param Content $content
* @param array $inputData
*
* @return mixed|void
*/
public static function createNew(Content &$content, array $inputData)
{
$settings = [
'phone' => $inputData['phone'],
'email' => $inputData['email'],
'contactEmail' => $inputData['contactEmail'],
'subject' => $inputData['subject'],
'companyName' => $inputData['companyName'],
'address' => $inputData['address'],
'gpsLat' => $inputData['gpsLat'],
'gpsLng' => $inputData['gpsLng'],
];
// save settings
$content->moduleSettings = $settings;
}
/**
* 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
*
* @return mixed|void
*/
public static function edit(Content $content, $request)
{
self::createNew($content, $request);
$content->save();
}
public static function getModuleId()
{
$handler = config('contactform.handler');
@@ -190,15 +149,4 @@ class ContactForm extends Handler implements ContentTitles, AdvancedContentModif
public static function delete(Content $content)
{
}
/**
* Load some extra data for content management form?
*
* @param Content $content
*
* @return mixed
*/
public static function loadExtraData(Content $content)
{
}
}
@@ -15,6 +15,7 @@ class SendNewEmailRequest extends Request
'name' => 'required',
'email' => 'required|email',
'message' => 'required',
'g-recaptcha-response' => 'required|recaptcha',
];
}
}
@@ -0,0 +1,39 @@
<?php
namespace Modules\ContactForm\Pipeline\SavePipeline;
use App\CMS\Contracts\Content\SavePipeline\Process;
use App\Models\Content\Content;
use Modules\ContactForm\Handlers\ContactForm;
class SaveContactInformation implements Process
{
/**
* Process and modify given page
*
* @param Content $page
* @param array $input
*
* @return void>
*/
function handle(Content & $page, array & $input)
{
if (trim($page->moduleHandler, '\\') != ContactForm::class) {
return;
}
$settings = [
'phone' => $input['phone'],
'email' => $input['email'],
'contactEmail' => $input['contactEmail'],
'subject' => $input['subject'],
'companyName' => $input['companyName'],
'address' => $input['address'],
'gpsLat' => $input['gpsLat'],
'gpsLng' => $input['gpsLng'],
];
// save settings
$page->moduleSettings = $settings;
$page->save();
}
}
@@ -2,6 +2,7 @@
use App\Providers\ModuleServiceProvider;
use Modules\ContactForm\Handlers\ContactForm;
use Modules\ContactForm\Pipeline\SavePipeline\SaveContactInformation;
use Modules\ContactForm\Widgets\Address\Address;
use Modules\ContactForm\Widgets\Form\Form;
@@ -16,6 +17,8 @@ class ContactFormServiceProvider extends ModuleServiceProvider
{
parent::boot();
$this->registerWidgets();
app('saveContentPipeline')->add(SaveContactInformation::class);
}
/**
@@ -25,8 +28,6 @@ class ContactFormServiceProvider extends ModuleServiceProvider
*/
public function register()
{
$registrator = $this->app->make('registerSettingsExtension');
$registrator->register('contactForm', 'contactform::module.name', 'contactform::admin.settings.form');
}
private function registerWidgets()
@@ -1,5 +0,0 @@
<?php
return [
"recaptchaSecret" => "Application secret kez pro reCaptcha",
"recaptchaSiteKey" => "Site key pro reCaptcha",
];
@@ -1,5 +0,0 @@
<?php
return [
'recaptchaSiteKey' => 'reCAPTCHA site key',
'recaptchaSecret' => 'reCAPTCHA application secret key',
];
@@ -1,5 +0,0 @@
<?php
return [
"recaptchaSecret" => "Application secret key pre reCaptcha",
"recaptchaSiteKey" => "Site key pre reCaptcha",
];
@@ -77,26 +77,26 @@
@lang('contactform::admin/content.email')
</label>
<input class="form-control" type="email" name="email" value="{{$page->moduleSettings->email or ""}}" />
<input class="form-control" type="email" name="email" value="{{$page->moduleSettings['email'] or ''}}" />
<label class="label-control">
@lang('contactform::admin/content.phone')
</label>
<input class="form-control" type="tel" name="phone" value="{{$page->moduleSettings->phone or ""}}" />
<input class="form-control" type="tel" name="phone" value="{{$page->moduleSettings['phone'] or ''}}" />
<label class="label-control">
@lang('contactform::admin/content.compName')
</label>
<input class="form-control" type="text" name="companyName"
value="{{$page->moduleSettings->companyName or ""}}" />
value="{{$page->moduleSettings['companyName'] or ''}}" />
<label class="label-control">
@lang('contactform::admin/content.address')
</label>
<textarea rows="3" class="form-control" name="address">{{$page->moduleSettings->address or ""}}</textarea>
<textarea rows="3" class="form-control" name="address">{{$page->moduleSettings['address'] or ''}}</textarea>
</div>
<div class="column col-lg-6">
@@ -105,14 +105,14 @@
</label>
<input class="form-control" type="email" name="contactEmail"
value="{{$page->moduleSettings->contactEmail or \Auth::user()->email}}" />
value="{{$page->moduleSettings['contactEmail'] or \Auth::user()->email}}" />
<label class="label-control">
@lang('contactform::admin/content.subject')
</label>
<input class="form-control" type="text" name="subject"
value="{{$page->moduleSettings->subject or trans('contactform::admin/content.defaultSubject')}}" />
value="{{$page->moduleSettings['subject'] or trans('contactform::admin/content.defaultSubject')}}" />
<div class="row">
<div class="column col-lg-6">
@@ -120,7 +120,7 @@
@lang('contactform::admin/content.gpsLat')
</label>
<input class="form-control" type="text" value="{{$page->moduleSettings->gpsLat or ""}}"
<input class="form-control" type="text" value="{{$page->moduleSettings['gpsLat'] or ''}}"
name="gpsLat" />
</div>
<div class="column col-lg-6">
@@ -128,7 +128,7 @@
@lang('contactform::admin/content.gpsLng')
</label>
<input class="form-control" type="text" value="{{$page->moduleSettings->gpsLng or ""}}"
<input class="form-control" type="text" value="{{$page->moduleSettings['gpsLng'] or ''}}"
name="gpsLng" />
</div>
</div>
@@ -1,13 +0,0 @@
<label class="control-label">
@lang('contactform::admin/settings.recaptchaSiteKey')
</label>
<input class="form-control" type="text" name="recaptchaSiteKey" value="{{old('recaptchaSiteKey', isset($settings->recaptchaSiteKey) ? $settings->recaptchaSiteKey['val'] : '')}}" />
<label class="control-label">
@lang('contactform::admin/settings.recaptchaSecret')
</label>
<input class="form-control" type="text" name="recaptchaSecret" value="{{old('recaptchaSecret', isset($settings->recaptchaSecret) ? $settings->recaptchaSecret['val'] : '')}}" />
<em><a href="https://www.google.com/recaptcha/admin#list" target="_blank">reCAPTCHA</a></em>
@@ -1,4 +0,0 @@
<p>
<strong>Ahoj {{$data->name}}</strong>
</p>
{{$data->message}}
@@ -24,15 +24,15 @@ class Presenter implements WidgetRenderer
if (!$form)
return null;
$formData = json_decode($form->moduleSettings);
$formData = $form->moduleSettings;
$code = '<div class="address-widget ' . e($widget->container_class) . '"';
if ($widget->container_id) {
$code .= ' id="' . e($widget->container_id).'"';
}
$code .= '>';
$code .= "<p class='name'>".e($formData->companyName).'</p>';
$code .= nl2br($formData->address);
$code .= "<p class='name'>".e($formData['companyName']).'</p>';
$code .= nl2br($formData['address']);
$code .= "</div>";
return $code;
@@ -32,8 +32,6 @@ class Presenter implements WidgetRenderer
return null;
}
$form->moduleSettings = json_decode($form->moduleSettings);
return view(self::$template, ['widget' => $widget, 'form' => $form]);
}
@@ -1,7 +1,5 @@
@import "../imports";
/* *******************************************
* Item List general styles
********************************************** */
@@ -10,7 +8,6 @@
list-style: none;
padding: 0;
margin: 0;
margin-bottom: 0;
line-height: $item-list-line-height;
@include media(lg) {
@@ -29,11 +26,11 @@
flex-flow: column nowrap;
&.striped {
& > li {
& > div {
border-bottom: 1px solid $item-list-color-border;
}
& > li:nth-child(2n + 1) {
& > div:nth-child(2n + 1) {
background-color: lighten($color-divider, 12%);
@include media-down(sm) {
@@ -47,12 +44,10 @@
}
}
/* *******************************************
* Item general styles
********************************************** */
.item-list {
.item {
display: flex;
@@ -117,12 +112,10 @@
}
}
/* *******************************************
* Item components
********************************************** */
.item-list {
/********************************************
@@ -195,7 +188,7 @@
display: flex;
flex-basis: 60px + $item-list-padding-x;
&.xs{
&.xs {
flex-basis: 30px + $item-list-padding-x;
}
@@ -220,7 +213,7 @@
.item-img {
flex-grow: 1;
align-self: stretch;
background-color: #efefef;
background-color: #EFEFEF;
padding-bottom: 100%;
width: 100%;
height: 0;
@@ -328,14 +321,13 @@
left: 100%;
}
.item-actions-list {
padding: 0;
list-style: none;
white-space: nowrap;
padding: 0 5px;
li{
li {
display: inline-block;
padding: 0;
}
@@ -367,7 +359,6 @@
}
/* *******************************************
* Adjustments
********************************************** */
@@ -1,5 +1,9 @@
@import "../../../imports";
.item-list {
}
.items-list-page {
.title-search-block {
@@ -313,12 +317,7 @@
text-align: left;
}
}
}
}
}
}
+56 -56
View File
@@ -1,59 +1,59 @@
<?php
return [
"actions" => "Akce",
"alreadyHomepage" => "Domovská stránka",
"appearance" => "Vzhled",
"basicInfo" => "Základní informace",
"category" => "Kategorie",
"content" => "Obsah stránky",
"createdAt" => "Vytvořeno",
"deletePage" => "Smazat",
"deleteTitlePhoto" => "Smazat titulní obrázek",
"edit" => "Editace :name",
"editPlain" => "Editace",
"field_meta_description" => "Popis stránky",
"field_meta_keywords" => "Klíčová slova",
"field_published_from" => "Publikováno od",
"field_published_to" => "Publikováno do",
"field_title" => "Titulek stránky",
"field_url" => "URL",
"files" => "Soubory",
"homepage" => "Domovská stránka",
"homepageProtected" => "Domovská stránka je zobrazena jen pro přihlášené uživatele. Toto může i nemusí být chyba.",
"homepageSetup" => "Domovská stránka úspěšně nastavena.",
"invalidPage" => "Požadovaná stránka neexistuje.",
"invalidStatus" => "Nelze změnit stav stránky na něco nedefinovaného.",
"invalidTemplateSelected" => "Není zvolena šablona pro vykreslení stránky! Stránka nebude pro návštěvníky vykreslena!",
"lockUrl" => "Zamknout URL?",
"makeDraft" => "Převést na koncept",
"makeProtected" => "Zobrazit jen pro přihlášené",
"makePublic" => "Publikovat",
"metaOptions" => "Meta informace",
"moduleName" => "Modul",
"new" => "Vytvořit nový :name",
"noCategory" => "-- Žádná kategorie --",
"noHomepage" => "Domovská stránka není nastavena (a nebo je nastavena jako Koncept)! Vyberte prosím jinou stránku, nebo stávající publikujte.",
"noPagesAvailable" => "Nejsou dostupné žádné stránky. Pro zobrazení přehledu nejprve nějakou vytvořte.",
"noParentPage" => "-- Nadřazená stránka nevybrána --",
"noTemplates" => "Nelze vytvořit stránku. Pro tento modul neexistuje žádná šablona, která by šla použít pro vykreslení obsahu.",
"nothingToEdit" => "Nebyly provedeny žádné změny, proto nedošlo k editaci.",
"overview" => "Seznam všech obsahových stránek",
"pageDeleted" => "Stránka :name (:url) úspěšně smazána.",
"parentPage" => "Nadřazená stránka",
"publicationOptions" => "Nastavení publikace",
"save" => "Uložit",
"setHomepage" => "Nastavit jako domovskou stránku",
"showHistory" => "Historie (:count)",
"status" => "Stav",
"statusChanged" => "Stav úspěšně změněn.",
"status_deleted" => "Smazáno",
"status_draft" => "Koncept",
"status_protected" => "Jen pro přihlášené",
"status_public" => "Veřejné",
"successfullyCreated" => "Stránka úspěšně vytvořena",
"successfullyEdited" => "Úprava úspěšně uložena.",
"template" => "Šablona pro tuto stránku",
"title" => "Titulek",
"uploadTitleImage" => "Nahrát titulní obrázek",
"viewPage" => "Zobrazit",
"actions" => "Akce",
"alreadyHomepage" => "Domovská stránka",
"appearance" => "Vzhled",
"basicInfo" => "Základní informace",
"category" => "Kategorie",
"content" => "Obsah stránky",
"createdAt" => "Vytvořeno",
"deletePage" => "Smazat",
"deleteTitlePhoto" => "Smazat titulní obrázek",
"edit" => "Editace :name",
"editPlain" => "Editace",
"field_meta_description" => "Popis stránky",
"field_meta_keywords" => "Klíčová slova",
"field_published_from" => "Publikováno od",
"field_published_to" => "Publikováno do",
"field_title" => "Titulek stránky",
"field_url" => "URL",
"files" => "Soubory",
"homepage" => "Domovská stránka",
"homepageProtected" => "Domovská stránka je zobrazena jen pro přihlášené uživatele. Toto může i nemusí být chyba.",
"homepageSetup" => "Domovská stránka úspěšně nastavena.",
"invalidPage" => "Požadovaná stránka neexistuje.",
"invalidStatus" => "Nelze změnit stav stránky na něco nedefinovaného.",
"invalidTemplateSelected" => "Není zvolena šablona pro vykreslení stránky! Stránka nebude pro návštěvníky vykreslena!",
"lockUrl" => "Zamknout URL?",
"makeDraft" => "Převést na koncept",
"makeProtected" => "Zobrazit jen pro přihlášené",
"makePublic" => "Publikovat",
"metaOptions" => "Meta informace",
"moduleName" => "Modul",
"new" => "Vytvořit nový :name",
"noCategory" => "-- Žádná kategorie --",
"noHomepage" => "Domovská stránka není nastavena (a nebo je nastavena jako Koncept)! Vyberte prosím jinou stránku, nebo stávající publikujte.",
"noPagesAvailable" => "Nejsou dostupné žádné stránky. Pro zobrazení přehledu nejprve nějakou vytvořte.",
"noParentPage" => "-- Nadřazená stránka nevybrána --",
"noTemplates" => "Nelze vytvořit stránku. Pro tento modul neexistuje žádná šablona, která by šla použít pro vykreslení obsahu.",
"nothingToEdit" => "Nebyly provedeny žádné změny, proto nedošlo k editaci.",
"overview" => "Seznam všech obsahových stránek",
"pageDeleted" => "Stránka :name (:url) úspěšně smazána.",
"parentPage" => "Nadřazená stránka",
"publicationOptions" => "Nastavení publikace",
"save" => "Uložit",
"setHomepage" => "Nastavit jako domovskou stránku",
"showHistory" => "Historie (:count)",
"status" => "Stav",
"statusChanged" => "Stav úspěšně změněn.",
"status_deleted" => "Smazáno",
"status_draft" => "Koncept",
"status_protected" => "Jen pro přihlášené",
"status_public" => "Veřejné",
"successfullyCreated" => "Stránka úspěšně vytvořena",
"successfullyEdited" => "Úprava úspěšně uložena.",
"template" => "Šablona pro tuto stránku",
"title" => "Titulek",
"uploadTitleImage" => "Nahrát titulní obrázek",
"viewPage" => "Zobrazit",
];
+4
View File
@@ -21,4 +21,8 @@ return [
],
"socialSites" => "Sociální sítě",
"successfullySaved" => "Nastavení úspěšně změněno",
'recaptcha' => 'reCaptcha',
"recaptchaSecret" => "Application secret key",
"recaptchaSiteKey" => "Site key",
'useInvisibleRecaptcha' => 'Neviditelná reCAPTCHA'
];
@@ -18,9 +18,9 @@
<label class="control-label">
@lang('admin/contents.uploadTitleImage')
</label>
<input type="file" id="titlePhoto" accept=".jpg,.jpeg,.png" name="titlePhoto" class="form-control" />
<input type="file" id="titlePhotoFile" accept=".jpg,.jpeg,.png" name="titlePhotoFile" class="form-control" />
@include('admin.snippets.hasError', ['field' => 'titlePhoto'])
@include('admin.snippets.hasError', ['field' => 'titlePhotoFile'])
</div>
</div>
@@ -34,6 +34,10 @@
<select class="form-control" name="template">
@foreach($templates as $template)
@if(\Illuminate\Support\Str::contains($template->template_name, '_partials' ))
@continue
@endif
<option value="{{$template->template_name}}"
@if(old('template', $page->template) == $template->template_name) selected @endif>
{{$template->name}}
@@ -1,7 +1,7 @@
<div class="row">
<div class="col-lg-6">
<label class="control-label">
@lang('admin/contents.field_publishedFrom')
@lang('admin/contents.field_published_from')
</label>
<input type="datetime" class="form-control" name="publishedFrom" value="{{old('publishedFrom', $page->publishedFrom)}}"
@@ -12,7 +12,7 @@
<div class="col-lg-6">
<label class="control-label">
@lang('admin/contents.field_publishedTo')
@lang('admin/contents.field_published_to')
</label>
<input type="datetime" class="form-control" name="publishedTo" value="{{old('publishedTo', $page->publishedTo)}}"
@@ -22,7 +22,9 @@
@endif
@if (count($pages) > 0)
<div class="item-list rows-striped">
<div class="card items">
<div class="card-block">
<div class="item-list striped rows-striped">
<div class="row bold p-tb-15">
<div class="col-md-1 hidden-sm-down"></div>
<div class="col-xs-10 col-md-3 col-lg-4">@lang('admin/contents.title')</div>
@@ -55,7 +57,8 @@
{{$page->title}}
</a>
@if($page->isHomepage) <span class="m-l-10 tag tag-primary">@lang('admin/contents.homepage')</span> @endif
@if($page->isHomepage) <span
class="m-l-10 tag tag-primary">@lang('admin/contents.homepage')</span> @endif
</div>
<div class="col-lg-2 col-md-3 hidden-sm-down">
<span class="tag @if($page->isPublic()) tag-success
@@ -85,7 +88,8 @@
<li>
<a href="{{route('content.setHomepage', ['id' => $page->id])}}"
data-toggle="tooltip" title="@lang('admin/contents.setHomepage')">
data-toggle="tooltip"
title="@lang('admin/contents.setHomepage')">
<i class="fa fa-home"></i>
</a>
</li>
@@ -115,7 +119,8 @@
</li>
@else
<li>
<a href="{{route('page.content', ['url' => $page->url])}}" target="_blank"
<a href="{{route('page.content', ['url' => $page->url])}}"
target="_blank"
data-toggle="tooltip" title="@lang('admin/contents.viewPage')"
class="button tiny secondary"><i class="fa fa-globe"></i>
</a>
@@ -144,10 +149,13 @@
</div>
@endforeach
</div>
</div>
<div class="row">
<div class="card-footer">
{!! $pages->render() !!}
</div>
</div>
@else
<div class="alert alert-info">
@@ -12,7 +12,7 @@
height: 550,
removePlugins: 'about,scayt', //elementspath
extraPlugins: 'justify',
enterMode: CKEDITOR.ENTER_DIV,
enterMode: CKEDITOR.ENTER_P,
toolbarGroups: [
{name: 'undo', groups: ['undo']},
{name: 'styles'},
@@ -6,6 +6,8 @@
<div class="row">
<div class="col-lg-8">
@if (count($areas) > 0)
<div class="card items">
<div class="card-block">
<table class="table item-list table-striped">
<tr>
<th>@lang('admin/widgetAreas.name')</th>
@@ -15,8 +17,10 @@
</tr>
@foreach($areas as $area)
<tr>
<td><a href="{{route('widgetareas.edit', ['id' => $area->id])}}">{{$area->name}}</a></td>
<td><a href="{{route('widgetareas.edit', ['id' => $area->id])}}">{{$area->code}}</a></td>
<td><a href="{{route('widgetareas.edit', ['id' => $area->id])}}">{{$area->name}}</a>
</td>
<td><a href="{{route('widgetareas.edit', ['id' => $area->id])}}">{{$area->code}}</a>
</td>
<td>{{str_limit($area->description, 100)}}</td>
<td class="text-center">
<div class="item-actions-dropdown">
@@ -40,7 +44,8 @@
</li>
@if($area->deletable)
<li>
<a class="confirm remove" data-toggle="tooltip" title="@lang('admin/widgetAreas.delete')"
<a class="confirm remove" data-toggle="tooltip"
title="@lang('admin/widgetAreas.delete')"
href="{{route('widgetareas.delete', ['id' => $area->id])}}"><i
class="fa fa-trash"></i></a>
</li>
@@ -53,6 +58,8 @@
</tr>
@endforeach
</table>
</div>
</div>
@else
<div class="alert alert-info">
<em>@lang('admin/widgetAreas.noEntries')</em>
@@ -60,11 +67,18 @@
@endif
</div>
<div class="col-lg-4">
<h3>@lang('admin/widgetAreas.new')</h3>
<div class="card items">
<div class="card-header">
<div class="header-block">
<h3 class="title">@lang('admin/widgetAreas.new')</h3>
</div>
</div>
<div class="card-block">
@include('admin.widgets.area.form', ['action' => route('widgetareas.postNew'), 'area' => new \App\Models\Widgets\WidgetArea()])
</div>
</div>
</div>
</div>
<div class="row pagination">
@@ -2,6 +2,12 @@
@section('pageHeading', @trans('widgets/htmlCode.edit', ['name' => $widget->name]))
@section('headerButtons')
<a href="{{route('widgets.overview')}}" class="btn btn-secondary btn-sm rounded" title="@lang('admin/widgets.overview')">
<i class="fa fa-list"></i>
</a>
@endsection
@section('content')
<div class="col-lg-8">
@include('admin.widgets.htmlCode.form', ['action' => route('widgets.postEdit', ['id' => $widget->id])])
@@ -2,11 +2,16 @@
@section('pageHeading', @trans('widgets/menu.edit', ['name' => $widget->name]))
@section('headerButtons')
<a href="{{route('widgets.overview')}}" class="btn btn-secondary btn-sm rounded" title="@lang('admin/widgets.overview')">
<i class="fa fa-list"></i>
</a>
@endsection
@section('content')
<div class="row">
<div class="col-lg-8">
@include('admin.widgets.menu.form', ['formAction' => route('widgets.postEdit', ['id' => $widget->id])])
</div>
<div class="col-lg-4">
<h3>@lang('widgets/menu.preview')</h3>
@@ -14,5 +19,5 @@
@widgetPreview($widget)
</div>
</div>
@stop
@endsection
@@ -1,5 +1,5 @@
<form action="{{$formAction}}" id="widget-menu" method="POST">
<input type="hidden" name="settings" id="widgetSettings" value="{{json_encode($widget->settings->links)}}" />
<input type="hidden" name="settings" id="widgetSettings" value="{{json_encode($links)}}" />
@include('admin.widgets.snippets.commonForm')
@@ -8,7 +8,7 @@
<h3>@lang('widgets/menu.addedPages')</h3>
<div id="menu-items-container">
@foreach($widget->settings->links as $pageId => $details)
@foreach($links as $pageId => $details)
<span class="added-menu-item btn btn-sm btn-info" data-page-id="{{$pageId}}"
id="item-{{$pageId}}">{{$details->text}}</span>
@endforeach
@@ -20,7 +20,7 @@
@foreach ($pages as $page)
<a href="#"
class="btn btn-sm menu-item @if(isset($widget->settings->links->{$page->id})) btn-secondary @else btn-info @endif "
class="btn btn-sm menu-item @if(isset($links->{$page->id})) btn-secondary @else btn-info @endif "
data-page-url="{{$page->url}}" data-page-id="{{$page->id}}"
id="page-{{$page->id}}">{{$page->title}}</a>
@endforeach
@@ -3,19 +3,28 @@
@section('pageHeading', @trans('admin/widgets.overview'))
@section('pageDescription', @trans('admin/widgets.descriptionOfWidgets'))
@section('headerButtons')
<a href="{{route('widgetareas.overview')}}" class="btn btn-secondary btn-sm rounded"
title="@lang('admin/widgetAreas.overview')">
<i class="fa fa-object-group"></i>
</a>
@endsection
@section('content')
@if (count($widgets))
<div class="card items">
<div class="card-block">
<table class="table table-striped item-list">
<tr>
<th>@lang('admin/widgets.widgetType')</th>
<th>@lang('admin/widgets.name')</th>
<th>@lang('admin/widgets.widgetType')</th>
<th>@lang('admin/widgets.description')</th>
<th>@lang('admin/widgets.actions')</th>
</tr>
@foreach($widgets as $widget)
<tr>
<td>{{trans(call_user_func([$widget->widget_type_handler, 'getName']))}}</td>
<td><a href="{{route('widgets.edit', ['id' => $widget->id])}}">{{$widget->name}}</a></td>
<td>{{trans(call_user_func([$widget->widget_type_handler, 'getName']))}}</td>
<td>{{$widget->description}}</td>
<td class="text-center">
@@ -51,8 +60,12 @@
</tr>
@endforeach
</table>
</div>
<div class="card-footer">
{!! $widgets->render() !!}
</div>
</div>
@else
<div class="alert alert-info">
<em>@lang('admin/widgets.noEntries')</em>
@@ -1,4 +1,6 @@
{!! csrf_field() !!}
<input type="hidden" name="id" value="{{$widget->id}}">
<label class="label-control">
@lang('widgets/common.name')
</label>
@@ -20,6 +22,8 @@
<input class="form-control" type="text" name="containerClass" placeholder="@lang('widgets/common.containerClass')"
value="{{old('containerClass', $widget->container_class)}}" />
@include('admin.snippets.hasError', ['field' => 'containerClass'])
</div>
<div class="col-md-6">
<label class="label-control">
@@ -28,6 +32,8 @@
<input class="form-control" type="text" name="containerId" placeholder="@lang('widgets/common.containerId')"
value="{{old('containerId', $widget->container_id)}}" />
@include('admin.snippets.hasError', ['field' => 'containerId'])
</div>
</div>
+2 -4
View File
@@ -270,12 +270,9 @@ if [ ! -e $ADMIN_CREATED_FILE ]; then
read EMAIL
echo ""
echo "Password: "
read PASSWORD
echo ""
# install new user
php artisan user:new $EMAIL $PASSWORD admin
php artisan user:new $EMAIL
echo $EMAIL > $ADMIN_CREATED_FILE
fi
@@ -310,4 +307,5 @@ echo "Do not forget to install desired modules!"
echo " Use php artisan install-module <ModuleName> or php artisan install-all-modules"
npm install
bower install
gulp --production
@@ -1,9 +1,9 @@
<?php
namespace Templates\Base\OnePage\Http\Controllers\Admin;
use App\CMS\Contracts\Repositories\Content as IContent;
use App\CMS\Helpers\Settings;
use App\Http\Controllers\Admin\Controller;
use App\CMS\Contracts\Repositories\Content as IContent;
use App\Models\Settings as SettingsModel;
use Illuminate\Support\Facades\Event;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
@@ -41,7 +41,8 @@ class SetHomepage extends Controller
$usedPagesIds = (array)Settings::getJson(OnePage::HOMEPAGE_PAGES_SETTINGS_KEY);
// get all pages - they will be separated for used and not used on next lines
$allPages = $this->content->getOverview();
$allPages = $this->content->getOverview()
->get();
// separate pages to used and not used - with help of $usedPAgesIds array defined above
$pages = $used = $notUsed = [];

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