Author SHA1 Message Date
Michal Kváček f51dd9458c FEATURE: change default email template 2017-10-29 21:45:01 +01:00
Michal Kváček 962225080d FEATURE: make intro text white 2017-10-29 21:38:43 +01:00
582 changed files with 117990 additions and 33718 deletions
+1 -1
View File
@@ -16,4 +16,4 @@ MAIL_PASSWORD=
SITE_URL=/
UPLOAD_URL=/public/uploads
THUMBNAIL_URL=/public/uploads/thumbnails
THUMBNAILS_URL=/uploads/thumbnails
-6
View File
@@ -27,9 +27,3 @@
# meta information created by installer
.install
/node_modules/
/public/css/
/public/js
/public/fonts
/bower_components
.sass-cache
@@ -1,18 +0,0 @@
<?php
namespace App\CMS\Contracts\Content;
use App\Http\Requests\Request;
use App\Models\Content\Content;
interface AdvancedContentModifier {
/**
* Method called right after content page is marked as deleted
*
* This method is supposed to clean after "deleted" page.
*
* @param Content $content
*
* @return mixed
*/
public static function delete(Content $content);
}
@@ -1,16 +0,0 @@
<?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);
}
@@ -1,15 +0,0 @@
<?php
namespace App\CMS\Contracts\Content\DisplayPipeline;
use App\Models\Content\Content;
interface Process {
/**
* Process and modify given page
*
* @param Content $page
*
* @return mixed
*/
function handle(Content & $page);
}
@@ -1,25 +0,0 @@
<?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);
}
@@ -1,16 +0,0 @@
<?php
namespace App\CMS\Contracts\Content\SavePipeline;
use App\Models\Content\Content;
interface Process {
/**
* Process and modify given page
*
* @param Content $page
* @param array $input
*
* @return mixed
*/
function handle(Content & $page, array & $input);
}
-21
View File
@@ -1,21 +0,0 @@
<?php
namespace App\CMS\Contracts;
interface Interaction {
/**
* Perform given action
*
* @param $data array input data
* @param $parameters array parameters
*
* @return mixed
*/
public function handle($data, $parameters);
/**
* @param $data array input data
*
* @return array
*/
public function getValidationRules($data = []);
}
-42
View File
@@ -1,42 +0,0 @@
<?php
namespace App\CMS\Contracts\Modules;
use App\Http\Requests\Request;
use App\Models\Content\Content;
interface AppHandler extends BaseModuleHandler
{
public static function getHistoryHandler();
/**
* Getter for section names in creating/editing content resource
*
* @return mixed
*/
public static function getExtendedFormSections();
/**
* Getter for views used in extended part of form for creating new content
*
* This method should return pairs <section, view-name>. View is returned only as name in plain text
*
* @return array of views/templates/html codes divided into section
*/
public static function getExtendedFormInputsCreate();
/**
* Getter for extended part of form for editing existing content
*
* Basically, this method may be
*
* @return array of views/templates/html codes divided into section
*/
public static function getExtendedFormInputsEdit();
/**
* Does this module support categories?
*
* @return boolean
*/
public static function supportCategories();
}
@@ -1,23 +0,0 @@
<?php
namespace App\CMS\Contracts\Modules;
use App\Models\Module;
interface InstallableModule {
/**
* Install module.
*
* This method is called after inserting info about module into database. It can be called only using Artisan in
* CLI.
*/
public static function install();
/**
* Uninstalls module
*
* @param Module $module
*
* @return mixed
*/
public static function uninstall(Module $module);
}
@@ -1,30 +0,0 @@
<?php
namespace App\CMS\Contracts\Modules;
use App\Http\Requests\Request;
use App\Models\Content\Content;
/**
* Interface TemplateHandler
*
* Inerface used for registering template into CMS core.
*
* @package App\CMS\Handlers\Contracts
*/
interface TemplateHandler extends BaseModuleHandler
{
/**
* Get list of registered templates and supported modules.
*
* Returned array is expected to be array of arrays with following items: module, namespace and templateName.
* Example:
* return [
* ['module' => 'Article', 'templateName' => 'article::template.name']
* ];
*
* When no "namespace" is specified, value strtolower(module) is used instaed.
*
* @return array
*/
public static function getPublicTemplatePaths();
}
@@ -1,7 +0,0 @@
<?php
namespace App\CMS\Contracts\Repositories;
interface BaseRepository {
public function getOne($id = null);
public function all();
}
@@ -1,15 +0,0 @@
<?php
namespace App\CMS\Contracts\Repositories;
interface Content extends BaseRepository
{
const STATUS_DRAFT = 'draft';
const STATUS_PROTECTED = 'protected';
const STATUS_PUBLIC = 'public';
public function getOverview($handler = null, $statuses = null);
public function getHomepage();
public function getByURL($url);
}
-20
View File
@@ -1,20 +0,0 @@
<?php
namespace App\CMS\Contracts\Repositories;
use App\Models\Content\Content as ContentModel;
use App\Models\Module as ModuleModel;
interface Module extends BaseRepository
{
public function getCreateContentTitle(ModuleModel $module);
public function getUpdateContentTitle(ModuleModel $module, ContentModel $content = null);
public function getOverviewTitle(ModuleModel $module);
public function getByHandler($handler);
public function call(ModuleModel $module, $method, $parameters = []);
public function callOnString($moduleHandler, $method, $parameters = []);
}
@@ -1,21 +0,0 @@
<?php
namespace App\CMS\Contracts\Repositories;
use App\Models\Module as ModuleModel;
use App\Models\Templates\Template as TemplateModel;
interface Template
{
const EDITED_TEMPLATES_DIRECTORY = 'custom';
const ASSETS_DIRECTORY = 'assets';
const MODULES_DIRECTORY = 'modules';
const TEMPLATE_SUFFIX = '.blade.php';
const CUSTOM_EDIT_DIRECTORY = 1;
const ORIGINAL_DIRECTORY = 2;
public function setModel(TemplateModel $model);
public function getPathToTemplate($mode = null);
public function getForModule(ModuleModel $module);
}
@@ -1,17 +0,0 @@
<?php
namespace App\CMS\Contracts\Widgets;
interface InstallableWidget extends PublicWidget {
/**
* Function for installing given widget
*
* @return mixed
*/
public static function install();
/**
* Function for uninstalling widget
*/
public static function uninstall();
}
@@ -1,6 +0,0 @@
<?php
namespace App\CMS\Exceptions\FileManager;
class SubdirectoryExistsInDirectory extends \Exception
{
}
@@ -1,19 +0,0 @@
<?php
namespace App\CMS\Exceptions\Validation;
use Exception;
class ValidationFailedException extends \Exception {
protected $validator;
public function __construct($validator, $message = null, $code = null, Exception $previous = null)
{
parent::__construct($message, $code, $previous);
$this->validator = $validator;
}
public function getValidator(){
return $this->validator;
}
}
-39
View File
@@ -1,39 +0,0 @@
<?php
namespace App\Cms\Handlers\Interactions;
use App\CMS\Contracts\Interaction as InteractionContract;
use App\CMS\Exceptions\Validation\ValidationFailedException;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Validator;
class Interaction
{
/**
* Handle interaction with application
*
* @param string $interactionClass
* @param array $data
* @param array $extraParameters
*
* @return mixed
* @throws ValidationFailedException
*/
public static function handle($interactionClass, $data, ...$extraParameters)
{
/**
* @var $interaction InteractionContract
*/
$interaction = app($interactionClass);
// validate interaction
$validator = Validator::make($data, $interaction->getValidationRules($extraParameters));
if ($validator->fails()) {
throw new ValidationFailedException($validator);
}
// handle it
return $interaction->handle($data, $extraParameters);
}
}
-99
View File
@@ -1,99 +0,0 @@
<?php
namespace App\CMS\Helpers;
use App\CMS\Contracts\Modules\TemplateHandler;
use App\Models\Content\Content;
use App\Models\Module;
use App\Models\User;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\Cache;
class CurrentTemplate implements TemplateHandler
{
protected static $template;
protected static $initialized = false;
/**
* Getter for currently set template
* @return Module
* @throws \ErrorException
*/
public static function get()
{
if (!self::$initialized) {
self::$template = Cache::rememberForever('current-template', function () {
$template = Module::where('is_template', true)
->where('enabled', true)
->first();
// todo remove after adding $casts into Module model
if ($template) {
$template->module_settings = json_decode($template->module_settings);
}
return $template;
});
self::$initialized = true;
}
return self::$template;
}
/**
* Shortcut for getting template handler
*
* @return string
* @throws \ErrorException
*/
public static function handler()
{
$template = self::get();
if (!$template) {
throw new \ErrorException('No template selected, no handler available!');
}
return $template->handler;
}
/**
* Reset currently set template and load another one on next call of get() method.
*/
public static function reset()
{
self::$initialized = false;
}
/**
* Register admin menu (or multiple ones)
*
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
* starting any middleware..
*
* @param User $user model of logged user
*/
public static function registerAdminMenu(User $user)
{
call_user_func_array([self::handler(), 'registerAdminMenu'], [$user]);
}
/**
* Get list of registered templates and supported modules.
*
* Returned array is expected to be array of arrays with following items: module, namespace and templateName.
* Example:
* return [
* ['module' => 'Article', 'templateName' => 'article::template.name']
* ];
*
* When no "namespace" is specified, value strtolower(module) is used instaed.
*
* @return array
*/
public static function getPublicTemplatePaths()
{
return call_user_func([self::handler(), 'getPublicTemplatePaths']);
}
}
-49
View File
@@ -1,49 +0,0 @@
<?php
namespace App\CMS\Helpers;
use App\Models\FileManager\Directory;
use App\Models\FileManager\File;
class RootDirectory
{
protected static $directory;
/**
* Create root directory
*
* @return Directory
*/
protected static function create()
{
$directory = new Directory();
$directory->name = 'Root';
$directory->is_root = true;
$directory->save();
Directory::whereNull('parent_id')
->where('is_root', false)
->update(['parent_id' => $directory->id]);
File::where('directory_id', null)
->update(['directory_id' => $directory->id]);
return $directory;
}
/**
* Get root directory
*
* @return Directory
*/
public static function get()
{
self::$directory = Directory::where('is_root', true)
->first();
if (is_null(self::$directory)) {
self::$directory = self::create();
}
return self::$directory;
}
}
-49
View File
@@ -1,49 +0,0 @@
<?php
namespace App\CMS\Helpers;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Process\Exception\InvalidArgumentException;
class Template
{
/**
* Getter for real template name
*
* @param $template
*
* @param bool $throwExceptions
*
* @return null|string
*/
public static function name($template, $throwExceptions = true)
{
$namespace = null;
if (strpos($template, '::')) {
list($namespace, $template) = explode('::', $template);
$namespace .= '::';
}
// list of prefixes
$prefixes = ['custom.', ''];
$view = null;
foreach ($prefixes as $prefix) {
if (view()->exists($namespace . 'visitor.' . $prefix . $template)) {
$view = $namespace . 'visitor.' . $prefix . $template;
break;
}
}
if (is_null($view)) {
if ($throwExceptions) {
throw new InvalidArgumentException('Cannot find template for ' . $namespace . $template);
} else {
return false;
}
}
return $view;
}
}
-33
View File
@@ -1,33 +0,0 @@
<?php
namespace App\CMS\Helpers\Traits;
use Carbon\Carbon;
/**
* Class Nullable
*
* @package App\CMS\Helpers\Traits
*/
trait Nullable {
/**
* Get null or parsed date
*
* @param $date
*
* @return null|string
*/
public function nullableDate($date) {
return empty($date) ? null : Carbon::parse($date)->toDateTimeString();
}
/**
* Get null or input value
*
* @param $string
*
* @return null
*/
public function nullable($string) {
return empty($string) ? null : $string;
}
}
-18
View File
@@ -1,18 +0,0 @@
<?php
namespace App\CMS\Helpers;
class Widget
{
public static function render(\App\Models\Widgets\Widget $widget)
{
$handler = $widget->widget_type_handler;
if (is_string($widget->settings)) {
$widget->settings = json_decode($widget->settings);
}
$presenter = call_user_func([$handler, 'getPresenter']);
return call_user_func([$presenter, 'render'], $widget);
}
}
@@ -1,38 +0,0 @@
<?php
namespace App\CMS\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Enumerations\ContentStatuses;
class ChangeStatus implements Interaction
{
/**
* Change status of content page
*
* @param array $data
* @param array $parameters
*
* @return mixed|void
*/
public function handle($data, $parameters)
{
list ($page) = $parameters;
$page->status = $data['status'];
$page->save();
}
/**
* Check if status is valid
*
* @param array $parameters
*
* @return array
*/
public function getValidationRules($parameters = [])
{
$statuses = ContentStatuses::getWithTranslations();
return ['status' => 'in:' . implode(',', array_keys($statuses))];
}
}
@@ -1,45 +0,0 @@
<?php
namespace App\CMS\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Contracts\Repositories\Module;
use App\Models\Content\Content;
use Illuminate\Support\Facades\App;
class DeletePage implements Interaction
{
/**
* Perform given action
*
* @param $data array input data
* @param $parameters array parameters
*
* @return void
*/
public function handle($data, $parameters)
{
/**
* @var $page Content
* @var $module Module
*/
$module = App::make(Module::class);
list ($page) = $parameters;
// delete page
$page->delete();
// let module to delete some extra content created during page's life
$module->callOnString($page->moduleHandler, 'delete', [$page]);
}
/**
* @param $data array input data
*
* @return array
*/
public function getValidationRules($data = [])
{
return [];
}
}
@@ -1,78 +0,0 @@
<?php
namespace App\Cms\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Contracts\Repositories\Module;
use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Helpers\CurrentTemplate;
use App\Events\EditContent as EditContentEvent;
use App\Http\Requests\Request;
use App\Models\Content\Content;
use App\Models\FileManager\File;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class EditContent implements Interaction
{
/**
* @var Module
*/
protected $module;
/**
* @var File
*/
protected $file;
public function __construct()
{
$this->module = App::make(Module::class);
$this->file = App::make(File::class);
}
/**
* Edit page
*
* @param array $data
* @param array $parameters
*
* @return mixed
*/
public function handle($data, $parameters)
{
/**
* @var $page Content
*/
list($page) = $parameters;
app('saveContentPipeline')->run($page, $data);
return $page;
}
/**
* Validate this interaction
*
* @param array $parameters
*
* @return array
*/
public function getValidationRules($parameters = [])
{
$id = $parameters[0]->id;
// get all available statuses
$statuses = ContentStatuses::getSimple();
$statuses = implode(',', $statuses);
return [
'title' => 'required',
'url' => 'required|unique:contents,url,' . $id.',id,deleted_at,NULL,language,' . LaravelLocalization::getCurrentLocale(),
'publishedFrom' => 'date',
'publishedTo' => 'date',
'status' => 'required|in:' . $statuses,
'parentPage' => 'exists:contents,id'
];
}
}
@@ -1,74 +0,0 @@
<?php
namespace App\Cms\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Contracts\Repositories\Content as ContentRepository;
use App\CMS\Contracts\Repositories\Module;
use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Helpers\CurrentTemplate;
use App\Models\Content\Content;
use App\Models\FileManager\File;
use Illuminate\Support\Facades\App;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class NewContent implements Interaction
{
/**
* @var ContentRepository
*/
protected $content;
/**
* @var File
*/
protected $file;
/**
* @var Module
*/
protected $module;
public function __construct()
{
$this->content = App::make(ContentRepository::class);
$this->module = App::make(Module::class);
$this->file = App::make(File::class);
}
/**
* Create new content page
*
* @param array $data
* @param $parameters
*
* @return Content
*/
public function handle($data, $parameters)
{
list($moduleHandler) = $parameters;
$data['userId'] = \Auth::user()->id;
$data['language'] = LaravelLocalization::getCurrentLocale();
$data['moduleHandler'] = $moduleHandler;
$page = new Content();
app('saveContentPipeline')->run($page, $data);
return $page;
}
public function getValidationRules($parameters = [])
{
// get all available statuses
$statuses = ContentStatuses::getSimple();
$statuses = implode(',', $statuses);
return [
'titlePhoto' => 'image',
'title' => 'required',
'url' => 'required|unique:contents,url,NULL,id,deleted_at,NULL,language,' . LaravelLocalization::getCurrentLocale(),
'status' => 'required|in:'.$statuses,
'parentPage' => 'exists:contents,id',
'publishedFrom' => 'date',
'publishedTo' => 'date',
];
}
}
@@ -1,43 +0,0 @@
<?php
namespace App\CMS\Interactions\Admin\Content;
use App\CMS\Contracts\Interaction;
use App\CMS\Enumerations\ContentStatuses;
use App\Models\Content\Content;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class SetHomepage implements Interaction
{
/**
* Set homepage of given page
*
* @param array $data
* @param array $parameters
*
* @return void
*/
public function handle($data, $parameters)
{
list ($page) = $parameters;
// disable any other existing homepage
Content::where('isHomepage', true)
->where('language', LaravelLocalization::getCurrentLocale())
->update(['isHomepage' => false]);
// set new homepage
$page->isHomepage = true;
$page->save();
}
/**
* Check if status is valid
*
* @param array $parameters
*
* @return array
*/
public function getValidationRules($parameters = [])
{
return [];
}
}
@@ -1,65 +0,0 @@
<?php
namespace App\CMS\Interactions\Admin\FileManager;
use App\CMS\Contracts\Interaction;
use App\CMS\Exceptions\FileManager\SubdirectoryExistsInDirectory;
use App\CMS\Repositories\FileManager\Directory as DirectoryRepository;
use App\Models\FileManager\Directory;
class CreateDirectory implements Interaction
{
/**
* @var DirectoryRepository
*/
private $repository;
public function __construct(DirectoryRepository $repository)
{
$this->repository = $repository;
}
/**
* Perform given action
*
* @param $data array input data
* @param $parameters array parameters
*
* @return Directory
* @throws SubdirectoryExistsInDirectory
*/
public function handle($data, $parameters)
{
$data['parentDirectory'] = isset($data['parentDirectory']) ? $data['parentDirectory'] : null;
// todo this should probably go into validation, but we are not able to get $data in getValidationRules
// check if created folder does not exist in current directory
if ($this->repository->checkIfNameExists($data['name'], $data['parentDirectory'])) {
throw new SubdirectoryExistsInDirectory();
}
// todo use Directory::create() and rename columns/fields in request
// create new database entry
$directory = new Directory();
$directory->name = $data['name'];
$directory->parent_id = $data['parentDirectory'];
$directory->user_id = \Auth::user()->id;
$directory->description = $data['description'];
$directory->save();
return $directory;
}
/**
* @param $data array input data
*
* @return array
* @throws SubdirectoryExistsInDirectory
*/
public function getValidationRules($data = [])
{
return [
'name' => 'required|max:255',
'parentDirectory' => 'exists:directories,id'
];
}
}
-168
View File
@@ -1,168 +0,0 @@
<?php
namespace App\CMS\Observers;
use App\CMS\Contracts\Repositories\Content as ContentContract;
use App\Events\CreateNewContent;
use App\Events\DeleteContent;
use App\Events\EditContent;
use App\Events\MakeDraftFromContent;
use App\Events\PublishContent;
use App\Events\SetHomepage;
use App\Models\Content\Content as ContentModel;
use App\Models\Content\ContentHistory;
use Illuminate\Support\Facades\Event;
/**
* Class Content
*
* Model observer for logging changes on content page.
*
* @package App\CMS\Observers
*/
class Content
{
/**
* @var string
*/
protected $changeset;
public function __construct()
{
$this->changeset = uniqid();
}
/**
* Log changes on edit
*
* @param ContentModel $content
*/
public function updated(ContentModel $content)
{
$fields = $this->getDirtyFields($content->getDirty(), $content->getOriginal());
$normalFieldsEdited = 0;
foreach ($fields as $field => $change) {
if ($field == 'viewed')
continue;
$history = [
'user_id' => \Auth::user()->id,
'content_id' => $content->id,
'edit_batch' => $this->changeset,
'column' => $field,
'old_value' => $change['old'],
'new_value' => $change['new']
];
// save history
ContentHistory::create($history);
// fire event
$this->fireEvent($field, $change, $content, $normalFieldsEdited);
}
if ($normalFieldsEdited > 0) {
Event::fire(new EditContent($content, $this->changeset));
}
}
/**
* Fire event when new instance of model is stored into database
*
* @param ContentModel $content
*/
public function created(ContentModel $content)
{
Event::fire(new CreateNewContent($content));
}
/**
* @param ContentModel $content
*/
public function deleted(ContentModel $content)
{
Event::fire(new DeleteContent($content));
}
/**
* Get all dirty changed from model.
*
* If user did not change moduleSettings column, return result from ContentModel::getDirty(). Otherwise append all
* changed columns from module settings.
*
* @param $changed
* @param $original
*
* @return array
*/
protected function getDirtyFields($changed, $original)
{
unset($changed['updated_at']);
$changes = $this->getNewAndOldValues(array_keys($changed), $changed, $original);
if (!isset($changed['moduleSettings'])) {
return $changes;
}
$moduleSettings = (array)json_decode($changed['moduleSettings']);
$originalSettings = isset($original['moduleSettings']) ? (array)json_decode($original['moduleSettings']) : [];
unset($changed['moduleSettings']);
$settingChanged = array_keys(array_diff_assoc($moduleSettings, $originalSettings));
$changesInSettings = $this->getNewAndOldValues($settingChanged, $moduleSettings, $originalSettings);
return array_merge($changes, $changesInSettings);
}
/**
* Get original and changed values in one array
*
* @param $fields
* @param $new
* @param $original
*
* @return array
*/
protected function getNewAndOldValues($fields, $new, $original)
{
$changes = [];
foreach ($fields as $field) {
$changes[$field] = [
'new' => isset($new[$field]) ? $new[$field] : null,
'old' => isset($original[$field]) ? $original[$field] : null
];
}
return $changes;
}
/**
* Fire events for publishing/making draft and setting homepage
*
* @param $field
* @param $change
* @param ContentModel $content
* @param $normalFieldsEdited
*/
protected function fireEvent($field, $change, ContentModel $content, &$normalFieldsEdited)
{
switch ($field) {
case 'status':
if ($change['new'] !== ContentContract::STATUS_DRAFT) {
Event::fire(new PublishContent($content, $this->changeset));
} else {
Event::fire(new MakeDraftFromContent($content, $this->changeset));
}
break;
case 'isHomepage':
Event::fire(new SetHomepage($content, $this->changeset));
break;
default:
$normalFieldsEdited++;
}
}
}
-71
View File
@@ -1,71 +0,0 @@
<?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;
}
}
@@ -1,58 +0,0 @@
<?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);
}
}
}
@@ -1,19 +0,0 @@
<?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();
}
}
@@ -1,20 +0,0 @@
<?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);
}
}
@@ -1,6 +0,0 @@
<?php
namespace App\CMS\Pipeline\Exceptions;
class InvalidProcessType extends \Exception
{
}
@@ -1,20 +0,0 @@
<?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);
}
}
@@ -1,75 +0,0 @@
<?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();
}
}
}
@@ -1,38 +0,0 @@
<?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();
}
}
@@ -1,69 +0,0 @@
<?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);
}
}
}
-130
View File
@@ -1,130 +0,0 @@
<?php
namespace App\CMS\Repositories\Content;
use App\CMS\Contracts\Repositories\Content as IContent;
use App\CMS\Enumerations\ContentStatuses;
use App\CMS\Repositories\Repository;
use App\Models\Content\Content as ContentModel;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class Content extends Repository implements IContent
{
/**
* @var ContentModel
*/
protected $model;
public function __construct(ContentModel $model)
{
$this->model = $model;
}
/**
* Getter for query with setup filter for non-deleted and non-draft pages
*/
protected function getPageQuery()
{
return ContentModel::where('status', '!=', IContent::STATUS_DRAFT)
->select('contents.*')
->with('author')
->join('modules', 'modules.handler', '=', 'contents.moduleHandler')
->where(function ($query) {
$query->where('publishedFrom', '<=', Carbon::now())
->orWhereNull('publishedFrom');
})
->where(function ($query) {
$query->where('publishedTo', '>=', Carbon::now())
->orWhereNull('publishedTo');
})
->where('language', LaravelLocalization::getCurrentLocale())
->whereNull('contents.deleted_at')
->where('modules.enabled', true);
}
public function all()
{
return $this->getPageQuery()
->get();
}
/**
* @param int $id
*
* @return mixed
*/
public function getOne($id = null)
{
if (is_null($id)) {
$page = new ContentModel();
$page->user_id = \Auth::user()->id;
$page->language = LaravelLocalization::getCurrentLocale();
$page->status = IContent::STATUS_DRAFT;
$page->moduleSettings = [];
} else {
$page = $this->model->findOrFail($id);
}
return $page;
}
/**
* Getter for homepage content page
* @return Content
*/
public function getHomepage()
{
return $this->getPageQuery()
->where('isHomepage', 1)
->first();
}
/**
* Getter for any page specified by its url.
*
* @param $url
*
* @return Content
*/
public function getByURL($url)
{
return $this->getPageQuery()
->where('url', $url)
->first();
}
/**
* Getter for overview of all content pages.
* These content pages may be filtered by using some handler
*
* @param bool $handler
* @param null $statuses
*
* @return
*/
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.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')
->where('contents.language', LaravelLocalization::getCurrentLocale())
->where('modules.enabled', 1)
->orderBy('contents.created_at', 'DESC');
// filter results using handler
if (!is_null($handler)) {
$query = $query->where('contents.moduleHandler', $handler);
}
// add filtering by status
if (is_array($statuses) && in_array($statuses, ContentStatuses::getSimple())) {
$query = $query->whereIn('contents.status', $statuses);
}
return $query;
}
}
@@ -1,54 +0,0 @@
<?php
namespace App\CMS\Repositories\FileManager;
use App\CMS\Helpers\RootDirectory;
use App\Models\FileManager\Directory as DirectoryModel;
class Directory
{
/**
* Checks if directory with given name does not exist in current directory
*
* @param $name
* @param $parentDirectoryId
* @param bool $ignoredId
*/
public function checkIfNameExists($name, $parentDirectoryId, $ignoredId = false)
{
$exists = DirectoryModel::where('name', $name)
->where('parent_id', $parentDirectoryId);
if ($ignoredId !== false) {
$exists = $exists->where('id', '!=', $ignoredId);
}
return $exists->exists();
}
public function update(DirectoryModel $directory, $data) {
$directory->name = $data['name'];
$directory->description = $data['description'];
$directory->save();
}
/**
* @param DirectoryModel $directory
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function getAllSubdirectories(DirectoryModel &$directory)
{
if (!$directory->exists) {
$directory = DirectoryModel::where('is_root', true)
->first();
if (is_null($directory)) {
$directory = RootDirectory::get();
}
}
$subdirectories = $directory->allSubdirectories();
return $subdirectories;
}
}
-82
View File
@@ -1,82 +0,0 @@
<?php
namespace App\CMS\Repositories;
use App\CMS\Contracts\Repositories\Module as IModule;
use App\Models\Content\Content;
use App\Models\Module as ModuleModel;
class Module extends Repository implements IModule
{
public function __construct(ModuleModel $module)
{
$this->model = $module;
}
public function getOne($id = null)
{
if (is_null($id)) {
return new ModuleModel();
}
if (is_numeric($id)) {
return ModuleModel::findOrFail($id);
} else {
return ModuleModel::where('alias', $id)
->firstOrFail();
}
}
public function getCreateContentTitle(ModuleModel $module)
{
$pageHeading = trans('admin/contents.new', ['name' => trans($module->name)]);
$moduleHeading = $this->call($module, 'getCreateNewTitle');
return is_null($moduleHeading) ? $pageHeading : $moduleHeading;
}
public function getUpdateContentTitle(ModuleModel $module, Content $content = null)
{
$pageHeading = trans('admin/contents.edit', ['name' => trans($module->name)]);
$moduleHeading = $this->call($module, 'getEditTitle', [$content]);
return is_null($moduleHeading) ? $pageHeading : $moduleHeading;
}
public function getOverviewTitle(ModuleModel $module)
{
$pageHeading = 'admin/contents.overview';
$moduleHeading = $this->call($module, 'getOverviewTitle');
return is_null($moduleHeading) ? $pageHeading : $moduleHeading;
}
public function all()
{
return ModuleModel::where('enabled', true)
->get();
}
public function getByHandler($handler)
{
return ModuleModel::where('handler', $handler)
->firstOrFail();
}
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);
}
return null;
}
public function callOnString($moduleHandler, $method, $parameters = [])
{
if (is_callable([$moduleHandler, $method])) {
return call_user_func_array([$moduleHandler, $method], $parameters);
}
return null;
}
}
-12
View File
@@ -1,12 +0,0 @@
<?php
namespace App\CMS\Repositories;
abstract class Repository
{
protected $model;
public function __call($method, $args)
{
return call_user_func_array([$this->model, $method], $args);
}
}
@@ -1,75 +0,0 @@
<?php
namespace App\Cms\Repositories\Templates;
use App\CMS\Contracts\Repositories\Template as ITemplate;
use App\CMS\Repositories\Repository;
use App\Models\Module;
use App\Models\Templates\Template as TemplateModel;
class Template extends Repository implements ITemplate
{
public function setModel(TemplateModel $model)
{
$this->model = $model;
}
/**
* Getter for absolute path to template
*
* @param null $mode
*
* @return string
*/
public function getPathToTemplate($mode = null)
{
$templateName = $this->model->template_name;
$path = $this->model->templatePath;
// delete namespace if given
if (strpos($this->model->template_name, '::')) {
list(, $templateName) = explode('::', $templateName);
}
// get template name, do not care about directories (they are already contained in path)
$parts = explode('.', $templateName);
$templateName = last($parts);
// just a shortcut for this unbelievable long constant name...
$_ = DIRECTORY_SEPARATOR;
// path parts
$absolutePath = base_path($path->path);
$templatePath = str_replace('.', $_, $templateName);
$file = $templatePath . ITemplate::TEMPLATE_SUFFIX;
// compose two versions of path - original and with "custom" directory
$original = $absolutePath . $_ . $file;
$edited = $absolutePath . $_ . ITemplate::EDITED_TEMPLATES_DIRECTORY . $_ . $file;
// decide which path will be returned
switch ($mode) {
case ITemplate::CUSTOM_EDIT_DIRECTORY:
return $edited;
break;
case ITemplate::ORIGINAL_DIRECTORY:
return $original;
break;
default:
if (file_exists($absolutePath . $_ . ITemplate::EDITED_TEMPLATES_DIRECTORY . $_ . $file)) {
return $edited;
}
return $original;
break;
}
}
public function getForModule(Module $module)
{
return TemplateModel::where('module_id', $module->id)
->select(['template_name', 'name', 'description'])
->get();
}
}
-52
View File
@@ -1,52 +0,0 @@
<?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));
}
}
@@ -1,55 +0,0 @@
<?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));
}
}
@@ -1,57 +0,0 @@
<?php
namespace App\CMS\Widgets\SocialButtons\Presenters;
use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetType;
use App\Models\Settings as SettingsModel;
use App\CMS\Contracts\Widgets\WidgetRenderer;
use App\CMS\Widgets\SocialButtons\Presenters\Route;
use Illuminate\Http\Request;
use Modules\Blog\Article\Entities\Article as ArticleModel;
use Modules\Blog\Article\Handlers\Article;
class SocialButtons implements WidgetRenderer
{
/**
* Method used for displaying widget.
*
* This method renders some HTML code for displaying.
*
* @param Widget $widget
*
* @return mixed
*/
public static function render(Widget $widget)
{
return view('visitor.widgets.shareButtons.all', compact('widget'));
}
/**
* Display form for creating new instance of widget
*
* @param WidgetType $type
*
* @return mixed
*/
public static function renderAddForm(WidgetType $type)
{
return view('admin.widgets.socialButtons.new', [
'type' => $type,
'widget' => new Widget(),
'settings' => new \stdClass()
]);
}
/**
* Display form for editing already existing widget
*
* @param Widget $widget
*
* @return mixed
*/
public static function renderEditForm(Widget $widget)
{
$settings = $widget->settings;
return view('admin.widgets.socialButtons.edit', ['widget' => $widget, 'settings' => $settings]);
}
}
@@ -1,55 +0,0 @@
<?php
namespace App\CMS\Widgets\SocialButtons;
use App\CMS\Contracts\Widgets\PublicWidget;
use App\CMS\Widgets\Exceptions\MissingParameterException;
use App\Http\Requests\Request;
use App\Models\Widgets\Widget;
class SocialButtons implements PublicWidget
{
/**
* Name getter
*
* @return string
*/
public static function getName()
{
return 'widgets/socialButtons.widgetName';
}
/**
* Getter for description
*
* @return string
*/
public static function getDescription()
{
return 'widgets/socialButtons.widgetDescription';
}
/**
* Getter for presenter/renderer of this widget
*
* @return WidgetRenderer
*/
public static function getPresenter()
{
return Presenters\SocialButtons::class;
}
/**
* @param Request $data
*
* @return array
* @throws MissingParameterException
*/
public static function save(Request $data)
{
//if (!isset($data->code) || empty($data->code)) {
// throw new MissingParameterException('code');
//}
return [];
}
}
+2
View File
@@ -32,6 +32,8 @@ class AddLanguage extends Command
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
+11 -17
View File
@@ -14,39 +14,33 @@ class ChangePassword extends Command
*
* @var string
*/
protected $signature = 'user:change-password {email}';
protected $signature = 'user:change-password {userID} {newPassword}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Change password for user with given e-mail';
protected $description = 'Change password for user with given ID';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$email = $this->argument('email');
$id = $this->argument('userID');
$newPassword = $this->argument('newPassword');
try {
$user = User::where(['email' => $email])
->first();
$user = User::findOrFail($id);
} catch (ModelNotFoundException $e) {
$this->error('Invalid user ' . $email . '.');
return;
$this->error('Invalid user ID ' . $id . '. Please see table `users` for correct IDs.');
exit(1);
}
do {
$password = $this->secret('Password');
$passwordAgain = $this->secret('Password again');
if ($password !== $passwordAgain) {
$this->error('Passwords does not match');
}
} while ($passwordAgain !== $password || strlen($password) === 0);
// set new password
$user->password = Hash::make($password);
$user->password = Hash::make($newPassword);
$user->save();
$this->info('Password successfully changed.');
+2 -7
View File
@@ -5,7 +5,6 @@ namespace App\Console\Commands;
use App\Models\Module;
use Illuminate\Console\Command;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
@@ -64,10 +63,6 @@ class InstallModule extends Command
// all mandatory fields are present, we can write it into database and create modules.json
$this->installModule($config);
// delete cache
Cache::forget('enabled-modules');
Cache::forget('module-handler-to-id-enumeration');
// inform user
$this->line('Module ' . $name . ' successfuly installed');
}
@@ -98,7 +93,7 @@ class InstallModule extends Command
}
// we cannot rely on config() helper, because this module does not have to be published
$config = include($path);
$config = @include($path);
return $config;
}
@@ -151,7 +146,7 @@ class InstallModule extends Command
throw new \Exception('Module ' . $config['name'] . ' already exists in database.');
}
if (is_null($module)) {
if (!$module) {
// insert module into database
$settings = [
'staticName' => $this->moduleName,
+11 -27
View File
@@ -2,10 +2,11 @@
namespace App\Console\Commands;
use App\CMS\Enumerations\UserRoles;
use App\Enumerations\UserRoles;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use Symfony\Component\Console\Exception\InvalidArgumentException;
class NewUser extends Command
{
@@ -14,7 +15,7 @@ class NewUser extends Command
*
* @var string
*/
protected $signature = 'user:new {email}';
protected $signature = 'user:new {email} {password} {role}';
/**
* The console command description.
*
@@ -24,37 +25,20 @@ class NewUser extends Command
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$email = $this->argument('email');
$password = $this->argument('password');
$role = $this->argument('role');
// check if username is really email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$this->error($email . ' is not a valid e-mail!');
return;
}
// ask for password
do {
$password = $this->secret('Password');
$passwordAgain = $this->secret('Password again');
if ($password !== $passwordAgain) {
$this->error('Passwords does not match');
}
} while ($passwordAgain !== $password || strlen($password) === 0);
// ask for role
// check if given role is valid
$roles = UserRoles::getSimple();
do {
$role = $this->ask('Role (default ' . User::ROLE_ADMIN . '): ', User::ROLE_ADMIN);
// check if given role is valid
if (!in_array($role, $roles)) {
$this->error('Invalid role specified. valid roles are: ' . implode(', ', $roles));
}
} while (!in_array($role, $roles));
if (!in_array($role, $roles)) {
throw new InvalidArgumentException('Invalid role specified. valid roles are: ' . implode(', ', $roles));
}
// create new user
$user = new User();
@@ -12,6 +12,7 @@ class PublishTemplateResources extends Command
* @var string
*/
protected $signature = 'template:publish';
/**
* The console command description.
*
@@ -26,7 +27,6 @@ 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]);
}
-4
View File
@@ -4,7 +4,6 @@ namespace App\Console\Commands;
use App\Models\Module;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SetTemplate extends Command
@@ -64,9 +63,6 @@ class SetTemplate extends Command
return;
}
// delete cached current template
Cache::forget('current-template');
// theme written
$this->line('Template successfully set up.');
-41
View File
@@ -1,41 +0,0 @@
<?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);
}
}
+1 -3
View File
@@ -3,7 +3,6 @@
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;
@@ -24,8 +23,7 @@ class Kernel extends ConsoleKernel
Commands\InitDatabaseSchema::class,
Commands\SetTemplate::class,
Commands\AddLanguage::class,
PublishTemplateResources::class,
TemplateInfo::class
PublishTemplateResources::class
];
/**
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace App\CustomFields;
class BaseField {
}
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace App\CustomFields;
class Date extends BaseField {
}
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace App\CustomFields;
class Number extends BaseField {
}
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace App\CustomFields;
class SelectboxList extends BaseField {
}
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace App\CustomFields;
class String extends BaseField {
}
@@ -1,5 +1,5 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\ActionLogType;
@@ -1,7 +1,7 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\ActionLog\ActionLogType;
use App\Models\ActionLogType;
class ActionLogTypesForLogger extends BaseEnumeration
{
@@ -1,7 +1,7 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\CMS\Exceptions\Enumerations\EnumerationExistsException;
use App\Enumerations\Exceptions\EnumerationExistsException;
abstract class BaseEnumeration
{
@@ -1,8 +1,7 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\CMS\Contracts\Repositories\Content;
use App\Models\Content;
class ContentStatuses extends BaseEnumeration
{
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace App\Enumerations;
use App\Models\CustomFieldResource;
class CustomFieldResources extends BaseEnumeration
{
public static $items = [];
public static function init()
{
// load items from database
$types = CustomFieldResource::all(['id', 'name']);
// push items into collection
foreach ($types as $type) {
self::push($type->id, $type->name);
}
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Enumerations;
use App\Models\CustomFieldType;
class CustomFieldTypes extends BaseEnumeration
{
public static $items = [];
public static function init()
{
// load items from database
$types = CustomFieldType::all(['id', 'name']);
// push items into collection
foreach ($types as $type) {
self::push($type->id, $type->name);
}
}
}
@@ -1,5 +1,5 @@
<?php
namespace App\CMS\Exceptions\Enumerations;
namespace App\Enumerations\Exceptions;
class EnumerationExistsException extends \Exception {
@@ -1,5 +1,5 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Module;
@@ -1,5 +1,5 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Module;
@@ -1,8 +1,7 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Module;
use Illuminate\Support\Facades\Cache;
class ModulesHandlerToId extends BaseEnumeration
{
@@ -13,9 +12,7 @@ class ModulesHandlerToId extends BaseEnumeration
*/
protected static function init()
{
$modules = Cache::rememberForever('module-handler-to-id-enumeration', function () {
return Module::all(['handler', 'id']);
});
$modules = Module::all(['handler', 'id']);
foreach ($modules as $module) {
self::push($module->handler, $module->id);
@@ -6,9 +6,9 @@
* Time: 10:33
*/
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Templates\TemplatePath;
use App\Models\TemplatePath;
class TemplatePaths extends BaseEnumeration
{
@@ -6,9 +6,9 @@
* Time: 10:33
*/
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Templates\TemplatePath;
use App\Models\TemplatePath;
class TemplatePathsHumanReadable extends BaseEnumeration
{
@@ -6,9 +6,9 @@
* Time: 10:33
*/
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Templates\TemplatePath;
use App\Models\TemplatePath;
class TemplatePathsHumanReadableRootOnly extends BaseEnumeration
{
@@ -6,9 +6,9 @@
* Time: 15:50
*/
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Templates\Template;
use App\Models\Template;
class Templates extends BaseEnumeration
{
@@ -1,5 +1,5 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\User;
@@ -6,7 +6,7 @@
* Time: 23:20
*/
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\User;
@@ -1,7 +1,7 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Widgets\WidgetType;
use App\Models\WidgetType;
class WidgetTypes extends BaseEnumeration
{
@@ -1,7 +1,7 @@
<?php
namespace App\CMS\Enumerations;
namespace App\Enumerations;
use App\Models\Widgets\WidgetType;
use App\Models\WidgetType;
class WidgetTypesWithHandlers extends BaseEnumeration
{
+2 -2
View File
@@ -2,8 +2,8 @@
namespace App\Events;
use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetArea;
use App\Models\Widget;
use App\Models\WidgetArea;
use Illuminate\Queue\SerializesModels;
class AssignWidget extends Event
+1 -1
View File
@@ -3,7 +3,7 @@
namespace App\Events;
use App\Events\Event;
use App\Models\Content\Content;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Events;
use App\Events\Event;
use App\Models\CustomField;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class CreateNewCustomField extends Event
{
use SerializesModels;
/**
* @var CustomField
*/
public $customField;
/**
* Create a new event instance.
*
* @param CustomField $customField
*/
public function __construct(CustomField $customField)
{
$this->customField = $customField;
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Widgets\Widget;
use App\Models\Widget;
use Illuminate\Queue\SerializesModels;
class CreateNewWidget extends Event
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Widgets\WidgetArea;
use App\Models\WidgetArea;
use Illuminate\Queue\SerializesModels;
class CreateNewWidgetArea extends Event
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Content\Content;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class DeleteContent extends Event
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Events;
use App\Events\Event;
use App\Models\CustomField;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class DeleteCustomField extends Event
{
use SerializesModels;
/**
* @var CustomField
*/
public $customField;
/**
* Create a new event instance.
*
* @param CustomField $customField
*/
public function __construct(CustomField $customField)
{
$this->customField = $customField;
}
}
+2 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Widgets\WidgetArea;
use App\Models\WidgetArea;
use Illuminate\Queue\SerializesModels;
class DeleteWidgetArea extends Event
@@ -20,6 +20,7 @@ class DeleteWidgetArea extends Event
*/
public function __construct(WidgetArea $widgetArea)
{
//
$this->widgetArea = $widgetArea;
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Content\Content;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class EditContent extends Event
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Events;
use App\Events\Event;
use App\Models\CustomField;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class EditCustomField extends Event
{
use SerializesModels;
/**
* @var CustomField
*/
public $customField;
/**
* Create a new event instance.
*
* @param CustomField $customField
*/
public function __construct(CustomField $customField)
{
$this->customField = $customField;
}
}
+1 -1
View File
@@ -3,7 +3,7 @@
namespace App\Events;
use App\Events\Event;
use App\Models\FileManager\File;
use App\Models\File;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Widgets\Widget;
use App\Models\Widget;
use Illuminate\Queue\SerializesModels;
class EditWidget extends Event
+3 -1
View File
@@ -2,8 +2,10 @@
namespace App\Events;
use App\Models\Widgets\WidgetArea;
use App\Events\Event;
use App\Models\WidgetArea;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class EditWidgetArea extends Event
{
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Content\Content;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class MakeDraftFromContent extends Event
+1 -1
View File
@@ -2,7 +2,7 @@
namespace App\Events;
use App\Models\Content\Content;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class PublishContent extends Event
+2 -2
View File
@@ -2,8 +2,8 @@
namespace App\Events;
use App\Models\Widgets\Widget;
use App\Models\Widgets\WidgetArea;
use App\Models\Widget;
use App\Models\WidgetArea;
use Illuminate\Queue\SerializesModels;
class RemoveWidgetFromArea extends Event
+1 -1
View File
@@ -3,7 +3,7 @@
namespace App\Events;
use App\Events\Event;
use App\Models\Content\Content;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
+2 -2
View File
@@ -12,11 +12,11 @@ class UploadFile extends Event
/**
* @var UploadedFile
*/
public $uploadedFile;
private $uploadedFile;
/**
* @var
*/
public $id;
private $id;
/**
* Create a new event instance.
+8 -16
View File
@@ -2,14 +2,13 @@
namespace App\Exceptions;
use App\CMS\Exceptions\Validation\ValidationFailedException;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
@@ -30,8 +29,7 @@ class Handler extends ExceptionHandler
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
*
* @param \Exception $e
* @return void
*/
public function report(Exception $e)
@@ -42,21 +40,15 @@ class Handler extends ExceptionHandler
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
*
* @return mixed
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof TokenMismatchException) {
if ($e instanceof TokenMismatchException){
//redirect to form an example of how I handle mine
return redirect($request->fullUrl())->with('error', trans('validation.csrf'));
} elseif ($e instanceof ValidationFailedException) {
return redirect()
->back()
->withInput()
->withErrors($e->getValidator());
}
return parent::render($request, $e);
@@ -1,9 +1,10 @@
<?php
namespace App\CMS\Handlers;
namespace App\Handlers;
use App\CMS\Contracts\Modules\BaseModuleHandler;
use App\CMS\Enumerations\TemplatePathsHumanReadableRootOnly;
use App\CMS\Enumerations\WidgetTypes;
use App\Enumerations\TemplatePathsHumanReadableRootOnly;
use App\Enumerations\WidgetTypes;
use App\Handlers\Contracts\AppHandler;
use App\Handlers\Contracts\BaseModuleHandler;
use App\Models\User;
abstract class BaseHandler implements BaseModuleHandler
@@ -34,6 +35,7 @@ abstract class BaseHandler implements BaseModuleHandler
* Submenus can be registered later
*/
$menu->dropdown(trans('admin/mainMenu.contentPages'), function ($sub) {
$sub->addDivider(9999);
$sub->route('content.overview', trans('admin/mainMenu.contentPageOverview'), [], 10000, ['icon' => 'fa fa-fw fa-list']);
}, 20, ['icon' => 'fa fa-fw fa-database']);
@@ -95,11 +97,22 @@ abstract class BaseHandler implements BaseModuleHandler
}, 60, ['icon' => 'fa fa-fw fa-file-code-o']);
}
// $menu->dropdown(trans('admin/mainMenu.customFields'), function ($sub) {
// $sub->route('customfields.new', trans('admin/mainMenu.customFieldsNew'), [], 10, ['icon' => 'fa fa-fw fa-code']);
// $sub->route('customfields.overview', trans('admin/mainMenu.customFieldsOverview'), [], 50, ['icon' => 'fa fa-fw fa-code-fork']);
// }, 30, ['icon' => 'fa fa-fw fa-code']);
$sub->route('log.overview', trans('admin/mainMenu.actionLog'), [], 70, ['icon' => 'fa fa-fw fa-history']);
$sub->route('settings.overview', trans('admin/mainMenu.settings'), [], 80, ['icon' => 'fa fa-fw fa-gear']);
}, 10000, ['icon' => 'fa fa-fw fa-gears']);
});
// order
// create menu with user profile
\Menu::create('profileMenu', function ($menu) {
$menu->route('users.detail', trans('admin/userManagement.profile'), [], 10, ['icon' => 'fa fa-fw fa-user icon']);

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