diff --git a/.env.example b/.env.example
index 69a303d4..dba86cf7 100644
--- a/.env.example
+++ b/.env.example
@@ -1,8 +1,8 @@
-APP_ENV=testing
-APP_DEBUG=true
-APP_KEY=ZKZAzM23wQ6BPji6zffBjaTzZ3yW7zKQ
+APP_KEY=
+APP_ENV=
+APP_DEBUG=
-DB_HOST=localhost
+DB_HOST=
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
@@ -16,5 +16,4 @@ MAIL_PASSWORD=
SITE_URL=/
UPLOAD_URL=/public/uploads
-THUMBNAILS_URL=/uploads/thumbnails
-THEME=
\ No newline at end of file
+THUMBNAILS_URL=/uploads/thumbnails
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 9c93cf6e..1bfe88c9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,9 @@
# published files from modules
-/resources/views/modules
/public/modules
-/resources/views/vendor
/public/assets
+/resources/views/modules
+/resources/views/visitor
+/resources/views/vendor
# directories with custom templates
**/views/**/custom/*
diff --git a/app/Console/Commands/InstallModule.php b/app/Console/Commands/InstallModule.php
index 2a9a0c7c..ad5fffc5 100644
--- a/app/Console/Commands/InstallModule.php
+++ b/app/Console/Commands/InstallModule.php
@@ -40,8 +40,6 @@ class InstallModule extends Command
/**
* Execute the console command.
- *
- * @return mixed
*/
public function handle()
{
@@ -56,6 +54,9 @@ class InstallModule extends Command
// get config
$config = $this->loadConfig();
+ if (empty($config))
+ return;
+
// check if it is valid
$this->checkMandatoryFields($config);
@@ -78,6 +79,9 @@ class InstallModule extends Command
$basePath = $this->modulesPath . DIRECTORY_SEPARATOR . $this->moduleName . DIRECTORY_SEPARATOR;
$path = $basePath . 'Config' . DIRECTORY_SEPARATOR . 'config.php';
+ if (basename($basePath) == 'Database')
+ return [];
+
// check if module has Config/config.php file
if (!file_exists($path)) {
$path = $basePath . 'info.php';
diff --git a/app/Console/Commands/SetTemplate.php b/app/Console/Commands/SetTemplate.php
new file mode 100644
index 00000000..462d5127
--- /dev/null
+++ b/app/Console/Commands/SetTemplate.php
@@ -0,0 +1,73 @@
+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');
+ }
+}
diff --git a/app/Console/Commands/SetTheme.php b/app/Console/Commands/SetTheme.php
deleted file mode 100644
index dd788a79..00000000
--- a/app/Console/Commands/SetTheme.php
+++ /dev/null
@@ -1,70 +0,0 @@
-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');
- }
-}
diff --git a/app/Console/Commands/TranslateAll.php b/app/Console/Commands/TranslateAll.php
index 26635d17..508802fc 100644
--- a/app/Console/Commands/TranslateAll.php
+++ b/app/Console/Commands/TranslateAll.php
@@ -29,15 +29,32 @@ class TranslateAll extends Command
/**
* Execute the console command.
- * @return mixed
*/
public function handle()
{
$this->call('translate:dir', ['dir' => 'resources/lang']);
-
- $modules = File::directories('modules');
- foreach ($modules as $module) {
- $this->call('translate:dir', ['dir' => $module.'/Resources/lang']);
+
+ $this->crawlDirectory('modules');
+ $this->crawlDirectory('templates', ['templates/Base']);
+ $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']);
}
}
}
\ No newline at end of file
diff --git a/app/Console/Commands/Translations.php b/app/Console/Commands/TranslateDirectory.php
similarity index 89%
rename from app/Console/Commands/Translations.php
rename to app/Console/Commands/TranslateDirectory.php
index aca0693c..22e1bcf5 100644
--- a/app/Console/Commands/Translations.php
+++ b/app/Console/Commands/TranslateDirectory.php
@@ -6,7 +6,7 @@ use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
-class Translations extends Command
+class TranslateDirectory extends Command
{
/**
* The name and signature of the console command.
@@ -25,7 +25,6 @@ class Translations extends Command
/**
* Execute the console command.
- * @return mixed
*/
public function handle()
{
@@ -33,11 +32,21 @@ class Translations extends Command
$defaultLocales = config('app.fallback_locale');
$currentLocales = config('app.locale');
- $defaultLocalesDir = $dir . '/' . $defaultLocales;
- $currentLocalesDir = $dir . '/' . $currentLocales;
+ $defaultLocalesDir = base_path($dir . '/' . $defaultLocales);
+ $currentLocalesDir = base_path($dir . '/' . $currentLocales);
if (!is_dir($defaultLocalesDir)) {
// 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;
}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 395f776d..4c3aadf1 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -18,10 +18,10 @@ class Kernel extends ConsoleKernel
Commands\ChangePassword::class,
Commands\InstallModule::class,
Commands\InstallAllModules::class,
- Commands\Translations::class,
+ Commands\TranslateDirectory::class,
Commands\TranslateAll::class,
Commands\InitDatabaseSchema::class,
- Commands\SetTheme::class,
+ Commands\SetTemplate::class,
AddLanguage::class
];
diff --git a/app/Enumerations/ActiveContentStatuses.php b/app/Enumerations/ActiveContentStatuses.php
deleted file mode 100644
index ed48c909..00000000
--- a/app/Enumerations/ActiveContentStatuses.php
+++ /dev/null
@@ -1,18 +0,0 @@
- $value) {
- if ($key == Content::STATUS_DELETED) {
- continue;
- }
-
- self::push($key, $value);
- }
- }
-}
\ No newline at end of file
diff --git a/app/Enumerations/ContentStatuses.php b/app/Enumerations/ContentStatuses.php
index 8ed34f9f..9ed89887 100644
--- a/app/Enumerations/ContentStatuses.php
+++ b/app/Enumerations/ContentStatuses.php
@@ -9,7 +9,6 @@ class ContentStatuses extends BaseEnumeration
{
$roles = [
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_PUBLIC => 'admin/contents.status_' . Content::STATUS_PUBLIC
];
diff --git a/app/Enumerations/UserStates.php b/app/Enumerations/UserStates.php
index a693dce9..e28d4662 100644
--- a/app/Enumerations/UserStates.php
+++ b/app/Enumerations/UserStates.php
@@ -15,7 +15,6 @@ class UserStates extends BaseEnumeration
public static function init()
{
$items = [
- User::STATE_DELETED => 'admin/userManagement.status_' . User::STATE_DELETED,
User::STATE_BLOCKED => 'admin/userManagement.status_' . User::STATE_BLOCKED,
User::STATE_ACTIVE => 'admin/userManagement.status_' . User::STATE_ACTIVE
];
diff --git a/app/Events/DeleteContent.php b/app/Events/DeleteContent.php
index fe1f555a..47e2a7ff 100644
--- a/app/Events/DeleteContent.php
+++ b/app/Events/DeleteContent.php
@@ -12,7 +12,6 @@ class DeleteContent extends Event
* @var Content
*/
public $page;
- public $revision;
/**
* Create a new event instance.
@@ -20,9 +19,8 @@ class DeleteContent extends Event
* @param Content $page
* @param $revision
*/
- public function __construct(Content $page, $revision)
+ public function __construct(Content $page)
{
$this->page = $page;
- $this->revision = $revision;
}
}
diff --git a/app/Handlers/Contracts/BaseModuleHandler.php b/app/Handlers/Contracts/BaseModuleHandler.php
index c66e8a4e..9cd17c6b 100644
--- a/app/Handlers/Contracts/BaseModuleHandler.php
+++ b/app/Handlers/Contracts/BaseModuleHandler.php
@@ -5,8 +5,6 @@ use App\Models\User;
interface BaseModuleHandler
{
- public static function getModuleId();
-
/**
* Register admin menu (or multiple ones)
*
@@ -18,9 +16,10 @@ interface BaseModuleHandler
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();
}
\ No newline at end of file
diff --git a/app/Handlers/Contracts/ContentTitles.php b/app/Handlers/Contracts/ContentTitles.php
new file mode 100644
index 00000000..5d44f24f
--- /dev/null
+++ b/app/Handlers/Contracts/ContentTitles.php
@@ -0,0 +1,40 @@
+ '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);
+}
\ No newline at end of file
diff --git a/app/Handlers/Handler.php b/app/Handlers/Handler.php
index 63ddab59..06a29ae4 100644
--- a/app/Handlers/Handler.php
+++ b/app/Handlers/Handler.php
@@ -2,6 +2,7 @@
namespace App\Handlers;
use App\Handlers\Contracts\AppHandler;
+use App\Http\Controllers\Controller;
use App\Models\Content;
/**
@@ -29,6 +30,19 @@ abstract class Handler extends BaseHandler implements AppHandler
return History::class;
}
+ /**
+ * Render given module into visitor area.
+ *
+ * @param Content $content DB model from table contents
+ * @param array $parameters parameters used for modifications/custom settings of given model
+ *
+ * @return mixed
+ */
+ public function render(Content $content, $parameters)
+ {
+ return Controller::VisitorsView($content->template, ['page' => $content, 'extra' => $parameters]);
+ }
+
public static function getExtendedFormSections()
{
return [
diff --git a/app/Handlers/Registrators/TemplateRegistrator.php b/app/Handlers/Registrators/TemplateRegistrator.php
index 6788df67..b2cd83db 100644
--- a/app/Handlers/Registrators/TemplateRegistrator.php
+++ b/app/Handlers/Registrators/TemplateRegistrator.php
@@ -28,6 +28,10 @@ class TemplateRegistrator
* @var int ID of module
*/
protected $moduleId;
+ /**
+ * @var array list of all registered template paths
+ */
+ protected $paths = [];
/**
* Set base path
@@ -64,7 +68,7 @@ class TemplateRegistrator
*/
public function setNamespace($namespace)
{
- $this->namespace = $namespace . '::';
+ $this->namespace = $namespace;
}
/**
@@ -80,24 +84,45 @@ class TemplateRegistrator
* Registers new template path.
* This method registeres given path itself with all subdirectories
*
+ * @param $baseDirectory
* @param string $path path relatively to root of the project
* @param string $name human readable identification of given template path
*
* @throws \Exception
*/
- public function register($path, $name)
+ public function register($baseDirectory, $path, $name)
{
- // check if base directory was set
- if (!$this->baseDirectory || !is_dir($this->baseDirectory)) {
- throw new \Exception('Set $baseDirectory before registering template path.');
+ $this->paths[] = [
+ 'namespace' => $this->namespace,
+ '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->registerPath($this->registeredPath, $name);
-
- $this->unsetNamespace();
+ $this->registeredPath = $this->baseDirectory . DIRECTORY_SEPARATOR . $path['path'];
+ // register path
+ $this->registerPath($this->registeredPath, $path['name']);
+ $this->unsetNamespace();
+ }
}
/**
@@ -146,7 +171,7 @@ class TemplateRegistrator
Template::ASSETS_DIRECTORY,
Template::MODULES_DIRECTORY
];
-
+
if (in_array($dirName, $ignoredDirectories)) {
return;
}
@@ -187,7 +212,6 @@ class TemplateRegistrator
$registeredTemplates = Templates::getWithTranslations();
if (!in_array($templateName, $registeredTemplates)) {
-
$params = [
'template_name' => $templateName,
'name' => $templateName,
@@ -197,8 +221,6 @@ class TemplateRegistrator
'editable' => 1
];
- echo 'ukladam do db '.$templateName."\n";
-
// save template into database
$newTemplate = Template::create($params);
diff --git a/app/Handlers/Registrators/WidgetRegistrator.php b/app/Handlers/Registrators/WidgetRegistrator.php
index e70cf9ee..f97aaef4 100644
--- a/app/Handlers/Registrators/WidgetRegistrator.php
+++ b/app/Handlers/Registrators/WidgetRegistrator.php
@@ -3,44 +3,56 @@ namespace App\Handlers\Registrators;
use App\Enumerations\WidgetTypesWithHandlers;
use App\Models\WidgetType;
-use App\Widgets\Contracts\PublicWidget;
-use Symfony\Component\Process\Exception\InvalidArgumentException;
class WidgetRegistrator
{
- protected $widgets;
+ protected $registeredWidgets = [];
- function __construct()
- {
- $this->widgets = WidgetTypesWithHandlers::getSimple();
- }
/**
* 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;
- if (!$class instanceof PublicWidget) {
- throw new InvalidArgumentException($class . ' must implement PublicWidget interface.');
- }
+ $this->registeredWidgets[] = [
+ 'class' => $classname,
+ 'templateId' => $templateId,
+ 'moduleId' => $moduleId
+ ];
+ }
- // register widget as new widget type
- if (!in_array($classname, $this->widgets)) {
- $widgetName = call_user_func($classname . '::getName');
- $widgetDescription = call_user_func($classname . '::getDescription');
+ /**
+ * Install all non-installed widgets
+ */
+ 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
- WidgetType::create([
- 'handler' => $classname,
- 'name' => $widgetName,
- 'description' => $widgetDescription
- ]);
+ // register widget as new widget type
+ if (!in_array($classname, $installed)) {
+ $widgetName = call_user_func($classname . '::getName');
+ $widgetDescription = call_user_func($classname . '::getDescription');
- // install widget (if neccessary)
- call_user_func($classname . '::install');
+ // create row in widget types
+ WidgetType::create([
+ 'handler' => $classname,
+ 'name' => $widgetName,
+ 'module_id' => $moduleId,
+ 'template_id' => $templateId,
+ 'description' => $widgetDescription
+ ]);
+
+ // install widget (if neccessary)
+ call_user_func($classname . '::install');
+ }
}
}
}
diff --git a/app/Handlers/Search/Files.php b/app/Handlers/Search/Files.php
index 5105b3c5..79d66bce 100644
--- a/app/Handlers/Search/Files.php
+++ b/app/Handlers/Search/Files.php
@@ -27,6 +27,7 @@ class Files extends Search
$token = $this->tokenize($term);
return File::where('original_filename', 'LIKE', $token)
+ ->orWhere('name', 'LIKE', $token)
->orWhere('keywords', 'LIKE', $token)
->orWhere('description', 'LIKE', $token)
->orWhere('mime_type', 'LIKE', $token)
diff --git a/app/Helpers/CurrentTemplate.php b/app/Helpers/CurrentTemplate.php
new file mode 100644
index 00000000..9f88dd88
--- /dev/null
+++ b/app/Helpers/CurrentTemplate.php
@@ -0,0 +1,57 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/app/Helpers/Date.php b/app/Helpers/Date.php
new file mode 100644
index 00000000..83e1866d
--- /dev/null
+++ b/app/Helpers/Date.php
@@ -0,0 +1,64 @@
+filename)) {
- $url = config('app.thumbnail_url') . '/' . $file->filename;
- } else {
- $url = config('app.upload_url') . '/' . $file->filename;
- }
+ $url = Template::thumbnail($file->filename);
return '';
break;
case 'text':
- return '';
+ return self::getIcon($file, 'fa-file-text-o');
break;
case 'application':
switch ($subtype) {
case 'pdf':
- return '';
+ return self::getIcon($file, 'fa-file-pdf-o');
break;
default:
- return '';
+ return self::getIcon($file, 'fa-newspaper-o');
break;
}
break;
default:
- return '';
+ return self::getIcon($file, 'fa-question');
break;
}
}
+ /**
+ * Shortcut for displaying icons
+ *
+ * @param $file
+ * @param $icon
+ *
+ * @return string
+ */
+ protected static function getIcon($file, $icon)
+ {
+ return '
' . e(str_limit($file->original_filename, 15)) . '
';
$string .= htmlspecialchars(file_get_contents($path));
$string .= '';
@@ -91,15 +98,8 @@ class FileManager
return $string;
break;
case 'application':
- switch ($subtype) {
- case 'pdf':
- return '';
- break;
- default:
- return '';
- break;
- }
- break;
+ return '';
+ break;
default:
return self::getPreview($file);
break;
@@ -119,19 +119,12 @@ class FileManager
switch ($type) {
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;
case 'image':
list ($width, $height) = getimagesize($path);
-
- return [
- trans('admin/fileManager.resolution') => $height . ' x ' . $width,
- ];
-
+ return [trans('admin/fileManager.resolution') => $height . ' x ' . $width,];
break;
}
diff --git a/app/Helpers/Gravatar.php b/app/Helpers/Gravatar.php
index de9e8407..7460cd9d 100644
--- a/app/Helpers/Gravatar.php
+++ b/app/Helpers/Gravatar.php
@@ -5,6 +5,6 @@ class Gravatar
{
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;
}
}
\ No newline at end of file
diff --git a/app/Helpers/PageRenderer.php b/app/Helpers/PageRenderer.php
new file mode 100644
index 00000000..f0acb176
--- /dev/null
+++ b/app/Helpers/PageRenderer.php
@@ -0,0 +1,43 @@
+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);
+ }
+}
diff --git a/app/Helpers/Settings.php b/app/Helpers/Settings.php
new file mode 100644
index 00000000..56499040
--- /dev/null
+++ b/app/Helpers/Settings.php
@@ -0,0 +1,83 @@
+$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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/Helpers/Template.php b/app/Helpers/Template.php
index a085d384..07332d77 100644
--- a/app/Helpers/Template.php
+++ b/app/Helpers/Template.php
@@ -13,7 +13,7 @@ class Template
*
* @return null|string
*/
- public static function name($template)
+ public static function name($template, $throwExceptions = true)
{
$namespace = null;
if (strpos($template, '::')) {
@@ -21,10 +21,8 @@ class Template
$namespace .= '::';
}
- $theme = config('app.theme');
-
// list of prefixes
- $prefixes = [$theme . '.custom.', $theme . '.', ''];
+ $prefixes = ['custom.', ''];
$view = null;
foreach ($prefixes as $prefix) {
@@ -35,7 +33,11 @@ class Template
}
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;
@@ -59,6 +61,25 @@ class Template
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)
{
if (env('APP_DEBUG')) {
@@ -75,6 +96,14 @@ class Template
return config('app.url') . '/assets/' . config('app.theme') . '/' . $path;
}
+ /**
+ * Print date in configured format
+ *
+ * @param $datestamp
+ * @param bool $withTime
+ *
+ * @return false|string
+ */
public static function date($datestamp, $withTime = true)
{
$timestamp = strtotime($datestamp);
diff --git a/app/Helpers/functions.php b/app/Helpers/functions.php
index 5fd8b190..8a163000 100644
--- a/app/Helpers/functions.php
+++ b/app/Helpers/functions.php
@@ -11,4 +11,20 @@
function e($value)
{
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;
}
\ No newline at end of file
diff --git a/app/Http/Controllers/Admin/ActionLog/Overview.php b/app/Http/Controllers/Admin/ActionLog/Overview.php
new file mode 100644
index 00000000..a93f3a6b
--- /dev/null
+++ b/app/Http/Controllers/Admin/ActionLog/Overview.php
@@ -0,0 +1,51 @@
+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]);
+ }
+}
diff --git a/app/Http/Controllers/Admin/ActionLogOverview.php b/app/Http/Controllers/Admin/ActionLogOverview.php
deleted file mode 100644
index 1f5d5f08..00000000
--- a/app/Http/Controllers/Admin/ActionLogOverview.php
+++ /dev/null
@@ -1,35 +0,0 @@
-log = $log;
- }
-
- public function getOverview()
- {
- $actions = $this->log->getLogActionsQuery(true)
- ->paginate(25);
-
- $this->log->translateLogMessages($actions);
-
- return view('admin.actionLog.overview', ['actions' => $actions]);
- }
-}
diff --git a/app/Http/Controllers/Admin/ContentOverview.php b/app/Http/Controllers/Admin/Contents/ContentOverview.php
similarity index 70%
rename from app/Http/Controllers/Admin/ContentOverview.php
rename to app/Http/Controllers/Admin/Contents/ContentOverview.php
index d6b95f39..6e96e6d5 100644
--- a/app/Http/Controllers/Admin/ContentOverview.php
+++ b/app/Http/Controllers/Admin/Contents/ContentOverview.php
@@ -1,7 +1,8 @@
handler;
+
+ if (is_callable([$module->handler, 'getOverviewTitle'])) {
+ $pageHeading = call_user_func([$module->handler, 'getOverviewTitle']);
+ }
}
// get pages for overview
@@ -47,10 +53,11 @@ class ContentOverview extends Controller
$homepage = $this->content->getHomepage();
return view('admin.content.overview', [
- 'pages' => $pages,
- 'homepage' => $homepage,
- 'statuses' => ContentStatuses::getWithTranslations(),
- 'module' => isset($module) ? $module : null
+ 'pages' => $pages,
+ 'homepage' => $homepage,
+ 'pageHeading' => $pageHeading,
+ 'statuses' => ContentStatuses::getWithTranslations(),
+ 'module' => isset($module) ? $module : null
]);
}
}
\ No newline at end of file
diff --git a/app/Http/Controllers/Admin/CreateNewContent.php b/app/Http/Controllers/Admin/Contents/CreateNewContent.php
similarity index 75%
rename from app/Http/Controllers/Admin/CreateNewContent.php
rename to app/Http/Controllers/Admin/Contents/CreateNewContent.php
index 1beee33b..2ccd4ba4 100644
--- a/app/Http/Controllers/Admin/CreateNewContent.php
+++ b/app/Http/Controllers/Admin/Contents/CreateNewContent.php
@@ -1,8 +1,10 @@
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)
->select(['template_name', 'name', 'description'])
->get();
- $categoryModule = ModuleInstance::get('categories');
// add categories, if supported
+ $categoryModule = ModuleInstance::get('categories');
$categories = [];
- if ($module->support_categories && $categoryModule->enabled()) {
+ if ($module->support_categories && !is_null($categoryModule) && $categoryModule->enabled()) {
$categories = Category::where('module_id', $moduleId)
->get();
}
@@ -61,6 +86,7 @@ class CreateNewContent extends Controller
// render view
return view('admin.content.new', [
+ 'pageHeading' => $pageHeading,
'contentStatuses' => $statuses,
'templates' => $templates,
'moduleId' => $moduleId,
@@ -86,7 +112,6 @@ class CreateNewContent extends Controller
*/
public function postNew(CreateNewContentRequest $request, $moduleId)
{
- $page = new Content();
try {
$module = Module::findOrFail($moduleId);
} catch (NotFoundHttpException $e) {
@@ -96,6 +121,10 @@ class CreateNewContent extends Controller
->with('error', trans('admin/contents.invalidModule'));
}
+ // create new page
+ $page = new Content();
+ $page->template = $request->template;
+
// setup basic info
$page->user_id = \Auth::user()->id;
$page->language = LaravelLocalization::getCurrentLocale();
@@ -107,20 +136,26 @@ class CreateNewContent extends Controller
$page->meta_description = $request->metaDescription;
$page->content = $request->pageContent;
$page->status = $request->status;
- $page->template = $request->template;
$page->module_handler = $module->handler;
$page->category_id = (int)$request->category > 0 ? $request->category : null;
+ // is any parent page specified?
if ($request->parentPage) {
$page->parent_id = $request->parentPage;
}
// upload file - if provided
- $page->uploadTitlePhoto($request);
+ $file = $page->uploadTitlePhoto($request);
+
+ $page->title_photo = $file ? $file['filename'] : null;
// save module-specific stuff
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();
// upload files assigned to content page
diff --git a/app/Http/Controllers/Admin/EditContent.php b/app/Http/Controllers/Admin/Contents/EditContent.php
similarity index 83%
rename from app/Http/Controllers/Admin/EditContent.php
rename to app/Http/Controllers/Admin/Contents/EditContent.php
index cae69a9a..44296dcc 100644
--- a/app/Http/Controllers/Admin/EditContent.php
+++ b/app/Http/Controllers/Admin/Contents/EditContent.php
@@ -1,14 +1,15 @@
history = $history;
@@ -56,27 +65,38 @@ class EditContent extends Controller
$page = Content::findOrFail($id);
$page->module_settings = json_decode($page->module_settings);
- $allModules = ModulesHandlerToId::getWithTranslations();
- $moduleId = $allModules[$page->module_handler];
- $module = Module::findOrFail($moduleId);
+ // get module ID
+ $module = Module::where('handler', $page->module_handler)
+ ->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'])
->get();
+ // get module for Categories - PingPong module
$categoryModule = ModuleInstance::get('categories');
// add categories, if supported
$categories = [];
- if ($module->support_categories && $categoryModule->enabled()) {
- $categories = Category::where('module_id', $moduleId)
+ if ($module->support_categories && !is_null($categoryModule) && $categoryModule->enabled()) {
+ $categories = Category::where('module_id', $module->id)
->get();
}
+ // modify data for edit form according to installed template
+ call_user_func_array([CurrentTemplate::handler(), 'beforePopulatingEditForm'], [&$page]);
+
$history = $this->history->getStructuredHistoryOf($page);
// render view
return view('admin.content.edit', [
+ 'pageHeading' => $pageHeading,
'contentStatuses' => $statuses,
'page' => $page,
'module' => $module,
@@ -118,12 +138,20 @@ class EditContent extends Controller
->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->parentPage = $request->parentPage ? $request->parentPage : null;
- $request->titlePhotoFilename = $page->title_photo;
- // upload file - if provided
- $page->uploadTitlePhoto($request);
+ if (!$file) {
+ $request->titlePhotoFilename = empty($request->existingTitlePhoto) ? null : $request->existingTitlePhoto;
+ } else {
+ $request->titlePhotoFilename = $file['filename'];
+ }
// array of fields in database and fields from request
$fields = [
@@ -142,7 +170,8 @@ class EditContent extends Controller
];
// save new values with history
- $data = self::getFields($request, $fields);
+ $data = self::getFields($request, array_values($fields));
+
list($revision, $changedColumns) = $page->updateWithHistory($fields, $data);
$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
return redirect()
- ->route('content.edit', ['id' => $page->id])
+ ->route('content.overview')
->with('success', trans('admin/contents.successfullyEdited'));
}
@@ -178,7 +207,6 @@ class EditContent extends Controller
{
// get possible statuses
$statuses = ContentStatuses::getWithTranslations();
- unset($statuses[Content::STATUS_DELETED]);
// check if given status is valid
if (!isset($statuses[$status])) {
@@ -241,23 +269,17 @@ class EditContent extends Controller
// change url to something unique
$oldURL = $page->url;
- $page->url = uniqid($page->url . '_deleted');
+ $page->url .= uniqid('deleted_');
$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
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
- Event::fire(new DeleteContent($page, $revision));
+ Event::fire(new DeleteContent($page));
// redirect back to overview with info for user
return redirect()
@@ -286,7 +308,7 @@ class EditContent extends Controller
} catch (NotFoundHttpException $e) {
// page not found
return redirect()
- ->route('content.overview')
+ ->back()
->with('error', trans('admin/contents.invalidPage'));
}
@@ -301,7 +323,7 @@ class EditContent extends Controller
// was something changed?
if ($changedColumns == 0) {
return redirect()
- ->route('content.overview')
+ ->back()
->with('error', trans('admin/contents.nothingToEdit'));
}
@@ -310,7 +332,7 @@ class EditContent extends Controller
// redirect back to overview with info for user
return redirect()
- ->route('content.overview')
+ ->back()
->with('success', trans('admin/contents.homepageSetup', [
'name' => $page->title,
'url' => $page->url
diff --git a/app/Http/Controllers/Admin/History.php b/app/Http/Controllers/Admin/Contents/History.php
similarity index 92%
rename from app/Http/Controllers/Admin/History.php
rename to app/Http/Controllers/Admin/Contents/History.php
index f7ad6d86..a58cdbcf 100644
--- a/app/Http/Controllers/Admin/History.php
+++ b/app/Http/Controllers/Admin/Contents/History.php
@@ -1,6 +1,7 @@
route('content.overview');
-
-// return view('admin.dashboard');
- }
-}
diff --git a/app/Http/Controllers/Admin/Dashboard/Dashboard.php b/app/Http/Controllers/Admin/Dashboard/Dashboard.php
new file mode 100644
index 00000000..3e666127
--- /dev/null
+++ b/app/Http/Controllers/Admin/Dashboard/Dashboard.php
@@ -0,0 +1,14 @@
+route('content.overview');
+ }
+}
diff --git a/app/Http/Controllers/Admin/CreateNewDirectory.php b/app/Http/Controllers/Admin/FileManager/CreateNewDirectory.php
similarity index 93%
rename from app/Http/Controllers/Admin/CreateNewDirectory.php
rename to app/Http/Controllers/Admin/FileManager/CreateNewDirectory.php
index 31e960fa..8f6bfc00 100644
--- a/app/Http/Controllers/Admin/CreateNewDirectory.php
+++ b/app/Http/Controllers/Admin/FileManager/CreateNewDirectory.php
@@ -1,8 +1,8 @@
route('upload.overview', ['id' => $request->parentDirectory])
- ->with('error', trans('admin/fileManager.subdirectoryExists'))
- ->withInput();
+ ->withInput()
+ ->with('error', trans('admin/fileManager.subdirectoryExists'));
}
}
diff --git a/app/Http/Controllers/Admin/EditDirectory.php b/app/Http/Controllers/Admin/FileManager/EditDirectory.php
similarity index 88%
rename from app/Http/Controllers/Admin/EditDirectory.php
rename to app/Http/Controllers/Admin/FileManager/EditDirectory.php
index 7992a7cb..d3fd42d2 100644
--- a/app/Http/Controllers/Admin/EditDirectory.php
+++ b/app/Http/Controllers/Admin/FileManager/EditDirectory.php
@@ -1,8 +1,8 @@
route('upload.overview', ['id' => $directoryId])
- ->with('error', trans('admin/fileManager.subdirectoryExists'))
- ->withInput();
+ ->withInput()
+ ->with('error', trans('admin/fileManager.subdirectoryExists'));
}
}
diff --git a/app/Http/Controllers/Admin/EditUploadedFile.php b/app/Http/Controllers/Admin/FileManager/EditUploadedFile.php
similarity index 96%
rename from app/Http/Controllers/Admin/EditUploadedFile.php
rename to app/Http/Controllers/Admin/FileManager/EditUploadedFile.php
index dc923eba..c29bb82a 100644
--- a/app/Http/Controllers/Admin/EditUploadedFile.php
+++ b/app/Http/Controllers/Admin/FileManager/EditUploadedFile.php
@@ -1,10 +1,10 @@
file = $file;
}
-
/**
* Uploads any file
*
- * @return \Illuminate\Http\RedirectResponse
+ * @param Request $request
+ *
+ * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/
public function postFile(Request $request)
{
@@ -38,12 +40,6 @@ class UploadFile extends Controller
$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()
->route('upload.overview', ['directory' => $request->directoryId])
->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)
{
return redirect()
->route('upload.overview')
->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);
- }
}
\ No newline at end of file
diff --git a/app/Http/Controllers/Admin/UploadedFilesOverview.php b/app/Http/Controllers/Admin/FileManager/UploadedFilesOverview.php
similarity index 93%
rename from app/Http/Controllers/Admin/UploadedFilesOverview.php
rename to app/Http/Controllers/Admin/FileManager/UploadedFilesOverview.php
index 6b5c0a21..c8d1def9 100644
--- a/app/Http/Controllers/Admin/UploadedFilesOverview.php
+++ b/app/Http/Controllers/Admin/FileManager/UploadedFilesOverview.php
@@ -1,9 +1,7 @@
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()
{
return redirect()
diff --git a/app/Http/Controllers/Admin/CopyTemplate.php b/app/Http/Controllers/Admin/Templates/CopyTemplate.php
similarity index 93%
rename from app/Http/Controllers/Admin/CopyTemplate.php
rename to app/Http/Controllers/Admin/Templates/CopyTemplate.php
index f4598804..1a407547 100644
--- a/app/Http/Controllers/Admin/CopyTemplate.php
+++ b/app/Http/Controllers/Admin/Templates/CopyTemplate.php
@@ -1,12 +1,10 @@
template_name, '::')) {
list($namespace) = explode('::', $template->template_name);
diff --git a/app/Http/Controllers/Admin/EditTemplate.php b/app/Http/Controllers/Admin/Templates/EditTemplate.php
similarity index 95%
rename from app/Http/Controllers/Admin/EditTemplate.php
rename to app/Http/Controllers/Admin/Templates/EditTemplate.php
index e7995dc5..fb372b83 100644
--- a/app/Http/Controllers/Admin/EditTemplate.php
+++ b/app/Http/Controllers/Admin/Templates/EditTemplate.php
@@ -1,6 +1,6 @@
getPath();
@@ -89,7 +92,7 @@ class EditTemplate extends Controller
}
// 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
if (!is_dir($customDir)) {
diff --git a/app/Http/Controllers/Admin/TemplateOverview.php b/app/Http/Controllers/Admin/Templates/TemplateOverview.php
similarity index 81%
rename from app/Http/Controllers/Admin/TemplateOverview.php
rename to app/Http/Controllers/Admin/Templates/TemplateOverview.php
index f766b14e..8baf7300 100644
--- a/app/Http/Controllers/Admin/TemplateOverview.php
+++ b/app/Http/Controllers/Admin/Templates/TemplateOverview.php
@@ -1,11 +1,9 @@
id;
}
- // @todo add some authorization (e.g. via can/cannot methods)
-
// try to find given user
- $user = User::where('status', '!=', User::STATE_DELETED)
- ->findOrFail($id);
+ $user = User::findOrFail($id);
$states = UserStates::getWithTranslations();
$roles = UserRoles::getWithTranslations();
@@ -87,7 +83,7 @@ class EditUser extends Controller
Event::fire(new EditUserEvent($user));
return redirect()
- ->route('users.detail', ['id' => $id])
+ ->back()
->with('success', trans('admin/userManagement.userSuccessfullyEdited'));
}
}
\ No newline at end of file
diff --git a/app/Http/Controllers/Admin/UserDetail.php b/app/Http/Controllers/Admin/Users/UserDetail.php
similarity index 86%
rename from app/Http/Controllers/Admin/UserDetail.php
rename to app/Http/Controllers/Admin/Users/UserDetail.php
index 46c4d461..60e78ebc 100644
--- a/app/Http/Controllers/Admin/UserDetail.php
+++ b/app/Http/Controllers/Admin/Users/UserDetail.php
@@ -1,10 +1,10 @@
log->getUserActions($id);
+ $actions = $this->log->getUserActions($id, 10);
$roles = UserRoles::getWithTranslations();
$states = UserStates::getWithTranslations();
diff --git a/app/Http/Controllers/Admin/UsersOverview.php b/app/Http/Controllers/Admin/Users/UsersOverview.php
similarity index 64%
rename from app/Http/Controllers/Admin/UsersOverview.php
rename to app/Http/Controllers/Admin/Users/UsersOverview.php
index e26513cb..86bf137d 100644
--- a/app/Http/Controllers/Admin/UsersOverview.php
+++ b/app/Http/Controllers/Admin/Users/UsersOverview.php
@@ -1,24 +1,21 @@
', User::STATE_DELETED)
- ->orderBy('id', 'desc');
+ $users = User::orderBy('id', 'desc');
// get statuses
$statuses = UserStates::getWithTranslations();
$statuses[''] = trans('admin/userManagement.allStatuses');
- unset($statuses[User::STATE_DELETED]);
// filter using status
if (!is_null($status) && isset($statuses[$status])) {
@@ -29,9 +26,9 @@ class UsersOverview extends Controller
$users = $users->paginate($perPage);
return view('admin.userManagement.overview', [
- 'users' => $users,
- 'roles' => UserRoles::getWithTranslations(),
- 'statuses' => $statuses,
+ 'users' => $users,
+ 'roles' => UserRoles::getWithTranslations(),
+ 'statuses' => $statuses,
'currentStatus' => $status
]);
}
diff --git a/app/Http/Controllers/Admin/CreateNewWidgetArea.php b/app/Http/Controllers/Admin/Widgets/Areas/CreateNewWidgetArea.php
similarity index 85%
rename from app/Http/Controllers/Admin/CreateNewWidgetArea.php
rename to app/Http/Controllers/Admin/Widgets/Areas/CreateNewWidgetArea.php
index 9fe19ce6..91c22e35 100644
--- a/app/Http/Controllers/Admin/CreateNewWidgetArea.php
+++ b/app/Http/Controllers/Admin/Widgets/Areas/CreateNewWidgetArea.php
@@ -1,9 +1,8 @@
new WidgetArea()]);
}
/**
diff --git a/app/Http/Controllers/Admin/EditWidgetArea.php b/app/Http/Controllers/Admin/Widgets/Areas/EditWidgetArea.php
similarity index 60%
rename from app/Http/Controllers/Admin/EditWidgetArea.php
rename to app/Http/Controllers/Admin/Widgets/Areas/EditWidgetArea.php
index 7dc3f31e..e2a9b834 100644
--- a/app/Http/Controllers/Admin/EditWidgetArea.php
+++ b/app/Http/Controllers/Admin/Widgets/Areas/EditWidgetArea.php
@@ -1,23 +1,45 @@
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)
{
try {
@@ -35,7 +57,7 @@ class EditWidgetArea extends Controller
Event::fire(new \App\Events\EditWidgetArea($area));
return redirect()
- ->route('widgetareas.edit', ['id' => $id])
+ ->route('widgetareas.overview')
->with('success', trans('admin/widgetAreas.editSuccessfull'));
}
@@ -55,6 +77,13 @@ class EditWidgetArea extends Controller
return $this->invalidArea();
}
+ // check if widget area is deletable
+ if (!$area->deletable) {
+ return redirect()
+ ->back()
+ ->with('error', trans('admin/widgetAreas.notDeletableArea'));
+ }
+
// delete area
$area->delete();
diff --git a/app/Http/Controllers/Admin/WidgetAreaOverview.php b/app/Http/Controllers/Admin/Widgets/Areas/WidgetAreaOverview.php
similarity index 84%
rename from app/Http/Controllers/Admin/WidgetAreaOverview.php
rename to app/Http/Controllers/Admin/Widgets/Areas/WidgetAreaOverview.php
index 079752cf..d813d1f2 100644
--- a/app/Http/Controllers/Admin/WidgetAreaOverview.php
+++ b/app/Http/Controllers/Admin/Widgets/Areas/WidgetAreaOverview.php
@@ -1,8 +1,8 @@
route('widgets.associate', ['widgetArea' => $widgetAreaId])
+ ->back()
->with('success', trans('admin/widgets.successfullyAssociated'));
}
diff --git a/app/Http/Controllers/Admin/CreateNewWidget.php b/app/Http/Controllers/Admin/Widgets/CreateNewWidget.php
similarity index 95%
rename from app/Http/Controllers/Admin/CreateNewWidget.php
rename to app/Http/Controllers/Admin/Widgets/CreateNewWidget.php
index 405d6739..39443084 100644
--- a/app/Http/Controllers/Admin/CreateNewWidget.php
+++ b/app/Http/Controllers/Admin/Widgets/CreateNewWidget.php
@@ -1,8 +1,8 @@
deletable) {
+ return redirect()
+ ->back()
+ ->with('error', trans('admin/widgets.notDeletable'));
+ }
+
$widget->delete();
// redirect with success notification
diff --git a/app/Http/Controllers/Admin/WidgetsOverview.php b/app/Http/Controllers/Admin/Widgets/WidgetsOverview.php
similarity index 81%
rename from app/Http/Controllers/Admin/WidgetsOverview.php
rename to app/Http/Controllers/Admin/Widgets/WidgetsOverview.php
index 424c2e84..4dc6ba1d 100644
--- a/app/Http/Controllers/Admin/WidgetsOverview.php
+++ b/app/Http/Controllers/Admin/Widgets/WidgetsOverview.php
@@ -1,6 +1,7 @@
status == Content::STATUS_PROTECTED && !Auth::user()) {
- throw new \Exception('Cannot access protected resources');
+// throw new \Exception('Cannot access protected resources');
+ abort(404);
}
- // get handler
- $handler = new $page->module_handler;
+ // add one new "view" for page
+ $page->view();
- // render page
- return $handler->render($page, '');
+ return PageRenderer::render($page);
}
}
diff --git a/app/Http/Controllers/Visitor/Homepage.php b/app/Http/Controllers/Visitor/Homepage.php
index 00c0264d..a40ba1da 100644
--- a/app/Http/Controllers/Visitor/Homepage.php
+++ b/app/Http/Controllers/Visitor/Homepage.php
@@ -17,10 +17,10 @@ class Homepage extends ContentPage
}
// render page
- try {
+// try {
return $this->renderPage($page);
- } catch (\Exception $e) {
- return view('errors.homepageNotAvailable', ['exception' => $e, 'reason' => 'exception']);
- }
+// } catch (\Exception $e) {
+// return view('errors.homepageNotAvailable', ['exception' => $e, 'reason' => 'exception']);
+// }
}
}
diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php
index 15940382..a3f84d26 100644
--- a/app/Http/Kernel.php
+++ b/app/Http/Kernel.php
@@ -2,8 +2,13 @@
namespace App\Http;
+use App\Http\Middleware\TemplatePathInstaller;
+use App\Http\Middleware\WidgetInstaller;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
+use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode;
use Illuminate\Routing\Middleware\ThrottleRequests;
+use Illuminate\Session\Middleware\StartSession;
+use Illuminate\View\Middleware\ShareErrorsFromSession;
use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter;
use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes;
use Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect;
@@ -18,7 +23,12 @@ class Kernel extends HttpKernel
* @var array
*/
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.
@@ -26,14 +36,16 @@ class Kernel extends HttpKernel
* @var array
*/
protected $middlewareGroups = [
- 'web' => [
- Middleware\EncryptCookies::class,
- \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
- \Illuminate\Session\Middleware\StartSession::class,
- \Illuminate\View\Middleware\ShareErrorsFromSession::class,
- Middleware\VerifyCsrfToken::class,
+ 'web' => [
+ CheckForMaintenanceMode::class,
],
- 'api' => [
+ 'admin' => [
+ Middleware\Authenticate::class,
+ Middleware\AdminMenuRegistrator::class,
+ TemplatePathInstaller::class,
+ WidgetInstaller::class,
+ ],
+ 'api' => [
'throttle:60,1',
],
];
diff --git a/app/Http/Middleware/AdminMenuRegistrator.php b/app/Http/Middleware/AdminMenuRegistrator.php
index 6c35d6f6..88d9549d 100644
--- a/app/Http/Middleware/AdminMenuRegistrator.php
+++ b/app/Http/Middleware/AdminMenuRegistrator.php
@@ -33,6 +33,9 @@ class AdminMenuRegistrator
// iterate over all enabled modules
foreach ($modules as $key => $module) {
+ if (!is_callable([$module->handler, 'registerAdminMenu']))
+ continue;
+
// try to register menus
try {
call_user_func([$module->handler, 'registerAdminMenu'], $user);
diff --git a/app/Http/Middleware/TemplatePathInstaller.php b/app/Http/Middleware/TemplatePathInstaller.php
new file mode 100644
index 00000000..f06d1446
--- /dev/null
+++ b/app/Http/Middleware/TemplatePathInstaller.php
@@ -0,0 +1,31 @@
+saveTemplates();
+
+ return $next($request);
+ }
+}
diff --git a/app/Http/Middleware/WidgetInstaller.php b/app/Http/Middleware/WidgetInstaller.php
new file mode 100644
index 00000000..883819f3
--- /dev/null
+++ b/app/Http/Middleware/WidgetInstaller.php
@@ -0,0 +1,30 @@
+installWidgets();
+
+ return $next($request);
+ }
+}
diff --git a/app/Http/Requests/CreateNewContentRequest.php b/app/Http/Requests/CreateNewContentRequest.php
index 7284b6ae..df25858b 100644
--- a/app/Http/Requests/CreateNewContentRequest.php
+++ b/app/Http/Requests/CreateNewContentRequest.php
@@ -15,7 +15,6 @@ class CreateNewContentRequest extends Request
'titlePhoto' => 'image',
'title' => 'required',
'url' => 'required|unique:contents,url',
- 'template' => 'required|exists:templates,template_name',
'status' => 'required|in:draft,protected,public',
'title_photo' => 'exists:files,id',
'parentPage' => 'exists:contents,id',
diff --git a/app/Http/Requests/EditContentRequest.php b/app/Http/Requests/EditContentRequest.php
index f92504b4..e04878e6 100644
--- a/app/Http/Requests/EditContentRequest.php
+++ b/app/Http/Requests/EditContentRequest.php
@@ -20,7 +20,6 @@ class EditContentRequest extends Request
return [
'title' => 'required',
'url' => 'required|unique:contents,url,' . $this->id,
- 'template' => 'required|exists:templates,template_name',
'published_from' => 'date',
'published_to' => 'date',
'title_photo' => 'exists:files,id',
diff --git a/app/Http/Requests/EditTemplateRequest.php b/app/Http/Requests/EditTemplateRequest.php
index 63b35b07..aedf05af 100644
--- a/app/Http/Requests/EditTemplateRequest.php
+++ b/app/Http/Requests/EditTemplateRequest.php
@@ -12,8 +12,7 @@ class EditTemplateRequest extends Request
public function rules()
{
return [
- 'name' => 'required|max:128',
- 'templateContent' => 'required'
+ 'name' => 'required|max:128',
];
}
}
diff --git a/app/Http/routes.php b/app/Http/routes.php
index d1913d45..4d9c385d 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -13,246 +13,36 @@ Route::pattern('url', '[0-9\-a-z]+');
Route::group([
'prefix' => LaravelLocalization::setLocale(),
- 'middleware' => ['localeSessionRedirect', 'localizationRedirect']
], function () {
/**
* This route group serves to handle request in admin
*/
Route::group([
- 'middleware' => ['web', 'auth', 'adminMenu'],
+ 'middleware' => ['admin'],
'namespace' => 'Admin',
'prefix' => 'admin'
], function () {
- // these routes are available only for user with role admin
- Route::group(['middleware' => 'onlyAdmin'], 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');
-
- // 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
+ // include all routes in routes/admin subfolder
+ $files = ['contents', 'fileManager', 'settings', 'templates', 'users', 'widgets'];
+ foreach ($files as $file) {
+ require_once __DIR__ . DIRECTORY_SEPARATOR . 'routes' . DIRECTORY_SEPARATOR . 'admin' . DIRECTORY_SEPARATOR . $file . '.php';
+ }
// display dashboard with some usefull information
- Route::get('/', 'Dashboard@getIndex')
+ Route::get('/', 'Dashboard\Dashboard@getIndex')
->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
- Route::get('actions', 'ActionLogOverview@getOverview')
+ Route::get('actions', 'ActionLog\Overview@getOverview')
->name('log.overview');
- // routes for widget areas
- 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');
-
+ // search form with results
Route::get('search', 'Search@getSearch')
->name('search');
- // custom fields
- // ------------------------------
-
- // list of all custom fields
- Route::get('customfields/overview', 'CustomFieldsOverview@getOverview')
- ->name('customfields.overview');
-
// logout method
- Route::get('logout', function () {
-
- // remove user information
- \Auth::logout();
-
- // redirect to login form with info about successfull logout
- return redirect()
- ->route('login')
- ->with('success', trans('admin/common.logoutSuccessfull'));
- })
+ Route::get('logout', 'Login@logout')
->name('logout');
});
@@ -264,13 +54,12 @@ Route::group([
Route::group(['middleware' => ['web']], function () {
+ // Homepage
Route::get('/', 'Visitor\Homepage@getIndex')
->name('page.index');
// display login form
- Route::get('admin/login', function () {
- return view('admin.loginForm');
- })
+ Route::get('admin/login', 'Admin\Login@getLogin')
->name('loginForm');
// handle login
diff --git a/app/Http/routes/admin/contents.php b/app/Http/routes/admin/contents.php
new file mode 100644
index 00000000..6e7b6a6a
--- /dev/null
+++ b/app/Http/routes/admin/contents.php
@@ -0,0 +1,42 @@
+ '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');
+});
\ No newline at end of file
diff --git a/app/Http/routes/admin/fileManager.php b/app/Http/routes/admin/fileManager.php
new file mode 100644
index 00000000..58eecfaf
--- /dev/null
+++ b/app/Http/routes/admin/fileManager.php
@@ -0,0 +1,32 @@
+ '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');
+});
diff --git a/app/Http/routes/admin/settings.php b/app/Http/routes/admin/settings.php
new file mode 100644
index 00000000..70b2b996
--- /dev/null
+++ b/app/Http/routes/admin/settings.php
@@ -0,0 +1,7 @@
+name('settings.overview');
+
+Route::post('settings', 'Settings@saveSettings')
+ ->name('settings.save');
\ No newline at end of file
diff --git a/app/Http/routes/admin/templates.php b/app/Http/routes/admin/templates.php
new file mode 100644
index 00000000..bb265533
--- /dev/null
+++ b/app/Http/routes/admin/templates.php
@@ -0,0 +1,15 @@
+ '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');
+});
\ No newline at end of file
diff --git a/app/Http/routes/admin/users.php b/app/Http/routes/admin/users.php
new file mode 100644
index 00000000..69d643f7
--- /dev/null
+++ b/app/Http/routes/admin/users.php
@@ -0,0 +1,27 @@
+ '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');
+});
diff --git a/app/Http/routes/admin/widgets.php b/app/Http/routes/admin/widgets.php
new file mode 100644
index 00000000..d10df3fd
--- /dev/null
+++ b/app/Http/routes/admin/widgets.php
@@ -0,0 +1,60 @@
+ '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');
+ });
+});
diff --git a/app/Listeners/LogDeleteContent.php b/app/Listeners/LogDeleteContent.php
index 1c443dd4..f5e9ff47 100644
--- a/app/Listeners/LogDeleteContent.php
+++ b/app/Listeners/LogDeleteContent.php
@@ -22,7 +22,6 @@ class LogDeleteContent extends Logger
'id' => $event->page->id,
'url' => $event->page->url,
'title' => $event->page->title,
- 'revision' => $event->revision
];
$this->saveLog($parameters);
diff --git a/app/Models/Content.php b/app/Models/Content.php
index 8d13ee10..6dee27a4 100644
--- a/app/Models/Content.php
+++ b/app/Models/Content.php
@@ -5,6 +5,7 @@ namespace App\Models;
use App\Enumerations\ContentStatuses;
use App\Http\Requests\Request;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
@@ -15,6 +16,7 @@ use Modules\Categories\Entities\Category;
*/
class Content extends Model
{
+ use SoftDeletes;
public $timestamps = true;
protected $fillable = [
'user_id',
@@ -36,9 +38,8 @@ class Content extends Model
'status'
];
protected $guarded = [];
- protected $subpages = [];
+ protected $foundSubpages = [];
protected $subpagesInit = false;
- const STATUS_DELETED = 'deleted';
const STATUS_DRAFT = 'draft';
const STATUS_PROTECTED = 'protected';
const STATUS_PUBLIC = 'public';
@@ -59,8 +60,11 @@ class Content extends Model
*/
public function getPageQuery()
{
- return Content::where('status', '!=', Content::STATUS_DELETED)
- ->where('status', '!=', Content::STATUS_DRAFT);
+ return Content::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()
{
return $this->getPageQuery()
- ->where('language', LaravelLocalization::getCurrentLocale())
->where('is_homepage', 1)
->first();
}
@@ -86,32 +89,39 @@ class Content extends Model
{
return $this->getPageQuery()
->where('url', $url)
- ->where('language', LaravelLocalization::getCurrentLocale())
->first();
}
/**
* 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) {
- $this->subpages = $this->getPageQuery()
- ->where('parent_id', $this->id)
- ->where('language', LaravelLocalization::getCurrentLocale())
- ->get();
+ $subpages = $this->getPageQuery()
+ ->where('contents.parent_id', $this->id);
+
+ if ($orderBy) {
+ $subpages->orderBy($orderBy, $orderDirection ? $orderDirection : 'ASC');
+ }
+
+ $subpages = $subpages->get();
// convert JSON settings into stdClass
- foreach ($this->subpages as $subpage) {
- $subpage->module_settings = json_decode($subpage->module_settings);
+ foreach ($subpages as $i => $subpage) {
+ $subpages[$i]->module_settings = json_decode($subpage->module_settings);
}
$this->subpagesInit = true;
+ $this->foundSubpages = $subpages;
}
- return $this->subpages;
+ return $this->foundSubpages;
}
/**
@@ -162,7 +172,6 @@ class Content extends Model
public function rootPages()
{
$rootPages = $this->getPageQuery()
- ->where('language', LaravelLocalization::getCurrentLocale())
->where('parent_id', null);
if ($this->id) {
@@ -179,6 +188,7 @@ class Content extends Model
* @param bool $handler
* @param bool $status
* @param bool $joinAuthor
+ * @param bool $joinParent
*
* @return
*/
@@ -186,9 +196,10 @@ class Content extends Model
{
$query = DB::table('contents')
->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')
+ ->whereNull('contents.deleted_at')
+ ->where('contents.language', LaravelLocalization::getCurrentLocale())
+ ->where('modules.enabled', 1)
->orderBy('created_at', 'DESC');
// filter results using handler
@@ -293,10 +304,10 @@ class Content extends Model
public function uploadTitlePhoto(Request $request)
{
if ($request->hasFile('titlePhoto')) {
- $file = $this->file->upload($request->file('titlePhoto'), $request);
-
- $this->title_photo = $file['filename'];
+ return $this->file->upload($request->file('titlePhoto'), $request);
}
+
+ return null;
}
/**
@@ -435,4 +446,12 @@ class Content extends Model
// save history
ContentHistory::create($history);
}
+
+ public function view()
+ {
+ $this->timestamps = false;
+ $this->viewed++;
+ $this->save();
+ $this->timestamps = true;
+ }
}
diff --git a/app/Models/File.php b/app/Models/File.php
index 1c7c39a0..6c171459 100644
--- a/app/Models/File.php
+++ b/app/Models/File.php
@@ -4,9 +4,13 @@ namespace App\Models;
use App\Events\UploadFile;
use App\Http\Requests\Request;
+use Franzose\ClosureTable\Extensions\Str;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
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\UploadedFile;
@@ -63,6 +67,12 @@ class File extends Model
// save file into physical location (local FS)
$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
$id = $this->saveIntoDatabase($uploadedFile, $request, $file->getClientOriginalName());
@@ -118,4 +128,29 @@ class File extends Model
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);
+ }
}
\ No newline at end of file
diff --git a/app/Models/Module.php b/app/Models/Module.php
index d782c2d9..bcf9d696 100644
--- a/app/Models/Module.php
+++ b/app/Models/Module.php
@@ -2,6 +2,7 @@
namespace App\Models;
+use App\Handlers\Contracts\TemplateHandler;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\App;
@@ -20,7 +21,8 @@ class Module extends Model
'module_settings',
'enabled',
'support_categories',
- 'manages_content'
+ 'manages_content',
+ 'is_template'
];
protected $guarded = [];
@@ -45,6 +47,7 @@ class Module extends Model
}
$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;
if ($parentModuleId) {
@@ -62,8 +65,9 @@ class Module extends Model
'support_categories' => $supportCategories,
'alias' => $alias,
'module_settings' => json_encode($settings),
- 'parent_id' => $parentModuleId,
- 'enabled' => 1
+ 'parent_id' => $parentModuleId ? $parentModuleId : null,
+ 'enabled' => 1,
+ 'is_template' => $isTemplate
]);
// install something module-specific
@@ -73,4 +77,52 @@ class Module extends Model
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);
+ }
+ }
}
\ No newline at end of file
diff --git a/app/Models/User.php b/app/Models/User.php
index ef114c18..be576578 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -6,6 +6,7 @@ use App\Helpers\Gravatar;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticableInterface;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\Access\Authorizable;
/**
@@ -13,8 +14,8 @@ use Illuminate\Foundation\Auth\Access\Authorizable;
*/
class User extends Model implements AuthenticableInterface
{
- use Authenticatable, Authorizable;
- public $timestamps = false;
+ use SoftDeletes, Authenticatable, Authorizable;
+ public $timestamps = true;
protected $fillable = [
'email',
'username',
diff --git a/app/Models/Widget.php b/app/Models/Widget.php
index 5ed96c28..dc0d14bf 100644
--- a/app/Models/Widget.php
+++ b/app/Models/Widget.php
@@ -17,7 +17,9 @@ class Widget extends Model
'user_id',
'name',
'settings',
- 'description'
+ 'language',
+ 'description',
+ 'deletable'
];
protected $guarded = [];
@@ -31,7 +33,6 @@ class Widget extends Model
*/
public function createNew(WidgetType $widgetType, $data)
{
-
// convert array or whatever into object
if (!is_object($data)) {
$data = (object)$data;
diff --git a/app/Models/WidgetArea.php b/app/Models/WidgetArea.php
index 009e5f32..1eaf2592 100644
--- a/app/Models/WidgetArea.php
+++ b/app/Models/WidgetArea.php
@@ -15,7 +15,8 @@ class WidgetArea extends Model
protected $fillable = [
'name',
'code',
- 'description'
+ 'description',
+ 'deletable'
];
protected $guarded = [];
diff --git a/app/Models/WidgetType.php b/app/Models/WidgetType.php
index 07330dc1..caa38892 100644
--- a/app/Models/WidgetType.php
+++ b/app/Models/WidgetType.php
@@ -15,6 +15,8 @@ class WidgetType extends Model
protected $fillable = [
'handler',
'name',
+ 'template_id',
+ 'module_id',
'description'
];
diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php
index fe7104a6..cb1c8fec 100644
--- a/app/Providers/AppServiceProvider.php
+++ b/app/Providers/AppServiceProvider.php
@@ -16,6 +16,7 @@ use App\Widgets\HtmlCode\HtmlCode;
use App\Widgets\Menu\Menu;
use App\Widgets\OrbitSlider\OrbitSlider;
use Illuminate\Support\Facades\App;
+use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\File;
use Illuminate\Support\ServiceProvider;
use Symfony\Component\Process\Exception\InvalidArgumentException;
@@ -30,22 +31,12 @@ class AppServiceProvider extends ServiceProvider
{
// ignore running from artisan
if (App::runningInConsole()) {
- $this->publishViewResources();
-
return;
}
$this->registerWidgets();
- $this->registerTemplates();
$this->registerSettings();
$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(Menu::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);
}
- /**
- * 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');
- }
- }
}
diff --git a/app/Providers/GlobalViewDataProvider.php b/app/Providers/GlobalViewDataProvider.php
index c0c92845..58c943fb 100644
--- a/app/Providers/GlobalViewDataProvider.php
+++ b/app/Providers/GlobalViewDataProvider.php
@@ -21,11 +21,7 @@ class GlobalViewDataProvider extends ServiceProvider
return;
}
- $settings = new Settings();
-
- foreach ($settings->getForView() as $key => $value) {
- view()->share($key, $value);
- }
+ view()->share('currentUrl', \Request::url());
$this->extendBlade();
}
@@ -65,7 +61,7 @@ class GlobalViewDataProvider extends ServiceProvider
return preg_replace($pattern, $code, $view);
});
- // shortcut for loading uploaded images
+ // shortcut for loading uploaded files
Blade::extend(function ($view) {
$pattern = $this->createPattern('upload');
$code = '';
@@ -73,6 +69,22 @@ class GlobalViewDataProvider extends ServiceProvider
return preg_replace($pattern, $code, $view);
});
+ // shortcut for loading thumbnails of uploaded images
+ Blade::extend(function ($view) {
+ $pattern = $this->createPattern('thumbnail');
+ $code = '';
+
+ return preg_replace($pattern, $code, $view);
+ });
+
+ // shortcut for displaying Gravatar
+ Blade::extend(function ($view) {
+ $pattern = $this->createPattern('gravatar');
+ $code = '';
+
+ return preg_replace($pattern, $code, $view);
+ });
+
// shortcut for assets (placed in /public/assets/
+
+ {{$comment->author->name}} ({{$comment->author->email}})
+
++ {{$comment->content}} +
+