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
+11 -14
View File
@@ -1,23 +1,20 @@
APP_ENV=local
APP_ENV=testing
APP_DEBUG=true
APP_KEY=SomeRandomString
APP_KEY=
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
REDIS_HOST=localhost
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_USERNAME=@binarity.cz
MAIL_PASSWORD=
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
SITE_URL=/
UPLOAD_URL=/public/uploads
THUMBNAILS_URL=/uploads/thumbnails
THEME=
+3
View File
@@ -2,6 +2,7 @@
/resources/views/modules
/public/modules
/resources/views/vendor
/public/assets
# directories with custom templates
**/views/**/custom/*
@@ -23,3 +24,5 @@
# PhpStorm project directory
/.idea
# meta information created by installer
.install
@@ -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]);
}
}
+1 -1
View File
@@ -97,7 +97,7 @@ return [
*/
'upload_url' => env('UPLOAD_URL', PHP_SAPI === 'cli' ? '' : url('uploads')),
'thumbnail_url' => env('THUMBNAIL_URL', PHP_SAPI === 'cli' ? '' : url('uploads/thumbnails')),
'theme' => 'default_theme',
'theme' => env('THEME', 'default_theme'),
/*
|--------------------------------------------------------------------------
| Logging Configuration
+2 -2
View File
@@ -28,7 +28,7 @@ return [
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'host' => env('MAIL_HOST', 'mail.binarity.cz'),
/*
|--------------------------------------------------------------------------
@@ -41,7 +41,7 @@ return [
|
*/
'port' => env('MAIL_PORT', 587),
'port' => env('MAIL_PORT', 25),
/*
|--------------------------------------------------------------------------
@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddSubpages extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::table('contents', function (Blueprint $table) {
$table->integer('parent_id')
->after('id')
->nullable()
->default(null)
->index()
->comment('ID of parent page');
$table->foreign('parent_id')
->references('id')
->on('contents')
->onDelete('cascade')
->onUpdate('cascade');
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::table('contents', function (Blueprint $table) {
$table->dropForeign('contents_parent_id_foreign');
$table->dropColumn('parent_id');
});
}
}
@@ -0,0 +1,86 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class ChangeContentTitleImageIdForFilename extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
try {
Schema::table('contents', function (Blueprint $table) {
$table->dropForeign('fk_content_file1');
});
} catch (\Illuminate\Database\QueryException $e) {
// probably foreign does not exist, try to remove one from migration
try {
Schema::table('contents', function (Blueprint $table) {
$table->dropForeign('contents_title_photo_foreign');
});
} catch (\Illuminate\Database\QueryException $ex) {
// ignore this error
}
}
// force Doctrine to consider enum type as string
$platform = Schema::getConnection()
->getDoctrineSchemaManager()
->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');
Schema::table('contents', function (Blueprint $table) {
$table->string('title_photo', 128)
->nullable()
->default(null)
->comment('This photo is supposed to be displayed e.g. on list of all pages.')
->change();
$table->foreign('title_photo')
->references('filename')
->on('files')
->onUpdate('cascade')
->onDelete('set null');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
// force Doctrine to consider enum type as string
$platform = Schema::getConnection()
->getDoctrineSchemaManager()
->getDatabasePlatform();
$platform->registerDoctrineTypeMapping('enum', 'string');
// delete all title photos
DB::statement('UPDATE contents SET title_photo = NULL');
Schema::table('contents', function (Blueprint $table) {
$table->dropForeign('contents_title_photo_foreign');
});
Schema::table('contents', function (Blueprint $table) {
$table->integer('title_photo', false)
->change();
});
Schema::table('contents', function (Blueprint $table) {
$table->foreign('title_photo')
->references('id')
->on('files');
});
}
}
@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class MakeUserIdNotMandatoryInDirectories extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('directories', function (Blueprint $table) {
$table->integer('user_id', false)
->nullable()
->default(null)
->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('directories', function (Blueprint $table) {
$table->integer('user_id', false)
->nullable(false)
->change();
});
}
}
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddNameForFiles extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('files', function (Blueprint $table) {
$table->string('name')
->after('file_size')
->comment('Some human readable name of file. May be used in different ways');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('files', function (Blueprint $table) {
$table->dropColumn('name');
});
}
}
+1 -1
View File
@@ -17,7 +17,7 @@ class SeedCustomFieldResources extends Seeder
];
foreach ($types as $type) {
\DB::table('custom_field_resources')
\DB::table('custom_field_resource')
->insert($type);
}
}
+223
View File
@@ -0,0 +1,223 @@
#/bin/bash
if [ "$1" == "devel" ]; then
INSTALL_DEVEL=1
else
INSTALL_DEVEL=0
fi
# dir with meta informatou about installation
INSTALL_METADATA_DIRECTORY=".install"
WEBSITE_DOMAIN_FILE=$INSTALL_METADATA_DIRECTORY"/.website_domain"
WEBSITE_PARENT_FILE=$INSTALL_METADATA_DIRECTORY"/.website_parent"
DB_INITIALIZED_FILE=$INSTALL_METADATA_DIRECTORY"/.db_initialized"
THEME_SET_FILE=$INSTALL_METADATA_DIRECTORY"/.theme_set"
ADMIN_CREATED_FILE=$INSTALL_METADATA_DIRECTORY"/.admin_created"
USER_INSTALLED_FILE=$INSTALL_METADATA_DIRECTORY"/.user"
INSTALL_DIR_EXISTS=0
while [ "$INSTALL_DIR" == "" ]; do
echo ""
echo "Install directory: "
read INSTALL_DIR
if [ -d $INSTALL_DIR ]; then
echo "Directory $INSTALL_DIR already exists."
cd $INSTALL_DIR
if [ -d ".git" ]; then
# try to continue in installation when directory exists
git remote -v |grep "minicms.git" > /dev/null
if [ $? -eq 0 ]; then
echo " ... continuing in installation"
INSTALL_DIR_EXISTS=1
else
echo " ... this directory does not contain installation of CMS! Use different directory."
INSTALL_DIR=""
fi
fi
cd - > /dev/null
fi
echo ""
done
# create installation directory for this instance of cms
if [ $INSTALL_DIR_EXISTS -eq 0 ]; then
mkdir -p $INSTALL_DIR
fi
cd $INSTALL_DIR
# setup website info
if [ ! -e $WEBSITE_DOMAIN_FILE ]; then
echo ""
echo "Website domain: "
read WEBSITE_DOMAIN
echo ""
else
WEBSITE_DOMAIN=`cat $WEBSITE_DOMAIN_FILE`
fi
if [ ! -e $WEBSITE_PARENT_FILE ]; then
echo ""
echo "Website parent (branch in minicms.git repository): "
read WEBSITE_PARENT
echo ""
else
WEBSITE_PARENT=`cat $WEBSITE_PARENT_FILE`
fi
# fetch data from server
if [ ! -n "$(ls -A)" ]; then
git clone git@binarity.cz:/opt/git/internal/cms/minicms.git -b $WEBSITE_PARENT .
if [ ! $? -eq 0 ]; then
echo ""
echo " -------------------------------------------"
echo "ERROR: cannot clone repository. Aborting"
echo ""
exit 2
fi
# ignore file permission changes
git config core.fileMode false
else
git branch |grep $WEBSITE_DOMAIN > /dev/null
if [ $? -eq 0 ]; then
echo "CMS already installed!"
exit 1
fi
fi
if [ ! -e $INSTALL_METADATA_DIRECTORY ]; then
mkdir $INSTALL_METADATA_DIRECTORY
fi
# save variables
echo $WEBSITE_DOMAIN > $WEBSITE_DOMAIN_FILE
echo $WEBSITE_PARENT > $WEBSITE_PARENT_FILE
# setup permissions
chmod 0777 bootstrap/cache -R
chmod 0777 storage -R
chmod 0777 resources/views/visitor/$TEMPLATE_NAME -R
chmod 0777 modules/*
chmod 0777 public/uploads -R
# copy settings if neccesarry
if [ ! -e .env ]; then
cp .env.example .env
# edit config
vim .env
fi
# create autoload files - no matter what
composer dump-autoload
# install dependencies - no matter what
if [ $INSTALL_DEVEL -eq 0 ]; then
composer install --no-dev
else
composer install
fi
# init database structure
if [ ! -e $DB_INITIALIZED_FILE ]; then
# init, migrate and seed database
php artisan db:init ./database/schema.sql &&
php artisan migrate &&
php artisan db:seed &&
touch $DB_INITIALIZED_FILE
if [ ! $? -eq 0 ]; then
echo ""
echo " ---------------------------------------------- "
echo "ERROR: Database was not initialized. Try to fix this error and then rerun installation."
echo ""
exit 3
fi
fi
# generate random key for ciphering
php artisan key:generate
if [ ! -e $THEME_SET_FILE ]; then
echo " --------------------------"
echo " * Theme setup * "
echo ""
while [ "$THEME_NAME" == "" ]; do
echo "Template name (use any of following): "
for i in $(ls -d resources/views/visitor/*/); do
basename `echo ${i%%/}`;
done
read THEME_NAME
if [ ! -d resources/views/visitor/$THEME_NAME ]; then
echo "Theme $THEME_NAME is not valid. Try again"
THEME_NAME=""
fi
done
# setup theme
php artisan theme:set $THEME_NAME
echo $THEME_NAME > $THEME_SET_FILE
fi
# publish assets and views
php artisan vendor:publish --tag=module-views
php artisan vendor:publish --tag=public-assets
if [ ! -e $ADMIN_CREATED_FILE ]; then
echo ""
echo " ------------------------------ "
echo " * CREATE ADMIN USER *"
echo ""
echo "New user email: "
read EMAIL
echo ""
echo "Password: "
read PASSWORD
echo ""
# install new user
php artisan user:new $EMAIL $PASSWORD admin
echo $EMAIL > $ADMIN_CREATED_FILE
fi
# create new branch in git
git checkout -b $WEBSITE_DOMAIN
git push origin $WEBSITE_DOMAIN
# save info about user, who installed this source copy
echo $USER > $USER_INSTALLED_FILE
echo ""
echo ""
echo ""
echo ""
echo ""
echo " INSTALLATION SUCCESSFULL."
echo ""
echo "Do not forget to install desired modules!"
echo " Use php artisan install-module <ModuleName> or php artisan install-all-modules"
View File
+12
View File
@@ -0,0 +1,12 @@
<?php
return [
'name' => 'ContactForm',
'translatedName' => 'contactform::module.name',
'translatedDescription' => 'contactform::module.description',
'alias' => 'contactform',
'handler' => '\\Modules\\ContactForm\\Handlers\\ContactForm',
'providers' => [\Modules\ContactForm\Providers\ContactFormServiceProvider::class],
'files' => ['start.php'],
'order' => 0,
];
@@ -0,0 +1,20 @@
<?php namespace Modules\Contactform\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class ContactFormDatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
// $this->call("OthersTableSeeder");
}
}
@@ -0,0 +1,172 @@
<?php
namespace Modules\ContactForm\Handlers;
use App\Enumerations\ModulesHandlerToId;
use App\Handlers\Handler;
use App\Http\Controllers\Admin\EditContent;
use App\Http\Controllers\Controller;
use App\Http\Requests\Request;
use App\Models\Content;
use App\Models\User;
class ContactForm extends Handler
{
/**
* 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)
{
$content->module_settings = json_decode($content->module_settings);
return Controller::VisitorsView($content->template, ['page' => $content]);
}
public static function getHistoryHandler()
{
return ContactFormHistory::class;
}
/**
* Save module-specific values into database
*
* @param Content $content
* @param Request $request
*
* @return mixed
* @internal param Widget $widget
*/
public static function createNew(Content &$content, Request $request)
{
$settings = [
'phone' => $request->phone,
'email' => $request->email,
'companyName' => $request->companyName,
'address' => $request->address,
'gpsLat' => $request->gpsLat,
'gpsLng' => $request->gpsLng,
];
// save settings
$content->module_settings = json_encode($settings);
}
/**
* Method used for editing existing content page.
*
* Reason why it is separated from createNew() method is simple - we need to save history of changes.
*
* @param Content $content
* @param Request $request
*
* @param $revisionID string ID of revision used
*
* @return int number of edited fields
*/
public static function edit(Content &$content, Request $request, $revisionID)
{
$fields = [
'phone' => 'phone',
'email' => 'email',
'companyName' => 'companyName',
'address' => 'address',
'gpsLat' => 'gpsLat',
'gpsLng' => 'gpsLng',
];
// get data and try to save them
$data = EditContent::getFields($request, $fields);
list($revision, $changedColumns) = $content->updateWithHistory($fields, $data, $revisionID);
// return amount of changed columns
return $changedColumns;
}
public static function getModuleId()
{
$handler = config('contactform.handler');
$allModules = ModulesHandlerToId::getWithTranslations();
$moduleId = isset($allModules[$handler]) ? $allModules[$handler] : null;
return $moduleId;
}
/**
* Getter for section names in creating/editing content resource
*
* @return mixed
*/
public static function getExtendedFormSections()
{
$sections = parent::getExtendedFormSections();
$sections['content'] = trans('contactform::admin/content.content');
return $sections;
}
/**
* Getter for views used in extended part of form for creating new content
*
* This method should return pairs <section, view-name>. View is returned only as name in plain text
*
* @return array of views/templates/html codes divided into section
*/
public static function getExtendedFormInputsCreate()
{
return [
'basicInfo' => 'contactform::admin.form.basicInfo',
'meta' => 'admin.content.formParts.metaInformation',
'appearance' => 'admin.content.formParts.appearance',
'publication' => 'admin.content.formParts.publicationSetup',
'content' => 'contactform::admin.form.content',
];
}
public static function getExtendedFormInputsEdit()
{
return self::getExtendedFormInputsCreate();
}
/**
* Register admin menu (or multiple ones)
*
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
* starting any middleware..
*
* @param User $user model of logged user
*/
public static function registerAdminMenu(User $user)
{
// register links in admin menu
$menu = \Menu::instance('mainMenu');
$menu->dropdown(trans('contactform::admin/adminMenu.contactForm'), function ($submenu) use ($user) {
$submenu->route('content.new', trans('contactform::admin/adminMenu.new'), ['moduleId' => self::getModuleId()], 10, ['icon' => 'fa fa-plus']);
$submenu->route('content.overview', trans('contactform::admin/adminMenu.overview'), ['moduleId' => self::getModuleId()], 20, ['icon' => 'fa fa-list']);
$submenu->route('emails.sent', trans('contactform::admin/adminMenu.sentMessages'), [], 30, ['icon' => 'fa fa-send']);
}, 25, ['icon' => 'fa fa-envelope-o']);
}
/**
* Does given module manage content? Or is it just module with widgets/something internal/something absolutely else?
*
* @return bool
*/
public static function managesContent()
{
return true;
}
/**
* Install module
*
* @return mixed
*/
public static function install()
{
// TODO: Implement install() method.
}
}
@@ -0,0 +1,28 @@
<?php
namespace Modules\ContactForm\Handlers;
use App\Handlers\History;
class ContactFormHistory extends History
{
/**
* Translate column name for history view
*
* @param $column
*
* @return mixed
*/
public static function parseColumnName($column)
{
// try to translate as contact form field
$translationString = 'contactform::admin/history.column' . ucfirst($column);
$translation = trans($translationString);
// when translation is not available, try to fallback into core fields
if ($translation == $translationString) {
return parent::parseColumnName($column);
}
return $translation;
}
}
@@ -0,0 +1,50 @@
<?php
namespace Modules\ContactForm\Http\Controllers\Visitor;
use App\Helpers\Template;
use App\Models\Content;
use Illuminate\Mail\Message;
use Illuminate\Support\Facades\Mail;
use Modules\ContactForm\Http\Requests\SendNewEmailRequest;
use Pingpong\Modules\Routing\Controller;
class CreateNewMessage extends Controller
{
/**
* Method for sending emails via contact form
*
* @param SendNewEmailRequest $request
* @param $formId
*
* @return mixed
*/
public function postMessage(SendNewEmailRequest $request, $formId)
{
// load form settings
$form = Content::where('module_handler', config('contactform.handler'))
->findOrFail($formId);
$form->module_settings = json_decode($form->module_settings);
// select template
$template = isset($form->module_settings->emailTemplate) ? $form->module_settings->emailTemplate : 'contactform::emails.default';
// send email
$status = Mail::send(Template::name($template), ['data' => $request], function (Message $message) use ($request, $form) {
$message->from($request->email, $request->name);
$message->to($form->module_settings->email)
->subject('Your Reminder!');
});
// inform user about success or failure
if ($status) {
return redirect()
->route('page.content', ['url' => $form->url])
->with('success', '');
} else {
return redirect()
->route('page.content', ['url' => $form->url])
->with('error', '');
}
}
}
@@ -0,0 +1,20 @@
<?php namespace Modules\ContactForm\Http\Requests;
use App\Http\Requests\Request;
class SendNewEmailRequest extends Request
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email',
'message' => 'required',
];
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
use App\Http\Requests\Request;
Route::group([
'middleware' => ['web', 'auth', 'adminMenu'],
'namespace' => '\Modules\ContactForm\Http\Controllers\Admin',
'prefix' => 'admin/contactform'
], function () {
Route::get('messsages/sent', 'SentMessagesOverview@getList')
->name('emails.sent');
});
Route::group([
'middleware' => ['web'],
'namespace' => '\Modules\ContactForm\Http\Controllers\Visitor',
'prefix' => 'contactform'
], function () {
// method for sending new message
Route::post('/message/{formId}', 'CreateNewMessage@postMessage')
->name('email.send');
});
@@ -0,0 +1,108 @@
<?php namespace Modules\ContactForm\Providers;
use App\Handlers\Registrators\TemplateRegistrator;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
use InvalidArgumentException;
class ContactFormServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Boot the application events.
*
* @return void
*/
public function boot()
{
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$registrator = $this->app->make('registerSettingsExtension');
$registrator->register('contactForm', 'contactform::module.name', 'contactform::admin.settings.form');
}
/**
* Register config.
*
* @return void
*/
protected function registerConfig()
{
$this->publishes([
__DIR__ . '/../Config/config.php' => config_path('contactform.php'),
]);
$this->mergeConfigFrom(__DIR__ . '/../Config/config.php', 'contactform');
}
/**
* Register views.
*
* @return void
*/
public function registerViews()
{
$viewPath = base_path('resources/views/modules/contactform');
$sourcePath = __DIR__ . '/../Resources/views';
$this->publishes([
$sourcePath => $viewPath
]);
$this->loadViewsFrom(array_merge(array_map(function ($path) {
return $path . '/modules/contactform';
}, \Config::get('view.paths')), [$sourcePath]), 'contactform');
/**
* @var $registrator TemplateRegistrator
*/
$registrator = $this->app->make('registerTemplateDir');
try {
// setup some global variables
$registrator->setBaseDirectory('resources/views/modules/contactform/visitor');
$registrator->setNamespace('contactform');
$registrator->setModuleId(call_user_func([config('contactform.handler'), 'getModuleId']));
// register path with current template name
$registrator->register(config('app.theme'), 'contactform::admin.templatePath');
} catch (InvalidArgumentException $e) {
// ignore this exception
}
}
/**
* Register translations.
*
* @return void
*/
public function registerTranslations()
{
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'contactform');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array ();
}
}
@@ -0,0 +1,7 @@
<?php
return [
'contactForm' => 'Contact form',
'new' => 'New',
'overview' => 'All contact forms',
'sentMessages' => 'Messages'
];
@@ -0,0 +1,12 @@
<?php
return [
'content' => 'Contact form content',
'address' => 'Address',
'emailList' => 'Send emails to these addresses',
'gpsLat' => 'GPS latitude',
'gpsLng' => 'GPS longitude',
'compName' => 'Name displayed above address',
'phone' => 'Contact phone',
'contactEmail' => 'E-mail, where messages from this form will be delivered',
'contactInformation' => 'Contact information'
];
@@ -0,0 +1,10 @@
<?php
return [
'columnPhone' => 'Phone',
'columnAddress' => 'Address',
'columnEmail' => 'E-mail',
'columnCompanyName' => 'Company name',
'columnGpsLat' => 'GPS Latitude',
'columnGpsLng' => 'Gps Longitude',
];
@@ -0,0 +1,5 @@
<?php
return [
'recaptchaSiteKey' => 'reCAPTCHA site key',
'recaptchaSecret' => 'reCAPTCHA application secret key',
];
@@ -0,0 +1,5 @@
<?php
return [
'name' => 'Contact form',
'description' => 'Simple contact form'
];
@@ -0,0 +1,113 @@
<div class="row">
<div class="columns large-6">
<label>
@lang('admin/contents.field_title')
<input type="text" name="title" placeholder="@lang('admin/contents.field_title')"
value="{{old('title', $page->title)}}" />
</label>
</div>
<div class="columns large-6">
<label>
@lang('admin/contents.field_url')
<input type="text" name="url" placeholder="@lang('admin/contents.field_url')"
value="{{old('url', $page->url)}}" />
@if (isset($errors) && $errors->has('url'))
<div class="callout alert">
{{ $errors->first('url') }}
</div>
@endif
</label>
</div>
</div>
<div class="row">
<div class="columns large-6">
<label>
<select name="status">
@foreach($contentStatuses as $status => $translation)
<option value="{{$status}}" @if(old('status', $page->status) == $status) selected @endif>
{{$translation}}
</option>
@endforeach
</select>
</label>
@if (isset($errors) && $errors->has('status'))
<div class="callout alert">
{{ $errors->first('status') }}
</div>
@endif
</div>
<div class="column large-6">
<label>
<select name="parentPage">
<option value="">@lang('admin/contents.noParentPage')</option>
@foreach($rootPages as $rootPage)
<option value="{{$rootPage->id}}"
@if(old('parent_page', $page->parent_id) == $rootPage->id) selected @endif>
{{$rootPage->title}}
</option>
@endforeach
</select>
</label>
@if (isset($errors) && $errors->has('parentPage'))
<div class="callout alert">
{{ $errors->first('parentPage') }}
</div>
@endif
</div>
</div>
<h2>@lang('contactform::admin/content.contactInformation')</h2>
<div class="row">
<div class="column large-6">
<label>
@lang('contactform::admin/content.phone')
<input type="tel" name="phone" value="{{$page->module_settings->phone or ""}}" />
</label>
</div>
<div class="column large-6">
<label>
@lang('contactform::admin/content.contactEmail')
<input type="email" name="email" value="{{$page->module_settings->email or \Auth::user()->email}}" />
</label>
</div>
</div>
<div class="row">
<div class="column large-6">
<label>
@lang('contactform::admin/content.compName')
<input type="text" name="companyName" value="{{$page->module_settings->companyName or ""}}" />
</label>
<label>
@lang('contactform::admin/content.address')
<textarea rows="3" name="address">{{$page->module_settings->address or ""}}</textarea>
</label>
</div>
<div class="column large-6">
<label>
@lang('contactform::admin/content.gpsLat')
<input type="text" value="{{$page->module_settings->gpsLat or ""}}" name="gpsLat" />
</label>
<label>
@lang('contactform::admin/content.gpsLng')
<input type="text" value="{{$page->module_settings->gpsLng or ""}}" name="gpsLng" />
</label>
</div>
</div>
@@ -0,0 +1,10 @@
<div class="row">
<div class="columns large-12">
<label>
<textarea name="pageContent" id="pageContent" class="wysiwyg-editor">
{{old('pageContent', $page->content)}}
</textarea>
</label>
</div>
</div>
@@ -0,0 +1,13 @@
<label>
@lang('contactform::admin/settings.recaptchaSiteKey')
<input type="text" name="recaptchaSiteKey" value="{{old('recaptchaSiteKey', isset($settings->recaptchaSiteKey) ? $settings->recaptchaSiteKey : null)}}" />
</label>
<label>
@lang('contactform::admin/settings.recaptchaSecret')
<input type="text" name="recaptchaSecret" value="{{old('recaptchaSecret', isset($settings->recaptchaSecret) ? $settings->recaptchaSecret : null)}}" />
</label>
<em><a href="https://www.google.com/recaptcha/admin#list" target="_blank">reCAPTCHA</a></em>
@@ -0,0 +1,4 @@
<p>
<strong>Ahoj {{$data->name}}</strong>
</p>
<p>Diky za zpravu: <em>{{$data->message}}</em></p>
View File
+15
View File
@@ -0,0 +1,15 @@
{
"name": "pingpong-modules/contactform",
"description": "",
"authors": [
{
"name": "Pingpong Labs",
"email": "pingpong.labs@gmail.com"
}
],
"autoload": {
"psr-4": {
"Modules\\ContactForm\\": ""
}
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
/*
|--------------------------------------------------------------------------
| Register Namespaces And Routes
|--------------------------------------------------------------------------
|
| When a module starting, this file will executed automatically. This helps
| to register some namespaces like translator or view. Also this file
| will load the routes file for each module. You may also modify
| this file as you want.
|
*/
require __DIR__ . '/Http/routes.php';
View File
View File
+12
View File
@@ -0,0 +1,12 @@
<?php
return [
'name' => 'Gallery',
'translatedName' => 'gallery::module.name',
'translatedDescription' => 'gallery::module.description',
'alias' => 'gallery',
'handler' => '\\Modules\\Gallery\\Handlers\\Gallery',
'providers' => [\Modules\Gallery\Providers\GalleryServiceProvider::class],
'files' => ['start.php'],
'order' => 0,
];
View File
@@ -0,0 +1,20 @@
<?php namespace Modules\Gallery\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class GalleryDatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Model::unguard();
// $this->call("OthersTableSeeder");
}
}
View File
+194
View File
@@ -0,0 +1,194 @@
<?php
namespace Modules\Gallery\Handlers;
use App\Enumerations\ModulesHandlerToId;
use App\Handlers\Contracts\AppHandler;
use App\Handlers\Handler;
use App\Handlers\History;
use App\Http\Controllers\Controller;
use App\Http\Requests\Request;
use App\Models\Content;
use App\Models\Directory;
use App\Models\File;
use App\Models\User;
use Illuminate\Support\Facades\Storage;
class Gallery implements AppHandler
{
const CONFIG_FILENAME = 'photogallery-config';
const DIRECTORY_NAME = 'photogallery-data';
/**
* 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)
{
// if settings is still string, convert it into object
if (is_string($content->module_settings)) {
$content->module_settings = json_decode($content->module_settings);
}
// get directory ID
$directoryId = $content->module_settings->directoryId;
// get all images in given directory
$images = File::where('directory_id', $directoryId)
->where('mime_type', 'LIKE', 'image%')
->get();
// render content
return Controller::VisitorsView($content->template, ['images' => $images, 'page' => $content]);
}
public static function getHistoryHandler()
{
return History::class;
}
/**
* Save module-specific values into database
*
* @param Content $content
* @param Request $request
*
* @return mixed
* @internal param Widget $widget
*/
public static function createNew(Content &$content, Request $request)
{
$parentDirectoryId = Storage::get(self::CONFIG_FILENAME);
// create new directory for images
$directory = Directory::create([
'name' => $request->title,
'description' => $request->description,
'parent_id' => $parentDirectoryId
]);
// save id into module_config array
$settings = [
'directoryId' => $directory->id
];
// save settings
$content->module_settings = json_encode($settings);
}
/**
* Method used for editing existing content page.
*
* Reason why it is separated from createNew() method is simple - we need to save history of changes.
*
* @param Content $content
* @param Request $request
*
* @param $revisionID string ID of revision used
*
* @return int number of edited fields
*/
public static function edit(Content &$content, Request $request, $revisionID)
{
// nothing to edit
}
/**
* Does given module manage content? Or is it just module with widgets/something internal/something absolutely else?
*
* @return bool
*/
public static function managesContent()
{
return true;
}
public static function getModuleId()
{
$handler = config('gallery.handler');
$allModules = ModulesHandlerToId::getWithTranslations();
$moduleId = isset($allModules[$handler]) ? $allModules[$handler] : null;
return $moduleId;
}
/**
* Getter for section names in creating/editing content resource
*
* @return mixed
*/
public static function getExtendedFormSections()
{
$sections = Handler::getExtendedFormSections();
$sections['upload'] = trans('gallery::admin/content.upload');
return $sections;
}
/**
* Getter for views used in extended part of form for creating new content
*
* This method should return pairs <section, view-name>. View is returned only as name in plain text
*
* @return array of views/templates/html codes divided into section
*/
public static function getExtendedFormInputsCreate()
{
$parts = Handler::getExtendedFormInputsCreate();
$parts['upload'] = 'gallery::admin.content.newUpload';
return $parts;
}
/**
* Getter for extended part of form for editing existing content
*
* Basically, this method may be
*
* @return array of views/templates/html codes divided into section
*/
public static function getExtendedFormInputsEdit()
{
$parts = Handler::getExtendedFormInputsCreate();
$parts['upload'] = 'gallery::admin.content.editUpload';
return $parts;
}
/**
* Register admin menu (or multiple ones)
*
* This cannot be in ServiceProvider because Session is started at middleware. And ServiceProvider is called before
* starting any middleware..
*
* @param User $user model of logged user
*/
public static function registerAdminMenu(User $user)
{
// nothing to register
}
/**
* Install module
*
* @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);
}
}
+1
View File
@@ -0,0 +1 @@
<?php
View File
@@ -0,0 +1,110 @@
<?php namespace Modules\Gallery\Providers;
use Illuminate\Support\ServiceProvider;
class GalleryServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Boot the application events.
*
* @return void
*/
public function boot()
{
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
/**
* Register config.
*
* @return void
*/
protected function registerConfig()
{
$this->publishes([
__DIR__ . '/../Config/config.php' => config_path('gallery.php'),
]);
$this->mergeConfigFrom(__DIR__ . '/../Config/config.php', 'gallery');
}
/**
* Register views.
*
* @return void
*/
public function registerViews()
{
$viewPath = base_path('resources/views/modules/gallery');
$sourcePath = __DIR__ . '/../Resources/views';
$this->publishes([
$sourcePath => $viewPath
]);
$this->loadViewsFrom(array_merge(array_map(function ($path) {
return $path . '/modules/gallery';
}, \Config::get('view.paths')), [$sourcePath]), 'gallery');
/**
* @var $registrator TemplateRegistrator
*/
$registrator = $this->app->make('registerTemplateDir');
try {
// setup some global variables
$registrator->setBaseDirectory('resources/views/modules/gallery/visitor');
$registrator->setNamespace('gallery');
$registrator->setModuleId(call_user_func([config('gallery.handler'), 'getModuleId']));
// register path with current template name
$registrator->register(config('app.theme'), 'gallery::admin.templatePath');
} catch (InvalidArgumentException $e) {
// ignore this exception
}
}
/**
* Register translations.
*
* @return void
*/
public function registerTranslations()
{
$langPath = base_path('resources/lang/modules/gallery');
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, 'gallery');
} else {
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'gallery');
}
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array ();
}
}
@@ -0,0 +1,5 @@
<?php
return [
'upload' => 'Upload photos',
'uploadAfterSavingGallery' => 'Uploading for this gallery is not available yet. You must create the gallery first and upload later.'
];
@@ -0,0 +1,6 @@
<?php
return [
'name' => 'Gallery',
'description' => 'Simple photogallery',
];
@@ -0,0 +1,3 @@
<div class="row column">
<a href="{{route('upload.overview', ['id' => $page->module_settings->directoryId])}}" class="button large expanded success">@lang('gallery::admin/content.upload')</a>
</div>
@@ -0,0 +1,3 @@
<div class="row column">
<em>@lang('gallery::admin/content.uploadAfterSavingGallery')</em>
</div>
View File
+15
View File
@@ -0,0 +1,15 @@
{
"name": "pingpong-modules/gallery",
"description": "",
"authors": [
{
"name": "Pingpong Labs",
"email": "pingpong.labs@gmail.com"
}
],
"autoload": {
"psr-4": {
"Modules\\Gallery\\": ""
}
}
}
+15
View File
@@ -0,0 +1,15 @@
<?php
/*
|--------------------------------------------------------------------------
| Register Namespaces And Routes
|--------------------------------------------------------------------------
|
| When a module starting, this file will executed automatically. This helps
| to register some namespaces like translator or view. Also this file
| will load the routes file for each module. You may also modify
| this file as you want.
|
*/
require __DIR__ . '/Http/routes.php';
@@ -1,6 +1,4 @@
@extends('visitor.layout')
@section('pageName', @trans('admin/userManagement.detail', ['name' => $user->name, 'email' => $user->email]))
@extendVisitor('layout')
@section('content')
{!! $page->content !!}
+4
View File
@@ -127,6 +127,10 @@ code {
font-size: 80%;
}
#appearance .title-photo img {
max-height: 10em;
}
.red {
color: red;
}
+3 -1
View File
@@ -35,5 +35,7 @@ return [
'template' => 'Template of this page',
'overview' => 'List of all content pages',
'homepageSetup' => 'Homepage successfully set up.',
'setHomepage' => 'Set page as homepage'
'setHomepage' => 'Set page as homepage',
'noParentPage' => ' -- No parent page -- ',
'uploadTitleImage' => 'Upload title image'
];
+1
View File
@@ -20,6 +20,7 @@ return [
'noFileSpecified' => 'You have not specified any file for upload',
'uploadSuccessfull' => 'Your file was successfully uploaded',
'selectFile' => 'Select file for upload',
'name' => 'Name',
'keywords' => 'Keywords (comma separated)',
'description' => 'File description',
'noFiles' => 'No files were found. Try to upload some.',
+19 -16
View File
@@ -1,20 +1,23 @@
<?php
return [
'pageName' => 'History of :name',
'columnPageContent' => 'Page content',
'columnUrl' => 'URL',
'columnTitle' => 'Title',
'columnMetaKeywords' => 'Meta keywords',
'columnMetaDescription' => 'Description',
'columnStatus' => 'Page visibility',
'columnTemplate' => 'Template',
'columnIs_homepage' => 'Homepage',
'changedFromTo' => 'Changed from <del>:from</del> to <ins>:to</ins>',
'numOfChanges' => 'One change|:count changes',
'diff' => 'Difference',
'diffPageName' => 'Difference of :column',
'backToOverview' => 'Back to history overview',
'backToEdit' => 'Back to editation form',
'setupAsHomepage' => 'Setup as homepage'
'pageName' => 'History of :name',
'columnPageContent' => 'Page content',
'columnUrl' => 'URL',
'columnTitle' => 'Title',
'columnMetaKeywords' => 'Meta keywords',
'columnMetaDescription' => 'Description',
'columnStatus' => 'Page visibility',
'columnTemplate' => 'Template',
'columnIs_homepage' => 'Homepage',
'columnParentPage' => 'Parent page',
'columnTitlePhotoFilename' => 'Title photo',
'emptyValue' => '<em>none</em>',
'changedFromTo' => 'Changed from <del>:from</del> to <ins>:to</ins>',
'numOfChanges' => 'One change|:count changes',
'diff' => 'Difference',
'diffPageName' => 'Difference of :column',
'backToOverview' => 'Back to history overview',
'backToEdit' => 'Back to editation form',
'setupAsHomepage' => 'Setup as homepage'
];
+1
View File
@@ -21,5 +21,6 @@ return [
'successfullyAssociated' => 'Association successfull',
'associationDoesNotExists' => 'This association does not exist',
'successfullyDeassociated' => 'Successfully removed from widget area',
'widgetExists' => 'Widget :id already exists.'
];
+15
View File
@@ -0,0 +1,15 @@
<?php
return [
'widgetName' => 'Orbit slider',
'widgetDescription' => 'Slider for images. Uses Foundation framework.',
'name' => 'Slider name',
'description' => 'Slider description',
'containerClass' => 'Extra HTML class for slider',
'createNew' => 'Create new',
'new' => 'Create new orbit slider',
'edit' => 'Edit slider :name',
'editExisting' => 'Save',
'preview' => 'Slider preview',
'upload' => 'Add photos into slider',
'code' => 'Some extra HTML/JS code for slider'
];
@@ -10,7 +10,7 @@
</div>
@endif
<form method="POST" action="{{route('content.editPost', ['pageId' => $page->id])}}">
<form method="POST" enctype="multipart/form-data" action="{{route('content.editPost', ['pageId' => $page->id])}}">
{!! csrf_field() !!}
@include('admin.content.formInputs')
@@ -1,3 +1,26 @@
@if($page->title_photo)
<div class="row">
<div class="column large-12 title-photo text-center">
<img src="{{config('app.upload_url')}}/{{$page->title_photo}}" alt="" />
</div>
</div>
@endif
<div class="row">
<div class="column large-12">
<label>
@lang('admin/contents.uploadTitleImage')
<input type="file" id="titlePhoto" name="titlePhoto" />
</label>
@if (isset($errors) && $errors->has('titlePhoto'))
<div class="callout alert">
{{ $errors->first('titlePhoto') }}
</div>
@endif
</div>
</div>
<div class="row">
<div class="columns large-12">
<label>

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