Merge branch 'dev' into dobrotyzpece.cz

This commit is contained in:
Michal Kváček
2016-10-09 23:18:11 +02:00
554 changed files with 91598 additions and 10368 deletions
+5 -6
View File
@@ -1,8 +1,8 @@
APP_ENV=testing APP_KEY=
APP_DEBUG=true APP_ENV=
APP_KEY=ZKZAzM23wQ6BPji6zffBjaTzZ3yW7zKQ APP_DEBUG=
DB_HOST=localhost DB_HOST=
DB_DATABASE= DB_DATABASE=
DB_USERNAME= DB_USERNAME=
DB_PASSWORD= DB_PASSWORD=
@@ -16,5 +16,4 @@ MAIL_PASSWORD=
SITE_URL=/ SITE_URL=/
UPLOAD_URL=/public/uploads UPLOAD_URL=/public/uploads
THUMBNAILS_URL=/uploads/thumbnails THUMBNAILS_URL=/uploads/thumbnails
THEME=
+3 -2
View File
@@ -1,8 +1,9 @@
# published files from modules # published files from modules
/resources/views/modules
/public/modules /public/modules
/resources/views/vendor
/public/assets /public/assets
/resources/views/modules
/resources/views/visitor
/resources/views/vendor
# directories with custom templates # directories with custom templates
**/views/**/custom/* **/views/**/custom/*
+6 -2
View File
@@ -40,8 +40,6 @@ class InstallModule extends Command
/** /**
* Execute the console command. * Execute the console command.
*
* @return mixed
*/ */
public function handle() public function handle()
{ {
@@ -56,6 +54,9 @@ class InstallModule extends Command
// get config // get config
$config = $this->loadConfig(); $config = $this->loadConfig();
if (empty($config))
return;
// check if it is valid // check if it is valid
$this->checkMandatoryFields($config); $this->checkMandatoryFields($config);
@@ -78,6 +79,9 @@ class InstallModule extends Command
$basePath = $this->modulesPath . DIRECTORY_SEPARATOR . $this->moduleName . DIRECTORY_SEPARATOR; $basePath = $this->modulesPath . DIRECTORY_SEPARATOR . $this->moduleName . DIRECTORY_SEPARATOR;
$path = $basePath . 'Config' . DIRECTORY_SEPARATOR . 'config.php'; $path = $basePath . 'Config' . DIRECTORY_SEPARATOR . 'config.php';
if (basename($basePath) == 'Database')
return [];
// check if module has Config/config.php file // check if module has Config/config.php file
if (!file_exists($path)) { if (!file_exists($path)) {
$path = $basePath . 'info.php'; $path = $basePath . 'info.php';
+73
View File
@@ -0,0 +1,73 @@
<?php
namespace App\Console\Commands;
use App\Models\Module;
use Illuminate\Console\Command;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SetTemplate extends Command
{
/**
* The name and signature of the console command.
* @var string
*/
protected $signature = 'template:set {template} {publish?}';
/**
* The console command description.
* @var string
*/
protected $description = 'Install template';
/**
* Execute the console command.
* @return mixed
*/
public function handle()
{
$template = $this->argument('template');
$publish = $this->argument('publish') !== 'no-publish';
$templatePath = app_path('../templates/' . $template);
if (!is_dir($templatePath) || !file_exists($templatePath . '/config.php')) {
throw new NotFoundHttpException('Invalid template ' . $template . '!');
}
// try to find currently installed template
$current = Module::where('is_template', true)
->first();
// install template
$config = @include $templatePath . '/config.php';
$config['staticName'] = $template;
if ($current) {
$info = json_decode($current->module_settings);
$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!');
if ($confirm) {
$this->line('Uninstalling ' . $current->name . '.');
$current->uninstall();
} else {
$this->line('Aborting installation.');
return;
}
}
try {
Module::install($config['name'], $config['alias'], $config['description'], $config['handler'], false, $config);
} catch (\Exception $e) {
$this->error('Cannot install template ' . $template . '. Message: ' . $e->getMessage());
return;
}
// theme written
$this->line('Template successfully set up.');
// run again artisan for publishing resources
// it cannot be done using $this->call, because we need to load different template into service providers
exec('php artisan vendor:publish');
}
}
-70
View File
@@ -1,70 +0,0 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class SetTheme extends Command
{
/**
* The name and signature of the console command.
* @var string
*/
protected $signature = 'theme:set {theme_name}';
/**
* The console command description.
* @var string
*/
protected $description = 'Set theme for visitor area';
/**
* Create a new command instance.
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
* @return mixed
*/
public function handle()
{
$theme = $this->argument('theme_name');
if (!is_dir(resource_path('views/visitor/' . $theme))) {
throw new NotFoundHttpException('Invalid theme ' . $theme . '!');
}
// load .env file
$envFile = base_path('.env');
$env = file_get_contents($envFile);
if (!Str::contains($env, 'THEME=')) {
$env = sprintf("%s\nTHEME=%s\n", $env, $theme);
} else {
$env = preg_replace('/THEME=(.*)/i', 'THEME=' . $theme, $env, -1, $cnt);
}
// try to write content
$bytesWritten = file_put_contents($envFile, $env);
// check if write was successfull
if (!$bytesWritten) {
throw new \Exception('Cannot write to ' . base_path('.env') . '. Add THEME=' . $theme . ' to your .env file manualy.');
}
// theme written
$this->line('Theme successfully setup.');
$this->line('');
$this->line(' ** PUBLISHING ASSETS AND VIEWS **');
// publish assets and views for module and theme
$this->call('vendor:publish', ['--tag' => ['public-assets'], '--force' => true]);
$this->call('vendor:publish', ['--tag' => ['module-views'], '--force' => true]);
$this->call('vendor:publish');
}
}
+22 -5
View File
@@ -29,15 +29,32 @@ class TranslateAll extends Command
/** /**
* Execute the console command. * Execute the console command.
* @return mixed
*/ */
public function handle() public function handle()
{ {
$this->call('translate:dir', ['dir' => 'resources/lang']); $this->call('translate:dir', ['dir' => 'resources/lang']);
$modules = File::directories('modules'); $this->crawlDirectory('modules');
foreach ($modules as $module) { $this->crawlDirectory('templates', ['templates/Base']);
$this->call('translate:dir', ['dir' => $module.'/Resources/lang']); $this->crawlDirectory('templates/Base');
}
/**
* Crawl directories and search for directories with translations
*
* @param $directory
* @param array $ignoredDirectories
*/
protected function crawlDirectory($directory, $ignoredDirectories = [])
{
$directories = File::directories($directory);
foreach ($directories as $dir) {
if (in_array($dir, $ignoredDirectories)) {
continue;
}
$this->call('translate:dir', ['dir' => $dir . '/Resources/lang']);
} }
} }
} }
@@ -6,7 +6,7 @@ use Illuminate\Console\Command;
use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\File;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class Translations extends Command class TranslateDirectory extends Command
{ {
/** /**
* The name and signature of the console command. * The name and signature of the console command.
@@ -25,7 +25,6 @@ class Translations extends Command
/** /**
* Execute the console command. * Execute the console command.
* @return mixed
*/ */
public function handle() public function handle()
{ {
@@ -33,11 +32,21 @@ class Translations extends Command
$defaultLocales = config('app.fallback_locale'); $defaultLocales = config('app.fallback_locale');
$currentLocales = config('app.locale'); $currentLocales = config('app.locale');
$defaultLocalesDir = $dir . '/' . $defaultLocales; $defaultLocalesDir = base_path($dir . '/' . $defaultLocales);
$currentLocalesDir = $dir . '/' . $currentLocales; $currentLocalesDir = base_path($dir . '/' . $currentLocales);
if (!is_dir($defaultLocalesDir)) { if (!is_dir($defaultLocalesDir)) {
// this is the place for checking for submodules // this is the place for checking for submodules
$modulePath = dirname(dirname($dir));
// does exist directory with translations?
if (is_dir(base_path($modulePath . '/Resources/lang')) || file_exists(base_path($modulePath.DIRECTORY_SEPARATOR.'info.php'))) {
$modules = File::directories($modulePath);
foreach ($modules as $module) {
$this->call('translate:dir', ['dir' => $module . '/Resources/lang']);
}
}
return; return;
} }
+2 -2
View File
@@ -18,10 +18,10 @@ class Kernel extends ConsoleKernel
Commands\ChangePassword::class, Commands\ChangePassword::class,
Commands\InstallModule::class, Commands\InstallModule::class,
Commands\InstallAllModules::class, Commands\InstallAllModules::class,
Commands\Translations::class, Commands\TranslateDirectory::class,
Commands\TranslateAll::class, Commands\TranslateAll::class,
Commands\InitDatabaseSchema::class, Commands\InitDatabaseSchema::class,
Commands\SetTheme::class, Commands\SetTemplate::class,
AddLanguage::class AddLanguage::class
]; ];
@@ -1,18 +0,0 @@
<?php
namespace App\Enumerations;
use App\Models\Content;
class ActiveContentStatuses extends BaseEnumeration
{
protected static function init()
{
foreach (ContentStatuses::getWithTranslations() as $key => $value) {
if ($key == Content::STATUS_DELETED) {
continue;
}
self::push($key, $value);
}
}
}
-1
View File
@@ -9,7 +9,6 @@ class ContentStatuses extends BaseEnumeration
{ {
$roles = [ $roles = [
Content::STATUS_DRAFT => 'admin/contents.status_' . Content::STATUS_DRAFT, Content::STATUS_DRAFT => 'admin/contents.status_' . Content::STATUS_DRAFT,
Content::STATUS_DELETED => 'admin/contents.status_' . Content::STATUS_DELETED,
Content::STATUS_PROTECTED => 'admin/contents.status_' . Content::STATUS_PROTECTED, Content::STATUS_PROTECTED => 'admin/contents.status_' . Content::STATUS_PROTECTED,
Content::STATUS_PUBLIC => 'admin/contents.status_' . Content::STATUS_PUBLIC Content::STATUS_PUBLIC => 'admin/contents.status_' . Content::STATUS_PUBLIC
]; ];
-1
View File
@@ -15,7 +15,6 @@ class UserStates extends BaseEnumeration
public static function init() public static function init()
{ {
$items = [ $items = [
User::STATE_DELETED => 'admin/userManagement.status_' . User::STATE_DELETED,
User::STATE_BLOCKED => 'admin/userManagement.status_' . User::STATE_BLOCKED, User::STATE_BLOCKED => 'admin/userManagement.status_' . User::STATE_BLOCKED,
User::STATE_ACTIVE => 'admin/userManagement.status_' . User::STATE_ACTIVE User::STATE_ACTIVE => 'admin/userManagement.status_' . User::STATE_ACTIVE
]; ];
+1 -3
View File
@@ -12,7 +12,6 @@ class DeleteContent extends Event
* @var Content * @var Content
*/ */
public $page; public $page;
public $revision;
/** /**
* Create a new event instance. * Create a new event instance.
@@ -20,9 +19,8 @@ class DeleteContent extends Event
* @param Content $page * @param Content $page
* @param $revision * @param $revision
*/ */
public function __construct(Content $page, $revision) public function __construct(Content $page)
{ {
$this->page = $page; $this->page = $page;
$this->revision = $revision;
} }
} }
+3 -4
View File
@@ -5,8 +5,6 @@ use App\Models\User;
interface BaseModuleHandler interface BaseModuleHandler
{ {
public static function getModuleId();
/** /**
* Register admin menu (or multiple ones) * Register admin menu (or multiple ones)
* *
@@ -18,9 +16,10 @@ interface BaseModuleHandler
public static function registerAdminMenu(User $user); public static function registerAdminMenu(User $user);
/** /**
* Install module * Install module.
* *
* @return mixed * This method is called after inserting info about module into database. It can be called only using Artisan in
* CLI.
*/ */
public static function install(); public static function install();
} }
+40
View File
@@ -0,0 +1,40 @@
<?php
namespace App\Handlers\Contracts;
use App\Models\Content;
/**
* Interface ContentTitles
*
* Classes which implement this interface get the ability to rewrite default text on edit/create/overview of content
* page.
*
* @package App\Handlers\Contracts
*/
interface ContentTitles
{
/**
* Get translated title for pages overview of given type.
*
* This value is used for rendering list of all content pages of given type in administration.
*
* @return string
*/
public static function getOverviewTitle();
/**
* Title displayed above for for creating new content page
*
* @return string
*/
public static function getCreateNewTitle();
/**
* Title for form displayed for editin content page
*
* @param Content $content
*
* @return mixed
*/
public static function getEditTitle(Content $content);
}
@@ -0,0 +1,64 @@
<?php
namespace App\Handlers\Contracts;
use App\Http\Requests\Request;
use App\Models\Content;
use App\Models\Module;
/**
* Interface TemplateHandler
*
* Inerface used for registering template into CMS core.
*
* @package App\Handlers\Contracts
*/
interface TemplateHandler extends BaseModuleHandler
{
/**
* Uninstall template
*
* Delete some items in database, delete files etc.
*
* @param Module $template
*/
public static function uninstall(Module $template);
/**
* Get list of registered templates and supported modules.
*
* Returned array is expected to be array of arrays with following items: module, namespace and templateName.
* Example:
* return [
* ['module' => 'Article', 'templateName' => 'article::template.name']
* ];
*
* When no "namespace" is specified, value strtolower(module) is used instaed.
*
* @return array
*/
public static function getPublicTemplatePaths();
/**
* Prepare Content object to be rendered using Blade template
*
* @param Content $content
*/
public static function beforeRender(Content & $content);
/**
* Modify input data into format which can be understood by edit template
*
* @param Content $content
*/
public static function beforePopulatingEditForm(Content & $content);
/**
* Slightly modify Content object before saving into database.
*
* This way we can do almost whatever we want - even in template
*
* @param Content $content
* @param Request $request
*/
public static function beforeSave(Content & $content, Request $request);
}
+14
View File
@@ -2,6 +2,7 @@
namespace App\Handlers; namespace App\Handlers;
use App\Handlers\Contracts\AppHandler; use App\Handlers\Contracts\AppHandler;
use App\Http\Controllers\Controller;
use App\Models\Content; use App\Models\Content;
/** /**
@@ -29,6 +30,19 @@ abstract class Handler extends BaseHandler implements AppHandler
return History::class; return History::class;
} }
/**
* Render given module into visitor area.
*
* @param Content $content DB model from table contents
* @param array $parameters parameters used for modifications/custom settings of given model
*
* @return mixed
*/
public function render(Content $content, $parameters)
{
return Controller::VisitorsView($content->template, ['page' => $content, 'extra' => $parameters]);
}
public static function getExtendedFormSections() public static function getExtendedFormSections()
{ {
return [ return [
@@ -28,6 +28,10 @@ class TemplateRegistrator
* @var int ID of module * @var int ID of module
*/ */
protected $moduleId; protected $moduleId;
/**
* @var array list of all registered template paths
*/
protected $paths = [];
/** /**
* Set base path * Set base path
@@ -64,7 +68,7 @@ class TemplateRegistrator
*/ */
public function setNamespace($namespace) public function setNamespace($namespace)
{ {
$this->namespace = $namespace . '::'; $this->namespace = $namespace;
} }
/** /**
@@ -80,24 +84,45 @@ class TemplateRegistrator
* Registers new template path. * Registers new template path.
* This method registeres given path itself with all subdirectories * This method registeres given path itself with all subdirectories
* *
* @param $baseDirectory
* @param string $path path relatively to root of the project * @param string $path path relatively to root of the project
* @param string $name human readable identification of given template path * @param string $name human readable identification of given template path
* *
* @throws \Exception * @throws \Exception
*/ */
public function register($path, $name) public function register($baseDirectory, $path, $name)
{ {
// check if base directory was set $this->paths[] = [
if (!$this->baseDirectory || !is_dir($this->baseDirectory)) { 'namespace' => $this->namespace,
throw new \Exception('Set $baseDirectory before registering template path.'); 'moduleId' => $this->moduleId,
'baseDirectory' => $baseDirectory,
'path' => $this->baseDirectory . DIRECTORY_SEPARATOR . $path,
'name' => $name
];
$this->unsetNamespace();
}
/**
* Save templates into database
*/
public function saveTemplates()
{
if (!is_array($this->paths) || empty($this->paths)) {
return;
} }
$this->registeredPath = $this->baseDirectory . DIRECTORY_SEPARATOR . $path; foreach ($this->paths as $path) {
if (!empty($path['namespace'])) {
$this->setNamespace($path['namespace'] . '::');
}
$this->setModuleId($path['moduleId']);
$this->setBaseDirectory($path['baseDirectory']);
// register path $this->registeredPath = $this->baseDirectory . DIRECTORY_SEPARATOR . $path['path'];
$this->registerPath($this->registeredPath, $name); // register path
$this->registerPath($this->registeredPath, $path['name']);
$this->unsetNamespace(); $this->unsetNamespace();
}
} }
/** /**
@@ -146,7 +171,7 @@ class TemplateRegistrator
Template::ASSETS_DIRECTORY, Template::ASSETS_DIRECTORY,
Template::MODULES_DIRECTORY Template::MODULES_DIRECTORY
]; ];
if (in_array($dirName, $ignoredDirectories)) { if (in_array($dirName, $ignoredDirectories)) {
return; return;
} }
@@ -187,7 +212,6 @@ class TemplateRegistrator
$registeredTemplates = Templates::getWithTranslations(); $registeredTemplates = Templates::getWithTranslations();
if (!in_array($templateName, $registeredTemplates)) { if (!in_array($templateName, $registeredTemplates)) {
$params = [ $params = [
'template_name' => $templateName, 'template_name' => $templateName,
'name' => $templateName, 'name' => $templateName,
@@ -197,8 +221,6 @@ class TemplateRegistrator
'editable' => 1 'editable' => 1
]; ];
echo 'ukladam do db '.$templateName."\n";
// save template into database // save template into database
$newTemplate = Template::create($params); $newTemplate = Template::create($params);
+37 -25
View File
@@ -3,44 +3,56 @@ namespace App\Handlers\Registrators;
use App\Enumerations\WidgetTypesWithHandlers; use App\Enumerations\WidgetTypesWithHandlers;
use App\Models\WidgetType; use App\Models\WidgetType;
use App\Widgets\Contracts\PublicWidget;
use Symfony\Component\Process\Exception\InvalidArgumentException;
class WidgetRegistrator class WidgetRegistrator
{ {
protected $widgets; protected $registeredWidgets = [];
function __construct()
{
$this->widgets = WidgetTypesWithHandlers::getSimple();
}
/** /**
* Method used for registering new widgets * Method used for registering new widgets
* *
* @param $classname * @param $classname
* @param null $templateId
* @param null $moduleId
*/ */
public function register($classname) public function register($classname, $templateId = null, $moduleId = null)
{ {
$class = new $classname; $this->registeredWidgets[] = [
if (!$class instanceof PublicWidget) { 'class' => $classname,
throw new InvalidArgumentException($class . ' must implement PublicWidget interface.'); 'templateId' => $templateId,
} 'moduleId' => $moduleId
];
}
// register widget as new widget type /**
if (!in_array($classname, $this->widgets)) { * Install all non-installed widgets
$widgetName = call_user_func($classname . '::getName'); */
$widgetDescription = call_user_func($classname . '::getDescription'); public function installWidgets()
{
$installed = WidgetTypesWithHandlers::getSimple();
foreach ($this->registeredWidgets as $registeredWidget) {
$classname = $registeredWidget['class'];
$templateId = $registeredWidget['templateId'];
$moduleId = $registeredWidget['moduleId'];
// create row in widget types // register widget as new widget type
WidgetType::create([ if (!in_array($classname, $installed)) {
'handler' => $classname, $widgetName = call_user_func($classname . '::getName');
'name' => $widgetName, $widgetDescription = call_user_func($classname . '::getDescription');
'description' => $widgetDescription
]);
// install widget (if neccessary) // create row in widget types
call_user_func($classname . '::install'); WidgetType::create([
'handler' => $classname,
'name' => $widgetName,
'module_id' => $moduleId,
'template_id' => $templateId,
'description' => $widgetDescription
]);
// install widget (if neccessary)
call_user_func($classname . '::install');
}
} }
} }
} }
+1
View File
@@ -27,6 +27,7 @@ class Files extends Search
$token = $this->tokenize($term); $token = $this->tokenize($term);
return File::where('original_filename', 'LIKE', $token) return File::where('original_filename', 'LIKE', $token)
->orWhere('name', 'LIKE', $token)
->orWhere('keywords', 'LIKE', $token) ->orWhere('keywords', 'LIKE', $token)
->orWhere('description', 'LIKE', $token) ->orWhere('description', 'LIKE', $token)
->orWhere('mime_type', 'LIKE', $token) ->orWhere('mime_type', 'LIKE', $token)
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace App\Helpers;
use App\Models\Module;
class CurrentTemplate
{
protected static $template;
protected static $initialized = false;
/**
* Getter for currently set template
*
* @return Module
*/
public static function get()
{
if (!self::$initialized) {
self::$template = Module::where('is_template', true)
->where('enabled', true)
->first();
if (self::$template) {
self::$template->module_settings = json_decode(self::$template->module_settings);
}
self::$initialized = true;
}
return self::$template;
}
/**
* Shortcut for getting template handler
*
* @return string
* @throws \ErrorException
*/
public static function handler()
{
$template = self::get();
if (!$template) {
throw new \ErrorException('No template selected, no handler available!');
}
return $template->handler;
}
/**
* Reset currently set template and load another one on next call of get() method.
*/
public static function reset()
{
self::$initialized = false;
}
}
+64
View File
@@ -0,0 +1,64 @@
<?php
namespace App\Helpers;
class Date
{
/**
* Print date in configured format
*
* @param $datestamp
* @param bool $withTime
*
* @return false|string
*/
public static function date($datestamp, $withTime = true)
{
$timestamp = strtotime($datestamp);
if ($timestamp <= 0) {
return '';
}
$format = $withTime ? config('app.datetime_format') : config('app.date_format');
return date($format, $timestamp);
}
public static function dateFormatted($format, $datestamp)
{
$timestamp = strtotime($datestamp);
if ($timestamp <= 0) {
return '';
}
return date($format, $timestamp);
}
public static function monthName($datestamp) {
$timestamp = strtotime($datestamp);
if ($timestamp <= 0) {
return '';
}
$months = [
trans('common.months.january'),
trans('common.months.february'),
trans('common.months.march'),
trans('common.months.april'),
trans('common.months.may'),
trans('common.months.june'),
trans('common.months.july'),
trans('common.months.august'),
trans('common.months.semptember'),
trans('common.months.october'),
trans('common.months.november'),
trans('common.months.december'),
];
$monthNumber = date('n', $timestamp);
return $months[$monthNumber - 1];
}
}
+22 -29
View File
@@ -17,34 +17,42 @@ class FileManager
switch ($type) { switch ($type) {
case 'image': case 'image':
// try to check if file have thumbnail $url = Template::thumbnail($file->filename);
if (file_exists(config('app.thumbnail_url') . '/' . $file->filename)) {
$url = config('app.thumbnail_url') . '/' . $file->filename;
} else {
$url = config('app.upload_url') . '/' . $file->filename;
}
return '<img src="' . $url . '" alt="' . $file->description . '" />'; return '<img src="' . $url . '" alt="' . $file->description . '" />';
break; break;
case 'text': case 'text':
return '<i class="fa fa-2x fa-file-text-o"></i>'; return self::getIcon($file, 'fa-file-text-o');
break; break;
case 'application': case 'application':
switch ($subtype) { switch ($subtype) {
case 'pdf': case 'pdf':
return '<i class="fa fa-2x fa-file-pdf-o"></i>'; return self::getIcon($file, 'fa-file-pdf-o');
break; break;
default: default:
return '<i class="fa fa-2x fa-newspaper-o"></i>'; return self::getIcon($file, 'fa-newspaper-o');
break; break;
} }
break; break;
default: default:
return '<i class="fa fa-2x fa-question"></i>'; return self::getIcon($file, 'fa-question');
break; break;
} }
} }
/**
* Shortcut for displaying icons
*
* @param $file
* @param $icon
*
* @return string
*/
protected static function getIcon($file, $icon)
{
return '<p><i class="fa fa-2x ' . $icon . '"></i><br /><span>' . e(str_limit($file->original_filename, 15)) . '</span></p>';
}
/** /**
* *
* *
@@ -83,7 +91,6 @@ class FileManager
return '<img src="' . $url . '" alt="' . $file->description . '" />'; return '<img src="' . $url . '" alt="' . $file->description . '" />';
break; break;
case 'text': case 'text':
$string = '<pre><code>'; $string = '<pre><code>';
$string .= htmlspecialchars(file_get_contents($path)); $string .= htmlspecialchars(file_get_contents($path));
$string .= '</pre></code>'; $string .= '</pre></code>';
@@ -91,15 +98,8 @@ class FileManager
return $string; return $string;
break; break;
case 'application': case 'application':
switch ($subtype) { return '<iframe src = "'.asset('resources/assets/admin/js/viewerJs/').'/#'.Template::upload($file->filename).'" style="width: 100%; height: 50em" allowfullscreen webkitallowfullscreen></iframe>';
case 'pdf': break;
return '<i class="fa fa-file-pdf-o"></i>';
break;
default:
return '<i class="fa fa-newspaper-o"></i>';
break;
}
break;
default: default:
return self::getPreview($file); return self::getPreview($file);
break; break;
@@ -119,19 +119,12 @@ class FileManager
switch ($type) { switch ($type) {
case 'text': case 'text':
return [trans('admin/fileManager.encoding') => mb_detect_encoding(file_get_contents($path))];
return [
trans('admin/fileManager.encoding') => mb_detect_encoding(file_get_contents($path))
];
break; break;
case 'image': case 'image':
list ($width, $height) = getimagesize($path); list ($width, $height) = getimagesize($path);
return [trans('admin/fileManager.resolution') => $height . ' x ' . $width,];
return [
trans('admin/fileManager.resolution') => $height . ' x ' . $width,
];
break; break;
} }
+1 -1
View File
@@ -5,6 +5,6 @@ class Gravatar
{ {
public static function img($email, $size = 50) public static function img($email, $size = 50)
{ {
return "http://www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?s=" . $size; return "//www.gravatar.com/avatar/" . md5(strtolower(trim($email))) . "?s=" . $size;
} }
} }
+43
View File
@@ -0,0 +1,43 @@
<?php
namespace App\Helpers;
use App\Handlers\Contracts\AppHandler;
use App\Models\Content;
use Webwizo\Shortcodes\Facades\Shortcode;
/**
* Class PageRenderer
*
* Simple class for rendering page for visitor
*
* @package App\Helpers
*/
class PageRenderer
{
/**
* Render page
*
* @param Content $page
*
* @return mixed
*/
public static function render(Content $page)
{
// decode module settings
$page->module_settings = json_decode($page->module_settings);
// do something template-specific
$parameters = call_user_func_array([CurrentTemplate::handler(), 'beforeRender'], [&$page]);
/**
* @var $handler AppHandler
*/
// get handler
$handler = new $page->module_handler;
$page->content = Shortcode::compile($page->content);
// render page
return $handler->render($page, $parameters);
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace App\Helpers;
use App\Models\Settings as SettingsModel;
/**
* Class Settings
*
* Helper class for easier obtaining system settings
*
* @package App\Helpers
*/
class Settings
{
/**
* @var array List of all used settings
*/
protected static $settings;
/**
* @var bool Are data already initialized?
*/
protected static $initialized = false;
/**
* Getter for settings determined with key.
*
* @param string $key settings key
* @param string|null $default default value, which will be returned when given key does not exist
*
* @param null $exists
*
* @return null|string
*/
public static function get($key, $default = null, & $exists = null)
{
self::init();
if (isset(self::$settings->$key)) {
$exists = true;
self::$initialized = true;
return self::$settings->$key;
}
$exists = false;
return $default;
}
/**
* Shortcut for obtaining settings saved as JSON
*
* @param $key
*
* @return mixed
*/
public static function getJson($key)
{
return json_decode(self::get($key, '{}'));
}
/**
* Get all settings
*
* @return array
*/
public static function all()
{
self::init();
return self::$settings;
}
/**
* Initialize settings array
*/
private static function init()
{
if (!self::$initialized) {
$model = new SettingsModel();
self::$settings = $model->getAll();
}
}
}
+34 -5
View File
@@ -13,7 +13,7 @@ class Template
* *
* @return null|string * @return null|string
*/ */
public static function name($template) public static function name($template, $throwExceptions = true)
{ {
$namespace = null; $namespace = null;
if (strpos($template, '::')) { if (strpos($template, '::')) {
@@ -21,10 +21,8 @@ class Template
$namespace .= '::'; $namespace .= '::';
} }
$theme = config('app.theme');
// list of prefixes // list of prefixes
$prefixes = [$theme . '.custom.', $theme . '.', '']; $prefixes = ['custom.', ''];
$view = null; $view = null;
foreach ($prefixes as $prefix) { foreach ($prefixes as $prefix) {
@@ -35,7 +33,11 @@ class Template
} }
if (is_null($view)) { if (is_null($view)) {
throw new InvalidArgumentException('Cannot find template for ' . $namespace . $template); if ($throwExceptions) {
throw new InvalidArgumentException('Cannot find template for ' . $namespace . $template);
} else {
return false;
}
} }
return $view; return $view;
@@ -59,6 +61,25 @@ class Template
return config('app.upload_url') . '/' . $filename; return config('app.upload_url') . '/' . $filename;
} }
public static function thumbnail($filename)
{
// try to check if file have thumbnail
if (file_exists(config('app.thumbnail_path') . '/' . $filename)) {
$url = config('app.thumbnail_url') . '/' . $filename;
} else {
$url = self::upload($filename);
}
return $url;
}
/**
* Get path to given asset
*
* @param $path
*
* @return string
*/
public static function asset($path) public static function asset($path)
{ {
if (env('APP_DEBUG')) { if (env('APP_DEBUG')) {
@@ -75,6 +96,14 @@ class Template
return config('app.url') . '/assets/' . config('app.theme') . '/' . $path; return config('app.url') . '/assets/' . config('app.theme') . '/' . $path;
} }
/**
* Print date in configured format
*
* @param $datestamp
* @param bool $withTime
*
* @return false|string
*/
public static function date($datestamp, $withTime = true) public static function date($datestamp, $withTime = true)
{ {
$timestamp = strtotime($datestamp); $timestamp = strtotime($datestamp);
+16
View File
@@ -11,4 +11,20 @@
function e($value) function e($value)
{ {
return htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); return htmlspecialchars($value, ENT_QUOTES, 'UTF-8');
}
/**
* Shortcut for \App\Helpers\Settings::get()
*
* @param $key
* @param null $default
*
* @return null|string
*/
function setting($key, $default = null) {
return \App\Helpers\Settings::get($key, $default);
}
function asset_path($path) {
return env('SITE_URL').'/assets/'.$path;
} }
@@ -0,0 +1,51 @@
<?php
namespace App\Http\Controllers\Admin\ActionLog;
use App\Http\Controllers\Admin\Controller;
use App\Models\ActionLog;
use App\Models\User;
use Illuminate\Support\Facades\Input;
class Overview extends Controller
{
/**
* @var ActionLog
*/
private $log;
/**
* ActionLog constructor.
*
* @param ActionLog $log
*/
public function __construct(ActionLog $log)
{
parent::__construct();
$this->log = $log;
}
/**
* Get overview of logged actions
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function getOverview()
{
$user = null;
$userId = Input::get('userId');
$actions = $this->log->getLogActionsQuery(true);
if ($userId) {
$user = User::findOrFail($userId);
$actions->where('users.id', $userId);
}
$actions = $actions->paginate(25);
$this->log->translateLogMessages($actions);
return view('admin.actionLog.overview', ['actions' => $actions, 'user' => $user]);
}
}
@@ -1,35 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use App\Models\ActionLog;
class ActionLogOverview extends Controller
{
/**
* @var ActionLog
*/
private $log;
/**
* ActionLog constructor.
*
* @param ActionLog $log
*/
public function __construct(ActionLog $log)
{
$this->log = $log;
}
public function getOverview()
{
$actions = $this->log->getLogActionsQuery(true)
->paginate(25);
$this->log->translateLogMessages($actions);
return view('admin.actionLog.overview', ['actions' => $actions]);
}
}
@@ -1,7 +1,8 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Contents;
use App\Enumerations\ContentStatuses; use App\Enumerations\ContentStatuses;
use App\Http\Controllers\Admin\Controller;
use App\Models\Content; use App\Models\Content;
use App\Models\Module; use App\Models\Module;
use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Input;
@@ -32,11 +33,16 @@ class ContentOverview extends Controller
{ {
$moduleFilterHandler = false; $moduleFilterHandler = false;
$perPage = Input::get('perPage') ? Input::get('perPage') : 20; $perPage = Input::get('perPage') ? Input::get('perPage') : 20;
$pageHeading = 'admin/contents.overview';
// does user want to filter results using module? // does user want to filter results using module?
if (is_numeric($moduleId)) { if (is_numeric($moduleId)) {
$module = Module::findOrFail($moduleId); $module = Module::findOrFail($moduleId);
$moduleFilterHandler = $module->handler; $moduleFilterHandler = $module->handler;
if (is_callable([$module->handler, 'getOverviewTitle'])) {
$pageHeading = call_user_func([$module->handler, 'getOverviewTitle']);
}
} }
// get pages for overview // get pages for overview
@@ -47,10 +53,11 @@ class ContentOverview extends Controller
$homepage = $this->content->getHomepage(); $homepage = $this->content->getHomepage();
return view('admin.content.overview', [ return view('admin.content.overview', [
'pages' => $pages, 'pages' => $pages,
'homepage' => $homepage, 'homepage' => $homepage,
'statuses' => ContentStatuses::getWithTranslations(), 'pageHeading' => $pageHeading,
'module' => isset($module) ? $module : null 'statuses' => ContentStatuses::getWithTranslations(),
'module' => isset($module) ? $module : null
]); ]);
} }
} }
@@ -1,8 +1,10 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Contents;
use App\Enumerations\ActiveContentStatuses; use App\Enumerations\ContentStatuses;
use App\Events\CreateNewContent as CreateNewContentEvent; use App\Events\CreateNewContent as CreateNewContentEvent;
use App\Helpers\CurrentTemplate;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\CreateNewContentRequest; use App\Http\Requests\CreateNewContentRequest;
use App\Models\Content; use App\Models\Content;
use App\Models\File; use App\Models\File;
@@ -14,6 +16,14 @@ use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Modules\Categories\Entities\Category; use Modules\Categories\Entities\Category;
use Pingpong\Modules\Facades\Module as ModuleInstance; use Pingpong\Modules\Facades\Module as ModuleInstance;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class CreateNewContent
*
* Controller for creating new content page.
*
* @package App\Http\Controllers\Admin\Contents
*/
class CreateNewContent extends Controller class CreateNewContent extends Controller
{ {
/** /**
@@ -25,6 +35,14 @@ class CreateNewContent extends Controller
*/ */
private $content; private $content;
/**
* CreateNewContent constructor.
*
* Sets File and Content models into class variables
*
* @param File $file
* @param Content $content
*/
public function __construct(File $file, Content $content) public function __construct(File $file, Content $content)
{ {
parent::__construct(); parent::__construct();
@@ -42,16 +60,23 @@ class CreateNewContent extends Controller
public function getNew($moduleId) public function getNew($moduleId)
{ {
$module = Module::findOrFail($moduleId); $module = Module::findOrFail($moduleId);
$statuses = ActiveContentStatuses::getWithTranslations(); $statuses = ContentStatuses::getWithTranslations();
// set default page title
$pageHeading = trans('admin/contents.new', ['name' => trans($module->name)]);
if (is_callable([$module->handler, 'getCreateNewTitle'])) {
$pageHeading = call_user_func([$module->handler, 'getCreateNewTitle']);
}
// get list of usable templates
$templates = Template::where('module_id', $moduleId) $templates = Template::where('module_id', $moduleId)
->select(['template_name', 'name', 'description']) ->select(['template_name', 'name', 'description'])
->get(); ->get();
$categoryModule = ModuleInstance::get('categories');
// add categories, if supported // add categories, if supported
$categoryModule = ModuleInstance::get('categories');
$categories = []; $categories = [];
if ($module->support_categories && $categoryModule->enabled()) { if ($module->support_categories && !is_null($categoryModule) && $categoryModule->enabled()) {
$categories = Category::where('module_id', $moduleId) $categories = Category::where('module_id', $moduleId)
->get(); ->get();
} }
@@ -61,6 +86,7 @@ class CreateNewContent extends Controller
// render view // render view
return view('admin.content.new', [ return view('admin.content.new', [
'pageHeading' => $pageHeading,
'contentStatuses' => $statuses, 'contentStatuses' => $statuses,
'templates' => $templates, 'templates' => $templates,
'moduleId' => $moduleId, 'moduleId' => $moduleId,
@@ -86,7 +112,6 @@ class CreateNewContent extends Controller
*/ */
public function postNew(CreateNewContentRequest $request, $moduleId) public function postNew(CreateNewContentRequest $request, $moduleId)
{ {
$page = new Content();
try { try {
$module = Module::findOrFail($moduleId); $module = Module::findOrFail($moduleId);
} catch (NotFoundHttpException $e) { } catch (NotFoundHttpException $e) {
@@ -96,6 +121,10 @@ class CreateNewContent extends Controller
->with('error', trans('admin/contents.invalidModule')); ->with('error', trans('admin/contents.invalidModule'));
} }
// create new page
$page = new Content();
$page->template = $request->template;
// setup basic info // setup basic info
$page->user_id = \Auth::user()->id; $page->user_id = \Auth::user()->id;
$page->language = LaravelLocalization::getCurrentLocale(); $page->language = LaravelLocalization::getCurrentLocale();
@@ -107,20 +136,26 @@ class CreateNewContent extends Controller
$page->meta_description = $request->metaDescription; $page->meta_description = $request->metaDescription;
$page->content = $request->pageContent; $page->content = $request->pageContent;
$page->status = $request->status; $page->status = $request->status;
$page->template = $request->template;
$page->module_handler = $module->handler; $page->module_handler = $module->handler;
$page->category_id = (int)$request->category > 0 ? $request->category : null; $page->category_id = (int)$request->category > 0 ? $request->category : null;
// is any parent page specified?
if ($request->parentPage) { if ($request->parentPage) {
$page->parent_id = $request->parentPage; $page->parent_id = $request->parentPage;
} }
// upload file - if provided // upload file - if provided
$page->uploadTitlePhoto($request); $file = $page->uploadTitlePhoto($request);
$page->title_photo = $file ? $file['filename'] : null;
// save module-specific stuff // save module-specific stuff
call_user_func_array([$module->handler, 'createNew'], [&$page, $request]); call_user_func_array([$module->handler, 'createNew'], [&$page, $request]);
// let template to modify request and content page
call_user_func_array([CurrentTemplate::handler(), 'beforeSave'], [&$page, $request]);
// save content of page before (possible) uploading related files
$page->save(); $page->save();
// upload files assigned to content page // upload files assigned to content page
@@ -1,14 +1,15 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Contents;
use App\Enumerations\ContentStatuses; use App\Enumerations\ContentStatuses;
use App\Enumerations\ModulesHandlerToId;
use App\Events\AttemptToEditInvalidContent; use App\Events\AttemptToEditInvalidContent;
use App\Events\DeleteContent; use App\Events\DeleteContent;
use App\Events\EditContent as EditContentEvent; use App\Events\EditContent as EditContentEvent;
use App\Events\MakeDraftFromContent; use App\Events\MakeDraftFromContent;
use App\Events\PublishContent; use App\Events\PublishContent;
use App\Events\SetHomepage; use App\Events\SetHomepage;
use App\Helpers\CurrentTemplate;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\EditContentRequest; use App\Http\Requests\EditContentRequest;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Models\Content; use App\Models\Content;
@@ -34,6 +35,14 @@ class EditContent extends Controller
*/ */
private $file; private $file;
/**
* EditContent constructor.
*
* Load ContentHistory and File into this controller
*
* @param ContentHistory $history
* @param File $file
*/
public function __construct(ContentHistory $history, File $file) public function __construct(ContentHistory $history, File $file)
{ {
$this->history = $history; $this->history = $history;
@@ -56,27 +65,38 @@ class EditContent extends Controller
$page = Content::findOrFail($id); $page = Content::findOrFail($id);
$page->module_settings = json_decode($page->module_settings); $page->module_settings = json_decode($page->module_settings);
$allModules = ModulesHandlerToId::getWithTranslations(); // get module ID
$moduleId = $allModules[$page->module_handler]; $module = Module::where('handler', $page->module_handler)
$module = Module::findOrFail($moduleId); ->firstOrFail();
$templates = Template::where('module_id', $moduleId) $pageHeading = trans('admin/contents.edit', ['name' => e($page->title)]);
if (is_callable([$module->handler, 'getCreateNewTitle'])) {
$pageHeading = call_user_func([$module->handler, 'getEditTitle'], $page);
}
// get all Blade templates for rendering page
$templates = Template::where('module_id', $module->id)
->select(['template_name', 'name', 'description']) ->select(['template_name', 'name', 'description'])
->get(); ->get();
// get module for Categories - PingPong module
$categoryModule = ModuleInstance::get('categories'); $categoryModule = ModuleInstance::get('categories');
// add categories, if supported // add categories, if supported
$categories = []; $categories = [];
if ($module->support_categories && $categoryModule->enabled()) { if ($module->support_categories && !is_null($categoryModule) && $categoryModule->enabled()) {
$categories = Category::where('module_id', $moduleId) $categories = Category::where('module_id', $module->id)
->get(); ->get();
} }
// modify data for edit form according to installed template
call_user_func_array([CurrentTemplate::handler(), 'beforePopulatingEditForm'], [&$page]);
$history = $this->history->getStructuredHistoryOf($page); $history = $this->history->getStructuredHistoryOf($page);
// render view // render view
return view('admin.content.edit', [ return view('admin.content.edit', [
'pageHeading' => $pageHeading,
'contentStatuses' => $statuses, 'contentStatuses' => $statuses,
'page' => $page, 'page' => $page,
'module' => $module, 'module' => $module,
@@ -118,12 +138,20 @@ class EditContent extends Controller
->with('error', trans('admin/contents.invalidPage')); ->with('error', trans('admin/contents.invalidPage'));
} }
// upload file - if provided
$file = $page->uploadTitlePhoto($request);
// let template to modify request and content page
call_user_func_array([CurrentTemplate::handler(), 'beforeSave'], [&$page, $request]);
$request->url = Str::slug($request->url); $request->url = Str::slug($request->url);
$request->parentPage = $request->parentPage ? $request->parentPage : null; $request->parentPage = $request->parentPage ? $request->parentPage : null;
$request->titlePhotoFilename = $page->title_photo;
// upload file - if provided if (!$file) {
$page->uploadTitlePhoto($request); $request->titlePhotoFilename = empty($request->existingTitlePhoto) ? null : $request->existingTitlePhoto;
} else {
$request->titlePhotoFilename = $file['filename'];
}
// array of fields in database and fields from request // array of fields in database and fields from request
$fields = [ $fields = [
@@ -142,7 +170,8 @@ class EditContent extends Controller
]; ];
// save new values with history // save new values with history
$data = self::getFields($request, $fields); $data = self::getFields($request, array_values($fields));
list($revision, $changedColumns) = $page->updateWithHistory($fields, $data); list($revision, $changedColumns) = $page->updateWithHistory($fields, $data);
$changedColumns += call_user_func_array([$page->module_handler, 'edit'], [&$page, $request, $revision]); $changedColumns += call_user_func_array([$page->module_handler, 'edit'], [&$page, $request, $revision]);
@@ -160,7 +189,7 @@ class EditContent extends Controller
// something was changed, inform user // something was changed, inform user
return redirect() return redirect()
->route('content.edit', ['id' => $page->id]) ->route('content.overview')
->with('success', trans('admin/contents.successfullyEdited')); ->with('success', trans('admin/contents.successfullyEdited'));
} }
@@ -178,7 +207,6 @@ class EditContent extends Controller
{ {
// get possible statuses // get possible statuses
$statuses = ContentStatuses::getWithTranslations(); $statuses = ContentStatuses::getWithTranslations();
unset($statuses[Content::STATUS_DELETED]);
// check if given status is valid // check if given status is valid
if (!isset($statuses[$status])) { if (!isset($statuses[$status])) {
@@ -241,23 +269,17 @@ class EditContent extends Controller
// change url to something unique // change url to something unique
$oldURL = $page->url; $oldURL = $page->url;
$page->url = uniqid($page->url . '_deleted'); $page->url .= uniqid('deleted_');
$page->save(); $page->save();
list ($revision, $changedColumns) = $page->updateWithHistory(['status' => 'status'], ['status' => Content::STATUS_DELETED]); // delete page
$page->delete();
// let module to delete some extra content created during page's life // let module to delete some extra content created during page's life
call_user_func([$page->module_handler, 'delete'], $page); call_user_func([$page->module_handler, 'delete'], $page);
// was something changed?
if ($changedColumns == 0) {
return redirect()
->route('content.edit', ['id' => $page->id])
->with('error', trans('admin/contents.nothingToEdit'));
}
// trigger delete event // trigger delete event
Event::fire(new DeleteContent($page, $revision)); Event::fire(new DeleteContent($page));
// redirect back to overview with info for user // redirect back to overview with info for user
return redirect() return redirect()
@@ -286,7 +308,7 @@ class EditContent extends Controller
} catch (NotFoundHttpException $e) { } catch (NotFoundHttpException $e) {
// page not found // page not found
return redirect() return redirect()
->route('content.overview') ->back()
->with('error', trans('admin/contents.invalidPage')); ->with('error', trans('admin/contents.invalidPage'));
} }
@@ -301,7 +323,7 @@ class EditContent extends Controller
// was something changed? // was something changed?
if ($changedColumns == 0) { if ($changedColumns == 0) {
return redirect() return redirect()
->route('content.overview') ->back()
->with('error', trans('admin/contents.nothingToEdit')); ->with('error', trans('admin/contents.nothingToEdit'));
} }
@@ -310,7 +332,7 @@ class EditContent extends Controller
// redirect back to overview with info for user // redirect back to overview with info for user
return redirect() return redirect()
->route('content.overview') ->back()
->with('success', trans('admin/contents.homepageSetup', [ ->with('success', trans('admin/contents.homepageSetup', [
'name' => $page->title, 'name' => $page->title,
'url' => $page->url 'url' => $page->url
@@ -1,6 +1,7 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Contents;
use App\Http\Controllers\Admin\Controller;
use App\Models\Content; use App\Models\Content;
use App\Models\ContentHistory; use App\Models\ContentHistory;
@@ -1,10 +1,11 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\CustomFields;
use App\Enumerations\CustomFieldResources; use App\Enumerations\CustomFieldResources;
use App\Enumerations\CustomFieldTypes; use App\Enumerations\CustomFieldTypes;
use App\Events\CreateNewCustomField as CreateNewCustomFieldEvent; use App\Events\CreateNewCustomField as CreateNewCustomFieldEvent;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\NewCustomFieldRequest; use App\Http\Requests\NewCustomFieldRequest;
use App\Models\CustomField; use App\Models\CustomField;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
@@ -1,11 +1,10 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\CustomFields;
use App\Enumerations\CustomFieldResources; use App\Enumerations\CustomFieldResources;
use App\Enumerations\CustomFieldTypes; use App\Enumerations\CustomFieldTypes;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Models\CustomField; use App\Models\CustomField;
class CustomFieldsOverview extends Controller class CustomFieldsOverview extends Controller
@@ -1,13 +1,12 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\CustomFields;
use App\Enumerations\CustomFieldResources; use App\Enumerations\CustomFieldResources;
use App\Enumerations\CustomFieldTypes; use App\Enumerations\CustomFieldTypes;
use App\Events\DeleteCustomField; use App\Events\DeleteCustomField;
use App\Events\EditCustomField as EditCustomFieldEvent; use App\Events\EditCustomField as EditCustomFieldEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Http\Requests\EditCustomFieldRequest; use App\Http\Requests\EditCustomFieldRequest;
use App\Models\CustomField; use App\Models\CustomField;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
-17
View File
@@ -1,17 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Requests;
use Illuminate\Support\Facades\Session;
class Dashboard extends Controller
{
public function getIndex(Request $request) {
return redirect()->route('content.overview');
// return view('admin.dashboard');
}
}
@@ -0,0 +1,14 @@
<?php
namespace App\Http\Controllers\Admin\Dashboard;
use App\Http\Controllers\Admin\Controller;
use Illuminate\Http\Request;
class Dashboard extends Controller
{
public function getIndex(Request $request)
{
return redirect()->route('content.overview');
}
}
@@ -1,8 +1,8 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\FileManager;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Models\Directory; use App\Models\Directory;
@@ -30,8 +30,8 @@ class CreateNewDirectory extends Controller
} else { } else {
return redirect() return redirect()
->route('upload.overview', ['id' => $request->parentDirectory]) ->route('upload.overview', ['id' => $request->parentDirectory])
->with('error', trans('admin/fileManager.subdirectoryExists')) ->withInput()
->withInput(); ->with('error', trans('admin/fileManager.subdirectoryExists'));
} }
} }
@@ -1,8 +1,8 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\FileManager;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Models\Directory; use App\Models\Directory;
@@ -12,7 +12,7 @@ class EditDirectory extends Controller
* @param Requests\EditDirectoryRequest $request * @param Requests\EditDirectoryRequest $request
* @param $directoryId * @param $directoryId
* *
* @return $this|\Illuminate\Http\JsonResponse * @return $this|\Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/ */
public function postEdit(Requests\EditDirectoryRequest $request, $directoryId) public function postEdit(Requests\EditDirectoryRequest $request, $directoryId)
{ {
@@ -34,8 +34,8 @@ class EditDirectory extends Controller
} else { } else {
return redirect() return redirect()
->route('upload.overview', ['id' => $directoryId]) ->route('upload.overview', ['id' => $directoryId])
->with('error', trans('admin/fileManager.subdirectoryExists')) ->withInput()
->withInput(); ->with('error', trans('admin/fileManager.subdirectoryExists'));
} }
} }
@@ -1,10 +1,10 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\FileManager;
use App\Events\EditFile; use App\Events\EditFile;
use App\Helpers\FileManager; use App\Helpers\FileManager;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\EditUploadedFileRequest; use App\Http\Requests\EditUploadedFileRequest;
use App\Models\File; use App\Models\File;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
@@ -1,8 +1,9 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\FileManager;
use App\Models\File; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use App\Models\File;
use Symfony\Component\HttpFoundation\File\Exception\FileException; use Symfony\Component\HttpFoundation\File\Exception\FileException;
class UploadFile extends Controller class UploadFile extends Controller
@@ -18,11 +19,12 @@ class UploadFile extends Controller
$this->file = $file; $this->file = $file;
} }
/** /**
* Uploads any file * Uploads any file
* *
* @return \Illuminate\Http\RedirectResponse * @param Request $request
*
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/ */
public function postFile(Request $request) public function postFile(Request $request)
{ {
@@ -38,12 +40,6 @@ class UploadFile extends Controller
$uploadedFiles[] = $uploadedFile; $uploadedFiles[] = $uploadedFile;
} }
// we do not want to redirect
if ($request->ajax()) {
return $this->jsonResponse($uploadedFiles);
}
// upload was not performed via ajax, redirect user
return redirect() return redirect()
->route('upload.overview', ['directory' => $request->directoryId]) ->route('upload.overview', ['directory' => $request->directoryId])
->with('success', trans_choice('admin/fileManager.uploadSuccessfull', $successfullUploads)); ->with('success', trans_choice('admin/fileManager.uploadSuccessfull', $successfullUploads));
@@ -52,31 +48,17 @@ class UploadFile extends Controller
} }
} }
/**
* Send message and redirect to upload.overview when upload failed
*
* @param $message
*
* @return \Illuminate\Http\RedirectResponse
*/
protected function invalidUpload($message) protected function invalidUpload($message)
{ {
return redirect() return redirect()
->route('upload.overview') ->route('upload.overview')
->with('error', trans('admin/fileManager.' . $message)); ->with('error', trans('admin/fileManager.' . $message));
} }
/**
* Send response about uploaded file as JSON
*
* @param $uploadedFile
*
* @return \Illuminate\Http\JsonResponse
*/
private function jsonResponse($uploadedFile)
{
$filename = $uploadedFile['file']->getFilename();
$url = config('app.upload_path') . DIRECTORY_SEPARATOR . $filename;
$data = [
'filename' => $filename,
'url' => $url,
'id' => $uploadedFile['id']
];
return response()->json($data);
}
} }
@@ -1,9 +1,7 @@
<?php <?php
namespace App\Http\Controllers\Admin\FileManager;
namespace App\Http\Controllers\Admin; use App\Http\Controllers\Admin\Controller;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use App\Models\Directory; use App\Models\Directory;
use App\Models\File; use App\Models\File;
use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Input;
+27
View File
@@ -17,6 +17,16 @@ use Illuminate\Support\Facades\Hash;
*/ */
class Login extends Controller class Login extends Controller
{ {
/**
* Display login form
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function getLogin()
{
return view('admin.loginForm');
}
/** /**
* Login handler * Login handler
* *
@@ -51,6 +61,23 @@ class Login extends Controller
return $this->loginFailed(); return $this->loginFailed();
} }
/**
* Logs out user
*
* @return \Illuminate\Http\RedirectResponse
*/
public function logout()
{
// remove user information
\Auth::logout();
// redirect to login form with info about successfull logout
return redirect()
->route('login')
->with('success', trans('admin/common.logoutSuccessfull'));
}
private function loginFailed() private function loginFailed()
{ {
return redirect() return redirect()
@@ -1,12 +1,10 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Templates;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Http\Requests\CopyTemplateRequest; use App\Http\Requests\CopyTemplateRequest;
use App\Models\Template; use App\Models\Template;
use Illuminate\Http\Request;
class CopyTemplate extends Controller class CopyTemplate extends Controller
{ {
@@ -28,11 +26,6 @@ class CopyTemplate extends Controller
// get template path // get template path
$template = Template::findOrFail($oldTemplateId); $template = Template::findOrFail($oldTemplateId);
// @todo add check for uniqueness of template_name
// get template path
$template = Template::findOrFail($oldTemplateId);
$namespace = null; $namespace = null;
if (strpos($template->template_name, '::')) { if (strpos($template->template_name, '::')) {
list($namespace) = explode('::', $template->template_name); list($namespace) = explode('::', $template->template_name);
@@ -1,6 +1,6 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Templates;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests; use App\Http\Requests;
@@ -20,6 +20,9 @@ class EditTemplate extends Controller
*/ */
public function getEdit($template) public function getEdit($template)
{ {
/**
* @var $template Template
*/
$template = Template::findOrFail($template); $template = Template::findOrFail($template);
$path = $template->getPath(); $path = $template->getPath();
@@ -89,7 +92,7 @@ class EditTemplate extends Controller
} }
// save new content only if something was changed // save new content only if something was changed
if ($this->isContentDifferent($originalTemplate, $customTemplate, $request->templateContent)) { if ($template->editable && $this->isContentDifferent($originalTemplate, $customTemplate, $request->templateContent)) {
// create directory for custom updates // create directory for custom updates
if (!is_dir($customDir)) { if (!is_dir($customDir)) {
@@ -1,11 +1,9 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Templates;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Models\TemplatePath; use App\Models\TemplatePath;
use Illuminate\Http\Request;
class TemplateOverview extends Controller class TemplateOverview extends Controller
{ {
@@ -1,14 +0,0 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use App\Http\Requests\CreateNewUserRequest;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
class UserProfile extends Controller {
}
@@ -1,11 +1,10 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Users;
use App\Enumerations\UserRoles; use App\Enumerations\UserRoles;
use App\Events\CreateNewUser as CreateNewUserEvent; use App\Events\CreateNewUser as CreateNewUserEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Http\Requests\CreateNewUserRequest; use App\Http\Requests\CreateNewUserRequest;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
@@ -1,12 +1,11 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Users;
use App\Enumerations\UserRoles; use App\Enumerations\UserRoles;
use App\Enumerations\UserStates; use App\Enumerations\UserStates;
use App\Events\EditUser as EditUserEvent; use App\Events\EditUser as EditUserEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Http\Requests\EditUserRequest; use App\Http\Requests\EditUserRequest;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@@ -22,11 +21,8 @@ class EditUser extends Controller
$id = Auth::user()->id; $id = Auth::user()->id;
} }
// @todo add some authorization (e.g. via can/cannot methods)
// try to find given user // try to find given user
$user = User::where('status', '!=', User::STATE_DELETED) $user = User::findOrFail($id);
->findOrFail($id);
$states = UserStates::getWithTranslations(); $states = UserStates::getWithTranslations();
$roles = UserRoles::getWithTranslations(); $roles = UserRoles::getWithTranslations();
@@ -87,7 +83,7 @@ class EditUser extends Controller
Event::fire(new EditUserEvent($user)); Event::fire(new EditUserEvent($user));
return redirect() return redirect()
->route('users.detail', ['id' => $id]) ->back()
->with('success', trans('admin/userManagement.userSuccessfullyEdited')); ->with('success', trans('admin/userManagement.userSuccessfullyEdited'));
} }
} }
@@ -1,10 +1,10 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Users;
use App\Enumerations\UserRoles; use App\Enumerations\UserRoles;
use App\Enumerations\UserStates; use App\Enumerations\UserStates;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Models\ActionLog; use App\Models\ActionLog;
use App\Models\User; use App\Models\User;
@@ -32,7 +32,7 @@ class UserDetail extends Controller
// try to find given user // try to find given user
$user = User::findOrFail($id); $user = User::findOrFail($id);
$actions = $this->log->getUserActions($id); $actions = $this->log->getUserActions($id, 10);
$roles = UserRoles::getWithTranslations(); $roles = UserRoles::getWithTranslations();
$states = UserStates::getWithTranslations(); $states = UserStates::getWithTranslations();
@@ -1,24 +1,21 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Users;
use App\Enumerations\UserRoles; use App\Enumerations\UserRoles;
use App\Enumerations\UserStates; use App\Enumerations\UserStates;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Models\User; use App\Models\User;
class UsersOverview extends Controller class UsersOverview extends Controller
{ {
public function getOverview($status = null, $perPage = 12) public function getOverview($status = null, $perPage = 12)
{ {
$users = User::where('status', '<>', User::STATE_DELETED) $users = User::orderBy('id', 'desc');
->orderBy('id', 'desc');
// get statuses // get statuses
$statuses = UserStates::getWithTranslations(); $statuses = UserStates::getWithTranslations();
$statuses[''] = trans('admin/userManagement.allStatuses'); $statuses[''] = trans('admin/userManagement.allStatuses');
unset($statuses[User::STATE_DELETED]);
// filter using status // filter using status
if (!is_null($status) && isset($statuses[$status])) { if (!is_null($status) && isset($statuses[$status])) {
@@ -29,9 +26,9 @@ class UsersOverview extends Controller
$users = $users->paginate($perPage); $users = $users->paginate($perPage);
return view('admin.userManagement.overview', [ return view('admin.userManagement.overview', [
'users' => $users, 'users' => $users,
'roles' => UserRoles::getWithTranslations(), 'roles' => UserRoles::getWithTranslations(),
'statuses' => $statuses, 'statuses' => $statuses,
'currentStatus' => $status 'currentStatus' => $status
]); ]);
} }
@@ -1,9 +1,8 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Widgets\Areas;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Http\Requests\NewWidgetAreaRequest; use App\Http\Requests\NewWidgetAreaRequest;
use App\Models\WidgetArea; use App\Models\WidgetArea;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
@@ -17,7 +16,7 @@ class CreateNewWidgetArea extends Controller
*/ */
public function getNew() public function getNew()
{ {
return view('admin.widgets.area.new'); return view('admin.widgets.area.new', ['area' => new WidgetArea()]);
} }
/** /**
@@ -1,23 +1,45 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Widgets\Areas;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Http\Requests\EditWidgetAreaRequest; use App\Http\Requests\EditWidgetAreaRequest;
use App\Models\Widget;
use App\Models\WidgetArea; use App\Models\WidgetArea;
use App\Models\WidgetInWidgetArea;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class EditWidgetArea extends Controller class EditWidgetArea extends Controller
{ {
/**
* Display form for editing given widget area
*
* @param $id
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function getEdit($id) public function getEdit($id)
{ {
$area = WidgetArea::findOrFail($id); $area = WidgetArea::findOrFail($id);
$associatedWidgetIds = WidgetInWidgetArea::getWidgetIdsFromArea($area->id);
$widgets = Widget::where('language', LaravelLocalization::getCurrentLocale())
->paginate(25);
return view('admin.widgets.area.edit', ['area' => $area]); return view('admin.widgets.area.edit', [
'area' => $area,
'widgets' => $widgets,
'associatedWidgetIds' => $associatedWidgetIds
]);
} }
/**
* @param EditWidgetAreaRequest $request
* @param $id
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postEdit(EditWidgetAreaRequest $request, $id) public function postEdit(EditWidgetAreaRequest $request, $id)
{ {
try { try {
@@ -35,7 +57,7 @@ class EditWidgetArea extends Controller
Event::fire(new \App\Events\EditWidgetArea($area)); Event::fire(new \App\Events\EditWidgetArea($area));
return redirect() return redirect()
->route('widgetareas.edit', ['id' => $id]) ->route('widgetareas.overview')
->with('success', trans('admin/widgetAreas.editSuccessfull')); ->with('success', trans('admin/widgetAreas.editSuccessfull'));
} }
@@ -55,6 +77,13 @@ class EditWidgetArea extends Controller
return $this->invalidArea(); return $this->invalidArea();
} }
// check if widget area is deletable
if (!$area->deletable) {
return redirect()
->back()
->with('error', trans('admin/widgetAreas.notDeletableArea'));
}
// delete area // delete area
$area->delete(); $area->delete();
@@ -1,8 +1,8 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Widgets\Areas;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Models\WidgetArea; use App\Models\WidgetArea;
@@ -1,11 +1,10 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Widgets;
use App\Events\AssignWidget; use App\Events\AssignWidget;
use App\Events\RemoveWidgetFromArea; use App\Events\RemoveWidgetFromArea;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests;
use App\Models\Widget; use App\Models\Widget;
use App\Models\WidgetArea; use App\Models\WidgetArea;
use App\Models\WidgetInWidgetArea; use App\Models\WidgetInWidgetArea;
@@ -46,7 +45,7 @@ class AssociateWidget extends Controller
Event::fire(new AssignWidget($widget, $widgetArea)); Event::fire(new AssignWidget($widget, $widgetArea));
return redirect() return redirect()
->route('widgets.associate', ['widgetArea' => $widgetAreaId]) ->back()
->with('success', trans('admin/widgets.successfullyAssociated')); ->with('success', trans('admin/widgets.successfullyAssociated'));
} }
@@ -1,8 +1,8 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Widgets;
use App\Http\Controllers\Controller; use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\NewWidgetRequest; use App\Http\Requests\NewWidgetRequest;
use App\Models\Widget; use App\Models\Widget;
use App\Models\WidgetType; use App\Models\WidgetType;
@@ -1,6 +1,7 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Widgets;
use App\Http\Controllers\Admin\Controller;
use App\Http\Requests\EditWidgetRequest; use App\Http\Requests\EditWidgetRequest;
use App\Models\Widget; use App\Models\Widget;
use App\Widgets\Exceptions\MissingParameterException; use App\Widgets\Exceptions\MissingParameterException;
@@ -79,6 +80,13 @@ class EditWidget extends Controller
// create new widget // create new widget
$widget = Widget::findOrFail($id); $widget = Widget::findOrFail($id);
// check if widget area is deletable
if (!$widget->deletable) {
return redirect()
->back()
->with('error', trans('admin/widgets.notDeletable'));
}
$widget->delete(); $widget->delete();
// redirect with success notification // redirect with success notification
@@ -1,6 +1,7 @@
<?php <?php
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin\Widgets;
use App\Http\Controllers\Admin\Controller;
use App\Models\Widget; use App\Models\Widget;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
+6 -6
View File
@@ -2,8 +2,8 @@
namespace App\Http\Controllers\Visitor; namespace App\Http\Controllers\Visitor;
use App\Helpers\PageRenderer;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests;
use App\Models\Content; use App\Models\Content;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@@ -47,13 +47,13 @@ class ContentPage extends Controller
{ {
// test if loaded page is visible or not // test if loaded page is visible or not
if ($page->status == Content::STATUS_PROTECTED && !Auth::user()) { if ($page->status == Content::STATUS_PROTECTED && !Auth::user()) {
throw new \Exception('Cannot access protected resources'); // throw new \Exception('Cannot access protected resources');
abort(404);
} }
// get handler // add one new "view" for page
$handler = new $page->module_handler; $page->view();
// render page return PageRenderer::render($page);
return $handler->render($page, '');
} }
} }
+4 -4
View File
@@ -17,10 +17,10 @@ class Homepage extends ContentPage
} }
// render page // render page
try { // try {
return $this->renderPage($page); return $this->renderPage($page);
} catch (\Exception $e) { // } catch (\Exception $e) {
return view('errors.homepageNotAvailable', ['exception' => $e, 'reason' => 'exception']); // return view('errors.homepageNotAvailable', ['exception' => $e, 'reason' => 'exception']);
} // }
} }
} }
+20 -8
View File
@@ -2,8 +2,13 @@
namespace App\Http; namespace App\Http;
use App\Http\Middleware\TemplatePathInstaller;
use App\Http\Middleware\WidgetInstaller;
use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Foundation\Http\Kernel as HttpKernel;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Routing\Middleware\ThrottleRequests;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter; use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter;
use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes; use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes;
use Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect; use Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect;
@@ -18,7 +23,12 @@ class Kernel extends HttpKernel
* @var array * @var array
*/ */
protected $middleware = [ protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, LocaleSessionRedirect::class,
LaravelLocalizationRedirectFilter::class,
Middleware\EncryptCookies::class,
StartSession::class,
ShareErrorsFromSession::class,
Middleware\VerifyCsrfToken::class
]; ];
/** /**
* The application's route middleware groups. * The application's route middleware groups.
@@ -26,14 +36,16 @@ class Kernel extends HttpKernel
* @var array * @var array
*/ */
protected $middlewareGroups = [ protected $middlewareGroups = [
'web' => [ 'web' => [
Middleware\EncryptCookies::class, CheckForMaintenanceMode::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
Middleware\VerifyCsrfToken::class,
], ],
'api' => [ 'admin' => [
Middleware\Authenticate::class,
Middleware\AdminMenuRegistrator::class,
TemplatePathInstaller::class,
WidgetInstaller::class,
],
'api' => [
'throttle:60,1', 'throttle:60,1',
], ],
]; ];
@@ -33,6 +33,9 @@ class AdminMenuRegistrator
// iterate over all enabled modules // iterate over all enabled modules
foreach ($modules as $key => $module) { foreach ($modules as $key => $module) {
if (!is_callable([$module->handler, 'registerAdminMenu']))
continue;
// try to register menus // try to register menus
try { try {
call_user_func([$module->handler, 'registerAdminMenu'], $user); call_user_func([$module->handler, 'registerAdminMenu'], $user);
@@ -0,0 +1,31 @@
<?php
namespace App\Http\Middleware;
use App\Handlers\Registrators\TemplateRegistrator;
use Closure;
use Illuminate\Support\Facades\App;
class TemplatePathInstaller
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
/**
* @var $registator TemplateRegistrator
*/
$registator = App::make('registerTemplateDir');
// install registered widgets
$registator->saveTemplates();
return $next($request);
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
namespace App\Http\Middleware;
use App\Handlers\Registrators\WidgetRegistrator;
use Closure;
use Illuminate\Support\Facades\App;
class WidgetInstaller
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
/**
* @var $registator WidgetRegistrator
*/
$registator = App::make('registerWidget');
// install registered widgets
$registator->installWidgets();
return $next($request);
}
}
@@ -15,7 +15,6 @@ class CreateNewContentRequest extends Request
'titlePhoto' => 'image', 'titlePhoto' => 'image',
'title' => 'required', 'title' => 'required',
'url' => 'required|unique:contents,url', 'url' => 'required|unique:contents,url',
'template' => 'required|exists:templates,template_name',
'status' => 'required|in:draft,protected,public', 'status' => 'required|in:draft,protected,public',
'title_photo' => 'exists:files,id', 'title_photo' => 'exists:files,id',
'parentPage' => 'exists:contents,id', 'parentPage' => 'exists:contents,id',
-1
View File
@@ -20,7 +20,6 @@ class EditContentRequest extends Request
return [ return [
'title' => 'required', 'title' => 'required',
'url' => 'required|unique:contents,url,' . $this->id, 'url' => 'required|unique:contents,url,' . $this->id,
'template' => 'required|exists:templates,template_name',
'published_from' => 'date', 'published_from' => 'date',
'published_to' => 'date', 'published_to' => 'date',
'title_photo' => 'exists:files,id', 'title_photo' => 'exists:files,id',
+1 -2
View File
@@ -12,8 +12,7 @@ class EditTemplateRequest extends Request
public function rules() public function rules()
{ {
return [ return [
'name' => 'required|max:128', 'name' => 'required|max:128',
'templateContent' => 'required'
]; ];
} }
} }
+12 -223
View File
@@ -13,246 +13,36 @@ Route::pattern('url', '[0-9\-a-z]+');
Route::group([ Route::group([
'prefix' => LaravelLocalization::setLocale(), 'prefix' => LaravelLocalization::setLocale(),
'middleware' => ['localeSessionRedirect', 'localizationRedirect']
], function () { ], function () {
/** /**
* This route group serves to handle request in admin * This route group serves to handle request in admin
*/ */
Route::group([ Route::group([
'middleware' => ['web', 'auth', 'adminMenu'], 'middleware' => ['admin'],
'namespace' => 'Admin', 'namespace' => 'Admin',
'prefix' => 'admin' 'prefix' => 'admin'
], function () { ], function () {
// these routes are available only for user with role admin // include all routes in routes/admin subfolder
Route::group(['middleware' => 'onlyAdmin'], function () { $files = ['contents', 'fileManager', 'settings', 'templates', 'users', 'widgets'];
// display form for creating new user foreach ($files as $file) {
Route::get('users/new', 'CreateNewUser@getNewUser') require_once __DIR__ . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . $file . '.php';
->name('users.new'); }
// POST methods
// display form for creating new user
Route::post('users/new', 'CreateNewUser@postRegistration')
->name('users.newPost');
// display form for edit of existing user
Route::get('users/edit/{id}', 'EditUser@getEditUser')
->name('users.edit');
// form for adding new custom field
Route::get('customfields/new', 'CreateNewCustomField@getNew')
->name('customfields.new');
// form for editing custom field
Route::get('customfields/edit/{id}', 'EditCustomField@getEditCustomField')
->name('customfields.edit');
// form for adding new custom field
Route::post('customfields/new', 'CreateNewCustomField@postNew')
->name('customfields.newPost');
// form for editing custom field
Route::post('customfields/edit/{id}', 'EditCustomField@postEditCustomField')
->name('customfields.editPost');
Route::get('customfields/delete/{id}', 'EditCustomField@deleteCustomField')
->name('customfields.delete');
Route::get('templates/overview/path/{id}', 'TemplateOverview@getPath')
->name('templates.overview');
Route::post('templates/copy', 'CopyTemplate@createCopy')
->name('templates.postCopy');
// Route::get('templates/new/{pathId}', 'TemplateOverview@getPath')
// ->name('templates.new');
Route::get('templates/edit/{id}', 'EditTemplate@getEdit')
->name('templates.edit');
Route::post('templates/edit/{id}', 'EditTemplate@postEdit')
->name('templates.postEdit');
});
// list of all static pages
Route::get('content/overview/{moduleId?}/{status?}', 'ContentOverview@getOverview')
->name('content.overview');
// form for creating new static page
Route::get('content/new/{moduleId}', 'CreateNewContent@getNew')
->name('content.new');
// form for editing existing static page
Route::get('content/edit/{id}', 'EditContent@getEdit')
->name('content.edit');
// post method for creating new static page
Route::post('content/new/{moduleId}', 'CreateNewContent@postNew')
->name('content.newPost');
// post method for creating new static page
Route::post('content/edit/{id}', 'EditContent@postEdit')
->name('content.editPost');
// routes for quick actions
// change status of page (protected, public or draft)
Route::get('content/status/{id}/{status}', 'EditContent@changeStatus')
->name('content.changeStatus');
// set homepage
Route::get('content/homepage/{id}', 'EditContent@setHomepage')
->name('content.setHomepage');
// delete page
Route::get('content/delete/{id}', 'EditContent@deletePage')
->name('content.delete');
// these routes are available for all logged (authenticated) users
// display dashboard with some usefull information // display dashboard with some usefull information
Route::get('/', 'Dashboard@getIndex') Route::get('/', 'Dashboard\Dashboard@getIndex')
->name('admin.dashboard'); ->name('admin.dashboard');
// display user detail in admin
Route::get('users/detail/{id?}', 'UserDetail@getDetail')
->name('users.detail');
// method for saving edited data of user
Route::post('users/edit/{id}', 'EditUser@postEdit')
->name('users.editPost');
// display list of all users registered into our system
Route::get('users/overview/{state?}/{perPage?}', 'UsersOverview@getOverview')
->name('users.overview');
// history of changes for specified page
Route::get('history/{id}', 'History@getOverview')
->name('content.history');
// history of changes for specified page
Route::get('history/{revision}/{id}', 'History@getDiff')
->name('history.diff');
// list of all actions // list of all actions
Route::get('actions', 'ActionLogOverview@getOverview') Route::get('actions', 'ActionLog\Overview@getOverview')
->name('log.overview'); ->name('log.overview');
// routes for widget areas // search form with results
Route::get('widgets/areas/overview', 'WidgetAreaOverview@getOverview')
->name('widgetareas.overview');
// form for new widget area
Route::get('widgets/areas/new', 'CreateNewWidgetArea@getNew')
->name('widgetareas.new');
// form for new widget area
Route::post('widgets/areas/new', 'CreateNewWidgetArea@postNew')
->name('widgetareas.postNew');
// edit form for widget area
Route::get('widgets/areas/edit/{id}', 'EditWidgetArea@getEdit')
->name('widgetareas.edit');
Route::post('widgets/areas/edit/{id}', 'EditWidgetArea@postEdit')
->name('widgetareas.postEdit');
// edit form for widget area
Route::get('widgets/areas/delete/{id}', 'EditWidgetArea@deleteArea')
->name('widgetareas.delete');
// list of all installed widget types
Route::get('widgets/overview', 'WidgetsOverview@getOverview')
->name('widgets.overview');
// create new instance of widget of given type
Route::get('widgets/new/{type}', 'CreateNewWidget@getNew')
->name('widgets.new');
Route::post('widgets/new/{type}', 'CreateNewWidget@postNew')
->name('widgets.postNew');
// edit widget settings
Route::get('widgets/edit/{id}', 'EditWidget@getEdit')
->name('widgets.edit');
// delete widget settings
Route::get('widgets/delete/{id}', 'EditWidget@deleteWidget')
->name('widgets.delete');
Route::post('widgets/edit/{id}', 'EditWidget@postEdit')
->name('widgets.postEdit');
// display form for association of widget and widget area
Route::get('widgets/associate/{widgetArea}', 'AssociateWidget@getList')
->name('widgets.associate');
Route::get('widgets/deassociate/{widgetId}/{widgetArea}', 'AssociateWidget@deleteAssociation')
->name('widgets.deleteAssociation');
Route::get('widgets/associate/{widgetId}/{widgetArea}', 'AssociateWidget@makeAssociation')
->name('widgets.makeAssociation');
// uploader methods
Route::get('directories/new/{id?}', 'CreateNewDirectory@getNew')
->name('upload.newDirectory');
Route::get('directories/edit/{id}', 'EditDirectory@getEdit')
->name('upload.editDirectory');
Route::post('directories/edit/{id}', 'EditDirectory@postEdit')
->name('upload.postEditDirectory');
Route::get('files/overview/{id?}/{type?}/{subtype?}', 'UploadedFilesOverview@getOverview')
->name('upload.overview');
route::post('directories/new', 'CreateNewDirectory@postNew')
->name('upload.postNewDirectory');
Route::get('upload/detail/{id}', 'EditUploadedFile@getDetail')
->name('upload.detail');
Route::post('upload/detail/{id}', 'EditUploadedFile@postEdit')
->name('upload.postEdit');
Route::get('upload/delete/{id}', 'EditUploadedFile@deleteFile')
->name('upload.delete');
// uploader methods
Route::post('upload/file', 'UploadFile@postFile')
->name('upload.postFile');
Route::post('upload/image', 'UploadFile@postImage')
->name('upload.postImage');
// form with settings
Route::get('settings', 'Settings@getOverview')
->name('settings.overview');
Route::post('settings', 'Settings@saveSettings')
->name('settings.save');
Route::get('search', 'Search@getSearch') Route::get('search', 'Search@getSearch')
->name('search'); ->name('search');
// custom fields
// ------------------------------
// list of all custom fields
Route::get('customfields/overview', 'CustomFieldsOverview@getOverview')
->name('customfields.overview');
// logout method // logout method
Route::get('logout', function () { Route::get('logout', 'Login@logout')
// remove user information
\Auth::logout();
// redirect to login form with info about successfull logout
return redirect()
->route('login')
->with('success', trans('admin/common.logoutSuccessfull'));
})
->name('logout'); ->name('logout');
}); });
@@ -264,13 +54,12 @@ Route::group([
Route::group(['middleware' => ['web']], function () { Route::group(['middleware' => ['web']], function () {
// Homepage
Route::get('/', 'Visitor\Homepage@getIndex') Route::get('/', 'Visitor\Homepage@getIndex')
->name('page.index'); ->name('page.index');
// display login form // display login form
Route::get('admin/login', function () { Route::get('admin/login', 'Admin\Login@getLogin')
return view('admin.loginForm');
})
->name('loginForm'); ->name('loginForm');
// handle login // handle login
+42
View File
@@ -0,0 +1,42 @@
<?php
Route::group(['namespace' => 'Contents'], function () {
// list of all static pages
Route::get('content/overview/{moduleId?}/{status?}', 'ContentOverview@getOverview')
->name('content.overview');
// form for creating new static page
Route::get('content/new/{moduleId}', 'CreateNewContent@getNew')
->name('content.new');
// form for editing existing static page
Route::get('content/edit/{id}', 'EditContent@getEdit')
->name('content.edit');
// post method for creating new static page
Route::post('content/new/{moduleId}', 'CreateNewContent@postNew')
->name('content.newPost');
// post method for creating new static page
Route::post('content/edit/{id}', 'EditContent@postEdit')
->name('content.editPost');
// change status of page (protected, public or draft)
Route::get('content/status/{id}/{status}', 'EditContent@changeStatus')
->name('content.changeStatus');
// set homepage
Route::get('content/homepage/{id}', 'EditContent@setHomepage')
->name('content.setHomepage');
// delete page
Route::get('content/delete/{id}', 'EditContent@deletePage')
->name('content.delete');
// history of changes for specified page
Route::get('history/{id}', 'History@getOverview')
->name('content.history');
// history of changes for specified page
Route::get('history/{revision}/{id}', 'History@getDiff')
->name('history.diff');
});
+32
View File
@@ -0,0 +1,32 @@
<?php
Route::group(['namespace' => 'FileManager'], function () {
Route::get('files/overview/{id?}/{type?}/{subtype?}', 'UploadedFilesOverview@getOverview')
->name('upload.overview');
// uploader methods
Route::get('directories/new/{id?}', 'CreateNewDirectory@getNew')
->name('upload.newDirectory');
Route::get('directories/edit/{id}', 'EditDirectory@getEdit')
->name('upload.editDirectory');
Route::post('directories/edit/{id}', 'EditDirectory@postEdit')
->name('upload.postEditDirectory');
route::post('directories/new', 'CreateNewDirectory@postNew')
->name('upload.postNewDirectory');
Route::get('upload/detail/{id}', 'EditUploadedFile@getDetail')
->name('upload.detail');
Route::post('upload/detail/{id}', 'EditUploadedFile@postEdit')
->name('upload.postEdit');
Route::get('upload/delete/{id}', 'EditUploadedFile@deleteFile')
->name('upload.delete');
// uploader methods
Route::post('upload', 'UploadFile@postFile')
->name('upload.postFile');
});
+7
View File
@@ -0,0 +1,7 @@
<?php
// form with settings
Route::get('settings', 'Settings@getOverview')
->name('settings.overview');
Route::post('settings', 'Settings@saveSettings')
->name('settings.save');
+15
View File
@@ -0,0 +1,15 @@
<?php
// these routes are available only for user with role admin
Route::group(['middleware' => 'onlyAdmin', 'namespace' => 'Templates'], function () {
Route::get('templates/overview/path/{id}', 'TemplateOverview@getPath')
->name('templates.overview');
Route::post('templates/copy', 'CopyTemplate@createCopy')
->name('templates.postCopy');
Route::get('templates/edit/{id}', 'EditTemplate@getEdit')
->name('templates.edit');
Route::post('templates/edit/{id}', 'EditTemplate@postEdit')
->name('templates.postEdit');
});
+27
View File
@@ -0,0 +1,27 @@
<?php
Route::group(['namespace' => 'Users'], function () {
// display form for creating new user
Route::get('users/new', 'CreateNewUser@getNewUser')
->name('users.new');
// POST methods
// display form for creating new user
Route::post('users/new', 'CreateNewUser@postRegistration')
->name('users.newPost');
// display form for edit of existing user
Route::get('users/edit/{id}', 'EditUser@getEditUser')
->name('users.edit');
// display user detail in admin
Route::get('users/detail/{id?}', 'UserDetail@getDetail')
->name('users.detail');
// method for saving edited data of user
Route::post('users/edit/{id}', 'EditUser@postEdit')
->name('users.editPost');
// display list of all users registered into our system
Route::get('users/overview/{state?}/{perPage?}', 'UsersOverview@getOverview')
->name('users.overview');
});
+60
View File
@@ -0,0 +1,60 @@
<?php
// routes for widget areas
Route::group(['namespace' => 'Widgets'], function () {
// list of all installed widget types
Route::get('widgets/overview', 'WidgetsOverview@getOverview')
->name('widgets.overview');
// create new instance of widget of given type
Route::get('widgets/new/{type}', 'CreateNewWidget@getNew')
->name('widgets.new');
Route::post('widgets/new/{type}', 'CreateNewWidget@postNew')
->name('widgets.postNew');
// edit widget settings
Route::get('widgets/edit/{id}', 'EditWidget@getEdit')
->name('widgets.edit');
// delete widget settings
Route::get('widgets/delete/{id}', 'EditWidget@deleteWidget')
->name('widgets.delete');
Route::post('widgets/edit/{id}', 'EditWidget@postEdit')
->name('widgets.postEdit');
// display form for association of widget and widget area
Route::get('widgets/associate/{widgetArea}', 'AssociateWidget@getList')
->name('widgets.associate');
Route::get('widgets/deassociate/{widgetId}/{widgetArea}', 'AssociateWidget@deleteAssociation')
->name('widgets.deleteAssociation');
Route::get('widgets/associate/{widgetId}/{widgetArea}', 'AssociateWidget@makeAssociation')
->name('widgets.makeAssociation');
Route::group(['namespace' => 'Areas'], function () {
Route::get('widgets/areas/overview', 'WidgetAreaOverview@getOverview')
->name('widgetareas.overview');
// form for new widget area
Route::get('widgets/areas/new', 'CreateNewWidgetArea@getNew')
->name('widgetareas.new');
// form for new widget area
Route::post('widgets/areas/new', 'CreateNewWidgetArea@postNew')
->name('widgetareas.postNew');
// edit form for widget area
Route::get('widgets/areas/edit/{id}', 'EditWidgetArea@getEdit')
->name('widgetareas.edit');
Route::post('widgets/areas/edit/{id}', 'EditWidgetArea@postEdit')
->name('widgetareas.postEdit');
// edit form for widget area
Route::get('widgets/areas/delete/{id}', 'EditWidgetArea@deleteArea')
->name('widgetareas.delete');
});
});
-1
View File
@@ -22,7 +22,6 @@ class LogDeleteContent extends Logger
'id' => $event->page->id, 'id' => $event->page->id,
'url' => $event->page->url, 'url' => $event->page->url,
'title' => $event->page->title, 'title' => $event->page->title,
'revision' => $event->revision
]; ];
$this->saveLog($parameters); $this->saveLog($parameters);
+40 -21
View File
@@ -5,6 +5,7 @@ namespace App\Models;
use App\Enumerations\ContentStatuses; use App\Enumerations\ContentStatuses;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
@@ -15,6 +16,7 @@ use Modules\Categories\Entities\Category;
*/ */
class Content extends Model class Content extends Model
{ {
use SoftDeletes;
public $timestamps = true; public $timestamps = true;
protected $fillable = [ protected $fillable = [
'user_id', 'user_id',
@@ -36,9 +38,8 @@ class Content extends Model
'status' 'status'
]; ];
protected $guarded = []; protected $guarded = [];
protected $subpages = []; protected $foundSubpages = [];
protected $subpagesInit = false; protected $subpagesInit = false;
const STATUS_DELETED = 'deleted';
const STATUS_DRAFT = 'draft'; const STATUS_DRAFT = 'draft';
const STATUS_PROTECTED = 'protected'; const STATUS_PROTECTED = 'protected';
const STATUS_PUBLIC = 'public'; const STATUS_PUBLIC = 'public';
@@ -59,8 +60,11 @@ class Content extends Model
*/ */
public function getPageQuery() public function getPageQuery()
{ {
return Content::where('status', '!=', Content::STATUS_DELETED) return Content::where('status', '!=', Content::STATUS_DRAFT)
->where('status', '!=', Content::STATUS_DRAFT); ->select('contents.*')
->join('modules', 'modules.handler', '=', 'contents.module_handler')
->where('language', LaravelLocalization::getCurrentLocale())
->where('modules.enabled', true);
} }
/** /**
@@ -70,7 +74,6 @@ class Content extends Model
public function getHomepage() public function getHomepage()
{ {
return $this->getPageQuery() return $this->getPageQuery()
->where('language', LaravelLocalization::getCurrentLocale())
->where('is_homepage', 1) ->where('is_homepage', 1)
->first(); ->first();
} }
@@ -86,32 +89,39 @@ class Content extends Model
{ {
return $this->getPageQuery() return $this->getPageQuery()
->where('url', $url) ->where('url', $url)
->where('language', LaravelLocalization::getCurrentLocale())
->first(); ->first();
} }
/** /**
* Get list of all subpages * Get list of all subpages
* *
* @return \Illuminate\Database\Eloquent\Relations\HasMany * @param bool $orderBy
* @param bool $orderDirection
*
* @return array
*/ */
public function subpages() public function subpages($orderBy = false, $orderDirection = false)
{ {
if (!$this->subpagesInit) { if (!$this->subpagesInit) {
$this->subpages = $this->getPageQuery() $subpages = $this->getPageQuery()
->where('parent_id', $this->id) ->where('contents.parent_id', $this->id);
->where('language', LaravelLocalization::getCurrentLocale())
->get(); if ($orderBy) {
$subpages->orderBy($orderBy, $orderDirection ? $orderDirection : 'ASC');
}
$subpages = $subpages->get();
// convert JSON settings into stdClass // convert JSON settings into stdClass
foreach ($this->subpages as $subpage) { foreach ($subpages as $i => $subpage) {
$subpage->module_settings = json_decode($subpage->module_settings); $subpages[$i]->module_settings = json_decode($subpage->module_settings);
} }
$this->subpagesInit = true; $this->subpagesInit = true;
$this->foundSubpages = $subpages;
} }
return $this->subpages; return $this->foundSubpages;
} }
/** /**
@@ -162,7 +172,6 @@ class Content extends Model
public function rootPages() public function rootPages()
{ {
$rootPages = $this->getPageQuery() $rootPages = $this->getPageQuery()
->where('language', LaravelLocalization::getCurrentLocale())
->where('parent_id', null); ->where('parent_id', null);
if ($this->id) { if ($this->id) {
@@ -179,6 +188,7 @@ class Content extends Model
* @param bool $handler * @param bool $handler
* @param bool $status * @param bool $status
* @param bool $joinAuthor * @param bool $joinAuthor
* @param bool $joinParent
* *
* @return * @return
*/ */
@@ -186,9 +196,10 @@ class Content extends Model
{ {
$query = DB::table('contents') $query = DB::table('contents')
->select('contents.*', 'modules.name AS module_name', 'modules.id AS module_id') ->select('contents.*', 'modules.name AS module_name', 'modules.id AS module_id')
->where('contents.status', '<>', self::STATUS_DELETED)
->where('contents.language', LaravelLocalization::getCurrentLocale())
->join('modules', 'modules.handler', '=', 'contents.module_handler') ->join('modules', 'modules.handler', '=', 'contents.module_handler')
->whereNull('contents.deleted_at')
->where('contents.language', LaravelLocalization::getCurrentLocale())
->where('modules.enabled', 1)
->orderBy('created_at', 'DESC'); ->orderBy('created_at', 'DESC');
// filter results using handler // filter results using handler
@@ -293,10 +304,10 @@ class Content extends Model
public function uploadTitlePhoto(Request $request) public function uploadTitlePhoto(Request $request)
{ {
if ($request->hasFile('titlePhoto')) { if ($request->hasFile('titlePhoto')) {
$file = $this->file->upload($request->file('titlePhoto'), $request); return $this->file->upload($request->file('titlePhoto'), $request);
$this->title_photo = $file['filename'];
} }
return null;
} }
/** /**
@@ -435,4 +446,12 @@ class Content extends Model
// save history // save history
ContentHistory::create($history); ContentHistory::create($history);
} }
public function view()
{
$this->timestamps = false;
$this->viewed++;
$this->save();
$this->timestamps = true;
}
} }
+35
View File
@@ -4,9 +4,13 @@ namespace App\Models;
use App\Events\UploadFile; use App\Events\UploadFile;
use App\Http\Requests\Request; use App\Http\Requests\Request;
use Franzose\ClosureTable\Extensions\Str;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\File as FileFacade;
use Intervention\Image\Constraint;
use Intervention\Image\Facades\Image;
use Symfony\Component\HttpFoundation\File\File as SymphonyFile; use Symfony\Component\HttpFoundation\File\File as SymphonyFile;
use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile;
@@ -63,6 +67,12 @@ class File extends Model
// save file into physical location (local FS) // save file into physical location (local FS)
$uploadedFile = $file->move($destination, $filename); $uploadedFile = $file->move($destination, $filename);
// is uploaded file an image?
if (Str::startsWith($uploadedFile->getMimeType(), 'image')) {
// yes, create thumbnail
$this->createThumbnail($uploadedFile);
}
// insert record into database // insert record into database
$id = $this->saveIntoDatabase($uploadedFile, $request, $file->getClientOriginalName()); $id = $this->saveIntoDatabase($uploadedFile, $request, $file->getClientOriginalName());
@@ -118,4 +128,29 @@ class File extends Model
return $newFile->id; return $newFile->id;
} }
/**
* Create thumbnail of given image
*
* @param SymphonyFile $file
*/
private function createThumbnail(SymphonyFile $file)
{
// does thumbnail directory exist?
if (!is_dir(config('app.thumbnail_path'))) {
FileFacade::makeDirectory(config('app.thumbnail_path'));
}
// get image instance
$image = Image::make(config('app.upload_path') . DIRECTORY_SEPARATOR . $file->getFilename());
// resize image and keep aspect ration
$image->resize(env('THUMBNAIL_WIDTH', 300), null, function (Constraint $constraint) {
$constraint->aspectRatio();
$constraint->upsize();
});
// save thumbnail with lower quality
$image->save(config('app.thumbnail_path') . DIRECTORY_SEPARATOR . $file->getFilename(), 75);
}
} }
+55 -3
View File
@@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Handlers\Contracts\TemplateHandler;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
@@ -20,7 +21,8 @@ class Module extends Model
'module_settings', 'module_settings',
'enabled', 'enabled',
'support_categories', 'support_categories',
'manages_content' 'manages_content',
'is_template'
]; ];
protected $guarded = []; protected $guarded = [];
@@ -45,6 +47,7 @@ class Module extends Model
} }
$managesContent = $handler ? in_array('App\Handlers\Contracts\AppHandler', class_implements($handler)) : false; $managesContent = $handler ? in_array('App\Handlers\Contracts\AppHandler', class_implements($handler)) : false;
$isTemplate = $handler ? in_array(TemplateHandler::class, class_implements($handler)) : false;
$supportCategories = $managesContent ? call_user_func([$handler, 'supportCategories']) : false; $supportCategories = $managesContent ? call_user_func([$handler, 'supportCategories']) : false;
if ($parentModuleId) { if ($parentModuleId) {
@@ -62,8 +65,9 @@ class Module extends Model
'support_categories' => $supportCategories, 'support_categories' => $supportCategories,
'alias' => $alias, 'alias' => $alias,
'module_settings' => json_encode($settings), 'module_settings' => json_encode($settings),
'parent_id' => $parentModuleId, 'parent_id' => $parentModuleId ? $parentModuleId : null,
'enabled' => 1 'enabled' => 1,
'is_template' => $isTemplate
]); ]);
// install something module-specific // install something module-specific
@@ -73,4 +77,52 @@ class Module extends Model
return $module; return $module;
} }
/**
* Delete module from database and uninstall its dependencies
*
* @throws \ErrorException
*/
public function uninstall()
{
// check if user does not want to install module in runtime
if (!App::runningInConsole()) {
throw new \ErrorException('Modules can be uninstalled only via Artisan!');
}
// delete everything in /resources/views/visitor
if ($this->is_template) {
$this->deleteDirectory(resource_path('views/visitor'));
$this->deleteDirectory(resource_path('views/modules'));
$this->deleteDirectory(public_path('assets'));
// delete all template paths
TemplatePath::getQuery()->delete();
}
if ($this->handler && is_callable([$this->handler, 'uninstall'])) {
call_user_func([$this->handler, 'uninstall'], $this);
}
$this->delete();
}
/**
* Delete directory when uninstalling module.
*
* @param $directory
*
* @throws \ErrorException
*/
private function deleteDirectory($directory)
{
if (!is_dir($directory))
return;
$success = \File::deleteDirectory($directory, true);
if (!$success) {
throw new \ErrorException('Cannot delete ' . $directory);
}
}
} }
+3 -2
View File
@@ -6,6 +6,7 @@ use App\Helpers\Gravatar;
use Illuminate\Auth\Authenticatable; use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticableInterface; use Illuminate\Contracts\Auth\Authenticatable as AuthenticableInterface;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\Access\Authorizable; use Illuminate\Foundation\Auth\Access\Authorizable;
/** /**
@@ -13,8 +14,8 @@ use Illuminate\Foundation\Auth\Access\Authorizable;
*/ */
class User extends Model implements AuthenticableInterface class User extends Model implements AuthenticableInterface
{ {
use Authenticatable, Authorizable; use SoftDeletes, Authenticatable, Authorizable;
public $timestamps = false; public $timestamps = true;
protected $fillable = [ protected $fillable = [
'email', 'email',
'username', 'username',
+3 -2
View File
@@ -17,7 +17,9 @@ class Widget extends Model
'user_id', 'user_id',
'name', 'name',
'settings', 'settings',
'description' 'language',
'description',
'deletable'
]; ];
protected $guarded = []; protected $guarded = [];
@@ -31,7 +33,6 @@ class Widget extends Model
*/ */
public function createNew(WidgetType $widgetType, $data) public function createNew(WidgetType $widgetType, $data)
{ {
// convert array or whatever into object // convert array or whatever into object
if (!is_object($data)) { if (!is_object($data)) {
$data = (object)$data; $data = (object)$data;
+2 -1
View File
@@ -15,7 +15,8 @@ class WidgetArea extends Model
protected $fillable = [ protected $fillable = [
'name', 'name',
'code', 'code',
'description' 'description',
'deletable'
]; ];
protected $guarded = []; protected $guarded = [];
+2
View File
@@ -15,6 +15,8 @@ class WidgetType extends Model
protected $fillable = [ protected $fillable = [
'handler', 'handler',
'name', 'name',
'template_id',
'module_id',
'description' 'description'
]; ];
+1 -60
View File
@@ -16,6 +16,7 @@ use App\Widgets\HtmlCode\HtmlCode;
use App\Widgets\Menu\Menu; use App\Widgets\Menu\Menu;
use App\Widgets\OrbitSlider\OrbitSlider; use App\Widgets\OrbitSlider\OrbitSlider;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\File;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Symfony\Component\Process\Exception\InvalidArgumentException; use Symfony\Component\Process\Exception\InvalidArgumentException;
@@ -30,22 +31,12 @@ class AppServiceProvider extends ServiceProvider
{ {
// ignore running from artisan // ignore running from artisan
if (App::runningInConsole()) { if (App::runningInConsole()) {
$this->publishViewResources();
return; return;
} }
$this->registerWidgets(); $this->registerWidgets();
$this->registerTemplates();
$this->registerSettings(); $this->registerSettings();
$this->registerSearch(); $this->registerSearch();
// check if given template is valid
$theme = config('app.theme');
$themeDir = resource_path('views/visitor/' . $theme);
if (!$theme || empty($theme) || !is_dir($themeDir)) {
throw new InvalidArgumentException('No or invalid theme set! Use artisan theme:set or edit .env file manually and include THEME option, please');
}
} }
/** /**
@@ -106,24 +97,6 @@ class AppServiceProvider extends ServiceProvider
$registrator->register(HtmlCode::class); $registrator->register(HtmlCode::class);
$registrator->register(Menu::class); $registrator->register(Menu::class);
$registrator->register(OrbitSlider::class); $registrator->register(OrbitSlider::class);
// register some menu extensions
// $menuExtensions = $this->app->make('registerMenuExtension');
// $menuExtensions->register(new URL());
}
/**
* Register path with editable contents
*/
private function registerTemplates()
{
/**
* @var $registrator TemplateRegistrator
*/
$registrator = $this->app->make('registerTemplateDir');
$registrator->setBaseDirectory('resources/views/visitor');
$registrator->register(config('app.theme'), 'admin/templates.core');
} }
/** /**
@@ -150,37 +123,5 @@ class AppServiceProvider extends ServiceProvider
$registrator->register(new Files(), new AdminFiles(), SearchEngineRegistrator::ADMIN); $registrator->register(new Files(), new AdminFiles(), SearchEngineRegistrator::ADMIN);
} }
/**
* Publish all public assets from all themes
*/
private function publishViewResources()
{
$theme = config('app.theme');
$themeDir = resource_path('views/visitor/' . $theme);
// publish assets if exists for current theme
if (is_dir($themeDir . '/' . Template::ASSETS_DIRECTORY)) {
$this->publishes([$themeDir . '/' . Template::ASSETS_DIRECTORY => public_path('assets/' . $theme)], 'public-assets');
}
if (is_dir($themeDir . '/' . Template::MODULES_DIRECTORY)) {
$this->publishModuleViews($themeDir . '/' . Template::MODULES_DIRECTORY);
}
}
private function publishModuleViews($themeModules)
{
$theme = config('app.theme');
$modules = File::directories($themeModules);
$moduleViews = [];
foreach ($modules as $module) {
$moduleName = strtolower(basename($module));
$moduleViews[$module] = resource_path('views/modules/' . $moduleName . '/visitor/' . $theme);
}
if (!empty($moduleViews)) {
$this->publishes($moduleViews, 'module-views');
}
}
} }
+33 -6
View File
@@ -21,11 +21,7 @@ class GlobalViewDataProvider extends ServiceProvider
return; return;
} }
$settings = new Settings(); view()->share('currentUrl', \Request::url());
foreach ($settings->getForView() as $key => $value) {
view()->share($key, $value);
}
$this->extendBlade(); $this->extendBlade();
} }
@@ -65,7 +61,7 @@ class GlobalViewDataProvider extends ServiceProvider
return preg_replace($pattern, $code, $view); return preg_replace($pattern, $code, $view);
}); });
// shortcut for loading uploaded images // shortcut for loading uploaded files
Blade::extend(function ($view) { Blade::extend(function ($view) {
$pattern = $this->createPattern('upload'); $pattern = $this->createPattern('upload');
$code = '<?php echo \App\Helpers\Template::upload($2); ?>'; $code = '<?php echo \App\Helpers\Template::upload($2); ?>';
@@ -73,6 +69,22 @@ class GlobalViewDataProvider extends ServiceProvider
return preg_replace($pattern, $code, $view); return preg_replace($pattern, $code, $view);
}); });
// shortcut for loading thumbnails of uploaded images
Blade::extend(function ($view) {
$pattern = $this->createPattern('thumbnail');
$code = '<?php echo \App\Helpers\Template::thumbnail($2); ?>';
return preg_replace($pattern, $code, $view);
});
// shortcut for displaying Gravatar
Blade::extend(function ($view) {
$pattern = $this->createPattern('gravatar');
$code = '<?php echo \App\Helpers\Gravatar::img($2); ?>';
return preg_replace($pattern, $code, $view);
});
// shortcut for assets (placed in /public/assets/<theme> // shortcut for assets (placed in /public/assets/<theme>
Blade::extend(function ($view) { Blade::extend(function ($view) {
$pattern = $this->createPattern('asset'); $pattern = $this->createPattern('asset');
@@ -88,6 +100,21 @@ class GlobalViewDataProvider extends ServiceProvider
return preg_replace($pattern, $code, $view); return preg_replace($pattern, $code, $view);
}); });
Blade::extend(function ($view) {
$pattern = $this->createPattern('customDate');
$code = '<?php echo \App\Helpers\Date::dateFormatted($2); ?>';
return preg_replace($pattern, $code, $view);
});
Blade::extend(function ($view) {
$pattern = $this->createPattern('monthName');
$code = '<?php echo \App\Helpers\Date::monthName($2); ?>';
return preg_replace($pattern, $code, $view);
});
// register extension for rendering widget areas // register extension for rendering widget areas
Blade::extend(function ($view) { Blade::extend(function ($view) {
$pattern = $this->createPattern('widgetArea'); $pattern = $this->createPattern('widgetArea');
@@ -5,18 +5,13 @@ use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Symfony\Component\Translation\Translator;
class LaravelLocalizationServiceProvider extends ServiceProvider class LaravelLocalizationServiceProvider extends ServiceProvider
{ {
public function register() public function register()
{ {
try { $languages = DB::table('languages')
$languages = DB::table('languages') ->get();
->get();
} catch (\Exception $e) {
$languages = [];
}
$supportedLocales = []; $supportedLocales = [];
if (empty($languages)) { if (empty($languages)) {
@@ -28,11 +23,7 @@ class LaravelLocalizationServiceProvider extends ServiceProvider
]; ];
// create default language // create default language
try { Language::create($supportedLocales[config('app.locale')]);
Language::create($supportedLocales[config('app.locale')]);
} catch (\Exception $e) {
// ignore, table languages probably does not exist.
}
} }
foreach ($languages as $language) { foreach ($languages as $language) {
+22 -8
View File
@@ -3,7 +3,6 @@
namespace App\Providers; namespace App\Providers;
use App\Models\Module; use App\Models\Module;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
@@ -15,16 +14,31 @@ class ModuleManager extends ServiceProvider
*/ */
public function boot() public function boot()
{ {
// ignore running from artisan // this service provider needs published config - config is merged right after this service provider
if (App::runningInConsole()) { try {
$modules = Module::where('enabled', true)
->get();
} catch (\Exception $e) {
// ignore error
return; return;
} }
// this service provider needs published config - config is merged right after this service provider
$modules = Module::get();
// iterate over all modules and enable or disable them // iterate over all modules and enable or disable them
foreach ($modules as $module) { foreach ($modules as $module) {
$module->module_settings = json_decode($module->module_settings);
if ($module->is_template) {
if (isset($module->module_settings->providers) && !empty($module->module_settings->providers)) {
foreach ($module->module_settings->providers as $provider) {
$this->app->register($provider);
}
}
continue;
}
$this->createModulesJson($module); $this->createModulesJson($module);
} }
} }
@@ -47,7 +61,7 @@ class ModuleManager extends ServiceProvider
*/ */
private function createModulesJson(Module $module) private function createModulesJson(Module $module)
{ {
$config = json_decode($module->module_settings); $config = $module->module_settings;
if (is_null($config)) { if (is_null($config)) {
return; return;
@@ -58,7 +72,7 @@ class ModuleManager extends ServiceProvider
// check if module config is writable // check if module config is writable
if (!is_writable(dirname($path))) { if (!is_writable(dirname($path))) {
Log::warning('Cannot write to '.$path); Log::warning('Cannot write to ' . $path);
return; return;
} }
+12 -2
View File
@@ -9,11 +9,11 @@ use Pingpong\Modules\Json;
class SubmodulesManager extends ServiceProvider class SubmodulesManager extends ServiceProvider
{ {
/** /**
* Register the service provider. * Boot submodules
* *
* @return void * @return void
*/ */
public function register() public function boot()
{ {
$enabledModules = \Module::enabled(); $enabledModules = \Module::enabled();
@@ -52,4 +52,14 @@ class SubmodulesManager extends ServiceProvider
} }
} }
} }
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
// TODO: Implement register() method.
}
} }
+100
View File
@@ -0,0 +1,100 @@
<?php
namespace App\Providers;
use App\Handlers\Registrators\TemplateRegistrator;
use App\Helpers\CurrentTemplate;
use App\Models\Template;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
class TemplateServiceProvider extends ServiceProvider
{
public function boot()
{
// ignore running from artisan
if (App::runningInConsole()) {
$this->publishViewResources();
return;
}
$template = CurrentTemplate::get();
if (!$template) {
throw new \ErrorException('Template is not set, cannot continue');
}
// include files
$files = isset($template->module_settings->files) ? $template->module_settings->files : [];
foreach ($files as $file) {
include_once $file;
}
// register templates
$publicTemplates = call_user_func([CurrentTemplate::handler(), 'getPublicTemplatePaths']);
if (!is_array($publicTemplates)) {
throw new \ErrorException(CurrentTemplate::handler() . '::getPublicTemplatePaths() must return array!');
}
/**
* @var $registrator TemplateRegistrator
*/
$registrator = $this->app->make('registerTemplateDir');
foreach ($publicTemplates as $template) {
// setup some global variables
$module = strtolower($template['module']);
$namespace = isset($template['namespace']) ? $template['namespace'] : strtolower($template['module']);
// register path with current template name
$registrator->setNamespace($namespace);
if (is_callable([config($module . '.handler'), 'getModuleId'])) {
$registrator->setModuleId(call_user_func([config($module . '.handler'), 'getModuleId']));
}
$registrator->register('resources/views/modules/' . $module, 'visitor', $template['templateName']);
}
// register also global resources/views/visitor directory
$registrator->register('resources/views/', 'visitor', 'admin/templates.core');
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
}
/**
* Publish all public assets from all themes
*/
private function publishViewResources()
{
$template = CurrentTemplate::get();
if (!$template) {
return;
}
$templateDir = base_path('templates/' . $template->module_settings->staticName . '/Resources');
$assetsDir = $templateDir . '/' . Template::ASSETS_DIRECTORY;
$viewsDir = $templateDir . '/views';
// publish assets if exists for current theme
if (is_dir($assetsDir)) {
$this->publishes([$assetsDir => public_path('assets/visitor')], 'public-assets');
}
// publish base visitors views
$this->publishes([$viewsDir . '/visitor' => resource_path('views/visitor')], 'module-views');
// publish admin views
if (is_dir($viewsDir . '/modules')) {
$this->publishes([$viewsDir . '/modules' => resource_path('views/modules')], 'module-views');
}
}
}
+8 -2
View File
@@ -72,9 +72,15 @@ class Menu extends NonInstallableWidget
public static function selectContentPages($ids) public static function selectContentPages($ids)
{ {
$pages = Content::where('status', '!=', Content::STATUS_DELETED) $allowedStatuses = [Content::STATUS_PUBLIC];
->where('language', LaravelLocalization::getCurrentLocale())
if (\Auth::user()) {
$allowedStatuses[] = Content::STATUS_PROTECTED;
}
$pages = Content::where('language', LaravelLocalization::getCurrentLocale())
->whereIn('id', $ids) ->whereIn('id', $ids)
->whereIn('status', $allowedStatuses)
->get(); ->get();
$used = []; $used = [];
foreach ($pages as $page) { foreach ($pages as $page) {
+7 -9
View File
@@ -5,10 +5,11 @@ use App\Models\Content;
use App\Models\Widget; use App\Models\Widget;
use App\Models\WidgetType; use App\Models\WidgetType;
use App\Widgets\Contracts\WidgetRenderer; use App\Widgets\Contracts\WidgetRenderer;
use App\Widgets\Menu\Menu as WidgetMenu;
use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
class Menu implements WidgetRenderer class Menu implements WidgetRenderer
{ {
@@ -24,11 +25,10 @@ class Menu implements WidgetRenderer
public static function render($settings) public static function render($settings)
{ {
$links = (array)$settings->links; $links = (array)$settings->links;
$pageIds = array_keys($links); $pageIds = array_keys($links);
// get pages // get pages
$pages = \App\Widgets\Menu\Menu::selectContentPages($pageIds); $pages = WidgetMenu::selectContentPages($pageIds);
// sort links using "order" // sort links using "order"
uasort($links, function ($a, $b) { uasort($links, function ($a, $b) {
@@ -46,18 +46,16 @@ class Menu implements WidgetRenderer
if (!isset($pages[$pageId])) { if (!isset($pages[$pageId])) {
continue; continue;
} }
$page = $pages[$pageId];
$active = false; $page = $pages[$pageId];
if (($page->is_homepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url)) { $active = ($page->is_homepage && $route == 'page.index') || ($route == 'page.content' && isset($parameters['url']) && $parameters['url'] == $page->url);
$active = true; $route = $page->is_homepage ? route('page.index') : route('page.content', ['url' => $page->url]);
}
$code .= '<li'; $code .= '<li';
if ($active) { if ($active) {
$code .= ' class="is-active active"'; $code .= ' class="is-active active"';
} }
$code .= '><a href="' . route('page.content', ['url' => $page->url]) . '">' . e($page->title) . '</a></li>'; $code .= '><a href="' . $route . '">' . e($page->title) . '</a></li>';
} }
$code .= "</ul>"; $code .= "</ul>";
+5 -8
View File
@@ -13,7 +13,9 @@
"pingpong/menus": "^2.2", "pingpong/menus": "^2.2",
"watson/sitemap": "^2.0", "watson/sitemap": "^2.0",
"mcamara/laravel-localization": "^1.1", "mcamara/laravel-localization": "^1.1",
"franzose/closure-table": "^4.1" "franzose/closure-table": "^4.1",
"intervention/image": "^2.3",
"webwizo/laravel-shortcodes": "1.0.4"
}, },
"require-dev": { "require-dev": {
"fzaninotto/faker": "~1.4", "fzaninotto/faker": "~1.4",
@@ -30,16 +32,11 @@
], ],
"psr-4": { "psr-4": {
"App\\": "app/", "App\\": "app/",
"Modules\\": "modules/" "Modules\\": "modules/",
"Templates\\": "templates/"
} }
}, },
"scripts": { "scripts": {
"post-root-package-install": [
"php -r \"copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"php artisan key:generate"
],
"post-install-cmd": [ "post-install-cmd": [
"php artisan clear-compiled", "php artisan clear-compiled",
"php artisan optimize" "php artisan optimize"
Generated
+240 -2
View File
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "34fec17afe62b99ed90d0f72d3536a7b", "hash": "1d486fb23e76c7af1daf00bee207919c",
"content-hash": "58f7e332f9be3faf1f8d481191cf1bb1", "content-hash": "957b49e5a2e691ad8dbc0e665a87d6c7",
"packages": [ "packages": [
{ {
"name": "classpreloader/classpreloader", "name": "classpreloader/classpreloader",
@@ -704,6 +704,133 @@
], ],
"time": "2016-07-08 08:19:46" "time": "2016-07-08 08:19:46"
}, },
{
"name": "guzzlehttp/psr7",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "64862e854f876bc5aee2996cab2f552db8586065"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/64862e854f876bc5aee2996cab2f552db8586065",
"reference": "64862e854f876bc5aee2996cab2f552db8586065",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Psr7\\": "src/"
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Michael Dowling",
"email": "mtdowling@gmail.com",
"homepage": "https://github.com/mtdowling"
},
{
"name": "Tobias Schultze",
"homepage": "https://github.com/Tobion"
}
],
"description": "PSR-7 message implementation that also provides common utility methods",
"keywords": [
"http",
"message",
"request",
"response",
"stream",
"uri",
"url"
],
"time": "2016-08-03 09:33:34"
},
{
"name": "intervention/image",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
"reference": "4064a980324f6c3bfa2bd981dfb247afa705ec3c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Intervention/image/zipball/4064a980324f6c3bfa2bd981dfb247afa705ec3c",
"reference": "4064a980324f6c3bfa2bd981dfb247afa705ec3c",
"shasum": ""
},
"require": {
"ext-fileinfo": "*",
"guzzlehttp/psr7": "~1.1",
"php": ">=5.4.0"
},
"require-dev": {
"mockery/mockery": "~0.9.2",
"phpunit/phpunit": "3.*"
},
"suggest": {
"ext-gd": "to use GD library based image processing.",
"ext-imagick": "to use Imagick based image processing.",
"intervention/imagecache": "Caching extension for the Intervention Image library"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.3-dev"
}
},
"autoload": {
"psr-4": {
"Intervention\\Image\\": "src/Intervention/Image"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Oliver Vogel",
"email": "oliver@olivervogel.net",
"homepage": "http://olivervogel.net/"
}
],
"description": "Image handling and manipulation library with support for Laravel integration",
"homepage": "http://image.intervention.io/",
"keywords": [
"gd",
"image",
"imagick",
"laravel",
"thumbnail",
"watermark"
],
"time": "2016-09-01 17:04:03"
},
{ {
"name": "jakub-onderka/php-console-color", "name": "jakub-onderka/php-console-color",
"version": "0.1", "version": "0.1",
@@ -1632,6 +1759,56 @@
"description": "Support Component of Pingpong Sky Package", "description": "Support Component of Pingpong Sky Package",
"time": "2016-01-07 08:23:04" "time": "2016-01-07 08:23:04"
}, },
{
"name": "psr/http-message",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06 14:39:51"
},
{ {
"name": "psr/log", "name": "psr/log",
"version": "dev-master", "version": "dev-master",
@@ -2678,6 +2855,67 @@
"sitemaps" "sitemaps"
], ],
"time": "2016-08-18 23:27:53" "time": "2016-08-18 23:27:53"
},
{
"name": "webwizo/laravel-shortcodes",
"version": "v1.0.4",
"source": {
"type": "git",
"url": "https://github.com/webwizo/laravel-shortcodes.git",
"reference": "da0774fcba968b11591693cc55b28fabe7eaf047"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webwizo/laravel-shortcodes/zipball/da0774fcba968b11591693cc55b28fabe7eaf047",
"reference": "da0774fcba968b11591693cc55b28fabe7eaf047",
"shasum": ""
},
"require": {
"illuminate/contracts": "~5.2",
"illuminate/support": "~5.2",
"illuminate/view": "~5.2",
"php": "~5.5|~7.0"
},
"require-dev": {
"orchestra/testbench": "~3.2",
"phpunit/phpunit": "4.*",
"scrutinizer/ocular": "~1.1",
"squizlabs/php_codesniffer": "~2.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"classmap": [
"tests/TestCase.php"
],
"psr-4": {
"Webwizo\\Shortcodes\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Asif Iqbal",
"email": "webwizo@gmail.com",
"homepage": "http://www.webwizo.com",
"role": "Developer"
}
],
"description": "Wordpress like shortcodes for Laravel 5.2",
"homepage": "https://github.com/webwizo/laravel-shortcodes",
"keywords": [
"laravel",
"shortcodes",
"wordpress"
],
"time": "2016-08-25 06:02:46"
} }
], ],
"packages-dev": [ "packages-dev": [
+1
View File
@@ -17,4 +17,5 @@
!services.php !services.php
!session.php !session.php
!sitemap.php !sitemap.php
!image.php
!view.php !view.php
+80 -77
View File
@@ -129,49 +129,51 @@ return [
'providers' => [ 'providers' => [
/* /*
* Laravel Framework Service Providers... * Laravel Framework Service Providers...
*/ */
Illuminate\Auth\AuthServiceProvider::class, Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class, Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class, Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class, Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class, Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class, Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class, Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class, Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class, Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class, Illuminate\Mail\MailServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class, Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class, Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class, Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class, Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class, Illuminate\View\ViewServiceProvider::class,
Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class, Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class,
// this class must be before ModulesServiceProvider from PingPong, because it handles files module.json // this class must be before ModulesServiceProvider from PingPong, because it handles files module.json
App\Providers\ModuleManager::class, App\Providers\ModuleManager::class,
Pingpong\Modules\ModulesServiceProvider::class, Pingpong\Modules\ModulesServiceProvider::class,
Pingpong\Menus\MenusServiceProvider::class, Pingpong\Menus\MenusServiceProvider::class,
App\Providers\SubmodulesManager::class, App\Providers\SubmodulesManager::class,
Franzose\ClosureTable\ClosureTableServiceProvider::class,
\Watson\Sitemap\SitemapServiceProvider::class,
Intervention\Image\ImageServiceProvider::class,
Webwizo\Shortcodes\ShortcodesServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\GlobalViewDataProvider::class,
\App\Providers\TemplateServiceProvider::class,
Franzose\ClosureTable\ClosureTableServiceProvider::class, ],
\Watson\Sitemap\SitemapServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\GlobalViewDataProvider::class,
],
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Class Aliases | Class Aliases
@@ -185,41 +187,42 @@ return [
'aliases' => [ 'aliases' => [
'App' => Illuminate\Support\Facades\App::class, 'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class, 'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class, 'Blade' => Illuminate\Support\Facades\Blade::class,
'Cache' => Illuminate\Support\Facades\Cache::class, 'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class, 'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class, 'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class, 'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class, 'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class, 'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class, 'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class, 'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class, 'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class, 'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class, 'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class, 'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class, 'Mail' => Illuminate\Support\Facades\Mail::class,
'Menu' => Pingpong\Menus\MenuFacade::class, 'Menu' => Pingpong\Menus\MenuFacade::class,
'Module' => Pingpong\Modules\Facades\Module::class, 'Module' => Pingpong\Modules\Facades\Module::class,
'Password' => Illuminate\Support\Facades\Password::class, 'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class, 'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class, 'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class, 'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class, 'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class, 'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class, 'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class, 'Session' => Illuminate\Support\Facades\Session::class,
'Sitemap' => Watson\Sitemap\Facades\Sitemap::class, 'Sitemap' => Watson\Sitemap\Facades\Sitemap::class,
'Storage' => Illuminate\Support\Facades\Storage::class, 'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class, 'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class, 'Validator' => Illuminate\Support\Facades\Validator::class,
'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class, 'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class,
'View' => Illuminate\Support\Facades\View::class, 'View' => Illuminate\Support\Facades\View::class,
'Shortcode' => Webwizo\Shortcodes\Facades\Shortcode::class,
], ],
]; ];
+20
View File
@@ -0,0 +1,20 @@
<?php
return array(
/*
|--------------------------------------------------------------------------
| Image Driver
|--------------------------------------------------------------------------
|
| Intervention Image supports "GD Library" and "Imagick" to process images
| internally. You may choose one of them according to your PHP
| configuration. By default PHP's "GD Library" implementation is used.
|
| Supported: "gd", "imagick"
|
*/
'driver' => 'gd'
);
@@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Schema;
class SaveTemplatesIntoModulesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('modules', function (Blueprint $table){
$table->boolean('is_template')->default(false)->comment('Templates can be treated as modules.');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('modules', function (Blueprint $table){
$table->dropColumn('is_template');
});
}
}
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNumberOfViewsOfPage extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('contents', function (Blueprint $table) {
$table->integer('viewed')
->comment('How many times has been this content page displayed?')
->after('updated_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('contents', function (Blueprint $table) {
$table->dropColumn('viewed');
});
}
}
@@ -0,0 +1,55 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddTemplateSupportToWidgets extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('widget_types', function (Blueprint $table) {
$table->integer('template_id')
->comment('Commes this widget with template?')
->after('handler')
->nullable(true)
->default(null);
$table->integer('module_id')
->comment('Commes this widget with some module?')
->after('template_id')
->nullable(true)
->default(null);
$table->foreign('template_id')
->references('id')
->on('modules')
->onDelete('cascade')
->onUpdate('cascade');
$table->foreign('module_id')
->references('id')
->on('modules')
->onDelete('cascade')
->onUpdate('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('widget_types', function (Blueprint $table) {
$table->dropForeign('widget_types_module_id_foreign');
$table->dropForeign('widget_types_template_id_foreign');
$table->dropColumn(['template_id', 'module_id']);
});
}
}
@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class MakeWidgetsAndWidgetAreasNotDeletable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('widgets', function (Blueprint $table) {
$table->boolean('deletable')
->default(true)
->comment('Can this widget be deleted?');
});
Schema::table('widget_areas', function (Blueprint $table) {
$table->boolean('deletable')
->default(true)
->comment('Can this widget area be deleted?');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('widgets', function (Blueprint $table) {
$table->dropColumn('deletable');
});
Schema::table('widget_areas', function (Blueprint $table) {
$table->dropColumn('deletable');
});
}
}

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