Merge branch 'dev' into widget_menu

This commit is contained in:
Michal Kváček
2016-04-01 21:57:44 +02:00
147 changed files with 5792 additions and 158 deletions
@@ -0,0 +1,51 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class InitDatabaseSchema extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'db:init {schema.sql}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$schema = $this->argument('schema.sql');
if (!file_exists($schema)) throw new NotFoundHttpException('File '.$schema.' does not exist.');
DB::unprepared(file_get_contents($schema));
$this->line('Successfully imported');
}
}
+55
View File
@@ -0,0 +1,55 @@
<?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 . '!');
}
$env = file_get_contents(base_path('.env'));
$env = preg_replace('/THEME=(.+)/i', 'THEME=' . $theme, $env);
if (!Str::contains($env, 'THEME')) {
$env = sprintf("%s\nTHEME=%s\n", $env, $theme);
}
file_put_contents(base_path('.env'), $env);
$this->line('Theme successfully setup.');
}
}
+65
View File
@@ -0,0 +1,65 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class SetupDatabase extends Command
{
/**
* The name and signature of the console command.
* @var string
*/
protected $signature = 'db:setup {host} {user} {password} {database}';
/**
* The console command description.
* @var string
*/
protected $description = 'Setup database credentials';
/**
* Create a new command instance.
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
* @return mixed
*/
public function handle()
{
echo "zpracovavam";
$host = $this->argument('host');
$user = $this->argument('user');
$password = $this->argument('password');
$database = $this->argument('database');
// try to connect with this settings
// @todo add credentials verification
// if pass, proceed to creating .env file
$parameters = [
'DB_HOST' => $host,
'DB_USERNAME' => $user,
'DB_PASSWORD' => $password,
'DB_DATABASE' => $database
];
$envPath = base_path('.env');
$env = file_get_contents($envPath);
if (!file_exists($envPath))
$env = file_get_contents($envPath.'.example');
foreach ($parameters as $parameter => $value) {
$env = preg_replace('/'.$parameter.'=(.*)/i', $parameter.'='.$value, $env);
}
file_put_contents($envPath, $env);
}
}
+3
View File
@@ -17,6 +17,9 @@ class Kernel extends ConsoleKernel
Commands\ChangePassword::class,
Commands\InstallModule::class,
Commands\InstallAllModules::class,
// Commands\SetupDatabase::class,
Commands\InitDatabaseSchema::class,
Commands\SetTheme::class,
];
/**
+5 -5
View File
@@ -65,7 +65,7 @@ abstract class Handler implements AppHandler
// create instance of main menu
\Menu::create('mainMenu', function ($menu) {
$menu->route('admin.dashboard', trans('admin/mainMenu.dashboard'), [], 10, ['icon' => 'fa fa-dashboard']);
// $menu->route('admin.dashboard', trans('admin/mainMenu.dashboard'), [], 10, ['icon' => 'fa fa-dashboard']);
$menu->dropdown(trans('admin/mainMenu.userManagement'), function ($sub) {
$sub->route('users.new', trans('admin/mainMenu.newUser'), [], 10, ['icon' => 'fa fa-user-plus']);
$sub->route('users.detail', trans('admin/mainMenu.userDetail'), [], 20, ['icon' => 'fa fa-user']);
@@ -118,10 +118,10 @@ abstract class Handler implements AppHandler
}
}, 29, ['icon' => 'fa fa-folder-open']);
}
$menu->dropdown(trans('admin/mainMenu.customFields'), function ($sub) {
$sub->route('customfields.new', trans('admin/mainMenu.customFieldsNew'), [], 10, ['icon' => 'fa fa-code']);
$sub->route('customfields.overview', trans('admin/mainMenu.customFieldsOverview'), [], 50, ['icon' => 'fa fa-code-fork']);
}, 30, ['icon' => 'fa fa-code']);
// $menu->dropdown(trans('admin/mainMenu.customFields'), function ($sub) {
// $sub->route('customfields.new', trans('admin/mainMenu.customFieldsNew'), [], 10, ['icon' => 'fa fa-code']);
// $sub->route('customfields.overview', trans('admin/mainMenu.customFieldsOverview'), [], 50, ['icon' => 'fa fa-code-fork']);
// }, 30, ['icon' => 'fa fa-code']);
$menu->route('log.overview', trans('admin/mainMenu.actionLog'), [], 40, ['icon' => 'fa fa-history']);
$menu->route('settings.overview', trans('admin/mainMenu.settings'), [], 50, ['icon' => 'fa fa-gear']);
});
+2 -2
View File
@@ -39,8 +39,8 @@ class History implements HistoryHandler
break;
default:
return trans('admin/history.changedFromTo', [
'from' => $changeset->old_value,
'to' => $changeset->new_value
'from' => is_null($changeset->old_value) ? trans('admin/history.emptyValue') : $changeset->old_value,
'to' => is_null($changeset->new_value) ? trans('admin/history.emptyValue') : $changeset->new_value,
]);
break;
}
@@ -5,14 +5,20 @@ use App\Enumerations\Exceptions\EnumerationExistsException;
use App\Handlers\Contracts\SearchHandler;
use App\Handlers\Contracts\SearchPresenterHandler;
use App\Handlers\Registrators\Items\SearchEngine;
use Symfony\Component\Process\Exception\InvalidArgumentException;
class SearchEngineRegistrator
{
const ADMIN = 'admin';
const VISITOR = 'visitor';
protected $searchEngines;
function __construct($app)
{
$this->searchEngines = [];
$this->searchEngines = [
self::ADMIN => [],
self::VISITOR => []
];
}
/**
@@ -21,37 +27,46 @@ class SearchEngineRegistrator
* @param SearchHandler $search
* @param SearchPresenterHandler $presenter
*
* @param $type
*
* @throws EnumerationExistsException
*/
public function register(SearchHandler $search, SearchPresenterHandler $presenter)
public function register(SearchHandler $search, SearchPresenterHandler $presenter, $type)
{
$this->checkIfRegistered($search->getId());
$this->checkIfRegistered($type, $search->getId());
// register new extension
$this->searchEngines[$search->getId()] = [$search, $presenter];
$this->searchEngines[$type][$search->getId()] = [$search, $presenter];
}
/**
* Getter for all registered extensions
*
* @param $type
*
* @return array
*/
public function get()
public function get($type)
{
return $this->searchEngines;
if (!isset($this->searchEngines[$type])) {
throw new InvalidArgumentException('Invalid type ' . $type);
}
return $this->searchEngines[$type];
}
/**
* Checks if this section is not already defined
*
* @param $type
* @param $id
*
* @throws EnumerationExistsException
*/
private function checkIfRegistered($id)
private function checkIfRegistered($type, $id)
{
if (isset($this->searchEngines[$id])) {
throw new EnumerationExistsException('Already existing search engine ' . $id);
if (isset($this->searchEngines[$type][$id])) {
throw new EnumerationExistsException('Already existing search engine ' . $id . ' in ' . $type);
}
}
}
@@ -21,7 +21,6 @@ class TemplateRegistrator
protected $namespace;
/**
* @var string absolute path to currently registered directory
*
* This variable is set in register() method as $baseDirectory/$path
*/
protected $registeredPath;
@@ -78,7 +77,6 @@ class TemplateRegistrator
/**
* Registers new template path.
*
* This method registeres given path itself with all subdirectories
*
* @param string $path path relatively to root of the project
@@ -140,7 +138,13 @@ class TemplateRegistrator
{
// skip custom directories (contains updated templates only)
$dirName = basename($path);
if ($dirName == Template::EDITED_TEMPLATES_DIRECTORY) {
$ignoredDirectories = [
Template::EDITED_TEMPLATES_DIRECTORY,
Template::ASSETS_DIRECTORY,
Template::MODULES_DIRECTORY
];
if (in_array($dirName, $ignoredDirectories)) {
return;
}
@@ -156,7 +160,6 @@ class TemplateRegistrator
/**
* Registers all templates
*
* This method takes all templates in given directory and registers them into database. Templates registered in
* this way may be used for further manipulation.
*
@@ -259,7 +262,6 @@ class TemplateRegistrator
/**
* Get template name
*
* Converts path to template to corresponding name
*
* @param $template
@@ -38,9 +38,9 @@ class WidgetRegistrator
'name' => $widgetName,
'description' => $widgetDescription
]);
}
// install widget (if neccessary)
call_user_func($classname . '::install');
// install widget (if neccessary)
call_user_func($classname . '::install');
}
}
}
+4
View File
@@ -39,4 +39,8 @@ class Template
return $view;
}
public static function asset($path) {
return env('SITE_URL').'/assets/'.config('app.theme').'/'.$path;
}
}
@@ -4,14 +4,30 @@ namespace App\Http\Controllers\Admin;
use App\Enumerations\ActiveContentStatuses;
use App\Http\Requests\CreateNewContentRequest;
use App\Models\Content;
use App\Models\File;
use App\Models\Module;
use App\Models\Template;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class CreateNewContent extends Controller
{
/**
* @var File
*/
private $file;
/**
* @var Content
*/
private $content;
public function __construct(File $file, Content $content)
{
parent::__construct();
$this->file = $file;
$this->content = $content;
}
/**
* Display form for new content page
*
@@ -30,15 +46,15 @@ class CreateNewContent extends Controller
->get();
// create default content object
$page = new Content();
$page->status = Content::STATUS_DRAFT;
$this->content->status = Content::STATUS_DRAFT;
// render view
return view('admin.content.new', [
'contentStatuses' => $statuses,
'templates' => $templates,
'moduleId' => $moduleId,
'page' => $page,
'page' => $this->content,
'rootPages' => $this->content->rootPages(),
'moduleName' => trans($module->name),
'formSectionNames' => call_user_func([$module->handler, 'getExtendedFormSections']),
'formSections' => call_user_func([$module->handler, 'getExtendedFormInputsCreate']),
@@ -78,13 +94,22 @@ class CreateNewContent extends Controller
$page->template = $request->template;
$page->module_handler = $module->handler;
if ($request->parentPage) {
$page->parent_id = $request->parentPage;
}
// upload file - if provided
if ($request->hasFile('titlePhoto')) {
$file = $this->file->upload($request->file('titlePhoto'), $request);
$page->title_photo = $file['filename'];
}
// save module-specific stuff
call_user_func_array([$module->handler, 'createNew'], [&$page, $request]);
$page->save();
Event::fire(new \Modules\StaticPages\Events\CreateNewStaticPage($page));
return redirect()
->route('content.overview')
->with('success', trans('admin/contents.successfullyCreated'));
+4 -1
View File
@@ -9,6 +9,9 @@ use Illuminate\Support\Facades\Session;
class Dashboard extends Controller
{
public function getIndex(Request $request) {
return view('admin.dashboard');
return redirect()->route('content.overview');
// return view('admin.dashboard');
}
}
+54 -22
View File
@@ -4,16 +4,12 @@ namespace App\Http\Controllers\Admin;
use App\Enumerations\ContentStatuses;
use App\Enumerations\ModulesHandlerToId;
use App\Http\Requests\EditContentRequest;
use App\Http\Requests\Request;
use App\Models\Content;
use App\Models\ContentHistory;
use App\Models\File;
use App\Models\Template;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Str;
use Modules\StaticPages\Events\DeleteStaticPage;
use Modules\StaticPages\Events\EditStaticPage as EditStaticPageEvent;
use Modules\StaticPages\Events\MakeDraftFromStaticPage;
use Modules\StaticPages\Events\PublishStaticPage;
use Modules\StaticPages\Http\Requests\EditStaticPageRequest;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class EditContent extends Controller
@@ -22,10 +18,15 @@ class EditContent extends Controller
* @var ContentHistory
*/
private $history;
/**
* @var File
*/
private $file;
public function __construct(ContentHistory $history)
public function __construct(ContentHistory $history, File $file)
{
$this->history = $history;
$this->file = $file;
}
/**
@@ -41,11 +42,11 @@ class EditContent extends Controller
$statuses = ContentStatuses::getWithTranslations();
// try to find requested page
$page = Content::where('module_handler', config('staticpages.handler'))
->findOrFail($id);
$page = Content::findOrFail($id);
$page->module_settings = json_decode($page->module_settings);
$allModules = ModulesHandlerToId::getWithTranslations();
$moduleId = $allModules[config('staticpages.handler')];
$moduleId = $allModules[$page->module_handler];
$templates = Template::where('module_id', $moduleId)
->select(['template_name', 'name', 'description'])
->get();
@@ -56,9 +57,10 @@ class EditContent extends Controller
return view('admin.content.edit', [
'contentStatuses' => $statuses,
'page' => $page,
'rootPages' => $page->rootPages(),
'templates' => $templates,
'formSectionNames' => call_user_func([$page->module_handler, 'getExtendedFormSections']),
'formSections' => call_user_func([$page->module_handler, 'getExtendedFormInputsCreate']),
'formSections' => call_user_func([$page->module_handler, 'getExtendedFormInputsEdit']),
'historySize' => count($history['changesets'])
]);
}
@@ -84,6 +86,15 @@ class EditContent extends Controller
}
$request->url = Str::slug($request->url);
$request->parentPage = $request->parentPage ? $request->parentPage : null;
$request->titlePhotoFilename = $page->title_photo;
// upload file - if provided
if ($request->hasFile('titlePhoto')) {
$file = $this->file->upload($request->file('titlePhoto'), $request);
$request->titlePhotoFilename = $file['filename'];
}
// array of fields in database and fields from request
$fields = [
@@ -95,11 +106,14 @@ class EditContent extends Controller
'meta_keywords' => 'metaKeywords',
'meta_description' => 'metaDescription',
'content' => 'pageContent',
'status' => 'status'
'parent_id' => 'parentPage',
'status' => 'status',
'title_photo' => 'titlePhotoFilename'
];
// save new values with history
list($revision, $changedColumns) = $page->updateWithHistory($fields, $request->all());
$data = self::getFields($request, $fields);
list($revision, $changedColumns) = $page->updateWithHistory($fields, $data);
$changedColumns += call_user_func_array([$page->module_handler, 'edit'], [&$page, $request, $revision]);
@@ -111,7 +125,7 @@ class EditContent extends Controller
}
// fire event with
Event::fire(new EditStaticPageEvent($page, $revision));
// Event::fire(new EditStaticPageEvent($page, $revision));
// something was changed, inform user
return redirect()
@@ -121,7 +135,6 @@ class EditContent extends Controller
/**
* Method for changing page status
*
* This method is called in static page overview from quick actions. It checks if status is valid, if page exists
* and updates status.
*
@@ -164,11 +177,11 @@ class EditContent extends Controller
}
// fire events
if ($status != Content::STATUS_DRAFT) {
Event::fire(new PublishStaticPage($page, $revision));
} else {
Event::fire(new MakeDraftFromStaticPage($page, $revision));
}
// if ($status != Content::STATUS_DRAFT) {
// Event::fire(new PublishStaticPage($page, $revision));
// } else {
// Event::fire(new MakeDraftFromStaticPage($page, $revision));
// }
// redirect back to overview with info for user
return redirect()
@@ -205,7 +218,7 @@ class EditContent extends Controller
}
// trigger delete event
Event::fire(new DeleteStaticPage($page, $revision));
// Event::fire(new DeleteStaticPage($page, $revision));
// redirect back to overview with info for user
return redirect()
@@ -253,7 +266,7 @@ class EditContent extends Controller
}
// trigger delete event
// Event::fire(new DeleteStaticPage($page, $revision));
// Event::fire(new DeleteStaticPage($page, $revision));
// redirect back to overview with info for user
return redirect()
@@ -263,4 +276,23 @@ class EditContent extends Controller
'url' => $page->url
]));
}
/**
* Convert object of all request data into array of only wanted fields
*
* @param Request $request
* @param $fields
*
* @return array
*/
public static function getFields(Request $request, $fields)
{
$requestData = [];
foreach ($fields as $field) {
$requestData[$field] = $request->$field;
}
return $requestData;
}
}
@@ -55,6 +55,7 @@ class EditUploadedFile extends Controller
}
// set values from form
$file->name = $request->name;
$file->keywords = $request->keywords;
$file->description = $request->description;
$file->save();
@@ -12,12 +12,6 @@ class EditWidget extends Controller
{
$widget = Widget::findOrFail($id);
// decompose widget settings
$settings = json_decode($widget->settings);
$widget->containerClass = $settings->containerClass;
$widget->code = $settings->code;
$presenter = call_user_func([$widget->widget_type_handler, 'getPresenter']);
return call_user_func([$presenter, 'renderEditForm'], $widget);
+2 -1
View File
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Admin;
use App\Handlers\Contracts\SearchHandler;
use App\Handlers\Contracts\SearchPresenterHandler;
use App\Handlers\Registrators\SearchEngineRegistrator;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use Illuminate\Support\Facades\App;
@@ -48,7 +49,7 @@ class Search extends Controller
protected function performSearch($term)
{
$engines = App::make('registerSearchEngine')
->get();
->get(SearchEngineRegistrator::ADMIN);
$resultsParts = [];
foreach ($engines as $engine) {
+16 -7
View File
@@ -43,18 +43,27 @@ class Settings extends Controller
$settings = $this->settings->getAll();
$updated = 0;
foreach($data as $key => $value) {
if ($settings->$key != $value) {
$updated ++;
\App\Models\Settings::where('key', $key)->update(['value' => $value]);
foreach ($data as $key => $value) {
if (isset($settings->$key)) {
if ($settings->$key != $value) {
$updated++;
\App\Models\Settings::where('key', $key)
->update(['value' => $value]);
}
} else {
\App\Models\Settings::create(['key' => $key, 'value' => $value]);
$updated++;
}
}
if ($updated > 0) {
return redirect()->route('settings.overview')->with('success', trans('admin/settings.successfullySaved'));
return redirect()
->route('settings.overview')
->with('success', trans('admin/settings.successfullySaved'));
} else {
return redirect()->route('settings.overview')->with('error', trans('admin/settings.nothingToSave'));
return redirect()
->route('settings.overview')
->with('error', trans('admin/settings.nothingToSave'));
}
}
}
@@ -12,14 +12,15 @@ class CreateNewContentRequest extends Request
public function rules()
{
return [
'title' => 'required',
'url' => 'required|unique:contents,url',
'template' => 'required|exists:templates,template_name',
'published_from' => 'date',
'published_to' => 'date',
'title_photo' => 'exists:files,id',
'module_settings' => 'json',
'status' => 'required|in:draft,protected,public'
'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',
'published_from' => 'date',
'published_to' => 'date',
];
}
}
+2 -1
View File
@@ -24,7 +24,8 @@ class EditContentRequest extends Request
'published_from' => 'date',
'published_to' => 'date',
'title_photo' => 'exists:files,id',
'status' => 'required|in:' . $statuses
'status' => 'required|in:' . $statuses,
'parentPage' => 'exists:contents,id'
];
}
}
+64 -8
View File
@@ -14,10 +14,13 @@ class Content extends Model
public $timestamps = true;
protected $fillable = [
'user_id',
'parent_id',
'module_handler',
'published_from',
'published_to',
'title_photo',
'template',
'is_homepage',
'title',
'url',
'meta_keywords',
@@ -43,7 +46,6 @@ class Content extends Model
/**
* Getter for homepage content page
*
* @return Content
*/
public function getHomepage()
@@ -68,8 +70,36 @@ class Content extends Model
}
/**
* Getter for overview of all content pages.
* Get list of all subpages
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function subpages()
{
return $this->getPageQuery()
->where('parent_id', $this->id)
->get();
}
/**
* Returns list of all root pages - those pages, which parent_id is null
*
* @return mixed
*/
public function rootPages()
{
$rootPages = $this->getPageQuery()
->where('parent_id', null);
if ($this->id) {
$rootPages = $rootPages->where('id', '!=', $this->id);
}
return $rootPages->get();
}
/**
* Getter for overview of all content pages.
* These content pages may be filtered by using some handler
*
* @param bool $handler
@@ -125,14 +155,31 @@ class Content extends Model
foreach ($fields as $fieldDB => $fieldRequest) {
// ignore non-existing fields
if (!isset($this->$fieldDB) || !isset($request[$fieldRequest])) {
if (!isset($request[$fieldRequest]) && !is_null($request[$fieldRequest])) {
continue;
}
// remove any whitespaces around real content
$request[$fieldRequest] = trim($request[$fieldRequest]);
// if module settings is still JSON, decode it to normal stdClass
if (is_string($this->module_settings)) {
$this->module_settings = json_decode($this->module_settings);
}
if ($this->$fieldDB != $request[$fieldRequest]) {
// are we editing common settings, or module-specific settings?
if (!in_array($fieldDB, $this->fillable)) {
// this field is not part of "core" content - probably it will be module settings
$commonField = false;
$fieldValue = $this->module_settings->$fieldDB;
} else {
$commonField = true;
$fieldValue = $this->$fieldDB;
}
// remove any whitespaces around real content
if (!is_null($request[$fieldRequest])) {
$request[$fieldRequest] = trim($request[$fieldRequest]);
}
if (trim($fieldValue) != $request[$fieldRequest]) {
// setup history object
$history = [
@@ -140,7 +187,7 @@ class Content extends Model
'content_id' => $this->id,
'edit_batch' => $revisionId,
'column' => $fieldRequest,
'old_value' => $this->$fieldDB,
'old_value' => $fieldValue,
'new_value' => $request[$fieldRequest]
];
@@ -148,12 +195,21 @@ class Content extends Model
ContentHistory::create($history);
// save change into database
$this->$fieldDB = $request[$fieldRequest];
if ($commonField) {
$this->$fieldDB = $request[$fieldRequest];
} else {
$this->module_settings->$fieldDB = $request[$fieldRequest];
}
$changed++;
}
}
// make JSON from stdClass
if (!is_string($this->module_settings)) {
$this->module_settings = json_encode($this->module_settings);
}
$this->save();
return [$revisionId, $changed];
+13 -11
View File
@@ -3,7 +3,7 @@
namespace App\Models;
use App\Events\UploadFile;
use App\Http\Requests\UploadRequest;
use App\Http\Requests\Request;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event;
@@ -49,13 +49,13 @@ class File extends Model
/**
* Saves file into FS and creates new record in database
*
* @param UploadedFile $file
* @param UploadRequest $request
* @param UploadedFile $file
* @param Request $request
*
* @return array associative array - key 'file' is type of SymphonyFile and contains info about real file, key 'id'
* is ID of row in files table
*/
public function upload(UploadedFile $file, UploadRequest $request)
public function upload(UploadedFile $file, Request $request)
{
$destination = config('app.upload_path');
$filename = $this->getFilename($file);
@@ -70,8 +70,9 @@ class File extends Model
Event::fire(new UploadFile($uploadedFile, $id));
return [
'file' => $file,
'id' => $id
'filename' => $filename,
'file' => $file,
'id' => $id
];
}
@@ -81,12 +82,12 @@ class File extends Model
* This file saves new record into database. It also calculates hash of given file, obtains MIME type etc.
*
* @param SymphonyFile $file
* @param UploadRequest $request
* @param Request $request
* @param $originalFilename
*
* @return mixed
*/
protected function saveIntoDatabase(SymphonyFile $file, UploadRequest $request, $originalFilename)
protected function saveIntoDatabase(SymphonyFile $file, Request $request, $originalFilename)
{
// get path and hash of uploaded file
$path = config('app.upload_path') . DIRECTORY_SEPARATOR . $file->getFilename();
@@ -101,13 +102,14 @@ class File extends Model
$newFile->hash_algorithm = self::HASH_ALGORITHM;
$newFile->mime_type = $file->getMimeType();
$newFile->file_size = $file->getSize();
$newFile->directory_id = $request->directoryId;
// save optional fields
$optionalFields = ['description', 'keywords'];
$optionalFields = ['name', 'description', 'keywords', 'directoryId'];
foreach ($optionalFields as $field) {
if ($request->has($field)) {
$newFile->$field = $request->$field;
$snakeField = snake_case($field);
$newFile->$snakeField = $request->$field;
}
}
+3
View File
@@ -21,6 +21,9 @@ class Template extends Model
protected $guarded = [];
protected $pathModel = null;
const EDITED_TEMPLATES_DIRECTORY = 'custom';
const ASSETS_DIRECTORY = 'assets';
const MODULES_DIRECTORY = 'modules';
const TEMPLATE_SUFFIX = '.blade.php';
const CUSTOM_EDIT_DIRECTORY = 1;
const ORIGINAL_DIRECTORY = 2;
+55 -4
View File
@@ -11,20 +11,30 @@ use App\Handlers\Search\Content;
use App\Handlers\Search\Files;
use App\Handlers\Search\Presenters\AdminContent as AdminContentPresenter;
use App\Handlers\Search\Presenters\AdminFiles;
use App\Models\Template;
use App\Widgets\HtmlCode\HtmlCode;
use App\Widgets\Menu\Extensions\URL;
use App\Widgets\Menu\Menu;
use App\Widgets\OrbitSlider\OrbitSlider;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\File;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// ignore running from artisan
if (App::runningInConsole()) {
$this->publishViewResources();
return;
}
$this->registerWidgets();
$this->registerTemplates();
$this->registerSettings();
@@ -33,7 +43,6 @@ class AppServiceProvider extends ServiceProvider
/**
* Register any application services.
*
* @return void
*/
public function register()
@@ -87,6 +96,7 @@ class AppServiceProvider extends ServiceProvider
// register some menu extensions
$menuExtensions = $this->app->make('registerMenuExtension');
$menuExtensions->register(new URL());
$registrator->register(OrbitSlider::class);
}
/**
@@ -121,7 +131,48 @@ class AppServiceProvider extends ServiceProvider
{
$registrator = $this->app->make('registerSearchEngine');
$registrator->register(new Content(), new AdminContentPresenter());
$registrator->register(new Files(), new AdminFiles());
$registrator->register(new Content(), new AdminContentPresenter(), SearchEngineRegistrator::ADMIN);
$registrator->register(new Files(), new AdminFiles(), SearchEngineRegistrator::ADMIN);
}
/**
* Publish all public assets from all themes
*/
private function publishViewResources()
{
$themes = File::directories(resource_path('views/visitor'));
$assets = [];
foreach ($themes as $theme) {
$themeName = basename($theme);
if (is_dir($theme . '/'.Template::ASSETS_DIRECTORY)) {
$assets[$theme . '/'.Template::ASSETS_DIRECTORY] = public_path('assets/' . $themeName);
}
if (is_dir($theme . '/'.Template::MODULES_DIRECTORY)) {
$this->publishModuleViews($theme . '/'.Template::MODULES_DIRECTORY, $themeName);
}
}
if (!empty($assets)) {
$this->publishes($assets, 'public-assets');
}
}
private function publishModuleViews($themeModules, $themeName)
{
$modules = File::directories($themeModules);
$moduleViews = [];
foreach ($modules as $module) {
$moduleName = strtolower(basename($module));
$moduleViews[$module] = resource_path('views/modules/' . $moduleName . '/visitor/' . $themeName);
}
if (!empty($moduleViews)) {
$this->publishes($moduleViews, 'module-views');
}
}
}
+14 -1
View File
@@ -3,6 +3,7 @@
namespace App\Providers;
use App\Models\Settings;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
@@ -15,6 +16,11 @@ class GlobalViewDataProvider extends ServiceProvider
*/
public function boot()
{
// ignore running from artisan
if (App::runningInConsole()) {
return;
}
$settings = new Settings();
foreach ($settings->getForView() as $key => $value) {
@@ -33,7 +39,7 @@ class GlobalViewDataProvider extends ServiceProvider
*/
private function createPattern($function)
{
return '/(?<!\w)(\s*)@' . $function . '\(\s*(.*)\)/';
return '/(?<!\w)(\s*)@' . $function.'\(([^)]+)*\)/';
}
/**
@@ -59,6 +65,13 @@ class GlobalViewDataProvider extends ServiceProvider
return preg_replace($pattern, $code, $view);
});
Blade::extend(function ($view) {
$pattern = $this->createPattern('asset');
$code = '<?php echo \App\Helpers\Template::asset($2); ?>';
return preg_replace($pattern, $code, $view);
});
// register extension for rendering widget areas
Blade::extend(function ($view) {
$pattern = $this->createPattern('widgetArea');
+7 -4
View File
@@ -3,17 +3,22 @@
namespace App\Providers;
use App\Models\Module;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
class ModuleManager extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
// ignore running from artisan
if (App::runningInConsole()) {
return;
}
// this service provider needs published config - config is merged right after this service provider
$modules = Module::get();
@@ -25,7 +30,6 @@ class ModuleManager extends ServiceProvider
/**
* Register the application services.
*
* @return void
*/
public function register()
@@ -34,7 +38,6 @@ class ModuleManager extends ServiceProvider
/**
* Read config file and merge it with module config in database.
*
* This method REQUIRES published config of given module (otherwise config(modulename) is not available)!
*
* @param Module $module
@@ -53,7 +56,7 @@ class ModuleManager extends ServiceProvider
$path = config('modules.paths.modules') . DIRECTORY_SEPARATOR . $config->staticName . DIRECTORY_SEPARATOR . 'module.json';
// check if module config is writable
if (!is_writable($path)) {
if (!is_writable(dirname($path))) {
return;
}
@@ -0,0 +1,14 @@
<?php
namespace App\Widgets\Exceptions;
use Exception;
class WidgetExistsException extends \Exception
{
public function __construct($message = "", $code = 0, Exception $previous = null)
{
$message = trans('admin/widgets.widgetExists', ['id' => $message]);
parent::__construct($message, $code, $previous);
}
}
+2 -1
View File
@@ -47,6 +47,7 @@ class HtmlCode implements WidgetRenderer
*/
public static function renderEditForm(Widget $widget)
{
return view('admin.widgets.htmlCode.edit', ['widget' => $widget]);
$settings = json_decode($widget->settings);
return view('admin.widgets.htmlCode.edit', ['widget' => $widget, 'settings' => $settings]);
}
}
+129
View File
@@ -0,0 +1,129 @@
<?php
namespace App\Widgets\OrbitSlider;
use App\Http\Requests\Request;
use App\Models\Directory;
use App\Models\Widget;
use App\Widgets\Contracts\PublicWidget;
use App\Widgets\Contracts\WidgetRenderer;
use App\Widgets\Exceptions\WidgetExistsException;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class OrbitSlider implements PublicWidget
{
const DIRECTORY_NAME = 'orbit-slider-data';
const CONFIG_FILENAME = 'orbit-slider-directory-id';
/**
* Name getter
*
* @return string
*/
public static function getName()
{
return 'widgets/orbitSlider.widgetName';
}
/**
* Getter for description
*
* @return string
*/
public static function getDescription()
{
return 'widgets/orbitSlider.widgetDescription';
}
/**
* @param Widget $widget
* @param Request $request
*
* @throws WidgetExistsException
*
* @return Widget
*/
public static function save(Widget $widget, Request $request)
{
$settings = json_decode($widget->settings);
$parentDirectoryId = Storage::get(self::CONFIG_FILENAME);
$directoryId = isset($settings->directoryId) ? $settings->directoryId : null;
$edit = false;
// check if directory does not exists
$exists = Directory::where('name', $request->name)
->where('parent_id', $parentDirectoryId);
if ($directoryId) {
$edit = true;
$exists = $exists->where('id', '!=', $directoryId);
}
$exists = $exists->exists();
if ($exists) {
throw new WidgetExistsException($request->name);
}
$directory = new Directory;
if ($edit) {
$directory = Directory::find($directoryId);
}
// setup some information about directory
$directory->user_id = Auth::user()->id;
$directory->parent_id = $parentDirectoryId;
$directory->name = $request->name;
$directory->description = $request->description;
$directory->save();
$settings = [
'directoryId' => $directory->id,
'sliderClass' => isset($request->containerClass) ? $request->containerClass : '',
'code' => $request->code
];
$widget->settings = json_encode($settings);
return $widget;
}
/**
* Getter for presenter/renderer of this widget
*
* @return WidgetRenderer
*/
public static function getPresenter()
{
return Presenters\OrbitSlider::class;
}
/**
* Function for installing given widget
*
* @return mixed
*/
public static function install()
{
$directory = Directory::where('name', self::DIRECTORY_NAME)
->first();
if (!count($directory)) {
$directory = Directory::create([
'name' => self::DIRECTORY_NAME,
'hidden' => true
]);
}
Storage::put(self::CONFIG_FILENAME, $directory->id);
}
/**
* Function for uninstalling widget
*/
public static function uninstall()
{
// TODO: Implement uninstall() method.
}
}
@@ -0,0 +1,56 @@
<?php
namespace App\Widgets\OrbitSlider\Presenters;
use App\Models\File;
use App\Models\Widget;
use App\Models\WidgetType;
use App\Widgets\Contracts\WidgetRenderer;
class OrbitSlider implements WidgetRenderer
{
/**
* Method used for displaying widget.
*
* This method renders some HTML code for displaying.
*
* @param object $settings
*
* @return mixed
*/
public static function render($settings)
{
$directoryId = $settings->directoryId;
$images = File::where('directory_id', $directoryId)
->where('mime_type', 'LIKE', 'image%')
->get();
return view('widgets.orbitSlider.element', ['images' => $images, 'settings' => $settings]);
}
/**
* Display form for creating new instance of widget
*
* @param WidgetType $type
*
* @return mixed
*/
public static function renderAddForm(WidgetType $type)
{
return view('admin.widgets.orbitSlider.new', ['type' => $type]);
}
/**
* Display form for editing already existing widget
*
* @param Widget $widget
*
* @return mixed
*/
public static function renderEditForm(Widget $widget)
{
$settings = json_decode($widget->settings);
return view('admin.widgets.orbitSlider.edit', ['widget' => $widget, 'settings' => $settings]);
}
}