diff --git a/app/Console/Commands/AddLanguage.php b/app/Console/Commands/AddLanguage.php new file mode 100644 index 00000000..b24ce5be --- /dev/null +++ b/app/Console/Commands/AddLanguage.php @@ -0,0 +1,62 @@ +argument('code'); + $translation = $this->argument('translation'); + $native = $this->argument('native'); + $script = $this->argument('script'); + + // check if language does not exist + $exist = Language::find($code); + + if ($exist) { + $this->error('Language ' . $code . ' already exists!'); + return; + } + + Language::create([ + 'code' => $code, + 'name' => $translation, + 'native' => $native, + 'script' => $script ? $script : 'Latn' + ]); + + $this->line('Successfully installed.'); + } +} diff --git a/app/Console/Commands/Translations.php b/app/Console/Commands/Translations.php index af851adf..5c6a2b66 100644 --- a/app/Console/Commands/Translations.php +++ b/app/Console/Commands/Translations.php @@ -36,6 +36,10 @@ class Translations extends Command $defaultLocalesDir = $dir . '/' . $defaultLocales; $currentLocalesDir = $dir . '/' . $currentLocales; + if (!is_dir($currentLocalesDir)) { + File::makeDirectory($currentLocalesDir); + } + $this->compareTranslationsInDirectory($defaultLocalesDir, $currentLocalesDir); } @@ -57,7 +61,7 @@ class Translations extends Command $default = include($file); $checked = file_exists($currentDir . '/' . $fileName) ? include $currentDir . '/' . $fileName : []; $this->translations = &$checked; - + $this->checkForMissingTranslations($default, $checked, $currentDir, $fileName); } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index e4fc0c23..395f776d 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,6 +2,7 @@ namespace App\Console; +use App\Console\Commands\AddLanguage; use Illuminate\Console\Scheduling\Schedule; use Illuminate\Foundation\Console\Kernel as ConsoleKernel; @@ -21,6 +22,7 @@ class Kernel extends ConsoleKernel Commands\TranslateAll::class, Commands\InitDatabaseSchema::class, Commands\SetTheme::class, + AddLanguage::class ]; /** diff --git a/app/Http/Controllers/Admin/AssociateWidget.php b/app/Http/Controllers/Admin/AssociateWidget.php index fbb366b8..4bcec19e 100644 --- a/app/Http/Controllers/Admin/AssociateWidget.php +++ b/app/Http/Controllers/Admin/AssociateWidget.php @@ -11,6 +11,7 @@ use App\Models\WidgetArea; use App\Models\WidgetInWidgetArea; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Event; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; class AssociateWidget extends Controller { @@ -18,7 +19,8 @@ class AssociateWidget extends Controller { $area = WidgetArea::findOrFail($widgetArea); $associatedWidgetIds = WidgetInWidgetArea::getWidgetIdsFromArea($area->id); - $widgets = Widget::paginate(25); + $widgets = Widget::where('language', LaravelLocalization::getCurrentLocale()) + ->paginate(25); return view('admin.widgets.association', [ 'widgetArea' => $area, diff --git a/app/Http/Controllers/Admin/CreateNewContent.php b/app/Http/Controllers/Admin/CreateNewContent.php index e01b0d08..44778f73 100644 --- a/app/Http/Controllers/Admin/CreateNewContent.php +++ b/app/Http/Controllers/Admin/CreateNewContent.php @@ -10,6 +10,7 @@ use App\Models\Module; use App\Models\Template; use Illuminate\Support\Facades\Event; use Illuminate\Support\Str; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class CreateNewContent extends Controller @@ -56,7 +57,8 @@ class CreateNewContent extends Controller 'templates' => $templates, 'moduleId' => $moduleId, 'page' => $this->content, - 'rootPages' => $this->content->getOverview()->get(), + 'rootPages' => $this->content->getOverview() + ->get(), 'moduleName' => trans($module->name), 'extraData' => call_user_func([$module->handler, 'loadExtraData'], $this->content), 'formSectionNames' => call_user_func([$module->handler, 'getExtendedFormSections']), @@ -86,6 +88,7 @@ class CreateNewContent extends Controller // setup basic info $page->user_id = \Auth::user()->id; + $page->language = LaravelLocalization::getLocale(); $page->title = $request->title; $page->url = Str::slug($request->url); $page->published_from = $request->publishedFrom; @@ -112,7 +115,7 @@ class CreateNewContent extends Controller call_user_func_array([$module->handler, 'createNew'], [&$page, $request]); $page->save(); - + // fire event about creating new content page Event::fire(new CreateNewContentEvent($page)); diff --git a/app/Http/Controllers/Admin/EditContent.php b/app/Http/Controllers/Admin/EditContent.php index 79c8723e..2e3ad79f 100644 --- a/app/Http/Controllers/Admin/EditContent.php +++ b/app/Http/Controllers/Admin/EditContent.php @@ -17,6 +17,7 @@ use App\Models\File; use App\Models\Template; use Illuminate\Support\Facades\Event; use Illuminate\Support\Str; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; class EditContent extends Controller @@ -65,8 +66,8 @@ class EditContent extends Controller 'contentStatuses' => $statuses, 'page' => $page, 'rootPages' => $page->getOverview() - ->where('contents.id', '!=', $page->id) - ->get(), + ->where('contents.id', '!=', $page->id) + ->get(), 'templates' => $templates, 'extraData' => call_user_func([$page->module_handler, 'loadExtraData'], $page), 'formSectionNames' => call_user_func([$page->module_handler, 'getExtendedFormSections']), @@ -223,14 +224,14 @@ class EditContent extends Controller // change url to something unique $oldURL = $page->url; - $page->url = uniqid($page->url.'_deleted'); + $page->url = uniqid($page->url . '_deleted'); $page->save(); list ($revision, $changedColumns) = $page->updateWithHistory(['status' => 'status'], ['status' => Content::STATUS_DELETED]); // let module to delete some extra content created during page's life call_user_func([$page->module_handler, 'delete'], $page); - + // was something changed? if ($changedColumns == 0) { return redirect() @@ -274,6 +275,7 @@ class EditContent extends Controller // disable any other existing homepage Content::where('is_homepage', 1) + ->where('language', LaravelLocalization::getCurrentLocale()) ->update(['is_homepage' => 0]); // set new homepage diff --git a/app/Http/Controllers/Admin/Settings.php b/app/Http/Controllers/Admin/Settings.php index cb935bd1..c677306e 100644 --- a/app/Http/Controllers/Admin/Settings.php +++ b/app/Http/Controllers/Admin/Settings.php @@ -4,30 +4,39 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; use App\Http\Requests; +use App\Models\Settings as SettingsModel; use Illuminate\Support\Facades\App; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; class Settings extends Controller { /** - * @var \App\Models\Settings + * @var SettingsModel */ protected $settings; /** * Settings constructor. * - * @param \App\Models\Settings $settings + * @param SettingsModel $settings */ - public function __construct(\App\Models\Settings $settings) + public function __construct(SettingsModel $settings) { $this->settings = $settings; } + /** + * Get overview (with form) for editing settings + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ public function getOverview() { $sections = App::make('registerSettingsExtension') ->get(); - $settings = $this->settings->getAll(); + + // load all settings with language info + $settings = $this->settings->getAllWithLanguage(); return view('admin.settings.overview', [ 'formSections' => $sections, @@ -35,35 +44,39 @@ class Settings extends Controller ]); } + /** + * Save all settings (ignore empty ones) + * + * When settings used to be non-empty string and user deletes it, key is also deleted from database + * + * @param Requests\SaveSettingsRequest $request + * + * @return \Illuminate\Http\RedirectResponse + */ public function saveSettings(Requests\SaveSettingsRequest $request) { $data = $request->all(); + $commonSettings = isset($data['commonSettings']) ? $data['commonSettings'] : []; + // remove CSRF token field - unset($data['_token']); + unset($data['_token'], $data['commonSettings']); - $settings = $this->settings->getAll(); - $updated = 0; 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++; + // select language for this setting key + $language = isset($commonSettings[$key]) ? null : LaravelLocalization::getCurrentLocale(); + $setting = SettingsModel::firstOrNew(['language' => $language, 'key' => $key]); + + if ($setting->value == $value) { + continue; } + + // set value and save or delete + $setting->value = $value; + empty($value) ? $setting->delete() : $setting->save(); } - if ($updated > 0) { - 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('success', trans('admin/settings.successfullySaved')); } } diff --git a/app/Http/Controllers/Admin/WidgetsOverview.php b/app/Http/Controllers/Admin/WidgetsOverview.php index 31506334..424c2e84 100644 --- a/app/Http/Controllers/Admin/WidgetsOverview.php +++ b/app/Http/Controllers/Admin/WidgetsOverview.php @@ -2,12 +2,14 @@ namespace App\Http\Controllers\Admin; use App\Models\Widget; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; class WidgetsOverview extends Controller { public function getOverview() { - $widgets = Widget::paginate(25); + $widgets = Widget::where('language', LaravelLocalization::getCurrentLocale()) + ->paginate(25); return view('admin.widgets.overview', ['widgets' => $widgets]); } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index ae2615b5..15940382 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -3,6 +3,10 @@ namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; +use Illuminate\Routing\Middleware\ThrottleRequests; +use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter; +use Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes; +use Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect; class Kernel extends HttpKernel { @@ -23,11 +27,11 @@ class Kernel extends HttpKernel */ protected $middlewareGroups = [ 'web' => [ - \App\Http\Middleware\EncryptCookies::class, + Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, - \App\Http\Middleware\VerifyCsrfToken::class, + Middleware\VerifyCsrfToken::class, ], 'api' => [ 'throttle:60,1', @@ -41,10 +45,13 @@ class Kernel extends HttpKernel * @var array */ protected $routeMiddleware = [ - 'auth' => \App\Http\Middleware\Authenticate::class, - 'onlyAdmin' => \App\Http\Middleware\RequireAdminRole::class, - 'adminMenu' => \App\Http\Middleware\AdminMenuRegistrator::class, - 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, - 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'auth' => Middleware\Authenticate::class, + 'onlyAdmin' => Middleware\RequireAdminRole::class, + 'adminMenu' => Middleware\AdminMenuRegistrator::class, + 'guest' => Middleware\RedirectIfAuthenticated::class, + 'throttle' => ThrottleRequests::class, + 'localize' => LaravelLocalizationRoutes::class, + 'localizationRedirect' => LaravelLocalizationRedirectFilter::class, + 'localeSessionRedirect' => LocaleSessionRedirect::class ]; } diff --git a/app/Http/routes.php b/app/Http/routes.php index fb2fbe13..471f47b8 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -4,274 +4,281 @@ * This routing groups is used for routing along public part of website */ +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; + Route::pattern('id', '\d+'); Route::pattern('url', '[0-9\-a-z]+'); /*******************************************************************************/ -/** - * This route group serves to handle request in admin - */ Route::group([ - 'middleware' => ['web', 'auth', 'adminMenu'], - 'namespace' => 'Admin', - 'prefix' => 'admin' + 'prefix' => LaravelLocalization::setLocale(), + 'middleware' => ['localeSessionRedirect', 'localizationRedirect'] ], function () { + /** + * This route group serves to handle request in admin + */ + Route::group([ + 'middleware' => ['web', 'auth', 'adminMenu'], + 'namespace' => 'Admin', + 'prefix' => 'admin' + ], function () { - // these routes are available only for user with role admin - Route::group(['middleware' => 'onlyAdmin'], function () { - // display form for creating new user - Route::get('users/new', 'CreateNewUser@getNewUser') - ->name('users.new'); + // these routes are available only for user with role admin + Route::group(['middleware' => 'onlyAdmin'], function () { + // display form for creating new user + Route::get('users/new', 'CreateNewUser@getNewUser') + ->name('users.new'); - // POST methods - // display form for creating new user - Route::post('users/new', 'CreateNewUser@postRegistration') - ->name('users.newPost'); + // POST methods + // display form for creating new user + Route::post('users/new', 'CreateNewUser@postRegistration') + ->name('users.newPost'); - // display form for edit of existing user - Route::get('users/edit/{id}', 'EditUser@getEditExistingUser') - ->name('users.edit'); + // display form for edit of existing user + Route::get('users/edit/{id}', 'EditUser@getEditExistingUser') + ->name('users.edit'); - // form for adding new custom field - Route::get('customfields/new', 'CreateNewCustomField@getNew') - ->name('customfields.new'); + // form for adding new custom field + Route::get('customfields/new', 'CreateNewCustomField@getNew') + ->name('customfields.new'); - // form for editing custom field - Route::get('customfields/edit/{id}', 'EditCustomField@getEditCustomField') - ->name('customfields.edit'); + // form for editing custom field + Route::get('customfields/edit/{id}', 'EditCustomField@getEditCustomField') + ->name('customfields.edit'); - // form for adding new custom field - Route::post('customfields/new', 'CreateNewCustomField@postNew') - ->name('customfields.newPost'); + // form for adding new custom field + Route::post('customfields/new', 'CreateNewCustomField@postNew') + ->name('customfields.newPost'); - // form for editing custom field - Route::post('customfields/edit/{id}', 'EditCustomField@postEditCustomField') - ->name('customfields.editPost'); + // form for editing custom field + Route::post('customfields/edit/{id}', 'EditCustomField@postEditCustomField') + ->name('customfields.editPost'); - Route::get('customfields/delete/{id}', 'EditCustomField@deleteCustomField') - ->name('customfields.delete'); + Route::get('customfields/delete/{id}', 'EditCustomField@deleteCustomField') + ->name('customfields.delete'); - Route::get('templates/overview/path/{id}', 'TemplateOverview@getPath') - ->name('templates.overview'); + Route::get('templates/overview/path/{id}', 'TemplateOverview@getPath') + ->name('templates.overview'); - Route::post('templates/copy', 'CopyTemplate@createCopy') - ->name('templates.postCopy'); + Route::post('templates/copy', 'CopyTemplate@createCopy') + ->name('templates.postCopy'); - // Route::get('templates/new/{pathId}', 'TemplateOverview@getPath') - // ->name('templates.new'); + // Route::get('templates/new/{pathId}', 'TemplateOverview@getPath') + // ->name('templates.new'); - Route::get('templates/edit/{id}', 'EditTemplate@getEdit') - ->name('templates.edit'); + Route::get('templates/edit/{id}', 'EditTemplate@getEdit') + ->name('templates.edit'); - Route::post('templates/edit/{id}', 'EditTemplate@postEdit') - ->name('templates.postEdit'); + Route::post('templates/edit/{id}', 'EditTemplate@postEdit') + ->name('templates.postEdit'); + }); + + // list of all static pages + Route::get('content/overview/{moduleId?}/{status?}', 'ContentOverview@getOverview') + ->name('content.overview'); + + // form for creating new static page + Route::get('content/new/{moduleId}', 'CreateNewContent@getNew') + ->name('content.new'); + + // form for editing existing static page + Route::get('content/edit/{id}', 'EditContent@getEdit') + ->name('content.edit'); + + // post method for creating new static page + Route::post('content/new/{moduleId}', 'CreateNewContent@postNew') + ->name('content.newPost'); + + // post method for creating new static page + Route::post('content/edit/{id}', 'EditContent@postEdit') + ->name('content.editPost'); + + // routes for quick actions + + // change status of page (protected, public or draft) + Route::get('content/status/{id}/{status}', 'EditContent@changeStatus') + ->name('content.changeStatus'); + + // set homepage + Route::get('content/homepage/{id}', 'EditContent@setHomepage') + ->name('content.setHomepage'); + + // delete page + Route::get('content/delete/{id}', 'EditContent@deletePage') + ->name('content.delete'); + + // these routes are available for all logged (authenticated) users + + // display dashboard with some usefull information + Route::get('/', 'Dashboard@getIndex') + ->name('admin.dashboard'); + + // display user detail in admin + Route::get('users/detail/{id?}', 'UserDetail@getDetail') + ->name('users.detail'); + + // method for saving edited data of user + Route::post('users/edit/{id}', 'EditUser@postEdit') + ->name('users.editPost'); + + // display list of all users registered into our system + Route::get('users/overview/{state?}/{perPage?}', 'UsersOverview@getOverview') + ->name('users.overview'); + + // history of changes for specified page + Route::get('history/{id}', 'History@getOverview') + ->name('content.history'); + + // history of changes for specified page + Route::get('history/{revision}/{id}', 'History@getDiff') + ->name('history.diff'); + + // list of all actions + Route::get('actions', 'ActionLogOverview@getOverview') + ->name('log.overview'); + + // routes for widget areas + Route::get('widgets/areas/overview', 'WidgetAreaOverview@getOverview') + ->name('widgetareas.overview'); + + // form for new widget area + Route::get('widgets/areas/new', 'CreateNewWidgetArea@getNew') + ->name('widgetareas.new'); + + // form for new widget area + Route::post('widgets/areas/new', 'CreateNewWidgetArea@postNew') + ->name('widgetareas.postNew'); + + // edit form for widget area + Route::get('widgets/areas/edit/{id}', 'EditWidgetArea@getEdit') + ->name('widgetareas.edit'); + + Route::post('widgets/areas/edit/{id}', 'EditWidgetArea@postEdit') + ->name('widgetareas.postEdit'); + + // edit form for widget area + Route::get('widgets/areas/delete/{id}', 'EditWidgetArea@deleteArea') + ->name('widgetareas.delete'); + + // list of all installed widget types + Route::get('widgets/overview', 'WidgetsOverview@getOverview') + ->name('widgets.overview'); + + // create new instance of widget of given type + Route::get('widgets/new/{type}', 'CreateNewWidget@getNew') + ->name('widgets.new'); + + Route::post('widgets/new/{type}', 'CreateNewWidget@postNew') + ->name('widgets.postNew'); + + // edit widget settings + Route::get('widgets/edit/{id}', 'EditWidget@getEdit') + ->name('widgets.edit'); + + Route::post('widgets/edit/{id}', 'EditWidget@postEdit') + ->name('widgets.postEdit'); + + // display form for association of widget and widget area + Route::get('widgets/associate/{widgetArea}', 'AssociateWidget@getList') + ->name('widgets.associate'); + + Route::get('widgets/deassociate/{widgetId}/{widgetArea}', 'AssociateWidget@deleteAssociation') + ->name('widgets.deleteAssociation'); + + Route::get('widgets/associate/{widgetId}/{widgetArea}', 'AssociateWidget@makeAssociation') + ->name('widgets.makeAssociation'); + + // uploader methods + Route::get('directories/new/{id?}', 'CreateNewDirectory@getNew') + ->name('upload.newDirectory'); + + Route::get('directories/edit/{id}', 'EditDirectory@getEdit') + ->name('upload.editDirectory'); + + Route::post('directories/edit/{id}', 'EditDirectory@postEdit') + ->name('upload.postEditDirectory'); + + Route::get('files/overview/{id?}/{type?}/{subtype?}', 'UploadedFilesOverview@getOverview') + ->name('upload.overview'); + + route::post('directories/new', 'CreateNewDirectory@postNew') + ->name('upload.postNewDirectory'); + + Route::get('upload/detail/{id}', 'EditUploadedFile@getDetail') + ->name('upload.detail'); + + Route::post('upload/detail/{id}', 'EditUploadedFile@postEdit') + ->name('upload.postEdit'); + + Route::get('upload/delete/{id}', 'EditUploadedFile@deleteFile') + ->name('upload.delete'); + + // uploader methods + Route::post('upload/file', 'UploadFile@postFile') + ->name('upload.postFile'); + + Route::post('upload/image', 'UploadFile@postImage') + ->name('upload.postImage'); + + // form with settings + Route::get('settings', 'Settings@getOverview') + ->name('settings.overview'); + + Route::post('settings', 'Settings@saveSettings') + ->name('settings.save'); + + Route::get('search', 'Search@getSearch') + ->name('search'); + + // custom fields + // ------------------------------ + + // list of all custom fields + Route::get('customfields/overview', 'CustomFieldsOverview@getOverview') + ->name('customfields.overview'); + + // logout method + Route::get('logout', function () { + + // remove user information + \Auth::logout(); + + // redirect to login form with info about successfull logout + return redirect() + ->route('login') + ->with('success', trans('admin/common.logoutSuccessfull')); + }) + ->name('logout'); }); - // list of all static pages - Route::get('content/overview/{moduleId?}/{status?}', 'ContentOverview@getOverview') - ->name('content.overview'); + /**************************************************************************************/ - // form for creating new static page - Route::get('content/new/{moduleId}', 'CreateNewContent@getNew') - ->name('content.new'); + /** + * This section must be specified as last one + */ - // form for editing existing static page - Route::get('content/edit/{id}', 'EditContent@getEdit') - ->name('content.edit'); + Route::group(['middleware' => ['web']], function () { - // post method for creating new static page - Route::post('content/new/{moduleId}', 'CreateNewContent@postNew') - ->name('content.newPost'); + Route::get('/', 'Visitor\Homepage@getIndex') + ->name('page.index'); - // post method for creating new static page - Route::post('content/edit/{id}', 'EditContent@postEdit') - ->name('content.editPost'); + // display login form + Route::get('admin/login', function () { + return view('admin.loginForm.form'); + }) + ->name('loginForm'); - // routes for quick actions + // handle login + Route::post('admin/login', 'Admin\Login@postLogin') + ->name('login'); - // change status of page (protected, public or draft) - Route::get('content/status/{id}/{status}', 'EditContent@changeStatus') - ->name('content.changeStatus'); + // route for sitemap + Route::get('sitemap.xml', 'Sitemap@getMap') + ->name('sitemap'); - // set homepage - Route::get('content/homepage/{id}', 'EditContent@setHomepage') - ->name('content.setHomepage'); - - // delete page - Route::get('content/delete/{id}', 'EditContent@deletePage') - ->name('content.delete'); - - // these routes are available for all logged (authenticated) users - - // display dashboard with some usefull information - Route::get('/', 'Dashboard@getIndex') - ->name('admin.dashboard'); - - // display user detail in admin - Route::get('users/detail/{id?}', 'UserDetail@getDetail') - ->name('users.detail'); - - // method for saving edited data of user - Route::post('users/edit/{id}', 'EditUser@postEdit') - ->name('users.editPost'); - - // display list of all users registered into our system - Route::get('users/overview/{state?}/{perPage?}', 'UsersOverview@getOverview') - ->name('users.overview'); - - // history of changes for specified page - Route::get('history/{id}', 'History@getOverview') - ->name('content.history'); - - // history of changes for specified page - Route::get('history/{revision}/{id}', 'History@getDiff') - ->name('history.diff'); - - // list of all actions - Route::get('actions', 'ActionLogOverview@getOverview') - ->name('log.overview'); - - // routes for widget areas - Route::get('widgets/areas/overview', 'WidgetAreaOverview@getOverview') - ->name('widgetareas.overview'); - - // form for new widget area - Route::get('widgets/areas/new', 'CreateNewWidgetArea@getNew') - ->name('widgetareas.new'); - - // form for new widget area - Route::post('widgets/areas/new', 'CreateNewWidgetArea@postNew') - ->name('widgetareas.postNew'); - - // edit form for widget area - Route::get('widgets/areas/edit/{id}', 'EditWidgetArea@getEdit') - ->name('widgetareas.edit'); - - Route::post('widgets/areas/edit/{id}', 'EditWidgetArea@postEdit') - ->name('widgetareas.postEdit'); - - // edit form for widget area - Route::get('widgets/areas/delete/{id}', 'EditWidgetArea@deleteArea') - ->name('widgetareas.delete'); - - // list of all installed widget types - Route::get('widgets/overview', 'WidgetsOverview@getOverview') - ->name('widgets.overview'); - - // create new instance of widget of given type - Route::get('widgets/new/{type}', 'CreateNewWidget@getNew') - ->name('widgets.new'); - - Route::post('widgets/new/{type}', 'CreateNewWidget@postNew') - ->name('widgets.postNew'); - - // edit widget settings - Route::get('widgets/edit/{id}', 'EditWidget@getEdit') - ->name('widgets.edit'); - - Route::post('widgets/edit/{id}', 'EditWidget@postEdit') - ->name('widgets.postEdit'); - - // display form for association of widget and widget area - Route::get('widgets/associate/{widgetArea}', 'AssociateWidget@getList') - ->name('widgets.associate'); - - Route::get('widgets/deassociate/{widgetId}/{widgetArea}', 'AssociateWidget@deleteAssociation') - ->name('widgets.deleteAssociation'); - - Route::get('widgets/associate/{widgetId}/{widgetArea}', 'AssociateWidget@makeAssociation') - ->name('widgets.makeAssociation'); - - // uploader methods - Route::get('directories/new/{id?}', 'CreateNewDirectory@getNew') - ->name('upload.newDirectory'); - - Route::get('directories/edit/{id}', 'EditDirectory@getEdit') - ->name('upload.editDirectory'); - - Route::post('directories/edit/{id}', 'EditDirectory@postEdit') - ->name('upload.postEditDirectory'); - - Route::get('files/overview/{id?}/{type?}/{subtype?}', 'UploadedFilesOverview@getOverview') - ->name('upload.overview'); - - route::post('directories/new', 'CreateNewDirectory@postNew') - ->name('upload.postNewDirectory'); - - Route::get('upload/detail/{id}', 'EditUploadedFile@getDetail') - ->name('upload.detail'); - - Route::post('upload/detail/{id}', 'EditUploadedFile@postEdit') - ->name('upload.postEdit'); - - Route::get('upload/delete/{id}', 'EditUploadedFile@deleteFile') - ->name('upload.delete'); - - // uploader methods - Route::post('upload/file', 'UploadFile@postFile') - ->name('upload.postFile'); - - Route::post('upload/image', 'UploadFile@postImage') - ->name('upload.postImage'); - - // form with settings - Route::get('settings', 'Settings@getOverview') - ->name('settings.overview'); - - Route::post('settings', 'Settings@saveSettings') - ->name('settings.save'); - - Route::get('search', 'Search@getSearch') - ->name('search'); - - // custom fields - // ------------------------------ - - // list of all custom fields - Route::get('customfields/overview', 'CustomFieldsOverview@getOverview') - ->name('customfields.overview'); - - // logout method - Route::get('logout', function () { - - // remove user information - \Auth::logout(); - - // redirect to login form with info about successfull logout - return redirect() - ->route('login') - ->with('success', trans('admin/common.logoutSuccessfull')); - }) - ->name('logout'); -}); - -/**************************************************************************************/ - -/** - * This section must be specified as last one - */ - -Route::group(['middleware' => ['web']], function () { - - Route::get('/', 'Visitor\Homepage@getIndex') - ->name('page.index'); - - // display login form - Route::get('admin/login', function () { - return view('admin.loginForm.form'); - }) - ->name('loginForm'); - - // handle login - Route::post('admin/login', 'Admin\Login@postLogin') - ->name('login'); - - // route for sitemap - Route::get('sitemap.xml', 'Sitemap@getMap') - ->name('sitemap'); - - // route for all content pages. This rule must be specified last (because it matches every route) - Route::get('{url}', 'Visitor\ContentPage@getPage') - ->name('page.content'); + // route for all content pages. This rule must be specified last (because it matches every route) + Route::get('{url}', 'Visitor\ContentPage@getPage') + ->name('page.content'); + }); }); \ No newline at end of file diff --git a/app/Models/Content.php b/app/Models/Content.php index 9172605b..44eb2123 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -5,6 +5,7 @@ namespace App\Models; use App\Enumerations\ContentStatuses; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; /** * Class Content @@ -15,6 +16,7 @@ class Content extends Model protected $fillable = [ 'user_id', 'parent_id', + 'language', 'module_handler', 'published_from', 'published_to', @@ -53,6 +55,7 @@ class Content extends Model public function getHomepage() { return $this->getPageQuery() + ->where('language', LaravelLocalization::getCurrentLocale()) ->where('is_homepage', 1) ->first(); } @@ -68,6 +71,7 @@ class Content extends Model { return $this->getPageQuery() ->where('url', $url) + ->where('language', LaravelLocalization::getCurrentLocale()) ->first(); } @@ -81,6 +85,7 @@ class Content extends Model if (!$this->subpagesInit) { $this->subpages = $this->getPageQuery() ->where('parent_id', $this->id) + ->where('language', LaravelLocalization::getCurrentLocale()) ->get(); // convert JSON settings into stdClass @@ -142,6 +147,7 @@ class Content extends Model public function rootPages() { $rootPages = $this->getPageQuery() + ->where('language', LaravelLocalization::getCurrentLocale()) ->where('parent_id', null); if ($this->id) { @@ -166,6 +172,7 @@ class Content extends Model $query = DB::table('contents') ->select('contents.*', 'modules.name AS module_name') ->where('contents.status', '<>', self::STATUS_DELETED) + ->where('contents.language', LaravelLocalization::getCurrentLocale()) ->join('modules', 'modules.handler', '=', 'contents.module_handler') ->orderBy('created_at', 'DESC'); diff --git a/app/Models/Language.php b/app/Models/Language.php new file mode 100644 index 00000000..2cef168a --- /dev/null +++ b/app/Models/Language.php @@ -0,0 +1,18 @@ +where('language', LaravelLocalization::getCurrentLocale()) + ->orWhere('language', null) + ->orderBy('language', 'DESC'); + } /** * Load all settings @@ -17,12 +31,33 @@ class Settings extends Model */ public function getAll() { - $settings = Settings::select(['key', 'value']) - ->get(); + $settings = $this->getSettingsQuery() + ->get(); return $this->returnPairs($settings); } + /** + * Get all settings with language info + * + * @return \stdClass + */ + public function getAllWithLanguage() + { + $settings = $this->getSettingsQuery() + ->get(); + + $data = new \stdClass(); + foreach ($settings as $conf) { + $data->{$conf->key} = [ + 'val' => $conf->value, + 'lang' => $conf->language + ]; + } + + return $data; + } + /** * Load only config for views * @@ -30,9 +65,9 @@ class Settings extends Model */ public function getForView() { - $settings = Settings::select(['key', 'value']) - ->where('load_into_views', 1) - ->get(); + $settings = $this->getSettingsQuery() + ->where('load_into_views', 1) + ->get(); return $this->returnPairs($settings); } diff --git a/app/Models/Widget.php b/app/Models/Widget.php index 1f6a607d..5ed96c28 100644 --- a/app/Models/Widget.php +++ b/app/Models/Widget.php @@ -4,6 +4,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Event; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; /** * Class Widget @@ -39,6 +40,7 @@ class Widget extends Model // create new widget $widget = new Widget(); $widget->widget_type_handler = $widgetType->handler; + $widget->language = LaravelLocalization::getCurrentLocale(); $widget->user_id = \Auth::user()->id; $widget->name = $data->name; diff --git a/app/Models/WidgetArea.php b/app/Models/WidgetArea.php index 7646b0d0..009e5f32 100644 --- a/app/Models/WidgetArea.php +++ b/app/Models/WidgetArea.php @@ -4,6 +4,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; /** * Class WidgetArea @@ -25,6 +26,7 @@ class WidgetArea extends Model ->where('code', $uniqueCode) ->join('widget_in_widget_area', 'widget_in_widget_area.widget_area_id', '=', 'widget_areas.id') ->join('widgets', 'widget_in_widget_area.widget_id', '=', 'widgets.id') + ->where('language', LaravelLocalization::getCurrentLocale()) ->orderBy('widget_in_widget_area.position'); } } \ No newline at end of file diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index dc872c35..fe7104a6 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -67,6 +67,7 @@ class AppServiceProvider extends ServiceProvider // register PingPong module extension $this->app->register('Pingpong\Modules\ModulesServiceProvider'); $this->app->register('Pingpong\Menus\MenusServiceProvider'); + $this->app->register(LaravelLocalizationServiceProvider::class); // create singletons for registering widgets $this->app->singleton('registerWidget', function ($app) { diff --git a/app/Providers/LaravelLocalizationServiceProvider.php b/app/Providers/LaravelLocalizationServiceProvider.php new file mode 100644 index 00000000..7cbdd327 --- /dev/null +++ b/app/Providers/LaravelLocalizationServiceProvider.php @@ -0,0 +1,42 @@ +get(); + + $supportedLocales = [ + config('app.locale') => [ + 'native' => env('LOCALE_NATIVE_NAME'), + 'script' => env('LOCALE_SCRIPT'), + 'name' => env('LOCALE_TRANSLATED_NAME'), + ] + ]; + foreach ($languages as $language) { + $supportedLocales[$language->code] = [ + 'native' => $language->native, + 'name' => $language->name, + 'script' => $language->script + ]; + } + + config([ + 'laravellocalization.supportedLocales' => $supportedLocales, + 'laravellocalization.useAcceptLanguageHeader' => true, + 'laravellocalization.hideDefaultLocaleInURL' => true + ]); + } + + public function boot() + { + \App::setLocale(LaravelLocalization::getCurrentLocale()); + } +} \ No newline at end of file diff --git a/app/Widgets/Menu/Menu.php b/app/Widgets/Menu/Menu.php index eff37d9c..b3ca55d9 100644 --- a/app/Widgets/Menu/Menu.php +++ b/app/Widgets/Menu/Menu.php @@ -1,10 +1,11 @@ settings); + $pages = self::selectContentPages(array_keys((array)$links)); + + foreach ($links as $link) { + if (!isset($pages[$link->id])) { + unset($links->{$link->id}); + } + } + $settings = [ - 'links' => json_decode($data->settings), + 'links' => $links, 'containerClass' => $data->containerClass ]; - + $widget->settings = json_encode($settings); return $widget; } + + public static function selectContentPages($ids) + { + $pages = Content::where('status', '!=', Content::STATUS_DELETED) + ->where('language', LaravelLocalization::getCurrentLocale()) + ->whereIn('id', $ids) + ->get(); + $used = []; + foreach ($pages as $page) { + $used[$page->id] = $page; + } + + return $used; + } } \ No newline at end of file diff --git a/app/Widgets/Menu/Presenters/Menu.php b/app/Widgets/Menu/Presenters/Menu.php index 471c5e4d..db3014d6 100644 --- a/app/Widgets/Menu/Presenters/Menu.php +++ b/app/Widgets/Menu/Presenters/Menu.php @@ -8,23 +8,10 @@ use App\Widgets\Contracts\WidgetRenderer; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Request; use Illuminate\Support\Facades\Route; +use Mcamara\LaravelLocalization\Facades\LaravelLocalization; class Menu implements WidgetRenderer { - protected static function selectContentPages($ids) - { - $pages = Content::where('status', '!=', Content::STATUS_DELETED) - ->whereIn('id', $ids) - ->get(); - $used = []; - - foreach ($pages as $page) { - $used[$page->id] = $page; - } - - return $used; - } - /** * Method used for displaying widget. * @@ -41,7 +28,7 @@ class Menu implements WidgetRenderer $pageIds = array_keys($links); // get pages - $pages = self::selectContentPages($pageIds); + $pages = \App\Widgets\Menu\Menu::selectContentPages($pageIds); // sort links using "order" uasort($links, function ($a, $b) { diff --git a/composer.json b/composer.json index 05841dde..d0811dcd 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,8 @@ "laravel/framework": "5.2.*", "pingpong/modules": "~2.0", "pingpong/menus": "^2.2", - "watson/sitemap": "^2.0" + "watson/sitemap": "^2.0", + "mcamara/laravel-localization": "^1.1" }, "require-dev": { "fzaninotto/faker": "~1.4", diff --git a/composer.lock b/composer.lock index 614082a9..5b296190 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "64dd6115505ac9f62926d5fccc14704d", - "content-hash": "8cefeb3bdf109c79d77ac6cb303a1a96", + "hash": "3a1cbb52ac8547058b740bac891b3b82", + "content-hash": "f274b2d31a4a37163ddd90984815797d", "packages": [ { "name": "classpreloader/classpreloader", @@ -796,12 +796,12 @@ "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "9d853b9b2db24849b68ce219d80fc68165807810" + "reference": "f6a4db472ca9013e56d8a7065c9fd64383a3d4d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/9d853b9b2db24849b68ce219d80fc68165807810", - "reference": "9d853b9b2db24849b68ce219d80fc68165807810", + "url": "https://api.github.com/repos/laravel/framework/zipball/f6a4db472ca9013e56d8a7065c9fd64383a3d4d4", + "reference": "f6a4db472ca9013e56d8a7065c9fd64383a3d4d4", "shasum": "" }, "require": { @@ -918,7 +918,7 @@ "framework", "laravel" ], - "time": "2016-07-21 15:40:02" + "time": "2016-07-22 22:19:36" }, { "name": "laravelcollective/html", @@ -1057,6 +1057,54 @@ ], "time": "2016-07-21 09:35:56" }, + { + "name": "mcamara/laravel-localization", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/mcamara/laravel-localization.git", + "reference": "239d711d1f861e333e6de73d98dabdf94500512e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mcamara/laravel-localization/zipball/239d711d1f861e333e6de73d98dabdf94500512e", + "reference": "239d711d1f861e333e6de73d98dabdf94500512e", + "shasum": "" + }, + "require": { + "laravel/framework": "~5.2", + "php": ">=5.5.0" + }, + "require-dev": { + "orchestra/testbench": "3.2.*" + }, + "type": "library", + "autoload": { + "classmap": [], + "psr-0": { + "Mcamara\\LaravelLocalization": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marc Cámara", + "email": "mcamara88@gmail.com", + "role": "Developer" + } + ], + "description": "Easy localization for Laravel", + "homepage": "https://github.com/mcamara/laravel-localization", + "keywords": [ + "laravel", + "localization", + "php" + ], + "time": "2016-07-11 12:59:33" + }, { "name": "monolog/monolog", "version": "1.x-dev", @@ -3551,28 +3599,28 @@ }, { "name": "sebastian/environment", - "version": "dev-master", + "version": "1.3.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "a13903bf5fd0239748fe322dfbdd5f5720ab20e6" + "reference": "622c5dc0a8036cfc4ccd73c7b1b668a431e69d96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a13903bf5fd0239748fe322dfbdd5f5720ab20e6", - "reference": "a13903bf5fd0239748fe322dfbdd5f5720ab20e6", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/622c5dc0a8036cfc4ccd73c7b1b668a431e69d96", + "reference": "622c5dc0a8036cfc4ccd73c7b1b668a431e69d96", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "^5.0" + "phpunit/phpunit": "^4.8 || ^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { @@ -3597,7 +3645,7 @@ "environment", "hhvm" ], - "time": "2016-06-11 08:54:23" + "time": "2016-06-11 08:21:19" }, { "name": "sebastian/exporter", diff --git a/config/app.php b/config/app.php index ae9dec1b..7967bb14 100644 --- a/config/app.php +++ b/config/app.php @@ -149,6 +149,7 @@ return [ Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, + Mcamara\LaravelLocalization\LaravelLocalizationServiceProvider::class, // this class must be before ModulesServiceProvider from PingPong, because it handles files module.json App\Providers\ModuleManager::class, Pingpong\Modules\ModulesServiceProvider::class, @@ -177,39 +178,40 @@ return [ 'aliases' => [ - 'App' => Illuminate\Support\Facades\App::class, - 'Artisan' => Illuminate\Support\Facades\Artisan::class, - 'Auth' => Illuminate\Support\Facades\Auth::class, - 'Blade' => Illuminate\Support\Facades\Blade::class, - 'Cache' => Illuminate\Support\Facades\Cache::class, - 'Config' => Illuminate\Support\Facades\Config::class, - 'Cookie' => Illuminate\Support\Facades\Cookie::class, - 'Crypt' => Illuminate\Support\Facades\Crypt::class, - 'DB' => Illuminate\Support\Facades\DB::class, - 'Eloquent' => Illuminate\Database\Eloquent\Model::class, - 'Event' => Illuminate\Support\Facades\Event::class, - 'File' => Illuminate\Support\Facades\File::class, - 'Gate' => Illuminate\Support\Facades\Gate::class, - 'Hash' => Illuminate\Support\Facades\Hash::class, - 'Lang' => Illuminate\Support\Facades\Lang::class, - 'Log' => Illuminate\Support\Facades\Log::class, - 'Mail' => Illuminate\Support\Facades\Mail::class, - 'Menu' => Pingpong\Menus\MenuFacade::class, - 'Module' => Pingpong\Modules\Facades\Module::class, - 'Password' => Illuminate\Support\Facades\Password::class, - 'Queue' => Illuminate\Support\Facades\Queue::class, - 'Redirect' => Illuminate\Support\Facades\Redirect::class, - 'Redis' => Illuminate\Support\Facades\Redis::class, - 'Request' => Illuminate\Support\Facades\Request::class, - 'Response' => Illuminate\Support\Facades\Response::class, - 'Route' => Illuminate\Support\Facades\Route::class, - 'Schema' => Illuminate\Support\Facades\Schema::class, - 'Session' => Illuminate\Support\Facades\Session::class, - 'Sitemap' => Watson\Sitemap\Facades\Sitemap::class, - 'Storage' => Illuminate\Support\Facades\Storage::class, - 'URL' => Illuminate\Support\Facades\URL::class, - 'Validator' => Illuminate\Support\Facades\Validator::class, - 'View' => Illuminate\Support\Facades\View::class, + 'App' => Illuminate\Support\Facades\App::class, + 'Artisan' => Illuminate\Support\Facades\Artisan::class, + 'Auth' => Illuminate\Support\Facades\Auth::class, + 'Blade' => Illuminate\Support\Facades\Blade::class, + 'Cache' => Illuminate\Support\Facades\Cache::class, + 'Config' => Illuminate\Support\Facades\Config::class, + 'Cookie' => Illuminate\Support\Facades\Cookie::class, + 'Crypt' => Illuminate\Support\Facades\Crypt::class, + 'DB' => Illuminate\Support\Facades\DB::class, + 'Eloquent' => Illuminate\Database\Eloquent\Model::class, + 'Event' => Illuminate\Support\Facades\Event::class, + 'File' => Illuminate\Support\Facades\File::class, + 'Gate' => Illuminate\Support\Facades\Gate::class, + 'Hash' => Illuminate\Support\Facades\Hash::class, + 'Lang' => Illuminate\Support\Facades\Lang::class, + 'Log' => Illuminate\Support\Facades\Log::class, + 'Mail' => Illuminate\Support\Facades\Mail::class, + 'Menu' => Pingpong\Menus\MenuFacade::class, + 'Module' => Pingpong\Modules\Facades\Module::class, + 'Password' => Illuminate\Support\Facades\Password::class, + 'Queue' => Illuminate\Support\Facades\Queue::class, + 'Redirect' => Illuminate\Support\Facades\Redirect::class, + 'Redis' => Illuminate\Support\Facades\Redis::class, + 'Request' => Illuminate\Support\Facades\Request::class, + 'Response' => Illuminate\Support\Facades\Response::class, + 'Route' => Illuminate\Support\Facades\Route::class, + 'Schema' => Illuminate\Support\Facades\Schema::class, + 'Session' => Illuminate\Support\Facades\Session::class, + 'Sitemap' => Watson\Sitemap\Facades\Sitemap::class, + 'Storage' => Illuminate\Support\Facades\Storage::class, + 'URL' => Illuminate\Support\Facades\URL::class, + 'Validator' => Illuminate\Support\Facades\Validator::class, + 'LaravelLocalization' => Mcamara\LaravelLocalization\Facades\LaravelLocalization::class, + 'View' => Illuminate\Support\Facades\View::class, ], diff --git a/config/database.php b/config/database.php index 66e88a90..dace41ee 100644 --- a/config/database.php +++ b/config/database.php @@ -59,7 +59,7 @@ return [ 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', + 'collation' => 'utf8_general_ci', 'prefix' => '', 'strict' => false, ], diff --git a/database/migrations/.gitkeep b/database/migrations/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/database/migrations/2016_07_21_205626_MakeLangEnumerations.php b/database/migrations/2016_07_21_205626_MakeLangEnumerations.php new file mode 100644 index 00000000..ad63f20e --- /dev/null +++ b/database/migrations/2016_07_21_205626_MakeLangEnumerations.php @@ -0,0 +1,33 @@ +string('code', 8) + ->primary(); + $table->string('name') + ->comment('Translated name for given language'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('languages'); + } +} diff --git a/database/migrations/2016_07_21_221547_AddFieldsIntoLanguages.php b/database/migrations/2016_07_21_221547_AddFieldsIntoLanguages.php new file mode 100644 index 00000000..434c5c45 --- /dev/null +++ b/database/migrations/2016_07_21_221547_AddFieldsIntoLanguages.php @@ -0,0 +1,37 @@ +string('script', 16) + ->default('Latn') + ->comment('ISO code for locale script (Latn, Arab, ...)'); + $table->string('native') + ->comment('Native name for language'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('languages', function (Blueprint $table) { + $table->dropColumn('script'); + $table->dropColumn('native'); + }); + } +} diff --git a/database/migrations/2016_07_22_095923_AddLanguageToContentPages.php b/database/migrations/2016_07_22_095923_AddLanguageToContentPages.php new file mode 100644 index 00000000..f154677b --- /dev/null +++ b/database/migrations/2016_07_22_095923_AddLanguageToContentPages.php @@ -0,0 +1,75 @@ +getDoctrineSchemaManager() + ->getDatabasePlatform(); + $platform->registerDoctrineTypeMapping('enum', 'string'); + + DB::raw('ALTER TABLE `languages` + CHANGE `code` `code` varchar(8) COLLATE \'utf8_general_ci\' NOT NULL FIRST, + CHANGE `name` `name` varchar(255) COLLATE \'utf8_general_ci\' NOT NULL COMMENT \'Translated name for given language\' AFTER `code`, + CHANGE `script` `script` varchar(16) COLLATE \'utf8_general_ci\' NOT NULL DEFAULT \'Latn\' COMMENT \'ISO code for locale script (Latn, Arab, ...)\' AFTER `name`, + CHANGE `native` `native` varchar(255) COLLATE \'utf8_general_ci\' NOT NULL COMMENT \'Native name for language\' AFTER `script`, + COLLATE \'utf8_general_ci\';'); + + Schema::table('contents', function (Blueprint $table) { + $table->string('language', 8) + ->after('template') + ->default(\App::getLocale()); + }); + + Schema::table('contents', function (Blueprint $table) { + $table->index('language') + ->change(); + + $table->unique(['language', 'url']); + + $doctrine = Schema::getConnection() + ->getDoctrineSchemaManager() + ->listTableDetails('contents'); + + // remove unique index from URL column + if ($doctrine->hasIndex('url_UNIQUE')) { + $table->dropUnique('url_UNIQUE'); + } else { + $table->dropUnique('contents_url_unique'); + } + + $table->foreign('language') + ->references('code') + ->on('languages') + ->onDelete('cascade') + ->onUpdate('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('contents', function (Blueprint $table) { + $table->dropForeign('contents_language_foreign'); + $table->dropIndex('contents_language_index'); + $table->dropUnique('contents_language_url_unique'); + $table->dropColumn('language'); + $table->unique('url'); + }); + } +} diff --git a/database/migrations/2016_07_22_130324_AddLanguageIntoWidgets.php b/database/migrations/2016_07_22_130324_AddLanguageIntoWidgets.php new file mode 100644 index 00000000..e183e7cc --- /dev/null +++ b/database/migrations/2016_07_22_130324_AddLanguageIntoWidgets.php @@ -0,0 +1,41 @@ +string('language', 8) + ->after('widget_type_handler') + ->default(\App::getLocale()); + + $table->foreign('language') + ->references('code') + ->on('languages') + ->onDelete('cascade') + ->onUpdate('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('widgets', function (Blueprint $table) { + $table->dropForeign('widgets_language_foreign'); + $table->dropColumn('language'); + }); + } +} diff --git a/database/migrations/2016_07_22_145402_AddLanguageIntoSettings.php b/database/migrations/2016_07_22_145402_AddLanguageIntoSettings.php new file mode 100644 index 00000000..9bd2a55b --- /dev/null +++ b/database/migrations/2016_07_22_145402_AddLanguageIntoSettings.php @@ -0,0 +1,53 @@ +string('language', 8) + ->after('id') + ->nullable(true) + ->default(null); + + $table->dropUnique('settings_key_unique'); + $table->unique(['key', 'language']); + + $table->foreign('language') + ->references('code') + ->on('languages') + ->onDelete('set null') + ->onUpdate('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('settings', function (Blueprint $table) { + $table->dropForeign('settings_language_foreign'); + $table->dropColumn('language'); + $table->dropUnique('settings_key_language_unique'); + $table->unique('key'); + }); + } +} diff --git a/modules/ContactForm/Resources/views/admin/settings/form.blade.php b/modules/ContactForm/Resources/views/admin/settings/form.blade.php index d1f0ffb7..86cce457 100644 --- a/modules/ContactForm/Resources/views/admin/settings/form.blade.php +++ b/modules/ContactForm/Resources/views/admin/settings/form.blade.php @@ -1,13 +1,13 @@ reCAPTCHA \ No newline at end of file diff --git a/resources/lang/cs/admin/contents.php b/resources/lang/cs/admin/contents.php new file mode 100644 index 00000000..685e47d0 --- /dev/null +++ b/resources/lang/cs/admin/contents.php @@ -0,0 +1,4 @@ + 'Seznam všech obsahových stránek', +]; \ No newline at end of file diff --git a/resources/lang/en/admin/settings.php b/resources/lang/en/admin/settings.php index ed86914c..42d87f27 100644 --- a/resources/lang/en/admin/settings.php +++ b/resources/lang/en/admin/settings.php @@ -11,8 +11,9 @@ return [ 'successfullySaved' => 'Settings successfully saved', 'nothingToSave' => 'You have submitted unchanged form. Try to change some attribute first.', 'meta' => 'Meta information', - 'socialSites' => 'Social networks', - 'social' => [ + 'commonSettings' => 'Use for all languages?', + 'socialSites' => 'Social networks', + 'social' => [ 'facebook' => 'Facebook profile', 'instagram' => 'Instagram profile', 'twitter' => 'Twitter profile', diff --git a/resources/lang/en/common.php b/resources/lang/en/common.php new file mode 100644 index 00000000..df0cb8ab --- /dev/null +++ b/resources/lang/en/common.php @@ -0,0 +1,7 @@ + [ + 'english' => 'English', + 'czech' => 'Czech' + ] +]; \ No newline at end of file diff --git a/resources/lang/en/visitor/common.php b/resources/lang/en/visitor/common.php deleted file mode 100644 index 8522c059..00000000 --- a/resources/lang/en/visitor/common.php +++ /dev/null @@ -1,4 +0,0 @@ - 'Welcome to my page' -]; \ No newline at end of file diff --git a/resources/lang/en/widgets/menu.php b/resources/lang/en/widgets/menu.php index 4be0f927..1e228c8a 100644 --- a/resources/lang/en/widgets/menu.php +++ b/resources/lang/en/widgets/menu.php @@ -10,5 +10,6 @@ return [ 'new' => 'New menu', 'edit' => 'Edit menu', 'preview' => 'Menu preview', - 'availablePages' => 'Available pages' + 'availablePages' => 'Available pages', + 'noLinks' => 'Cannot save menu without any link!', ]; \ No newline at end of file diff --git a/resources/views/admin/layout.blade.php b/resources/views/admin/layout.blade.php index a99bb576..8e6c8aba 100644 --- a/resources/views/admin/layout.blade.php +++ b/resources/views/admin/layout.blade.php @@ -5,7 +5,7 @@ @yield('head_meta') - @yield('pageName', @trans('admin/common.admin')) | {{$pageName}} + @yield('pageName', @trans('admin/common.admin')) | {{isset($pageName) ? $pageName : ''}} @@ -17,7 +17,21 @@