diff --git a/app/CMS/Contracts/Content/AdvancedContentModifier.php b/app/CMS/Contracts/Content/AdvancedContentModifier.php
index eef8c9d7..a8b43da1 100644
--- a/app/CMS/Contracts/Content/AdvancedContentModifier.php
+++ b/app/CMS/Contracts/Content/AdvancedContentModifier.php
@@ -21,12 +21,11 @@ interface AdvancedContentModifier {
* Reason why it is separated from createNew() method is simple - we need to save history of changes.
*
* @param Content $content
- * @param Request $request
- * @param string $revisionId
+ * @param $request
*
* @return mixed
*/
- public static function edit(Content &$content, Request $request, $revisionId);
+ public static function edit(Content $content, $request);
/**
* Method called right after content page is marked as deleted
*
diff --git a/app/CMS/Contracts/Interaction.php b/app/CMS/Contracts/Interaction.php
index 6ae65a66..f4bb27c6 100644
--- a/app/CMS/Contracts/Interaction.php
+++ b/app/CMS/Contracts/Interaction.php
@@ -1,9 +1,21 @@
$statuses[$changeset->new_value]
]);
break;
- case 'is_homepage':
+ case 'isHomepage':
return trans('admin/history.setupAsHomepage');
break;
default:
diff --git a/app/CMS/Handlers/Interaction.php b/app/CMS/Handlers/Interaction.php
index d2f08439..25b0fb35 100644
--- a/app/CMS/Handlers/Interaction.php
+++ b/app/CMS/Handlers/Interaction.php
@@ -3,30 +3,37 @@ namespace App\Cms\Handlers\Interactions;
use App\CMS\Contracts\Interaction as InteractionContract;
use App\CMS\Exceptions\Validation\ValidationFailedException;
-use App\Http\Requests\Request;
+use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Validator;
-class Interaction {
+class Interaction
+{
/**
* Handle interaction with application
*
- * @param Request $request
- * @param InteractionContract $interaction
- * @param array $parameters
+ * @param string $interactionClass
+ * @param array $data
+ * @param array $extraParameters
*
* @return mixed
* @throws ValidationFailedException
*/
- public static function handle(Request $request, InteractionContract $interaction, ...$parameters) {
+ public static function handle($interactionClass, $data, ...$extraParameters)
+ {
+ /**
+ * @var $interaction InteractionContract
+ */
+ $interaction = App::make($interactionClass);
// validate interaction
- $validator = Validator::make($request->all(), $interaction->getValidationRules($parameters));
+ $validator = Validator::make($data, $interaction->getValidationRules($extraParameters));
if ($validator->fails()) {
throw new ValidationFailedException($validator);
}
// handle it
- return $interaction->handle($request, $parameters);
+
+ return $interaction->handle($data, $extraParameters);
}
}
\ No newline at end of file
diff --git a/app/CMS/Helpers/CurrentTemplate.php b/app/CMS/Helpers/CurrentTemplate.php
index a9670900..68b8fec0 100644
--- a/app/CMS/Helpers/CurrentTemplate.php
+++ b/app/CMS/Helpers/CurrentTemplate.php
@@ -1,12 +1,13 @@
where('enabled', true)
- ->first();
+ self::$template = Module::where('is_template', true)
+ ->where('enabled', true)
+ ->first();
} catch (QueryException $e) {
throw new \ErrorException('DB not migrated, please, do so!');
}
if (self::$template) {
- self::$template->module_settings = json_decode(self::$template->module_settings);
+ self::$template->moduleSettings = json_decode(self::$template->moduleSettings);
}
self::$initialized = true;
@@ -60,4 +61,68 @@ class CurrentTemplate
{
self::$initialized = false;
}
+
+ /**
+ * Register admin menu (or multiple ones)
+ *
+ * This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
+ * starting any middleware..
+ *
+ * @param User $user model of logged user
+ */
+ public static function registerAdminMenu(User $user)
+ {
+ call_user_func_array([self::handler(), 'registerAdminMenu'], [$user]);
+ }
+
+ /**
+ * Get list of registered templates and supported modules.
+ *
+ * Returned array is expected to be array of arrays with following items: module, namespace and templateName.
+ * Example:
+ * return [
+ * ['module' => 'Article', 'templateName' => 'article::template.name']
+ * ];
+ *
+ * When no "namespace" is specified, value strtolower(module) is used instaed.
+ *
+ * @return array
+ */
+ public static function getPublicTemplatePaths()
+ {
+ return call_user_func([self::handler(), 'getPublicTemplatePaths']);
+ }
+
+ /**
+ * 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]);
+ }
}
\ No newline at end of file
diff --git a/app/CMS/Helpers/PageRenderer.php b/app/CMS/Helpers/PageRenderer.php
index a9b0702a..63ccd665 100644
--- a/app/CMS/Helpers/PageRenderer.php
+++ b/app/CMS/Helpers/PageRenderer.php
@@ -24,7 +24,7 @@ class PageRenderer
public static function render(Content $page)
{
// decode module settings
- $page->module_settings = json_decode($page->module_settings);
+ $page->moduleSettings = json_decode($page->moduleSettings);
// do something template-specific
$parameters = call_user_func_array([CurrentTemplate::handler(), 'beforeRender'], [&$page]);
@@ -33,7 +33,7 @@ class PageRenderer
* @var $handler AppHandler
*/
// get handler
- $handler = new $page->module_handler;
+ $handler = new $page->moduleHandler;
$page->content = Shortcode::compile($page->content);
diff --git a/app/CMS/Helpers/Traits/Nullable.php b/app/CMS/Helpers/Traits/Nullable.php
new file mode 100644
index 00000000..7221d013
--- /dev/null
+++ b/app/CMS/Helpers/Traits/Nullable.php
@@ -0,0 +1,33 @@
+toDateTimeString();
+ }
+
+ /**
+ * Get null or input value
+ *
+ * @param $string
+ *
+ * @return null
+ */
+ public function nullable($string) {
+ return empty($string) ? null : $string;
+ }
+}
\ No newline at end of file
diff --git a/app/CMS/Helpers/functions.php b/app/CMS/Helpers/functions.php
index c7b4002e..e758d6f7 100644
--- a/app/CMS/Helpers/functions.php
+++ b/app/CMS/Helpers/functions.php
@@ -27,4 +27,8 @@ function setting($key, $default = null) {
function asset_path($path) {
return env('SITE_URL').'/assets/'.$path;
+}
+
+function template_name($name, $throwExceptions = true) {
+ return \App\CMS\Helpers\Template::name($name, $throwExceptions);
}
\ No newline at end of file
diff --git a/app/CMS/Interactions/Admin/Content/ChangeStatus.php b/app/CMS/Interactions/Admin/Content/ChangeStatus.php
index e69de29b..07386aa4 100644
--- a/app/CMS/Interactions/Admin/Content/ChangeStatus.php
+++ b/app/CMS/Interactions/Admin/Content/ChangeStatus.php
@@ -0,0 +1,24 @@
+route('content.overview')
+ ->with('error', trans('admin/contents.invalidStatus'));
+ }
+ }
+
+ public function getValidationRules($parameters)
+ {
+ // TODO: Implement getValidationRules() method.
+ }
+}
\ No newline at end of file
diff --git a/app/CMS/Interactions/Admin/Content/EditContent.php b/app/CMS/Interactions/Admin/Content/EditContent.php
index dbe34624..897d3098 100644
--- a/app/CMS/Interactions/Admin/Content/EditContent.php
+++ b/app/CMS/Interactions/Admin/Content/EditContent.php
@@ -7,6 +7,8 @@ use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Helpers\CurrentTemplate;
use App\Events\EditContent as EditContentEvent;
use App\Http\Requests\Request;
+use App\Models\Content\Content;
+use App\Models\FileManager\File;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
@@ -17,74 +19,59 @@ class EditContent implements Interaction
* @var Module
*/
protected $module;
+ /**
+ * @var File
+ */
+ protected $file;
+
public function __construct()
{
$this->module = App::make(Module::class);
+ $this->file = App::make(File::class);
}
- public function handle(Request $request, $parameters)
+ /**
+ * Edit page
+ *
+ * @param array $data
+ * @param array $parameters
+ *
+ * @return mixed|void
+ */
+ public function handle($data, $parameters)
{
- $page = $parameters[0];
-
- // upload file - if provided
- // todo use interaction
- $file = $page->uploadTitlePhoto($request);
+ /**
+ * @var $page Content
+ */
+ list($page, $titlePhoto, $relatedFiles) = $parameters;
// let template to modify request and content page
- call_user_func_array([CurrentTemplate::handler(), 'beforeSave'], [&$page, $request]);
+ CurrentTemplate::beforeSave($page, $data);
- $request->url = Str::slug($request->url);
- $request->parentPage = $request->parentPage ? $request->parentPage : null;
- $request->publishedFrom = empty($request->publishedFrom) ? null : $request->publishedFrom;
- $request->publishedTo = empty($request->publishedTo) ? null : $request->publishedTo;
+ // upload file - if provided
+ $data['titlePhoto'] = isset($data['existingTitlePhoto']) ? $data['existingTitlePhoto'] : null;
- if (!$file) {
- $request->titlePhotoFilename = empty($request->existingTitlePhoto) ? null : $request->existingTitlePhoto;
- } else {
- $request->titlePhotoFilename = $file['filename'];
+ if (!is_null($titlePhoto)) {
+ $file = $this->file->upload($titlePhoto);
+ $data['titlePhoto'] = $file ? $file['filename'] : null;
}
- // array of fields in database and fields from request
- $fields = [
- 'title' => 'title',
- 'url' => 'url',
- 'template' => 'template',
- 'published_from' => 'publishedFrom',
- 'published_to' => 'publishedTo',
- 'meta_keywords' => 'metaKeywords',
- 'meta_description' => 'metaDescription',
- 'content' => 'pageContent',
- 'parent_id' => 'parentPage',
- 'status' => 'status',
- 'title_photo' => 'titlePhotoFilename',
- 'category_id' => 'category'
- ];
-
- // save new values with history
- // todo move this method out of the controller!
- $data = \App\Http\Controllers\Admin\Contents\EditContent::getFields($request, array_values($fields));
-
- // todo use Model Observer and model::original attributes
-
- list($revision, $changedColumns) = $page->updateWithHistory($fields, $data);
-
- $module = $this->module->getByHandler($page->module_handler);
-
-
- $changedColumns += $this->module->call($module, 'edit', [&$page, $request, $revision]);
-
+ $page->update($data);
+ $this->module->callOnString($page->moduleHandler, 'edit', [$page, $data]);
// move to interaction
- $changedColumns += $page->uploadRelatedFiles($request, $revision);
-
- if ($changedColumns > 0) {
- Event::fire(new EditContentEvent($page, $revision));
- }
-
- return [$page, $revision, $changedColumns];
+ $keepAssigned = isset($data->keepAssigned) ? $data->keepAssigned : [];
+ $page->uploadRelatedFiles($relatedFiles, $keepAssigned);
}
- public function getValidationRules($parameters)
+ /**
+ * Validate this interaction
+ *
+ * @param array $parameters
+ *
+ * @return array
+ */
+ public function getValidationRules($parameters = [])
{
$id = $parameters[0]->id;
@@ -97,7 +84,7 @@ class EditContent implements Interaction
'url' => 'required|unique:contents,url,' . $id,
'publishedFrom' => 'date',
'publishedTo' => 'date',
- 'title_photo' => 'exists:files,id',
+ 'titlePhoto' => 'exists:files,id',
'status' => 'required|in:' . $statuses,
'parentPage' => 'exists:contents,id'
];
diff --git a/app/CMS/Interactions/Admin/Content/NewContent.php b/app/CMS/Interactions/Admin/Content/NewContent.php
index 3e8a25f6..14713e0c 100644
--- a/app/CMS/Interactions/Admin/Content/NewContent.php
+++ b/app/CMS/Interactions/Admin/Content/NewContent.php
@@ -2,10 +2,13 @@
namespace App\Cms\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
+use App\CMS\Contracts\Repositories\Content as ContentRepository;
+use App\CMS\Contracts\Repositories\Module;
use App\CMS\Helpers\CurrentTemplate;
use App\Events\CreateNewContent;
-use App\Http\Requests\Request;
use App\Models\Content\Content;
+use App\Models\FileManager\File;
+use Carbon\Carbon;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
@@ -13,73 +16,70 @@ use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class NewContent implements Interaction
{
+ /**
+ * @var ContentRepository
+ */
protected $content;
+ /**
+ * @var File
+ */
+ protected $file;
+ /**
+ * @var Module
+ */
+ protected $module;
public function __construct()
{
- $this->content = App::make(\App\CMS\Contracts\Repositories\Content::class);
+ $this->content = App::make(ContentRepository::class);
+ $this->module = App::make(Module::class);
+ $this->file = App::make(File::class);
}
/**
- * @param Request $request
+ * Create new content page
+ *
+ * @param array $data
* @param $parameters
*
* @return Content
*/
- public function handle(Request $request, $parameters)
+ public function handle($data, $parameters)
{
- list($moduleHandler) = $parameters;
-
- // create new page
- $page = new Content();
- $page->template = $request->template;
-
- // setup basic info
- $page->user_id = \Auth::user()->id;
- $page->language = LaravelLocalization::getCurrentLocale();
- $page->title = $request->title;
- $page->url = Str::slug($request->url);
- $page->published_from = empty($request->publishedFrom) ? null : $request->publishedFrom;
- $page->published_to = empty($request->publishedTo) ? null : $request->publishedTo;
- $page->meta_keywords = $request->metaKeywords;
- $page->meta_description = $request->metaDescription;
- $page->content = $request->pageContent;
- $page->status = $request->status;
- $page->module_handler = $moduleHandler;
- $page->category_id = (int)$request->category > 0 ? $request->category : null;
- $page->parent_id = $request->parentPage ? $request->parentPage : null;
+ list($moduleHandler, $titlePhoto, $relatedFiles) = $parameters;
// upload file - if provided
- $file = $page->uploadTitlePhoto($request);
+ $file = !is_null($titlePhoto) ? $this->file->upload($titlePhoto) : null;
- $page->title_photo = $file ? $file['filename'] : null;
+ $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
- call_user_func_array([$request->handler, 'createNew'], [&$page, $request]);
+ $this->module->callOnString($moduleHandler, 'createNew', [&$page, $data]);
- // let template to modify request and content page
- call_user_func_array([CurrentTemplate::handler(), 'beforeSave'], [&$page, $request]);
+ // 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($request);
-
- Event::fire(new CreateNewContent($this));
-
+ $page->uploadRelatedFiles($relatedFiles);
return $page;
}
- public function getValidationRules($parameters)
+ public function getValidationRules($parameters = [])
{
return [
'titlePhoto' => 'image',
'title' => 'required',
'url' => 'required|unique:contents,url',
'status' => 'required|in:draft,protected,public',
- 'title_photo' => 'exists:files,id',
'parentPage' => 'exists:contents,id',
'publishedFrom' => 'date',
'publishedTo' => 'date',
diff --git a/app/CMS/Observers/Content.php b/app/CMS/Observers/Content.php
new file mode 100644
index 00000000..a44a88be
--- /dev/null
+++ b/app/CMS/Observers/Content.php
@@ -0,0 +1,102 @@
+changeset = uniqid();
+ }
+
+ /**
+ * @param ContentModel $content
+ */
+ public function created(ContentModel $content)
+ {
+ Event::fire(new CreateNewContent($content));
+ }
+
+ /**
+ * Get all dirty changed from model.
+ *
+ * If user did not change moduleSettings column, return result from ContentModel::getDirty(). Otherwise append all
+ * changed columns from module settings.
+ *
+ * @param $changed
+ * @param $original
+ *
+ * @return array
+ */
+ protected function getDirtyFields($changed, $original)
+ {
+ unset($changed['updated_at']);
+
+ $changes = $this->getNewAndOldValues(array_keys($changed), $changed, $original);
+
+ if (!isset($changed['moduleSettings']))
+ return $changes;
+
+ $moduleSettings = (array)json_decode($changed['moduleSettings']);
+ $originalSettings = (array)json_decode($original['moduleSettings']);
+ unset($changed['moduleSettings']);
+
+ $settingChanged = array_keys(array_diff_assoc($moduleSettings, $originalSettings));
+ $changesInSettings = $this->getNewAndOldValues($settingChanged, $moduleSettings, $originalSettings);
+
+ return array_merge($changes, $changesInSettings);
+ }
+
+ /**
+ *
+ *
+ * @param $fields
+ * @param $new
+ * @param $original
+ *
+ * @return array
+ */
+ protected function getNewAndOldValues($fields, $new, $original) {
+ $changes = [];
+ foreach ($fields as $field) {
+ $changes[$field] = [
+ 'new' => isset($new[$field]) ? $new[$field] : null,
+ 'old' => isset($original[$field])? $original[$field] : null
+ ];
+ }
+
+ return $changes;
+ }
+
+ public function updated(ContentModel $content)
+ {
+ $fields = $this->getDirtyFields($content->getDirty(), $content->getOriginal());
+
+ foreach ($fields as $field => $change) {
+ $history = [
+ 'user_id' => \Auth::user()->id,
+ 'content_id' => $content->id,
+ 'edit_batch' => $this->changeset,
+ 'column' => $field,
+ 'old_value' => $change['old'],
+ 'new_value' => $change['new']
+ ];
+
+ // save history
+ ContentHistory::create($history);
+ }
+ }
+
+ /**
+ * @param ContentModel $content
+ */
+ public function deleted(ContentModel $content)
+ {
+ }
+}
\ No newline at end of file
diff --git a/app/CMS/Repositories/Content/Content.php b/app/CMS/Repositories/Content/Content.php
index 4270c21f..b810d397 100644
--- a/app/CMS/Repositories/Content/Content.php
+++ b/app/CMS/Repositories/Content/Content.php
@@ -29,14 +29,14 @@ class Content extends Repository implements IContent
return ContentModel::where('status', '!=', IContent::STATUS_DRAFT)
->select('contents.*')
->with('author')
- ->join('modules', 'modules.handler', '=', 'contents.module_handler')
+ ->join('modules', 'modules.handler', '=', 'contents.moduleHandler')
->where(function ($query) {
- $query->where('published_from', '<', Carbon::now())
- ->orWhereNull('published_from');
+ $query->where('publishedFrom', '<=', Carbon::now())
+ ->orWhereNull('publishedFrom');
})
->where(function ($query) {
- $query->where('published_to', '>', Carbon::now())
- ->orWhereNull('published_to');
+ $query->where('publishedTo', '>=', Carbon::now())
+ ->orWhereNull('publishedTo');
})
->where('language', LaravelLocalization::getCurrentLocale())
->whereNull('contents.deleted_at')
@@ -46,9 +46,14 @@ class Content extends Repository implements IContent
public function all()
{
return $this->getPageQuery()
- ->get();
+ ->get();
}
+ /**
+ * @param int $id
+ *
+ * @return mixed
+ */
public function getOne($id = null)
{
if (is_null($id)) {
@@ -56,16 +61,9 @@ class Content extends Repository implements IContent
$page->user_id = \Auth::user()->id;
$page->language = LaravelLocalization::getCurrentLocale();
$page->status = IContent::STATUS_DRAFT;
- $page->module_settings = [];
+ $page->moduleSettings = [];
} else {
- if (is_numeric($id)) {
$page = $this->model->findOrFail($id);
- } else {
- $page = $this->model->where('language', LaravelLocalization::getCurrentLocale())
- ->where('url', $id)
- ->firstOrFail();
- }
- $page->module_settings = json_decode($page->module_settings);
}
return $page;
@@ -78,8 +76,9 @@ class Content extends Repository implements IContent
public function getHomepage()
{
return $this->getPageQuery()
- ->where('is_homepage', 1)
- ->first();
+ ->where('isHomepage', 1)
+ ->first();
+
}
/**
@@ -91,9 +90,17 @@ class Content extends Repository implements IContent
*/
public function getByURL($url)
{
- return $this->getPageQuery()
- ->where('url', $url)
- ->first();
+ $page = $this->getPageQuery()
+ ->where('url', $url)
+ ->first();
+
+ if (is_null($page)) {
+ return null;
+ }
+
+ $page->moduleSettings = json_decode($page->moduleSettings);
+
+ return $page;
}
/**
@@ -108,8 +115,8 @@ class Content extends Repository implements IContent
public function getOverview($handler = null, $statuses = null)
{
$query = ContentModel::select('contents.*', 'modules.name AS module_name', 'modules.id AS module_id')
- ->join('modules', 'modules.handler', '=', 'contents.module_handler')
- ->join('users', 'users.id', '=', 'contents.user_id')
+ ->join('modules', 'modules.handler', '=', 'contents.moduleHandler')
+ ->join('users', 'users.id', '=', 'contents.userId')
->addSelect(DB::raw('COALESCE(users.name, users.email) AS author_name'))
->addSelect('users.email AS author_email')
->whereNull('contents.deleted_at')
@@ -119,7 +126,7 @@ class Content extends Repository implements IContent
// filter results using handler
if (!is_null($handler)) {
- $query = $query->where('contents.module_handler', $handler);
+ $query = $query->where('contents.moduleHandler', $handler);
}
// add filtering by status
@@ -127,6 +134,8 @@ class Content extends Repository implements IContent
$query = $query->whereIn('contents.status', $statuses);
}
- return $query->paginate(20);
+ $pages = $query->paginate(setting('paginatedResults', 20));
+
+ return $pages;
}
}
\ No newline at end of file
diff --git a/app/CMS/Repositories/Module.php b/app/CMS/Repositories/Module.php
index ac82725f..b8320d39 100644
--- a/app/CMS/Repositories/Module.php
+++ b/app/CMS/Repositories/Module.php
@@ -36,8 +36,8 @@ class Module extends Repository implements IModule
public function getUpdateContentTitle(ModuleModel $module, Content $content = null)
{
- $pageHeading = trans('admin/contents.new', ['name' => trans($module->name)]);
- $moduleHeading = $this->call($module, 'getEditTitle', $content);
+ $pageHeading = trans('admin/contents.edit', ['name' => trans($module->name)]);
+ $moduleHeading = $this->call($module, 'getEditTitle', [$content]);
return is_null($moduleHeading) ? $pageHeading : $moduleHeading;
}
@@ -62,7 +62,7 @@ class Module extends Repository implements IModule
->firstOrFail();
}
- public function call(ModuleModel $module, $method, ...$parameters)
+ public function call(ModuleModel $module, $method, $parameters = [])
{
if (!is_null($module) && is_callable([$module->handler, $method])) {
return call_user_func_array([$module->handler, $method], $parameters);
@@ -70,4 +70,13 @@ class Module extends Repository implements IModule
return null;
}
+
+ public function callOnString($moduleHandler, $method, $parameters = [])
+ {
+ if (is_callable([$moduleHandler, $method])) {
+ return call_user_func_array([$moduleHandler, $method], $parameters);
+ }
+
+ return null;
+ }
}
\ No newline at end of file
diff --git a/app/CMS/Widgets/Menu/Presenters/Menu.php b/app/CMS/Widgets/Menu/Presenters/Menu.php
index b10e8858..567848b0 100644
--- a/app/CMS/Widgets/Menu/Presenters/Menu.php
+++ b/app/CMS/Widgets/Menu/Presenters/Menu.php
@@ -54,8 +54,8 @@ class Menu implements WidgetRenderer
}
$page = $pages[$pageId];
- $active = ($page->is_homepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
- $route = $page->is_homepage ? route('page.index') : route('page.content', ['url' => $page->url]);
+ $active = ($page->isHomepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
+ $route = $page->isHomepage ? route('page.index') : route('page.content', ['url' => $page->url]);
$code .= '
module_settings);
+ $info = json_decode($current->moduleSettings);
$this->line('Template is already installed. Currently using template ' . trans($current->name) . ' located in /templates/' . $info->staticName . '.');
$confirm = $this->confirm('Uninstall it and install *' . trans($config['name']) . '*? All data associated with installed template will be lost!');
diff --git a/app/Http/Controllers/Admin/Contents/ContentActions.php b/app/Http/Controllers/Admin/Contents/ContentActions.php
index be6e6bc4..7fdd4773 100644
--- a/app/Http/Controllers/Admin/Contents/ContentActions.php
+++ b/app/Http/Controllers/Admin/Contents/ContentActions.php
@@ -36,18 +36,17 @@ class ContentActions extends Controller
->with('error', trans('admin/contents.invalidStatus'));
}
- try {
// try to find this page
$page = Content::findOrFail($id);
- } catch (NotFoundHttpException $e) {
- // page not found
- return redirect()
- ->route('content.overview')
- ->with('error', trans('admin/contents.invalidPage'));
- }
// try to change the page
list ($revision, $changedColumns) = $page->updateWithHistory(['status' => 'status'], ['status' => $status]);
+ // fire events
+ if ($status != Content::STATUS_DRAFT) {
+ Event::fire(new PublishContent($page, $revision));
+ } else {
+ Event::fire(new MakeDraftFromContent($page, $revision));
+ }
// was something changed?
if ($changedColumns == 0) {
@@ -56,12 +55,7 @@ class ContentActions extends Controller
->with('error', trans('admin/contents.nothingToEdit'));
}
- // fire events
- if ($status != Content::STATUS_DRAFT) {
- Event::fire(new PublishContent($page, $revision));
- } else {
- Event::fire(new MakeDraftFromContent($page, $revision));
- }
+
// redirect back to overview with info for user
return redirect()
@@ -97,7 +91,7 @@ class ContentActions extends Controller
$page->delete();
// let module to delete some extra content created during page's life
- call_user_func([$page->module_handler, 'delete'], $page);
+ call_user_func([$page->moduleHandler, 'delete'], $page);
// trigger delete event
Event::fire(new DeleteContent($page));
@@ -134,12 +128,12 @@ class ContentActions extends Controller
}
// disable any other existing homepage
- Content::where('is_homepage', 1)
+ Content::where('isHomepage', 1)
->where('language', LaravelLocalization::getCurrentLocale())
- ->update(['is_homepage' => 0]);
+ ->update(['isHomepage' => 0]);
// set new homepage
- list ($revision, $changedColumns) = $page->updateWithHistory(['is_homepage' => 'is_homepage'], ['is_homepage' => 1]);
+ list ($revision, $changedColumns) = $page->updateWithHistory(['isHomepage' => 'isHomepage'], ['isHomepage' => 1]);
// was something changed?
if ($changedColumns == 0) {
diff --git a/app/Http/Controllers/Admin/Contents/CreateNewContent.php b/app/Http/Controllers/Admin/Contents/CreateNewContent.php
index d9e6fb02..6abe97e5 100644
--- a/app/Http/Controllers/Admin/Contents/CreateNewContent.php
+++ b/app/Http/Controllers/Admin/Contents/CreateNewContent.php
@@ -103,8 +103,11 @@ class CreateNewContent extends Controller
{
$module = $this->module->getOne($moduleId);
+ $titlePhoto = $request->file('titlePhoto');
+ $relatedFiles = $request->all()['files'];
+
// create new page
- Interaction::handle($request, new NewContent(), $module->handler);
+ Interaction::handle(NewContent::class, $request->all(), $module->handler, $titlePhoto, $relatedFiles);
return redirect()
->route('content.overview')
diff --git a/app/Http/Controllers/Admin/Contents/EditContent.php b/app/Http/Controllers/Admin/Contents/EditContent.php
index 952ed303..fe760795 100644
--- a/app/Http/Controllers/Admin/Contents/EditContent.php
+++ b/app/Http/Controllers/Admin/Contents/EditContent.php
@@ -71,24 +71,24 @@ class EditContent extends Controller
/**
* Display form for editing static page
*
- * @param $url
+ * @param $id
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
- public function edit($url)
+ public function edit($id)
{
$statuses = ContentStatuses::getWithTranslations();
- $page = $this->content->getOne($url);
+ $page = $this->content->getOne($id);
// get module ID
- $module = $this->module->getByHandler($page->module_handler);
+ $module = $this->module->getByHandler($page->moduleHandler);
$pageHeading = $this->module->getUpdateContentTitle($module, $page);
$templates = $this->template->getForModule($module);
$categories = $this->category->getForModule($module);
$history = $this->history->getStructuredHistoryOf($page);
// modify data for edit form according to installed template
- call_user_func_array([CurrentTemplate::handler(), 'beforePopulatingEditForm'], [&$page]);
+ CurrentTemplate::beforePopulatingEditForm($page);
// render view
return view('admin.content.edit', [
@@ -132,14 +132,10 @@ class EditContent extends Controller
}
// edit page
- list($page, $revision, $changedColumns) = Interaction::handle($request, new EditContentInteraction(), $page);
+ $titlePhoto = $request->file('titlePhoto');
+ $relatedFiles = $request->all()['files'];
- // was something changed?
- if ($changedColumns == 0) {
- return redirect()
- ->route('content.edit', ['id' => $page->id])
- ->with('error', trans('admin/contents.nothingToEdit'));
- }
+ Interaction::handle(EditContentInteraction::class, $request->all(), $page, $titlePhoto, $relatedFiles);
// something was changed, inform user
return redirect()
@@ -150,12 +146,12 @@ class EditContent extends Controller
/**
* Convert object of all request data into array of only wanted fields
*
- * @param Request $request
+ * @param $request
* @param $fields
*
* @return array
*/
- public static function getFields(Request $request, $fields)
+ public static function getFields($request, $fields)
{
$requestData = [];
diff --git a/app/Http/Controllers/Sitemap.php b/app/Http/Controllers/Sitemap.php
index 8d42930d..fe5c4360 100644
--- a/app/Http/Controllers/Sitemap.php
+++ b/app/Http/Controllers/Sitemap.php
@@ -2,8 +2,8 @@
namespace App\Http\Controllers;
+use App\CMS\Contracts\Repositories\Content;
use App\Http\Requests;
-use App\Models\Content\Content;
class Sitemap extends Controller
{
@@ -30,14 +30,13 @@ class Sitemap extends Controller
public function getMap()
{
// load all public pages
- $pages = $this->content->getPageQuery()
- ->get();
+ $pages = $this->content->all();
// iterate over all pages and add tag for each of them
foreach ($pages as $page) {
// is this page a homepage? because of URL
- if ($page->is_homepage) {
+ if ($page->isHomepage) {
$route = route('page.index');
$priority = 1;
} else {
diff --git a/app/Http/routes/admin/contents.php b/app/Http/routes/admin/contents.php
index 712cb998..54b70c6b 100644
--- a/app/Http/routes/admin/contents.php
+++ b/app/Http/routes/admin/contents.php
@@ -9,7 +9,7 @@ Route::group(['namespace' => 'Contents'], function () {
->name('content.new');
// form for editing existing static page
- Route::get('content/edit/{url}', 'EditContent@edit')
+ Route::get('content/edit/{id}', 'EditContent@edit')
->name('content.edit');
// post method for creating new static page
diff --git a/app/Models/Content/Content.php b/app/Models/Content/Content.php
index 93d1e5f7..fce60e27 100644
--- a/app/Models/Content/Content.php
+++ b/app/Models/Content/Content.php
@@ -2,10 +2,14 @@
namespace App\Models\Content;
+use App\CMS\Contracts\Repositories\Content as ContentContract;
+use App\CMS\Helpers\Traits\Nullable;
+use App\CMS\Observers\Content as ContentObserver;
use App\Models\FileManager\File;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
+use Illuminate\Support\Str;
use Modules\Categories\Entities\Category;
/**
@@ -13,27 +17,41 @@ use Modules\Categories\Entities\Category;
*/
class Content extends Model
{
- use SoftDeletes, ModelTraits\Content;
+ use SoftDeletes, ModelTraits\Content, Nullable;
public $timestamps = true;
protected $fillable = [
- 'user_id',
- 'parent_id',
- 'category_id',
+ 'userId',
+ 'parentId',
+ 'categoryId',
'language',
- 'module_handler',
- 'published_from',
- 'published_to',
- 'title_photo',
+ 'moduleHandler',
+ 'publishedFrom',
+ 'publishedTo',
+ 'titlePhoto',
'template',
- 'is_homepage',
+ 'isHomepage',
'title',
'url',
- 'meta_keywords',
- 'meta_description',
- 'content',
- 'module_settings',
+ 'metaKeywords',
+ 'metaDescription',
+ 'pageContent',
+ 'moduleSettings',
'status'
];
+ protected $casts = [
+ 'isHomepage' => 'boolean',
+ 'moduleSettings' => 'array'
+ ];
+
+ /**
+ * Assign observer for this model for logging
+ */
+ protected static function boot()
+ {
+ parent::boot();
+
+ self::observe(ContentObserver::class);
+ }
/**
* Mark relationship with its historical records
@@ -52,7 +70,7 @@ class Content extends Model
*/
public function author()
{
- return $this->belongsTo(User::class, 'user_id');
+ return $this->belongsTo(User::class, 'userId');
}
/**
@@ -74,4 +92,75 @@ class Content extends Model
{
return $this->belongsTo(Category::class);
}
+
+ /**
+ * Subpages assigned to page
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\HasMany
+ */
+ public function subpages()
+ {
+ return $this->hasMany(Content::class, 'parentId');
+ }
+
+ /**
+ * Parent page
+ *
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function parentPage()
+ {
+ return $this->belongsTo(Content::class, 'parentId');
+ }
+
+ /**
+ * Is current content draft?
+ *
+ * @return bool
+ */
+ public function isDraft()
+ {
+ return $this->status == ContentContract::STATUS_DRAFT;
+ }
+
+ /**
+ * Is current content visible for all visitors?
+ *
+ * @return bool
+ */
+ public function isPublic()
+ {
+ return $this->status == ContentContract::STATUS_PUBLIC;
+ }
+
+ /**
+ * Is current content visible only for logged users?
+ *
+ * @return bool
+ */
+ public function isProtected()
+ {
+ return $this->status == ContentContract::STATUS_PROTECTED;
+ }
+
+ /**
+ * Is current content visible for logged user OR for everyone?
+ *
+ * @return bool
+ */
+ public function isVisible()
+ {
+ return $this->isPublic() || $this->isProtected();
+ }
+
+ public function save(array $options = [])
+ {
+ $this->parentId = $this->nullable($this->parentId);
+ $this->categoryId = $this->nullable($this->categoryId);
+ $this->publishedFrom = $this->nullableDate($this->publishedFrom);
+ $this->publishedTo = $this->nullableDate($this->publishedTo);
+ $this->url = Str::slug($this->url);
+
+ return parent::save($options);
+ }
}
diff --git a/app/Models/Content/ContentHasFile.php b/app/Models/Content/ContentHasFile.php
index 688f35e1..d6fb39f6 100644
--- a/app/Models/Content/ContentHasFile.php
+++ b/app/Models/Content/ContentHasFile.php
@@ -2,15 +2,25 @@
namespace App\Models\Content;
+use App\Models\FileManager\File;
use Illuminate\Database\Eloquent\Model;
class ContentHasFile extends Model
{
public $timestamps = false;
public $table = 'contents_has_files';
-
protected $fillable = [
'content_id',
'file_id'
];
+
+ public function content()
+ {
+ return $this->hasOne(Content::class);
+ }
+
+ public function file()
+ {
+ return $this->hasOne(File::class);
+ }
}
\ No newline at end of file
diff --git a/app/Models/Content/ModelTraits/Content.php b/app/Models/Content/ModelTraits/Content.php
index 16069185..ae8c210f 100644
--- a/app/Models/Content/ModelTraits/Content.php
+++ b/app/Models/Content/ModelTraits/Content.php
@@ -1,215 +1,29 @@
file = App::make(File::class);
- }
-
- /**
- * Is current content draft?
- *
- * @return bool
- */
- public function isDraft()
- {
- return $this->status == IContent::STATUS_DRAFT;
- }
-
- /**
- * Is current content visible for all visitors?
- *
- * @return bool
- */
- public function isPublic()
- {
- return $this->status == IContent::STATUS_PUBLIC;
- }
-
- /**
- * Is current content visible only for logged users?
- *
- * @return bool
- */
- public function isProtected()
- {
- return $this->status == IContent::STATUS_PROTECTED;
- }
-
- /**
- * Is current content visible for logged user OR for everyone?
- *
- * @return bool
- */
- public function isVisible()
- {
- return $this->isPublic() || $this->isProtected();
- }
-
- /**
- * Get list of all subpages
- *
- * @param bool $orderBy
- * @param bool $orderDirection
- *
- * @return array
- */
- public function subpages($orderBy = false, $orderDirection = false)
- {
- if (!$this->subpagesInit) {
- $subpages = $this->getPageQuery()
- ->where('contents.parent_id', $this->id);
-
- if ($orderBy) {
- $subpages->orderBy($orderBy, $orderDirection ? $orderDirection : 'ASC');
- }
-
- $subpages = $subpages->get();
-
- // convert JSON settings into stdClass
- foreach ($subpages as $i => $subpage) {
- $subpages[$i]->module_settings = json_decode($subpage->module_settings);
- }
-
- $this->subpagesInit = true;
- $this->foundSubpages = $subpages;
- }
-
- return $this->foundSubpages;
- }
-
- /**
- * Returns list of all root pages - those pages, which parent_id is null
- *
- * @return mixed
- */
- public function rootPages()
- {
- $rootPages = $this->getPageQuery()
- ->where('parent_id', null);
-
- if ($this->id) {
- $rootPages = $rootPages->where('id', '!=', $this->id);
- }
-
- return $rootPages->get();
- }
-
- /**
- * Updates current model with information about changed columns
- *
- * @param array $fields
- * @param array $request
- * @param string $revisionId
- *
- * @return array revisionID and number of changed columns
- */
- public function updateWithHistory(array $fields, array $request, $revisionId = null)
- {
- if (!$revisionId) {
- $revisionId = uniqid();
- }
-
- $changed = 0;
-
- foreach ($fields as $fieldDB => $fieldRequest) {
- // ignore non-existing fields
- if (!isset($request[$fieldRequest]) && !is_null($request[$fieldRequest])) {
- continue;
- }
-
- // if module settings is still JSON, decode it to normal stdClass
- if (is_string($this->module_settings)) {
- $this->module_settings = json_decode($this->module_settings);
- }
-
- // are we editing common settings, or module-specific settings?
- if (!in_array($fieldDB, $this->fillable)) {
- // this field is not part of "core" content - probably it will be module settings
- $commonField = false;
- $fieldValue = isset($this->module_settings->$fieldDB) ? $this->module_settings->$fieldDB : null;
- } else {
- $commonField = true;
- $fieldValue = $this->$fieldDB;
- }
-
- // remove any whitespaces around real content
- if (!is_null($request[$fieldRequest])) {
- $request[$fieldRequest] = trim($request[$fieldRequest]);
- }
-
- if (trim($fieldValue) != $request[$fieldRequest]) {
-
- $this->saveHistory($revisionId, $fieldRequest, $fieldValue, $request);
-
- // save change into database
- if ($commonField) {
- $this->$fieldDB = $request[$fieldRequest];
- } else {
- $this->module_settings->$fieldDB = $request[$fieldRequest];
- }
-
- $changed++;
- }
- }
-
- // make JSON from stdClass
- if (!is_string($this->module_settings)) {
- $this->module_settings = json_encode($this->module_settings);
- }
-
- $this->save();
-
- return [$revisionId, $changed];
- }
-
- /**
- * Upload and set some image as title photo
- *
- * @param Request $request
- */
- public function uploadTitlePhoto(Request $request)
- {
- if ($request->hasFile('titlePhoto')) {
- return $this->file->upload($request->file('titlePhoto'), $request);
- }
-
- return null;
- }
-
/**
* Upload and assign files to newly created content page
*
- * @param Request $request
- * @param null $revisionId
+ * @param $files
+ * @param $assignedFiles
+ * @param null $revisionId
*
* @return int
*/
- public function uploadRelatedFiles(Request $request, $revisionId = null)
+ public function uploadRelatedFiles($files, $assignedFiles = [], $revisionId = null)
{
- $files = $request->all()['files'];
$changed = 0;
// check if any file was removed
if ($revisionId) {
- $changed += $this->removeRelatedFiles($revisionId, $request);
+ $changed += $this->removeRelatedFiles($revisionId, $assignedFiles);
}
// allow uploading only on created pages
@@ -222,13 +36,16 @@ trait Content
'name' => '.content_files',
'hidden' => true
]);
- $request->directoryId = $directory->id;
+ $data = new \stdClass();
+ $data->directoryId = $directory->id;
+
+ $fileModel = App::make(File::class);
foreach ($files as $file) {
if (!$file) {
continue;
}
- $uploaded = $this->file->upload($file, $request);
+ $uploaded = $fileModel->upload($file, $data);
// add assignement
ContentHasFile::create([
@@ -250,16 +67,13 @@ trait Content
* Delete files from association
*
* @param $revisionId
- * @param $request
*
* @return int
*/
- private function removeRelatedFiles($revisionId, $request)
+ private function removeRelatedFiles($revisionId, $assignedFiles)
{
- $files = array_keys((array)$request->keepAssigned);
-
$allFiles = $this->files()
- ->whereNotIn('id', $files)
+ ->whereNotIn('id', $assignedFiles)
->get();
foreach ($allFiles as $file) {
@@ -273,29 +87,6 @@ trait Content
return count($allFiles);
}
- /**
- * Save history entry into database
- *
- * @param $revisionId
- * @param $fieldRequest
- * @param $fieldValue
- * @param $request
- */
- private function saveHistory($revisionId, $fieldRequest, $fieldValue, $request)
- { // setup history object
- $history = [
- 'user_id' => \Auth::user()->id,
- 'content_id' => $this->id,
- 'edit_batch' => $revisionId,
- 'column' => $fieldRequest,
- 'old_value' => $fieldValue,
- 'new_value' => $request[$fieldRequest]
- ];
-
- // save history
- ContentHistory::create($history);
- }
-
public function view()
{
$this->viewed++;
diff --git a/app/Models/Content/ModelTraits/ContentHistory.php b/app/Models/Content/ModelTraits/ContentHistory.php
index ee852408..84f58489 100644
--- a/app/Models/Content/ModelTraits/ContentHistory.php
+++ b/app/Models/Content/ModelTraits/ContentHistory.php
@@ -18,7 +18,7 @@ trait ContentHistory
public function getStructuredHistoryOf(Content $content)
{
$data = $content->history()
- ->select('content_history.*', 'contents.module_handler', 'users.email AS user_email', 'users.name AS user_name')
+ ->select('content_history.*', 'contents.moduleHandler', 'users.email AS user_email', 'users.name AS user_name')
->join('users', 'users.id', '=', 'content_history.user_id')
->join('contents', 'contents.id', '=', 'content_history.content_id')
->orderBy('changed_at', 'DESC')
@@ -61,7 +61,7 @@ trait ContentHistory
*/
// get handler of given content page
- $handler = $change->module_handler;
+ $handler = $change->moduleHandler;
return $handler::getHistoryHandler();
}
diff --git a/app/Models/CustomFields/ModuleHasCustomField.php b/app/Models/CustomFields/ModuleHasCustomField.php
index 56b306a6..69236ded 100644
--- a/app/Models/CustomFields/ModuleHasCustomField.php
+++ b/app/Models/CustomFields/ModuleHasCustomField.php
@@ -13,7 +13,7 @@ class ModuleHasCustomField extends Model
public $timestamps = false;
protected $fillable = [
- 'module_handler',
+ 'moduleHandler',
'custom_field_id'
];
diff --git a/app/Models/FileManager/ModelTraits/File.php b/app/Models/FileManager/ModelTraits/File.php
index aea2fe73..a35fa861 100644
--- a/app/Models/FileManager/ModelTraits/File.php
+++ b/app/Models/FileManager/ModelTraits/File.php
@@ -3,7 +3,6 @@
namespace App\Models\FileManager\ModelTraits;
use App\Events\UploadFile;
-use App\Http\Requests\Request;
use App\Models\FileManager\File as FileModel;
use Franzose\ClosureTable\Extensions\Str;
use Illuminate\Support\Facades\Auth;
@@ -34,13 +33,15 @@ trait File
* Saves file into FS and creates new record in database
*
* @param UploadedFile $file
- * @param Request $request
+ * @param $data
*
* @return array associative array - key 'file' is type of SymphonyFile and contains info about real file, key 'id'
* is ID of row in files table
*/
- public function upload(UploadedFile $file, Request $request)
+ public function upload(UploadedFile $file, $data = [])
{
+ $data = (object)$data;
+
$destination = config('app.upload_path');
$filename = $this->getFilename($file);
@@ -54,7 +55,7 @@ trait File
}
// insert record into database
- $id = $this->saveIntoDatabase($uploadedFile, $request, $file->getClientOriginalName());
+ $id = $this->saveIntoDatabase($uploadedFile, $data, $file->getClientOriginalName());
// fire event about new file
Event::fire(new UploadFile($uploadedFile, $id));
@@ -72,12 +73,12 @@ trait File
* This file saves new record into database. It also calculates hash of given file, obtains MIME type etc.
*
* @param SymphonyFile $file
- * @param Request $request
+ * @param $request
* @param $originalFilename
*
* @return mixed
*/
- protected function saveIntoDatabase(SymphonyFile $file, Request $request, $originalFilename)
+ protected function saveIntoDatabase(SymphonyFile $file, $request, $originalFilename)
{
// get path and hash of uploaded file
$path = config('app.upload_path') . DIRECTORY_SEPARATOR . $file->getFilename();
@@ -92,10 +93,10 @@ trait File
'hash_algorithm' => FileModel::HASH_ALGORITHM,
'mime_type' => $file->getMimeType(),
'file_size' => $file->getSize(),
- 'name' => $request->name,
- 'description' => $request->description,
- 'directory_id' => $request->directoryId ? $request->directoryId : null,
- 'keywords' => $request->keywords
+ 'name' => isset($request->name) ? $request->name : '',
+ 'description' => isset($request->description) ? $request->description : '',
+ 'directory_id' => isset($request->directoryId) ? $request->directoryId ? $request->directoryId : null : null,
+ 'keywords' => isset($request->keyword) ? $request->keyword : ''
]);
return $newFile->id;
diff --git a/app/Models/ModelTraits/Module.php b/app/Models/ModelTraits/Module.php
index 938f3b73..7f206f2b 100644
--- a/app/Models/ModelTraits/Module.php
+++ b/app/Models/ModelTraits/Module.php
@@ -44,7 +44,7 @@ trait Module {
'manages_content' => $managesContent,
'support_categories' => $supportCategories,
'alias' => $alias,
- 'module_settings' => json_encode($settings),
+ 'moduleSettings' => json_encode($settings),
'parent_id' => $parentModuleId ? $parentModuleId : null,
'enabled' => 1,
'is_template' => $isTemplate
diff --git a/app/Models/Module.php b/app/Models/Module.php
index f6940aad..ab569966 100644
--- a/app/Models/Module.php
+++ b/app/Models/Module.php
@@ -17,7 +17,7 @@ class Module extends Model
'name',
'description',
'alias',
- 'module_settings',
+ 'moduleSettings',
'enabled',
'support_categories',
'manages_content',
diff --git a/app/Models/User.php b/app/Models/User.php
index 4ffbea03..35d4911f 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -20,6 +20,7 @@ class User extends Model implements AuthenticableInterface
'username',
'password',
'name',
+ 'role'
];
/**
* The attributes excluded from the model's JSON form.
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index f5b55649..d48a6a6f 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -32,18 +32,16 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
- // ignore running from artisan
- if (App::runningInConsole()) {
- return;
- }
-
- $this->registerWidgets();
- $this->registerSettings();
- $this->registerSearch();
-
$this->app->bind(IContent::class, ContentRepository::class);
$this->app->bind(IModule::class, ModuleRepository::class);
$this->app->bind(ITemplate::class, TemplateRepository::class);
+
+ // ignore running from artisan
+ if (!App::runningInConsole()) {
+ $this->registerWidgets();
+ $this->registerSettings();
+ $this->registerSearch();
+ }
}
/**
diff --git a/app/Providers/LaravelLocalizationServiceProvider.php b/app/Providers/LaravelLocalizationServiceProvider.php
index 94f761fc..00b3db64 100644
--- a/app/Providers/LaravelLocalizationServiceProvider.php
+++ b/app/Providers/LaravelLocalizationServiceProvider.php
@@ -1,7 +1,5 @@
env('LOCALE_NATIVE_NAME'),
- 'script' => env('LOCALE_SCRIPT'),
- 'name' => env('LOCALE_TRANSLATED_NAME'),
+ 'native' => env('LOCALE_NATIVE_NAME', config('app.locale')),
+ 'script' => env('LOCALE_SCRIPT', 'Latn'),
+ 'name' => env('LOCALE_TRANSLATED_NAME', config('app.locale')),
'code' => config('app.locale'),
];
-
// create default language
- Language::create($supportedLocales[config('app.locale')]);
+ DB::table('languages')
+ ->insert($supportedLocales[config('app.locale')]);
}
foreach ($languages as $language) {
diff --git a/app/Providers/ModuleManager.php b/app/Providers/ModuleManager.php
index f925aec1..369ddd6c 100644
--- a/app/Providers/ModuleManager.php
+++ b/app/Providers/ModuleManager.php
@@ -26,12 +26,12 @@ class ModuleManager extends ServiceProvider
// iterate over all modules and enable or disable them
foreach ($modules as $module) {
- $module->module_settings = json_decode($module->module_settings);
+ $module->moduleSettings = json_decode($module->moduleSettings);
if ($module->is_template) {
- if (isset($module->module_settings->providers) && !empty($module->module_settings->providers)) {
- foreach ($module->module_settings->providers as $provider) {
+ if (isset($module->moduleSettings->providers) && !empty($module->moduleSettings->providers)) {
+ foreach ($module->moduleSettings->providers as $provider) {
$this->app->register($provider);
}
}
@@ -61,7 +61,7 @@ class ModuleManager extends ServiceProvider
*/
private function createModulesJson(Module $module)
{
- $config = $module->module_settings;
+ $config = $module->moduleSettings;
if (is_null($config)) {
return;
diff --git a/app/Providers/TemplateServiceProvider.php b/app/Providers/TemplateServiceProvider.php
index 10fbdd71..d61eecf5 100644
--- a/app/Providers/TemplateServiceProvider.php
+++ b/app/Providers/TemplateServiceProvider.php
@@ -2,9 +2,9 @@
namespace App\Providers;
+use App\CMS\Contracts\Repositories\Template as TemplateContract;
use App\CMS\Handlers\Registrators\TemplateRegistrator;
use App\CMS\Helpers\CurrentTemplate;
-use App\Models\Templates\Template;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
@@ -13,7 +13,7 @@ class TemplateServiceProvider extends ServiceProvider
public function boot()
{
// ignore running from artisan
- if (App::runningInConsole()) {
+ if (App::runningInConsole() || App::environment('testing')) {
$this->publishViewResources();
return;
@@ -26,19 +26,24 @@ class TemplateServiceProvider extends ServiceProvider
}
// include files
- $files = isset($template->module_settings->files) ? $template->module_settings->files : [];
+ $files = isset($template->moduleSettings->files) ? $template->moduleSettings->files : [];
foreach ($files as $file) {
include_once $file;
}
// register templates
- $publicTemplates = call_user_func([CurrentTemplate::handler(), 'getPublicTemplatePaths']);
+ $publicTemplates = CurrentTemplate::getPublicTemplatePaths();
if (!is_array($publicTemplates)) {
throw new \ErrorException(CurrentTemplate::handler() . '::getPublicTemplatePaths() must return array!');
}
+ $this->registerTemplatePaths($publicTemplates);
+ }
+
+ public function registerTemplatePaths($publicTemplates)
+ {
/**
* @var $registrator TemplateRegistrator
*/
@@ -76,12 +81,12 @@ class TemplateServiceProvider extends ServiceProvider
private function publishViewResources()
{
$template = CurrentTemplate::get();
- if (!$template) {
+ if (!$template || is_null($template->moduleSettings)) {
return;
}
- $templateDir = base_path('templates/' . $template->module_settings->staticName . '/Resources');
- $assetsDir = $templateDir . '/' . Template::ASSETS_DIRECTORY;
+ $templateDir = base_path('templates/' . $template->moduleSettings->staticName . '/Resources');
+ $assetsDir = $templateDir . '/' . TemplateContract::ASSETS_DIRECTORY;
$viewsDir = $templateDir . '/views';
// publish assets if exists for current theme
diff --git a/config/database.php b/config/database.php
index dace41ee..3e451f83 100644
--- a/config/database.php
+++ b/config/database.php
@@ -55,8 +55,8 @@ return [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
- 'database' => env('DB_DATABASE', 'forge'),
- 'username' => env('DB_USERNAME', 'forge'),
+ 'database' => env('DB_DATABASE'),
+ 'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
@@ -64,6 +64,18 @@ return [
'strict' => false,
],
+ 'mysqlTesting' => [
+ 'driver' => 'mysql',
+ 'host' => env('DB_UNIT_TESTS_HOST', 'localhost'),
+ 'database' => env('DB_UNIT_TESTS_DATABASE'),
+ 'username' => env('DB_UNIT_TESTS_USERNAME'),
+ 'password' => env('DB_UNIT_TESTS_PASSWORD', ''),
+ 'charset' => 'utf8',
+ 'collation' => 'utf8_general_ci',
+ 'prefix' => '',
+ 'strict' => false,
+ ],
+
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
@@ -74,17 +86,6 @@ return [
'prefix' => '',
'schema' => 'public',
],
-
- 'sqlsrv' => [
- 'driver' => 'sqlsrv',
- 'host' => env('DB_HOST', 'localhost'),
- 'database' => env('DB_DATABASE', 'forge'),
- 'username' => env('DB_USERNAME', 'forge'),
- 'password' => env('DB_PASSWORD', ''),
- 'charset' => 'utf8',
- 'prefix' => '',
- ],
-
],
/*
diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php
index 0876c70c..96f72d25 100644
--- a/database/factories/ModelFactory.php
+++ b/database/factories/ModelFactory.php
@@ -11,11 +11,32 @@
|
*/
-$factory->define(App\User::class, function (Faker\Generator $faker) {
+use App\CMS\Contracts\Repositories\Content as ContentContract;
+use App\Models\Content\Content;
+use App\Models\User;
+use Carbon\Carbon;
+
+$factory->define(User::class, function (Faker\Generator $faker) {
+ $email = $faker->email;
return [
- 'name' => $faker->name,
- 'email' => $faker->email,
+ 'username' => $email,
+ 'email' => $email,
+ 'name' => $faker->name,
'password' => bcrypt(str_random(10)),
- 'remember_token' => str_random(10),
+ 'role' => 'admin',
];
});
+
+$factory->define(Content::class, function (Faker\Generator $faker) {
+ return [
+ 'title' => $faker->sentence(5),
+ 'userId' => 1,
+ 'url' => $faker->slug(5),
+ 'pageContent' => $faker->text(1500),
+ 'metaDescription' => $faker->text,
+ 'moduleHandler' => config('staticpages.handler'),
+ 'language' => env('LOCALES'),
+ 'publishedFrom' => Carbon::now(),
+ 'status' => ContentContract::STATUS_PUBLIC
+ ];
+});
\ No newline at end of file
diff --git a/database/migrations/2016_10_11_135756_AddUniqueCodeToWidgets.php b/database/migrations/2016_10_11_135756_AddUniqueCodeToWidgets.php
index 36141a15..c8456ba9 100644
--- a/database/migrations/2016_10_11_135756_AddUniqueCodeToWidgets.php
+++ b/database/migrations/2016_10_11_135756_AddUniqueCodeToWidgets.php
@@ -26,7 +26,7 @@ class AddUniqueCodeToWidgets extends Migration
});
// migrate data
- $widgets = \App\Models\Widget::all();
+ $widgets = \App\Models\Widgets\Widget::all();
foreach ($widgets as $widget) {
$widget->settings = json_decode($widget->settings);
if (isset($widget->settings->containerClass)) {
diff --git a/database/migrations/2016_10_25_071455_rename_column_in_contents.php b/database/migrations/2016_10_25_071455_rename_column_in_contents.php
new file mode 100644
index 00000000..45b03e33
--- /dev/null
+++ b/database/migrations/2016_10_25_071455_rename_column_in_contents.php
@@ -0,0 +1,67 @@
+getDoctrineSchemaManager()->getDatabasePlatform();
+ $platform->registerDoctrineTypeMapping('enum', 'string');
+
+ $this->columns = [
+ 'user_id',
+ 'parent_id',
+ 'category_id',
+ 'language',
+ 'module_handler',
+ 'published_from',
+ 'published_to',
+ 'title_photo',
+ 'template',
+ 'is_homepage',
+ 'title',
+ 'url',
+ 'meta_keywords',
+ 'meta_description',
+ 'content',
+ 'module_settings',
+ 'status'
+ ];
+ }
+
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+ Schema::table('contents', function (Blueprint $table) {
+ foreach ($this->columns as $column) {
+ $table->renameColumn($column, camel_case($column));
+ }
+
+ $table->renameColumn('content', 'pageContent');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('contents', function (Blueprint $table) {
+ foreach ($this->columns as $column) {
+ $table->renameColumn(camel_case($column), $column);
+ }
+
+ $table->renameColumn('pageContent', 'content');
+ });
+ }
+}
diff --git a/modules/Blog/Article/Handlers/Article.php b/modules/Blog/Article/Handlers/Article.php
index 7365f423..901eaa2b 100644
--- a/modules/Blog/Article/Handlers/Article.php
+++ b/modules/Blog/Article/Handlers/Article.php
@@ -5,7 +5,6 @@ use App\CMS\Contracts\Content\AdvancedContentModifier;
use App\CMS\Contracts\Content\ContentTitles;
use App\CMS\Contracts\Modules\InstallableModule;
use App\CMS\Handlers\Handler;
-use App\Http\Controllers\Admin\Contents\EditContent;
use App\Http\Controllers\Controller;
use App\Http\Requests\Request;
use App\Models\ActionLog\ActionLogType;
@@ -27,7 +26,7 @@ class Article extends Handler implements ContentTitles, AdvancedContentModifier,
public function render(Content $content, $parameters)
{
$content->comments = [];
- if (isset($content->module_settings->allowComments) && $content->module_settings->allowComments) {
+ if (isset($content->moduleSettings->allowComments) && $content->moduleSettings->allowComments) {
$content->comments = Comment::where('content_id', $content->id)
->with('author')
->where('approved', 1)
@@ -62,7 +61,7 @@ class Article extends Handler implements ContentTitles, AdvancedContentModifier,
*/
public static function createNew(Content &$content, Request $request)
{
- $content->module_settings = json_encode(['allowComments' => (int)$request->has('allowComments')]);
+ $content->moduleSettings = ['allowComments' => (int)$request->has('allowComments')];
}
/**
@@ -73,23 +72,18 @@ class Article extends Handler implements ContentTitles, AdvancedContentModifier,
* @param Content $content
* @param Request $request
*
- * @param $revisionID string ID of revision used
- *
- * @return int number of edited fields
+ * @return void
*/
- public static function edit(Content &$content, Request $request, $revisionID)
+ public static function edit(Content $content, $request)
{
- $fields = ['allowComments' => 'allowComments'];
+ $settings = $content->moduleSettings;
+ if (!is_object($settings))
+ $settings = new \stdClass();
- // get data and try to save them
- $data = EditContent::getFields($request, $fields);
+ $settings->allowComments = isset($request['allowComments']) ? (int)$request['allowComments'] : 0;
- $data['allowComments'] = (int)$data['allowComments'];
-
- list($revision, $changedColumns) = $content->updateWithHistory($fields, $data, $revisionID);
-
- // return amount of changed columns
- return $changedColumns;
+ $content->moduleSettings = $settings;
+ $content->save();
}
/**
@@ -99,8 +93,6 @@ class Article extends Handler implements ContentTitles, AdvancedContentModifier,
*/
public static function registerAdminMenu(User $user)
{
- parent::registerAdminMenu($user);
-
$menu = \Menu::instance('mainMenu');
$blogSubmenu = $menu->whereTitle(trans('article::module.blog'));
diff --git a/modules/Blog/Article/Http/Controllers/Visitor/CreateNewComment.php b/modules/Blog/Article/Http/Controllers/Visitor/CreateNewComment.php
index 6811187b..8af7ba9b 100644
--- a/modules/Blog/Article/Http/Controllers/Visitor/CreateNewComment.php
+++ b/modules/Blog/Article/Http/Controllers/Visitor/CreateNewComment.php
@@ -14,12 +14,12 @@ class CreateNewComment extends Controller
public function postNew(\Modules\Blog\Article\Http\Requests\CreateNewComment $request, $articleId)
{
$article = Content::where('id', $articleId)
- ->where('module_handler', Article::class)
+ ->where('moduleHandler', Article::class)
->firstOrFail();
- $article->module_settings = json_decode($article->module_settings);
+ $article->moduleSettings = json_decode($article->moduleSettings);
- if (!isset($article->module_settings->allowComments) || !$article->module_settings->allowComments) {
+ if (!isset($article->moduleSettings->allowComments) || !$article->moduleSettings->allowComments) {
return redirect()
->route('page.content', ['url' => $article->url])
->with('error', trans('article::comments.disabledComments'));
diff --git a/modules/Blog/Article/Resources/views/admin/content/basicInfo.blade.php b/modules/Blog/Article/Resources/views/admin/content/basicInfo.blade.php
index ec02b51e..dd808110 100644
--- a/modules/Blog/Article/Resources/views/admin/content/basicInfo.blade.php
+++ b/modules/Blog/Article/Resources/views/admin/content/basicInfo.blade.php
@@ -37,12 +37,12 @@
@include('admin.snippets.hasError', ['field' => 'status'])
-